1. 引言
STM32CubeMX 是 ST 官方提供的图形化配置工具,可以快速完成引脚、时钟和外设的初始化配置,并生成工程代码。默认情况下,CubeMX 会生成基于 Keil、IAR 或 Makefile 的工程,但很多开发者更习惯使用 VSCode 配合 CMake 进行跨平台编译和调试。本文将详细介绍如何用 STM32CubeMX 生成 CMake 工程,并在 VSCode 中完成编译与调试的完整流程。
2. 准备工作
在开始之前,需要先安装以下软件和工具:
- STM32CubeMX:用于图形化配置芯片并生成工程代码。
- STM32Cube 固件包:在 CubeMX 中下载对应芯片系列的固件库。
- VSCode:代码编辑与调试工具。
- CMake:跨平台构建工具,负责生成构建系统。
- Ninja:轻量级构建系统,配合 CMake 使用可加快编译速度。
- ARM 交叉编译工具链:如 arm-none-eabi-gcc,用于编译 ARM 目标代码。
- OpenOCD:开源调试工具,配合 ST-Link 等调试器使用。
- VSCode 扩展:C/C++ 扩展、CMake Tools 扩展、Cortex-Debug 扩展。
3. 在 CubeMX 中配置工程
打开 STM32CubeMX,选择目标芯片或开发板,完成时钟、引脚和外设的配置后,进入工程生成设置。
在 Project Manager 页面中,需要重点关注以下设置:
- Toolchain / IDE:选择 CMake,这样 CubeMX 会生成 CMakeLists.txt 文件。
- Project Name:填写工程名称,注意不要包含中文和空格。
- Project Location:选择工程保存路径。
- Code Generator:建议勾选 "Generate peripheral initialization as a pair of .c/.h files per peripheral",这样每个外设会生成独立的源文件和头文件,便于管理。
设置完成后,点击右上角的 Generate Code 按钮,CubeMX 会生成包含 CMakeLists.txt 的完整工程结构。
4. 工程目录结构
生成后的工程目录大致如下:
bash
my_project/
├── CMakeLists.txt
├── Core/
│ ├── Inc/
│ └── Src/
├── Drivers/
│ ├── CMSIS/
│ └── STM32F4xx_HAL_Driver/
└── build/
其中 CMakeLists.txt 是构建系统的核心文件,Core 目录存放用户代码,Drivers 目录存放 HAL 库和 CMSIS 文件。
5. 配置 CMake 工具链
为了让 CMake 使用 ARM 交叉编译工具链,需要创建一个工具链文件。在工程根目录下新建一个名为 arm-none-eabi-gcc.cmake 的文件,内容如下:
cmake
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(TOOLCHAIN_PREFIX arm-none-eabi-)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_OBJDUMP ${TOOLCHAIN_PREFIX}objdump)
set(CMAKE_SIZE ${TOOLCHAIN_PREFIX}size)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
这个文件告诉 CMake 使用 arm-none-eabi 工具链进行交叉编译,并避免在编译测试时尝试链接可执行文件。
6. 在 VSCode 中配置构建
用 VSCode 打开工程根目录,安装 CMake Tools 扩展后,需要创建 .vscode/settings.json 文件,指定 CMake 工具链和构建目录:
json
{
"cmake.configureOnOpen": true,
"cmake.generator": "Ninja",
"cmake.toolchainFile": "${workspaceFolder}/arm-none-eabi-gcc.cmake",
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.buildArgs": ["--", "-j8"]
}
配置完成后,点击 VSCode 底部的 CMake 状态栏按钮,选择 "Build" 即可开始编译。编译生成的 .elf、.bin 和 .hex 文件会存放在 build 目录下。
7. 配置调试环境
调试需要 OpenOCD 和 Cortex-Debug 扩展配合。首先创建 .vscode/launch.json 文件,配置调试器连接参数:
json
{
"version": "0.2.0",
"configurations": [
{
"name": "STM32 Debug",
"type": "cortex-debug",
"request": "launch",
"servertype": "openocd",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/my_project.elf",
"device": "STM32F407VG",
"configFiles": [
"interface/stlink.cfg",
"target/stm32f4x.cfg"
],
"svdFile": "${workspaceFolder}/STM32F407.svd"
}
]
}
其中 executable 指向编译生成的 .elf 文件,configFiles 指定 OpenOCD 的接口和芯片配置文件,svdFile 用于在调试时显示外设寄存器。
8. 编译与调试实操
完成上述配置后,就可以在 VSCode 中进行编译和调试了。
**编译操作:**点击 VSCode 底部状态栏的 Build 按钮,或按快捷键 Ctrl+Shift+B,CMake Tools 会自动调用 Ninja 进行编译。编译完成后,可以在终端看到生成的 .elf 文件路径。
**调试操作:**将 ST-Link 调试器连接到开发板,点击 VSCode 左侧的 Run and Debug 图标,选择 "STM32 Debug" 配置,点击开始调试按钮。Cortex-Debug 会自动启动 OpenOCD,连接目标板并加载固件,随后进入断点调试模式。
在调试过程中,可以设置断点、单步执行、查看变量值和外设寄存器,极大方便了嵌入式开发。
9. 常见问题与解决
- 编译时报找不到头文件:检查 CMakeLists.txt 中的 include 路径是否正确,确认 Core/Inc 和 Drivers 目录已包含。
- 链接时报 undefined reference:检查是否遗漏了启动文件和链接脚本,确认 CMakeLists.txt 中已添加 startup 文件和 .ld 链接脚本。
- OpenOCD 连接失败:检查 ST-Link 驱动是否安装,确认 launch.json 中的 configFiles 路径正确。
- 调试时无法命中断点:确认编译时开启了调试信息,即 CMake 构建类型为 Debug。
10. 总结
通过 STM32CubeMX 生成 CMake 工程,再配合 VSCode 的 CMake Tools 和 Cortex-Debug 扩展,可以搭建一套完全免费、跨平台的嵌入式开发环境。这套流程不仅适用于 STM32,也适用于其他支持 GCC 和 OpenOCD 的 ARM 芯片,值得开发者掌握。