Skip to content

Repository files navigation

STM32 SPL + CMake + VSCode 工程模板(以 STM32F407 为例)

项目背景

这个仓库用于把传统 Keil/SPL 工程,迁移到 VSCode + CMake + STM32CubeCLT 的现代开发流程。

目标不是只“能编译”,而是做到:

  • 工程结构清晰(应用层 / 驱动层 / 平台层分离)
  • 构建配置可追踪(参数集中、可复用、可移植)
  • 调试链路稳定(ST-Link 可重复配置)
  • 新人可按步骤上手,不依赖 IDE 向导

当前工程已在 STM32F407VG 场景下打通:可编译、可下载、可调试。


技术路线

本项目的技术路线是:

  1. 外设库路线:使用 STM32 SPL(StdPeriph),不是 HAL。
  2. 构建系统:使用 CMake + Ninja,目标产物为 .elf/.hex/.bin/.map
  3. 工具链arm-none-eabi-gcc(通过 STM32CubeCLT 提供)。
  4. 编辑与诊断:VSCode + clangd(读取 compile_commands.json)。
  5. 调试:VSCode ST-Link 调试适配器(stlinkgdbtarget)。

核心思想:
把“芯片相关参数”“源码清单”“工具链参数”“调试配置”拆开管理,迁移时只改必要点。


工程结构

  • Core/Inc, Core/Src:应用入口、中断、系统初始化、syscalls
  • HARDWARE:板级驱动(LED 等)
  • Drivers/CMSIS:内核与器件头文件
  • Drivers/SPL:SPL 外设驱动源码
  • Startup:启动文件
  • cmake:子 CMake 与工具链配置
  • STM32F40_41xxx_FLASH.ld:链接脚本
  • .vscode:VSCode 构建/调试配置
  • docs:详细流程文档

快速开始(当前工程)

1) 配置与构建

cmake --preset Debug
cmake --build --preset Debug

产物默认在 build/debug/

  • STM32Vs-try-SPL.elf
  • STM32Vs-try-SPL.hex
  • STM32Vs-try-SPL.bin
  • STM32Vs-try-SPL.map

2) 调试

直接在 VSCode 运行 STM32 ST-Link Debug (CMake) 启动配置。

本工程已固定调试关键项:

  • deviceName = STM32F407VG
  • deviceCore = Cortex-M4
  • 显式指定 gdb/serverExe/serverCwd/serverCubeProgPath

这样可以避开“自动解析 bundle 失败”的常见问题。


快速移植(从 Keil/SPL 到本模板)

下面是推荐的“最短路径”迁移步骤。

步骤 1:替换芯片启动三件套

按目标芯片替换:

  • 启动文件:Startup/startup_xxx.s
  • 系统时钟文件:Core/Src/system_stm32f4xx.c(或对应系列)
  • 链接脚本:STM32F40_41xxx_FLASH.ld(改成你的芯片容量)

步骤 2:修改宏定义(最关键)

cmake/CMakeLists.txtSPL_DEFINES 修改:

  • 芯片族宏(如 STM32F40_41xxx
  • HSE_VALUE=xxxxxxxU(与你板子晶振一致)

步骤 3:修改源码清单

cmake/CMakeLists.txt

  • APP_SOURCES:加你的业务模块(如 USART.cKEY.c
  • SPL_SOURCES:确保你用到的 SPL 驱动源码已加入

步骤 4:修改工具链参数

cmake/gcc-arm-none-eabi.cmake 确认:

  • -mcpu=...
  • -mfpu=...
  • -mfloat-abi=...
  • 链接脚本路径 -T"...ld"

步骤 5:调整链接脚本内存布局

STM32F40_41xxx_FLASH.ld 中修改:

  • FLASH 容量
  • RAM / CCMRAM 容量

并保持当前这种权限写法,避免 RWX 警告:

  • MEMORY 里 RAM 使用 (rw),不要 (xrw)
  • 只读段使用 (READONLY)

步骤 6:构建 + 调试联调

cmake --preset Debug
cmake --build --preset Debug

如果能进 main 且外设行为正确,迁移基本完成。


Keil 与本工程配置对照

Keil 位置 本工程位置
Options for Target -> C/C++ -> Define cmake/CMakeLists.txt -> SPL_DEFINES
Options for Target -> C/C++ -> Include Paths cmake/CMakeLists.txt -> SPL_INCLUDE_DIRS
工程分组中的源文件列表 cmake/CMakeLists.txt -> APP_SOURCES / SPL_SOURCES
Target 里的 CPU/FPU/ABI 相关编译参数 cmake/gcc-arm-none-eabi.cmake -> TARGET_FLAGS
Scatter / Linker Script STM32F40_41xxx_FLASH.ld + 工具链文件里的 -T
fromelf 后处理 顶层 CMakeLists.txt 里的 objcopy 后处理
调试器设备型号选择 .vscode/launch.json -> deviceName / deviceCore

常见问题(已在本工程验证)

1) Device not found: ... STM32F407VGTx

原因:deviceName 用了料号后缀。
处理:改为 CMSIS 设备名,如 STM32F407VG

2) Failed to list bundles

原因:调试插件自动按 Cube 工程解析 bundle 失败。
处理:在 launch.json 显式固定 gdb/serverExe/serverCwd/serverCubeProgPath

3) _write/_read/_close/_lseek is not implemented

原因:nosys.specs 默认桩函数会告警。
处理:保留并加入 Core/Src/syscalls.c

4) xxx.elf has a LOAD segment with RWX permissions

原因:链接脚本段权限未显式区分。
处理:按当前链接脚本写法,RAM 用 rw,只读段加 (READONLY)


进一步阅读

  • 详细流程文档:docs/VSCode_STM32_SPL_开发标准流程.md
  • 技术路线与避坑文档:docs/VSCode_STM32_SPL_技术路线与迁移避坑.md
  • 顶层构建入口:CMakeLists.txt
  • SPL 配置入口:cmake/CMakeLists.txt
  • 工具链配置:cmake/gcc-arm-none-eabi.cmake

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages