Ubuntu 22.04 下使用 CMSIS-DAP 编译和烧录 STM32 本文记录本工程在 Ubuntu 22.04 下通过 ATK ATK-HS-V3-CMSIS-DAP 烧录器编译并烧录 STM32F407ZGTx 的完整流程。当前工程信息工程目录/home/sg/aaaaMCUSTM32F407ZGT6pyOCD target 名称stm32f407zgtxCMake presetDebug编译产物/home/sg/aaaa/build/Debug/aaaa.elf烧录器ATK ATK-HS-V3-CMSIS-DAP1. 硬件连接CMSIS-DAP 和目标板至少需要连接以下信号DAP SWDIO - 目标板 SWDIO DAP SWCLK - 目标板 SWCLK DAP GND - 目标板 GND DAP VTref - 目标板 3.3V 参考电压注意目标板必须供电。DAP 和目标板必须共地。如果目标板自己供电DAP 的VTref/3V3 sense需要接到目标板 3.3V用于检测目标电压。如果连接失败可以降低 SWD 频率例如烧录时加--frequency 1000000。2. 检查工具链本工程使用 CMake Ninja arm-none-eabi-gcc 编译使用 pyOCD 烧录。各工具的作用CMake负责生成构建系统。它读取CMakeLists.txt和CMakePresets.json根据工程配置、源文件、头文件路径、编译宏、链接脚本和工具链文件生成 Ninja 可以执行的构建文件。CMake 本身通常不直接编译代码。Ninja负责实际调度编译任务。CMake 生成build.ninja后Ninja 根据依赖关系调用编译器、汇编器和链接器。Ninja 的特点是速度快、输出简洁适合嵌入式工程反复增量编译。arm-none-eabi-gccARM Cortex-M 裸机交叉编译器。它把 C 代码、启动汇编文件编译链接成 STM32 可以运行的 ELF 固件。这里的none-eabi表示目标环境不是 Linux/Windows 这类操作系统而是裸机或 RTOS 环境ABI 使用 ARM Embedded ABI。pyOCDPython 编写的 Cortex-M 调试和烧录工具。它通过 CMSIS-DAP、DAPLink、J-Link、ST-LINK 等调试探针访问目标芯片支持下载程序、擦除 flash、复位目标板、GDB 调试服务和命令行交互。本工程里的分工可以理解为CMake 读取工程配置 - Ninja 执行构建任务 - arm-none-eabi-gcc 编译链接生成 aaaa.elf - pyOCD 通过 CMSIS-DAP 把 aaaa.elf 烧录进 STM32F407检查命令command-vcmakecommand-vninjacommand-varm-none-eabi-gcccommand-vpyocd pyocd--version本机已检测到/opt/st/stm32cubeclt_1.21.0/CMake/bin/cmake /opt/st/stm32cubeclt_1.21.0/Ninja/bin/ninja /opt/st/stm32cubeclt_1.21.0/GNU-tools-for-STM32/bin/arm-none-eabi-gcc /home/sg/.local/bin/pyocd pyOCD 0.44.13. 其他可选方案本工程当前采用 CMake Ninja arm-none-eabi-gcc pyOCD这套方案适合在 Linux 命令行、脚本、CI 或 VS Code 环境中使用。除此之外还有以下常见方案。3.1 Makefile arm-none-eabi-gcc使用make直接管理编译规则不使用 CMake。特点优点简单直接依赖少很多老工程和教程都使用 Makefile。缺点大型工程里维护源文件、头文件路径、编译选项和多配置构建会比较繁琐。适合工程结构简单、手写 Makefile、只需要命令行编译的场景。典型命令makemakeclean如果要烧录仍然可以配合 pyOCDpyocd flash-tstm32f407zgtx build/firmware.elf3.2 STM32CubeIDEST 官方 Eclipse 系列 IDE集成工程管理、编译、调试和烧录。特点优点图形界面完整适合初学者和 CubeMX 集成较好对 ST-LINK 支持最好。缺点相对重工程文件较多自动生成配置较强命令行自动化不如 CMake 直接。适合主要使用 ST-LINK、希望图形化调试、偏向官方 IDE 工作流的场景。常见流程导入 .ioc 或 STM32 工程 - Build - Debug/Run - 通过 ST-LINK 烧录和调试注意STM32CubeIDE 对 ST-LINK 支持最好。普通 CMSIS-DAP 是否能直接用于 CubeIDE 调试取决于插件和调试后端配置通常不如 pyOCD/OpenOCD 直接。3.3 STM32CubeCLTST 官方命令行工具包包含 CMake、Ninja、GNU Arm 工具链、STM32CubeProgrammer CLI 等。本机使用的 CMake、Ninja 和 arm-none-eabi-gcc 就来自 STM32CubeCLT/opt/st/stm32cubeclt_1.21.0/特点优点官方提供组件比较完整适合 Linux 命令行和 CI。缺点STM32CubeProgrammer 的 SWD/JTAG 主要面向 ST-LINK/J-LINK 等支持的接口普通 CMSIS-DAP 烧录 STM32 时不一定比 pyOCD 方便。使用 STM32CubeProgrammer CLI 通过 ST-LINK 烧录的典型命令STM32_Programmer_CLI-cportSWD-wbuild/Debug/aaaa.elf-v-rst如果使用的不是 ST-LINK而是 CMSIS-DAP本工程更推荐 pyOCD。3.4 OpenOCDOpenOCD 是常见的开源片上调试工具支持多种调试器和芯片。特点优点生态成熟GDB 调试常用支持 CMSIS-DAP、ST-LINK、J-Link、FTDI 等多种接口。缺点配置文件组合较多不同发行版自带版本可能偏旧遇到具体探针兼容性时需要调试配置。适合需要 GDB server、自动化烧录、非 pyOCD 支持目标、复杂调试配置的场景。如果系统安装了 OpenOCD并且有对应配置文件可用类似命令openocd\-finterface/cmsis-dap.cfg\-ftarget/stm32f4x.cfg\-cprogram build/Debug/aaaa.elf verify reset exit本次机器上没有检测到openocd命令所以本次没有采用该方案。3.5 J-Link JLinkExe/JFlash如果使用 SEGGER J-Link 调试器可以使用 SEGGER 官方工具。特点优点速度快、稳定性好、商业工具链支持广。缺点需要 J-Link 硬件部分场景涉及授权要求。适合长期调试、量产测试、对烧录速度和稳定性要求较高的场景。典型方式是写一个 J-Link command file然后执行JLinkExe-deviceSTM32F407ZG-ifSWD-speed4000-CommanderScriptflash.jlink示例flash.jlink内容connect loadfile build/Debug/aaaa.elf r g exit3.6 ST-LINK STM32CubeProgrammer如果使用 ST-LINK/V2、ST-LINK/V3 或 Nucleo/Discovery 板载 ST-LINK可以直接用 STM32CubeProgrammer。特点优点ST 官方支持识别 STM32 最完整图形界面和命令行都可用。缺点需要 ST-LINK 硬件不适用于所有 CMSIS-DAP 探针。命令行烧录STM32_Programmer_CLI-cportSWDfreq4000-wbuild/Debug/aaaa.elf-v-rst3.7 通过系统 Bootloader 烧录STM32F407 内置系统 Bootloader可通过 UART、USB DFU 等方式烧录具体取决于 BOOT0/BOOT1 启动配置和芯片支持的接口。特点优点不需要 SWD 调试器适合只做固件下载。缺点需要控制 BOOT0 进入系统 Bootloader不能像 SWD 一样方便调试接口和流程受硬件设计影响。UART Bootloader 可配合 STM32CubeProgrammerSTM32_Programmer_CLI-cport/dev/ttyUSB0br115200-wbuild/Debug/aaaa.elf-vUSB DFU Bootloader 可用STM32_Programmer_CLI-cportUSB1-wbuild/Debug/aaaa.elf-v也可以使用开源工具例如dfu-util但需要先生成或转换成合适格式。3.8 方案选择建议本工程目前最合适的路线CMake Ninja arm-none-eabi-gcc pyOCD CMSIS-DAP原因当前工程已经是 CMake 工程。当前烧录器已经被识别为 CMSIS-DAP。pyOCD 安装 STM32F4 pack 后已经成功烧录。全流程可以命令行自动化适合反复编译和烧录。如果以后更换硬件可以按下面选择使用 CMSIS-DAP优先 pyOCD其次 OpenOCD。使用 ST-LINK优先 STM32CubeProgrammer 或 STM32CubeIDE也可以用 OpenOCD。使用 J-Link优先 J-Link 官方工具也可以用 pyOCD/OpenOCD。没有调试器考虑 STM32 系统 Bootloader通过 UART 或 USB DFU 烧录。4. 检查 USB 烧录器查看 USB 设备lsusb能看到类似设备即可Bus 003 Device 002: ID 04d8:00df Microchip Technology, Inc. ATK-HS-V3-CMSIS-DAP使用 pyOCD 查看探针pyocd list正常情况下会看到# Probe/Board Unique ID Target ------------------------------------------------------- 0 ATK ATK-HS-V3-CMSIS-DAP ATK 20190528 n/a这里Target显示n/a不一定是错误。它表示 pyOCD 没有自动识别目标 MCU后续烧录时手动指定-t stm32f407zgtx即可。5. 确认工程 MCU 型号查看.ioc文件中的 MCU 信息rg-nMcu\\.CPN|Mcu\\.Name|Mcu\\.UserName|ProjectManager\\.DeviceIdaaaa.ioc本工程结果Mcu.CPNSTM32F407ZGT6 Mcu.NameSTM32F407Z(E-G)Tx Mcu.UserNameSTM32F407ZGTx ProjectManager.DeviceIdSTM32F407ZGTx所以 pyOCD target 应使用stm32f407zgtx6. 编译工程进入工程目录cd/home/sg/aaaa配置 CMakecmake--presetDebug编译cmake--build--presetDebug本次编译成功后的关键信息[22/22] Linking C executable aaaa.elf Memory region Used Size Region Size %age Used RAM: 1584 B 128 KB 1.21% CCMRAM: 0 B 64 KB 0.00% FLASH: 4820 B 1 MB 0.46%检查产物findbuild/Debug-maxdepth2-typef\(-name*.elf-o-name*.hex-o-name*.bin-o-name*.map\)-print本工程生成build/Debug/aaaa.elf build/Debug/aaaa.map7. 安装 STM32F4 pyOCD 支持包pyOCD 默认不一定内置所有 STM32 型号。本机最初执行pyocd flash-tstm32f407zg /home/sg/aaaa/build/Debug/aaaa.elf报错Target type stm32f407zg not recognized.因此需要安装 STM32F4 的 DFP pack。安装命令pyocd packinstallSTM32F407ZG第一次执行时pyOCD 会先下载 pack 索引No pack index present, downloading now... Downloading descriptors (1768/1768) Downloading packs: Keil.STM32F4xx_DFP.3.1.1安装完成后查看已安装 packpyocd pack show正常结果Pack Version -------------------------------- Keil.STM32F4xx_DFP 3.1.1查询 STM32F407 目标名称pyocd list--targets|rg-istm32f407zg|stm32f407能看到stm32f407zg STMicroelectronics STM32F407ZG STM32F4 Series, STM32F407 pack stm32f407zgtx STMicroelectronics STM32F407ZGTx STM32F4 Series, STM32F407 pack本工程使用STM32F407ZGTx所以烧录时使用-t stm32f407zgtx8. 烧录固件烧录当前 Debug ELFpyocd flash-tstm32f407zgtx /home/sg/aaaa/build/Debug/aaaa.elf本次成功输出Loading /home/sg/aaaa/build/Debug/aaaa.elf Erasing... Programming... Erased 16384 bytes (1 sector), programmed 5120 bytes (5 pages), skipped 0 bytes (0 pages)烧录完成后复位目标板pyocd reset-tstm32f407zgtx9. 全流程命令汇总如果环境已经配置好、pack 已安装可以直接执行cd/home/sg/aaaa cmake--presetDebug cmake--build--presetDebug pyocd flash-tstm32f407zgtx /home/sg/aaaa/build/Debug/aaaa.elf pyocd reset-tstm32f407zgtx如果是第一次在这台机器上烧录 STM32F407需要先执行pyocd packinstallSTM32F407ZG完整首次流程cd/home/sg/aaaa# 检查工具command-vcmakecommand-vninjacommand-varm-none-eabi-gcccommand-vpyocd pyocd--version# 检查 DAPlsusb pyocd list# 安装 STM32F4 支持包pyocd packinstallSTM32F407ZG pyocd pack show pyocd list--targets|rg-istm32f407zg|stm32f407# 编译cmake--presetDebug cmake--build--presetDebug# 烧录并复位pyocd flash-tstm32f407zgtx /home/sg/aaaa/build/Debug/aaaa.elf pyocd reset-tstm32f407zgtx10. 常见问题10.1pyocd list能看到 DAP但 Target 是n/a这是常见现象。CMSIS-DAP 被识别了但 pyOCD 没有自动识别目标芯片。解决方式烧录时手动指定 target。pyocd flash-tstm32f407zgtx /home/sg/aaaa/build/Debug/aaaa.elf10.2Target type ... not recognized说明 pyOCD 没有对应芯片支持包。安装 packpyocd packinstallSTM32F407ZG然后确认pyocd list--targets|rg-istm32f407zg|stm32f40710.3 无法访问 USB 或需要权限如果普通用户执行pyocd list或lsusb出现 USB 权限问题可以临时使用sudo测试sudopyocd listsudopyocd flash-tstm32f407zgtx /home/sg/aaaa/build/Debug/aaaa.elf长期建议配置 udev 规则让普通用户可以访问 CMSIS-DAP。10.4 连接目标失败检查以下项目目标板是否供电。DAP 和目标板是否共地。SWDIO和SWCLK是否接反。是否连接了目标板 3.3V 到 DAP 的VTref。目标芯片是否被其他调试器占用。尝试降低 SWD 频率pyocd flash-tstm32f407zgtx--frequency1000000/home/sg/aaaa/build/Debug/aaaa.elf10.5 编译失败先确认 CMake preset 是否存在cmake --list-presets再重新配置和编译cmake--presetDebug cmake--build--presetDebug如果工具链找不到检查 STM32CubeCLT 或 arm-none-eabi-gcc 是否安装并加入PATH。11. 本次实际执行记录本次执行过的关键命令cd/home/sg/aaaa cmake--presetDebug cmake--build--presetDebug lsusb pyocd list pyocd packinstallSTM32F407ZG pyocd pack show pyocd list--targets|rg-istm32f407zg|stm32f407pyocd flash-tstm32f407zgtx /home/sg/aaaa/build/Debug/aaaa.elf pyocd reset-tstm32f407zgtx最终结果编译成功。 烧录成功。 已擦除 16384 bytes。 已写入 5120 bytes。 目标板已复位。