基于 VSCode + PlatformIO IDE + STM32CubeMX 的现代 STM32 工具

介绍现代化的 STM32 开发工具链,包括 VSCode、PlatformIO IDE 和 STM32CubeMX 的安装配置与使用方法

建议的工具

  • VSCode
  • VSCode 插件 Platform IDE
  • 良好的科学上网环境
  • STM32CubeMX
  • 基于 STM32G474RE 的 Nucleo G474RE 开发板
  • 有 8051 如 STC89C52RC 的一点基础

安装

首先在 VSCode 内装载 Platform IDE 插件,注意科学上网环境,会下载 PlatformIO Core 以及相关组件在 C:\Users\"你的用户名字",即个人文件夹下,等待完成后能够显示出如下 PIO Home,若未显示,请点击左侧 Quick Access -> PIO Home -> Open 以打开,该页面基于本地服务,即 localhost 下的端口服务,所以请务必检查可能的冲突,如来自 WSL 或 Hyper-V 等服务的自动保留端口与 PIO 的服务端口(好像是 3030)是否有冲突,具体可通过命令查询,不在此赘述,可搜索相关案例以及参考:

【问题解决】我遇到并解决PlatformIO无法使用的各种问题汇总及解决方法,简单粗暴使用的网络问题解决方法…_51CTO博客_platformio 调试

同时官方文档也能提供帮助:Your Gateway to Embedded Software Development Excellence — PlatformIO latest documentation

访问官方指南可得到更为详细的介绍:PlatformIO IDE for VSCode — PlatformIO 最新文档

安装完成界面
安装完成界面

项目构建

项目构建有两种方式,其一为直接使用 PIO 自带进行 New Project,该方式无需设定时钟树和外板载外设,均由官方预置,对相当一部分板子做了适配;其二为 STM32CubeMX 选择 CMake/Makefile 编译来创建通用工程,由命令行导入,也需要对 PIO 方面进行配置。优点是可以自由配置时钟和外设,但是需要对 PIO 进行修改。对于前期而言,可直接采用 PIO 预置,两种都会说到。

PIO 新建项目

点击 New Project 选择对应板型号,创建即可,该过程首次会下载数据,注意网络环境

创建 PIO 项目
创建 PIO 项目

其中 Framework 一项需选择 STM32Cube 以使用板载 ST-Link 进行连接,默认位置 default location 在默认的 Documents/PlatformIO 即"文档"文件夹下

默认文件夹架构如下

其中 .pio.vscode 分别放置 PIO 与 VSCode 相关驱动文件,includelibsrctest 分别存放自定义头文件、项目资源/驱动/库、项目代码文件、自动测试脚本

.pio 由PlatformIO自动生成和管理,它存放着编译过程中产生的所有中间文件(.o 文件)、最终生成的固件(firmware.elf, firmware.bin),以及为本项目下载的工具链和框架源码

.vscode 配置了 PIO 与 VSCode 的集成部分,包括调试与 IntelliSense 的集成等,后者为代码补全显示引用等诸多现代 IDE 功能的必要组成

test 文件夹用于存放自动化脚本,假设您写了一个复杂的函数,用来解析GPS模块发来的一长串NMEA数据。您怎么能确定这个函数在各种正常和异常情况下(比如数据丢了几个字节)都能正确工作?传统的方法是把代码烧到板子里,接上GPS模块,然后守着串口看打印信息,费时费力。而单元测试允许您在不运行整个程序的情况下,单独、自动地测试这一个函数。在test文件夹下,为您想测试的每个功能模块创建一个子文件夹,比如 test/test_gps_parser。在这个子文件夹里,创建一个C/C++文件(如test_main.cpp),编写专门的测试代码。您只需要在PlatformIO终端里运行一个命令:

PlatformIO会自动查找 test 目录下的所有测试,将每一个测试都独立编译成一个可执行程序,然后:上传到您的STM32开发板上运行,并将测试结果(PASS / FAIL)通过串口返回到电脑上。这被称为片上测试 (On-Target Test),可以验证与硬件交互的代码。或者,如果您的代码不涉及硬件(比如纯算法),它甚至可以直接在您的电脑上编译并运行测试,速度极快。这被称为原生测试 (Native Test)

platformio.ini 结构

基本构成元素

[section]: 方括号定义一个配置区块。最重要的区块是 [platformio](全局配置)和 [env:NAME](特定环境配置)。

key = value: 每一行是一个配置项,= 左边是键(选项名称),右边是值。

;: 分号开头表示注释。

继承与引用: PlatformIO支持在一个环境中引用另一个环境的配置,以减少重复。

[platformio] 全局配置区块

这个区块下的配置项会影响PlatformIO工具本身的行为,而不是某个特定的编译环境。

default_envs = nucleo_g474re 功能: (极其有用) 定义默认环境。当您的项目有多个[env:...]区块时,如果您只点击VSCode状态栏的通用"Build"或"Upload"按钮,PlatformIO将只操作这里指定的环境。这完美地解决了我们之前遇到的"16个项目全部失败"的问题。

src_dir = src 功能: 指定源代码目录的位置,默认为 src

include_dir = include 功能: 指定项目级头文件目录的位置,默认为include

lib_dir = lib 功能: 指定私有库目录的位置,默认为lib

[env:NAME] 环境配置区块

这是我们99%的工作所在。NAME是您给这个环境起的名字,比如我们用的nucleo_g474re

1. 平台选项 (Platform Options) [必需]

这是定义项目"身份"的基础。

platform = ststm32 功能: 指定MCU的平台/家族。例如 ststm32, espressif32, atmelavr等。

board = nucleo_g474re 功能: 指定具体的开发板ID。PlatformIO会根据这个ID自动配置MCU型号、时钟频率、内存大小、上传工具、调试工具等一系列参数。您可以在 PlatformIO Boards 找到所有支持的ID。

framework = stm32cube 功能: 指定使用的软件框架。例如 stm32cube, arduino, mbed

2. 编译选项 (Build Options) [常用]

控制代码如何被编译。

  • build_flags = 功能: (极其强大) 向编译器(GCC)传递额外的指令。可以写多行,每行一个指令。

    • -O2: 设置优化等级为2级(默认值)。-Os为尺寸优化,-O0为不优化(方便调试)。

    • -D MACRO_NAME: 定义一个宏,等效于在代码里写#define MACRO_NAME

    • -D MACRO_NAME=VALUE: 定义一个带值的宏。例如 -D BAUD_RATE=9600

    • -I path/to/headers: 添加一个额外的头文件搜索路径。

    • -Wl,-Map,output.map: 让链接器生成map文件,用于高级调试。

  • src_filter = +<*> -<extra/> 功能: 源代码过滤器。可以精确控制哪些文件参与编译。+< >表示包含,-< >表示排除。例如 +<*> -<test/> -<examples/> 表示编译所有文件,但排除testexamples目录下的文件。

  • extra_scripts = pre:my_script.py 功能: (高级) 在编译前(pre:)或编译后(post:)执行一个Python脚本,用于实现高度自动化,比如在编译后自动生成固件版本号。

3. 库选项 (Library Options) [核心功能]

管理项目依赖的库。

  • lib_deps = 功能: (PlatformIO的灵魂) 指定项目依赖的库。PlatformIO会自动下载、安装并链接它们。

    • adafruit/DHT sensor library: 根据库的 所有者/名称 从官方库中心查找。

    • DHT sensor library@1.3.4: 指定库的版本号。

    • https://github.com/user/repo.git: 直接从一个Git仓库依赖。

    • file://path/to/local/library: 依赖本地的一个库文件夹。

  • lib_ignore = SomeLib, AnotherLib 功能: 明确告诉PlatformIO忽略某些库,以解决可能发生的库冲突。

4. 上传选项 (Upload Options)
  • upload_protocol = stlink 功能: 指定烧录固件的协议/工具。对于NUCLEO板,stlink是默认值,通常可以省略。其他可选值如 jlink, cmsis-dap, mbed等。

  • upload_port = COM3 功能: 在使用串口烧录时(比如Arduino Uno),指定烧录端口。对于ST-LINK则不需要。

  • upload_flags = 功能: 向烧录工具传递额外的命令行参数,用于非常特殊的烧录场景。

5. 串口监视器选项 (Serial Monitor Options)
  • monitor_speed = 115200 功能: (即将用到) 设置串口监视器的波特率。必须与您代码中UART初始化的波特率严格一致。

  • monitor_port = COM3 功能: 手动指定要监听的串口。默认情况下PlatformIO会自动检测。

  • monitor_filters = colorize, log2file 功能: (高级) 监视器过滤器。可以在数据被打印出来之前对其进行处理。colorize可以给输出加上颜色,log2file可以把串口输出自动保存到文件中。

6. 调试选项 (Debug Options)
  • debug_tool = stlink 功能: 指定进行硬件调试的工具。NUCLEO板默认为stlink

  • debug_init_break = tbreak main 功能: 设置调试开始时的第一个断点。tbreak main表示在main函数入口处设置一个临时断点,程序会在这里停下。

  • debug_speed = 1800 功能: 设置调试器与目标芯片的通信速度(kHz)。

由 STM32CubeMX 创建并导入

编译与烧录

PIO 界面按钮
PIO 界面按钮

依次为 PIO Home 主页面、编译、烧录、清除文件、测试、PIO CLI、项目环境

调试请按 F5