以下介紹PY32F0系列在Ubuntu下如何使用GCC Arm Embedded Toolchain環境進行開發和燒錄. GitHub 倉庫地址: https://github.com/IOsetting/py32f0-template ...
目錄
- 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU簡介
- 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode開發環境
- 普冉PY32系列(三) PY32F002A資源實測 - 這個型號不簡單
以下介紹PY32F0系列在Ubuntu下如何使用GCC Arm Embedded Toolchain環境進行開發和燒錄
項目模板
GitHub 倉庫地址: https://github.com/IOsetting/py32f0-template
倉庫文件結構
├── Build # 編譯結果
├── Docs # 數據手冊和用戶手冊
├── Examples
│ ├── FreeRTOS # FreeRTOS 例子(暫時為空)
│ ├── Raw # 非 FreeRTOS 的例子
│ └── Raw_LL # 非 FreeRTOS 的例子, 基於LL外設庫
├── Libraries
│ ├── BSP # delay 和 printf 的 BSP 庫
│ ├── BSP_LL # delay 和 printf 的 BSP 庫, 基於LL外設庫
│ ├── CMSIS
│ ├── LDScripts # 鏈接描述文件
│ ├── PY32F0xx_HAL_Driver # 外設驅動庫
│ └── PY32F0xx_LL_Driver # LL(low layer)外設驅動庫
├── Makefile # Make設置
├── Misc
│ ├── Flash
│ │ ├── Devices # 全系列 Flash 演算法文件
│ │ └── Sources # Flash 演算法文件源代碼
│ └── SVD # SVD 文件, 用於 Debug
├── README.md
├── rules.mk # 預置的 make 規則
└── User # 用戶項目代碼目錄
環境準備
硬體方面
- PY32F0 開發板, 或任何基於 PY32F002/003/030 系列的電路
- 燒錄工具(任一)
- J-Link: J-Link OB programmer
- PyOCD: DAPLink or J-Link
註: STLink測試不成功, 寫入會有Timeout錯誤
軟體方面
- SEGGER J-Link 軟體 https://www.segger.com/downloads/jlink/
- 或者 PyOCD https://pyocd.io/
- GNU Arm Embedded Toolchain
環境配置和編譯過程
1. 安裝 GNU Arm Embedded Toolchain
根據你的PC架構, 從 Arm GNU Toolchain Downloads 下載工具鏈, 然後解壓文件到合適的目錄下, 例如
sudo mkdir -p /opt/gcc-arm/
sudo tar xvf arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi.tar.xz -C /opt/gcc-arm/
cd /opt/gcc-arm/
sudo chown -R root:root arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/
2. (選項一) 安裝 SEGGER J-Link
從 J-Link / J-Trace Downloads 下載並安裝 SEGGER JLink
# installation command for .deb
sudo dpkg -i JLink_Linux_V770a_x86_64.deb
預設的安裝路徑是 /opt/SEGGER
將目錄 [項目目錄]/Misc/Flash/Devices/Puya 下的所有Flash演算法文件(.FLM 文件), 複製到 [JLink 安裝目錄]/Devices/Puya 目錄下
cd py32f0-template
sudo cp -r Misc/Flash/Devices/* /opt/SEGGER/JLink/Devices/
編輯 JLinkDevices.xml
sudo vi /opt/SEGGER/JLink/JLinkDevices.xml
在 <DataBase>
中增加以下內容
<!-- -->
<!-- Puya -->
<!-- -->
<Device>
<ChipInfo Vendor="Puya" Name="PY32F002AX5" WorkRAMAddr="0x20000000" WorkRAMSize="0xC00" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_20K" BaseAddr="0x08000000" MaxSize="0x5000" Loader="Devices/Puya/PY32F0xx_20.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F002X5" WorkRAMAddr="0x20000000" WorkRAMSize="0xC00" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_20K" BaseAddr="0x08000000" MaxSize="0x5000" Loader="Devices/Puya/PY32F0xx_20.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F003X4" WorkRAMAddr="0x20000000" WorkRAMSize="0x800" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_16K" BaseAddr="0x08000000" MaxSize="0x4000" Loader="Devices/Puya/PY32F003xx_16.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F003X6" WorkRAMAddr="0x20000000" WorkRAMSize="0x1000" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_32K" BaseAddr="0x08000000" MaxSize="0x8000" Loader="Devices/Puya/PY32F003xx_32.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F003X8" WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_64K" BaseAddr="0x08000000" MaxSize="0x10000" Loader="Devices/Puya/PY32F003xx_64.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F030X4" WorkRAMAddr="0x20000000" WorkRAMSize="0x800" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_16K" BaseAddr="0x08000000" MaxSize="0x4000" Loader="Devices/Puya/PY32F030xx_16.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F030X6" WorkRAMAddr="0x20000000" WorkRAMSize="0x1000" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_32K" BaseAddr="0x08000000" MaxSize="0x8000" Loader="Devices/Puya/PY32F030xx_32.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F030X7" WorkRAMAddr="0x20000000" WorkRAMSize="0x1800" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_48K" BaseAddr="0x08000000" MaxSize="0xC000" Loader="Devices/Puya/PY32F030xx_48.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
<Device>
<ChipInfo Vendor="Puya" Name="PY32F030X8" WorkRAMAddr="0x20000000" WorkRAMSize="0x2000" Core="JLINK_CORE_CORTEX_M0"/>
<FlashBankInfo Name="Flash_64K" BaseAddr="0x08000000" MaxSize="0x10000" Loader="Devices/Puya/PY32F030xx_64.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>
2. (選項二): 安裝 PyOCD
不要使用Ubuntu自帶的apt倉庫里的PyOCD, 這個版本 0.13.1+dfsg-1 太低, 無法識別 JLink OB
從Pip安裝PyOCD
pip uninstall pyocd
這樣會將 PyOCD 安裝到這些目錄
/home/[user]/.local/bin/pyocd
/home/[user]/.local/bin/pyocd-gdbserver
/home/[user]/.local/lib/python3.10/site-packages/pyocd-0.34.2.dist-info/*
/home/[user]/.local/lib/python3.10/site-packages/pyocd/*
在 Ubuntu 中, .profile 會自動把 .local 加入 PATH, 所以只需要執行一下 source ~/.profile
就能用 pyocd 命令了
3. 導出這個模板倉庫
Clone到本地目錄下
git clone https://github.com/IOsetting/py32f0-template.git
4. 修改 Makefile
根據自己本地環境, 修改Makefile
- 確認 ARM_TOOCHAIN 指向的是正確的 arm-none-eabi-gcc 路徑
- 如果使用 J-Link, FLASH_PROGRM 可以用 jlink 或 pyocd
- 如果使用 DAPLink, 要把 FLASH_PROGRM 設為 pyocd
- ST-LINK 還不支持. ST-LINK 在 Windows Keil5 下可以使用, 但是在 Ubuntu 燒錄 PY32 會報錯
- Puya 提供了兩套外設驅動庫, HAL lib 和 LL lib, 可以在 USE_LL_LIB 選項中切換, 預設的 User 應用使用的是 HAL 庫
- ENABLE_PRINTF_FLOAT 用於對 printf 中的
%f
增加支持, 會在連接參數中增加-u _printf_float
, 會大大增加最後生成的燒錄文件尺寸.
##### Project #####
PROJECT ?= app
# The path for generated files
BUILD_DIR = Build
##### Options #####
# 是否使用 LL 庫
USE_LL_LIB ?= y
# 是否啟用 printf float %f 支持, y:yes, n:no
ENABLE_PRINTF_FLOAT ?= n
# 是否使用 CMSIS DSP 函數, y:yes, n:no
USE_DSP ?= n
# 編程器選擇, jlink 或 pyocd
FLASH_PROGRM ?= pyocd
##### Toolchains #######
ARM_TOOCHAIN ?= /opt/gcc-arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin
# JLinkExe 的路徑
JLINKEXE ?= /opt/SEGGER/JLink/JLinkExe
# JLink 設備類型, 選項:
# PY32F002AX5, PY32F002X5,
# PY32F003X4, PY32F003X6, PY32F003X8,
# PY32F030X4, PY32F030X6, PY32F030X7, PY32F030X8
JLINK_DEVICE ?= PY32F003X8
# PyOCD 路徑
PYOCD_EXE ?= pyocd
# PyOCD 設備類型, 選項:
# py32f002ax5, py32f002x5,
# py32f003x4, py32f003x6, py32f003x8,
# py32f030x3, py32f030x4, py32f030x6, py32f030x7, py32f030x8
# py32f072xb
PYOCD_DEVICE ?= py32f003x8
##### Paths ############
# Link descript file: py32f003x6.ld, py32f003x8.ld, py32f030x6.ld, py32f030x8.ld
LDSCRIPT = Libraries/LDScripts/py32f003x8.ld
# Library 編譯附加參數:
# PY32F002x5, PY32F002Ax5,
# PY32F003x4, PY32F003x6, PY32F003x8,
# PY32F030x3, PY32F030x4, PY32F030x6, PY32F030x7, PY32F030x8,
# PY32F072xB
LIB_FLAGS = PY32F003x8
5. 編譯和燒錄
編譯執行
# clean source code
make clean
# build
make
# or make with verbose output
V=1 make
寫入, 會根據前面的配置調用對應的燒錄方法
# flash
make flash
這個例子會展示
- 驅動 PB5 上的LED燈亮滅, 如果你使用的型號不帶 PB5 pin, 需要修改一下 main.c, 換成其它的pin.
- PA2, PA3 通過UART輸出
echo
字元串, 需要接在 USB2TTL 上通過PC端串口軟體查看, Ubuntu下可以用 Screen 或 CuteCOM 等軟體
嘗試其它例子
在 Examples 目錄下有更多的代碼示例, 可以複製替換掉 User 目錄下的文件, 然後編譯燒錄查看運行效果
配置 VSCode 開發環境
安裝好 VSCode 的 c/cpp 擴展後, 直接打開項目所在目錄就好了, 代碼高亮, 倉庫方法都是可用的, 需要的額外配置一個是c/cpp配置, 另一個是task
C/C++配置
Ctrl+Shift+P調出快捷菜單, 在裡面選擇 C/C++ Edit Configurations(JSON), 會創建對應的初始化配置, 然後根據自己的環境修改, 以下是我用的環境. 如果換了不同型號的晶元, defines 裡面的參數也要跟著換
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/User/**",
"${workspaceFolder}/Libraries/CMSIS/Include",
"/opt/gcc-arm/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/arm-none-eabi/include",
"/opt/gcc-arm/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/lib/gcc/arm-none-eabi/12.2.0/include"
],
"defines": [
"PY32F002Ax5"
],
"compilerPath": "/opt/gcc-arm/arm-gnu-toolchain-12.2.mpacbti-bet1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc",
"cStandard": "gnu99",
"cppStandard": "gnu++14",
"intelliSenseMode": "gcc-arm",
"configurationProvider": "ms-vscode.makefile-tools"
}
],
"version": 4
}
Task 配置
同樣喚出快捷菜單後, 在Task中創建預設模板進行配置, 我使用的tasks.json內容為
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "clean, build",
"type": "shell",
"command": "make clean;make",
"problemMatcher": []
},
{
"label": "build, download",
"type": "shell",
"command": "make;make flash",
"problemMatcher": []
},
{
"label": "download",
"type": "shell",
"command": "make flash",
"problemMatcher": []
},
{
"label": "build",
"type": "shell",
"command": "make",
"problemMatcher": []
},
{
"label": "clean",
"type": "shell",
"command": "make clean",
"problemMatcher": []
}
]
}
用 Shift + Alt + F10 調出 Task 菜單, 選擇對應的條目進行編譯或燒錄