普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境
目录
- 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介
- 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境
- 普冉PY32系列(三) PY32F002A资源实测 - 这个型号不简单
- 普冉PY32系列(四) PY32F002A/003/030的时钟设置
- 普冉PY32系列(五) 使用JLink RTT代替串口输出日志
- 普冉PY32系列(六) 通过I2C接口驱动PCF8574扩展的1602LCD
以下介绍PY32F0系列在Ubuntu下如何使用GCC Arm Embedded Toolchain环境进行开发和烧录
项目模板
GitHub 仓库地址: https://github.com/IOsetting/py32f0-template
仓库文件结构
├── Build # 编译结果
├── Docs # 数据手册和用户手册
├── Examples
│ ├── FreeRTOS # FreeRTOS 例子
│ ├── HAL # 非 FreeRTOS 的例子, 基于HAL外设库
│ └── LL # 非 FreeRTOS 的例子, 基于LL外设库
├── Libraries
│ ├── BSP # delay 和 printf 的 BSP 库, 用于 HAL外设库
│ ├── BSP_LL # delay 和 printf 的 BSP 库, 用于 LL外设库
│ ├── CMSIS
│ ├── FreeRTOS # FreeRTOS library
│ ├── LDScripts # 编译连接描述文件
│ ├── PY32F0xx_HAL_Driver # HAL 外设驱动库
│ └── PY32F0xx_LL_Driver # LL(low layer)外设驱动库
├── Makefile # Make设置
├── Misc
│ ├── Flash
│ │ ├── JLinkDevices # JLink Flash 算法文件
│ │ └── Sources # Flash 算法文件源代码
│ ├── Puya.PY32F0xx_DFP.x.pack # DFP pack文件, 用于 PyOCD 烧录
│ └── 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_V784f_x86_64.deb
# uncompression command for .tar.gz
sudo tar xvf JLink_Linux_V784f_x86_64.tgz -C [target folder]
默认的安装路径是 /opt/SEGGER
将目录 [项目目录]/Misc/Flash/JLinkDevices 复制到 [User home]/.config/SEGGER/JLinkDevices/ 目录下, 对于最新版本 V7.67之后的 JLink, 不再需要单独编辑 JLinkDevices.xml 了
cd py32f0-template
cp -r Misc/Flash/JLinkDevices/ ~/.config/SEGGER/
关于如果给JLink配置新型号的芯片: https://wiki.segger.com/J-Link_Device_Support_Kit
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
- USE_LL_LIB 普冉的开发包中提供了两套外设驱动库, HAL 和 LL, 设置
USE_LL_LIB ?= y
就会切换到LL. - ENABLE_PRINTF_FLOAT 设置为
y
会在编译中添加-u _printf_float
参数, 这样可以支持 printf 打印浮点数, 但是这也会增加最后固件的大小. - USE_FREERTOS 设置
USE_FREERTOS ?= y
用于在项目中包含 FreeRTOS - USE_DSP 在项目中包含 CMSIS DSP
- FLASH_PROGRM
- 如果用 J-Link, FLASH_PROGRM 可以设为 jlink 或 pyocd
- 如果用的是 DAPLink, 设为
FLASH_PROGRM ?= pyocd
- ST-LINK 暂时还不支持, 等能解决问题的大佬出手
- ARM_TOOCHAIN 确认这个指向了正确的 arm-none-eabi-gcc 所在路径
##### Project #####
PROJECT ?= app
# The path for generated files
BUILD_DIR = Build
##### Options #####
# Use LL library instead of HAL, y:yes, n:no
USE_LL_LIB ?= n
# Enable printf float %f support, y:yes, n:no
ENABLE_PRINTF_FLOAT ?= n
# Build with FreeRTOS, y:yes, n:no
USE_FREERTOS ?= n
# Build with CMSIS DSP functions, y:yes, n:no
USE_DSP ?= n
# Programmer, jlink or pyocd
FLASH_PROGRM ?= pyocd
##### Toolchains #######
ARM_TOOCHAIN ?= /opt/gcc-arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin
# path to JLinkExe
JLINKEXE ?= /opt/SEGGER/JLink/JLinkExe
# JLink device type, options:
# PY32F002AX5, PY32F002X5,
# PY32F003X4, PY32F003X6, PY32F003X8,
# PY32F030X4, PY32F030X6, PY32F030X7, PY32F030X8
JLINK_DEVICE ?= PY32F030X6
# path to PyOCD,
PYOCD_EXE ?= pyocd
# PyOCD device type, options:
# py32f002ax5, py32f002x5,
# py32f003x4, py32f003x6, py32f003x8,
# py32f030x3, py32f030x4, py32f030x6, py32f030x7, py32f030x8
# py32f072xb
PYOCD_DEVICE ?= py32f030x8
##### Paths ############
# Link descript file: py32f002x5.ld, py32f003x6.ld, py32f003x8.ld, py32f030x6.ld, py32f030x8.ld
LDSCRIPT = Libraries/LDScripts/py32f030x8.ld
# Library build flags:
# PY32F002x5, PY32F002Ax5,
# PY32F003x4, PY32F003x6, PY32F003x8,
# PY32F030x3, PY32F030x4, PY32F030x6, PY32F030x7, PY32F030x8,
# PY32F072xB
LIB_FLAGS = PY32F030x6
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 菜单, 选择对应的条目进行编译或烧录
Debug 配置
在VSCode中安装 Cortex Debug 扩展后, 在 launch.json 中新增一个运行配置, 例如
{
"armToolchainPath": "/opt/gcc-arm/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin/",
"toolchainPrefix": "arm-none-eabi",
"name": "Cortex Debug",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/Build/app.elf",
"request": "launch", // can be launch or attach
"type": "cortex-debug",
"runToEntryPoint": "Reset_Handler", // "main" or other function name. runToMain is deprecated
"servertype": "jlink", // jlink, openocd, pyocd, pe and stutil
"device": "PY32F030X8",
"interface": "swd",
"preLaunchTask": "build", // Set this to run a task from tasks.json before starting a debug session
// "preLaunchCommands": ["Build all"], // Uncomment this if not using preLaunchTask
"svdFile": "${workspaceFolder}/Misc/SVD/py32f030xx.svd", // svd for this part number
"showDevDebugOutput": "vscode", // parsed, raw, vscode:vscode log and raw
"swoConfig":
{
"enabled": true,
"cpuFrequency": 8000000, // Target CPU frequency in Hz
"swoFrequency": 4000000,
"source": "probe", // either be “probe” to get directly from the debug probe,
// or a serial port device to use a serial port external to the debug probe.
"decoders":
[
{
"label": "ITM port 0 output",
"type": "console",
"port": 0,
"showOnStartup": true,
"encoding": "ascii"
}
]
}
}
如果 Cortex Debug 无法找到 JLinkGDBServerCLExe, 可以在 settings.json 中增加以下的配置
"cortex-debug.JLinkGDBServerPath": "/opt/SEGGER/JLink/JLinkGDBServerCLExe",