1. 为什么我最终把STM32开发从 Keil 搬到了 VS Code
先交代一个背景。我做嵌入式开发有几年了,早期一直用 Keil MDK,后来逐渐转向 VS Code + GCC 工具链。这个转变不是“赶时髦”,而是被几个非常实际的问题逼出来的。
Keil 的问题在于:工程文件是私有的.uvprojx格式,代码浏览、搜索、重构能力偏弱,插件生态几乎没有。最痛苦的是,当你想引入单元测试、静态检查、自动格式化这些现代开发流程时,Keil 的配合度很低。另外,Keil 的许可证管理和版本兼容也是老生常谈的痛点。相比之下,VS Code 有完全开放的插件体系、强大的 IntelliSense、内置终端、Git 集成,还能接各种 AI 编程助手,这正好契合系列的主题——嵌入式软件 AI 编程。
那么,VS Code 是不是装完就能替代 Keil?答案是否定的。VS Code 本体只是一个编辑器,真正干活的是它背后那套工具链。这也是这篇文章要重点解决的问题:装完 VS Code 之后,还需要哪些扩展工具,才能让 STM32 的编译、烧录、调试流畅跑起来。
这套环境不只适合 STM32,也适用于其他 ARM Cortex-M 内核的 MCU,比如 GD32、MM32、NXP 的部分系列。核心思路是:VS Code 做前端界面,GCC 编译器做后端编译,OpenOCD 做烧录调试,CubeMX 做寄存器初始化——各司其职,组合起来就是一个非常顺手的嵌入式 IDE。
2. 基础工具链选型:编译器、调试器、构建系统一个都不能少
很多人第一次用 VS Code 做 STM32 开发,装完 C/C++ 插件就直接打开一个 Keil 工程,发现完全跑不起来。原因很简单——VS Code 默认不认识.uvprojx,也不会自己调用 ARMCC 编译器。你需要手动搭一层"编译-烧录-调试"的通路。
2.1 编译器:选 arm-none-eabi-gcc 而不是 ARMCC
STM32 开发可以用 ARMCC(Keil 内置)或 GCC(GNU 工具链)。在 VS Code 生态里,几乎清一色选择 GCC。
原因有几点:
- GCC 是所有平台通用的,Windows、Linux、macOS 都有对应的发行版。
- 配合 Makefile 或 CMake,可以非常自然地与 VS Code 的任务系统(Tasks)和调试配置(launch.json)对接。
- GCC 对 C99/C11、C++14/17 的支持比 ARMCC 更规范,语法检查也更严格,这在跑 AI 辅助代码生成时尤其重要——代码写错了,编译错误信息能定位到具体行。
安装方式:去 ARM 官方开发者网站下载arm-none-eabi-gcc工具链,Windows 下选.exe安装包。装完后把bin目录加进系统 PATH。检查是否装好,命令行里执行:
arm-none-eabi-gcc --version如果打印出版本号,比如arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 12.2.1),就说明编译器正常。注意版本尽量选 10.3 以上,新版对 Cortex-M33、M55 这类新内核支持更好。
2.2 调试器:OpenOCD 是 VS Code 和 ST-Link 之间的翻译官
STM32 调试最常用的硬件调试器是 ST-Link,但 ST-Link 本身只负责 JTAG/SWD 协议的物理层,调试软件需要单独配。
VS Code 里最经典的方案是 OpenOCD + Cortex-Debug 插件。OpenOCD 是一个开源调试软件,支持 ST-Link、J-Link、CMSIS-DAP 等几十种调试器,它负责读取你的芯片配置文件(比如stm32f103c8t6.cfg),然后通过 GDB 协议与调试器通信。
安装 OpenOCD 时要注意:Windows 下如果直接下载源编译,会比较费事。建议用winget install OpenOCD或者直接下载开源社区打包好的 release 版本,把解压后的bin目录加入 PATH。验证方式:
openocd --version2.3 构建系统:CMake + Ninja 的组合比 Makefile 更省心
VS Code 做 STM32 开发,构建系统主流有两个选择:Makefile 和 CMake。
Makefile 的优点是简单直接,很多开发板 SDK(比如 STM32Cube 官方例程)都是 Makefile 写的。缺点是可读性差,缩进和 Tab 的问题非常折腾人。
CMake 的优势是跨平台、可读性好、VS Code 的 CMake Tools 插件支持得非常完善,能够自动识别 target、提供智能提示,配合 Ninja 构建系统,编译速度比 Makefile 快不少。
我推荐直接用 CMake,尤其是 STM32CubeMX 从 6.x 版本开始已经支持生成 CMake 工程。这样流程会非常顺滑:CubeMX 生成工程骨架 -> VS Code 打开 CMakeLists.txt -> 一键构建。
CMake 和编译器的关系可以这样理解:CMake 是"包工头",负责理解整个工程的构成;GCC 是"砌墙工人",负责把每一行代码变成机器码;Ninja 是"现场调度员",决定先干哪个后干哪个,加速整个过程。
2.4 STM32CubeMX:生成初始化代码,而不是让你手撸寄存器
很多老手一开始不愿意用 CubeMX,觉得它生成的代码臃肿。但我觉得,对于绝大多数项目,CubeMX 能省下至少一天的初始化时间。尤其是时钟树配置、引脚复用这些容易出错的地方,图形化界面直接帮你算好了。
需要注意一个关键点:CubeMX 生成代码时要先选好工具链,在 Project Manager 页里把 Toolchain 改成 CMake。如果你用的是 Makefile 工作流,也可以选 Makefile,但 CMake 的后续体验更好。
选型总结:
| 工具 | 作用 | 推荐版本 |
|---|---|---|
| arm-none-eabi-gcc | 交叉编译 | 10.3+ |
| OpenOCD | 烧录/调试桥接 | 0.11+ |
| CMake | 构建系统 | 3.21+ |
| Ninja | 加速构建 | 1.10+ |
| STM32CubeMX | 初始化代码生成 | 6.6+ |
3. VS Code 安装细节:这一步卡住的人最多
VS Code 的安装本身很简单,但我在帮同事配环境时发现,很多人容易在几个细节点上卡住。这些地方看似不起眼,却直接影响后面的使用体验。
3.1 安装包选择与系统架构
VS Code 有两个主要版本:User Installer 和 System Installer。User Installer 不需要管理员权限,安装在当前用户目录下,适合办公电脑权限受限的场景;System Installer 装到 Program Files 里,所有用户共享。
我个人建议 Windows 下用 System Installer。因为嵌入式开发经常要接 J-Link 的 DLL、各种驱动,权限不足时有时会出稀奇古怪的问题。System Installer 可以省掉很多"文件无法写入"的报错。
另外注意区分 x64 和 ARM64。绝大多数 PC 是 x64,如果你的电脑是骁龙 X 系列芯片的 ARM 笔记本,要下载专门的 ARM64 版本,否则扩展插件会速度慢甚至无法安装。
3.2 安装选项里的"添加到 PATH"
VS Code 安装向导有几个复选框,其中有一项是"添加到 PATH"。这一项务必勾选。如果漏了,终端里输code命令会提示找不到命令。日常使用中,我会用code .快速从命令行打开当前目录的 VS Code,这个操作配合 Git Bash 或 PowerShell 非常高频。
如果装完发现没勾选,也不用重新安装。Windows 下可以手动把 VS Code 的安装目录(默认是C:\Users\你的用户名\AppData\Local\Programs\Microsoft VS Code\bin)加进系统环境变量。
3.3 首次启动的基础配置
装完 VS Code 后,不用急着装插件,先把几个基础设置改好。
打开设置面板(快捷键Ctrl + ,),推荐先调整这几项:
files.autoSave:设为onFocusChange,光标离开当前编辑区域时自动保存,避免调试时改了代码忘了编译。editor.formatOnSave:设为true,配合 clang-format 自动格式化,后面讲插件时会详细展开。search.exclude:增加**/build/**、**/Debug/**、**/Release/**,把编译产物排除在全局搜索外,否则搜一个函数名会被几百个二进制文件干扰。C_Cpp.default.compileCommands:这个可以先不设,等工程配好后再指向compile_commands.json,能大幅提升 IntelliSense 的准确度。
3.4 必须要装的几个基础插件
STM32 开发环境下,我推荐的插件组合如下(按重要程度排序):
- C/C++(Microsoft 官方发布)——提供 IntelliSense、代码导航、调试支持,是整个嵌入式开发者体验的基础。
- Cortex-Debug——专门为 ARM Cortex-M 芯片设计的调试插件,支持查看寄存器、外设、RTOS 任务列表。比 C/C++ 插件自带的调试能力强很多。
- CMake Tools——CMake 工程的编译、配置、切换 kit 都在这个插件里完成。
- clangd(可选)——如果你的工程已经生成了
compile_commands.json,用 clangd 代替 C/C++ 的 IntelliSense,代码补全更准确、更快。但 clangd 和 C/C++ 插件会冲突,两者只能开一个。 - GitLens——查看代码历史、作者信息。这不是嵌入式特有,但做项目协作时非常实用。
- LinkerScript——对
.ld链接脚本提供语法高亮。别小看它,没有高亮时,看分散加载文件简直折磨眼睛。 - Hexdump或Intel HEX 查看器——查看编译产物的二进制内容,适合做 bootloader、固件分析。
4. STM32 专门扩展与工程配置:从空白工程到点亮 LED
插件装完之后,真正关键的是如何把 VS Code、编译器、调试器全部串起来。这一节我以 STM32F103C8T6 最小系统板为例,从 CubeMX 生成工程开始,一步步演示完整的配置流程。
4.1 用 CubeMX 生成 CMake 工程
打开 STM32CubeMX,新建一个基于 STM32F103C8T6 的工程(选 MCU 时可以直接搜索型号),配置以下几项:
- Pinout:把 PA5 设为 GPIO_Output(这是 STM32F103C8T6 最小系统板上的板载 LED 引脚,低电平点亮)。
- Clock:用 HSE 晶振,主频拉到 72MHz。如果板子上没有外部晶振,就选 HSI,配 64MHz 或 8MHz 都行。
- Project Manager:Project Name 填
led_demo,Toolchain 选CMake,然后点 GENERATE CODE。
生成出来的目录结构大致长这样:
led_demo/ ├── CMakeLists.txt ├── Core/ │ ├── Inc/ │ └── Src/ │ ├── main.c │ ├── stm32f1xx_hal_msp.c │ └── ... ├── Drivers/ │ └── STM32F1xx_HAL_Driver/ ├── startup_stm32f103c8tx.s └── STM32F103C8Tx_FLASH.ld4.2 VS Code 打开工程并配置 CMake
用 VS Code 打开led_demo文件夹。首次打开时,CMake Tools 插件会提示你选择一个 Kit。Kit 在这里指的是"编译器方案"。选择arm-none-eabi-gcc对应的那个(如果你前面正确安装了工具链,它应该会自动出现在列表里)。
没有自动出现时,CMake Tools 设置里可以手动指定:
"cmake.configureSettings": { "CMAKE_MAKE_PROGRAM": "ninja", "CMAKE_C_COMPILER": "arm-none-eabi-gcc", "CMAKE_CXX_COMPILER": "arm-none-eabi-g++" }然后执行CMake: Configure,CMake 会读取 CubeMX 生成的CMakeLists.txt,生成build目录。
如果配置成功,VS Code 底部的状态栏会出现 Build 按钮,点击后就开始编译。编译完成后,build目录下会生成led_demo.elf、led_demo.bin、led_demo.hex。
4.3 配置烧录任务:用 OpenOCD 而不是另外装烧录软件
编译完成不代表能烧录,还需要配置烧录环节。
在工程根目录里新建一个.vscode/tasks.json,内容如下:
{ "version": "2.0.0", "tasks": [ { "label": "build", "type": "shell", "command": "cmake --build build", "group": { "kind": "build", "isDefault": true } }, { "label": "flash", "type": "shell", "command": "openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c \"program build/led_demo.elf verify reset exit\"", "dependsOn": "build", "problemMatcher": [] } ] }说明一下这里命令的组成:
interface/stlink.cfg告诉 OpenOCD 你用的是 ST-Link 调试器。target/stm32f1x.cfg是 STM32F1 系列的目标芯片配置。换芯片时对应改这里,比如 F4 系列用stm32f4x.cfg。program ... verify reset exit表示:烧录文件 -> 校验 -> 复位运行 -> 退出 OpenOCD。
如果想用图形化烧录工具,也可以装 STM32CubeProgrammer,然后把命令行换成:
STM32_Programmer_CLI -c port=SWD -w build/led_demo.hex -v -rst不过 OpenOCD 的优势在于它同时被调试功能复用,一套工具解决烧录和调试,少一个依赖。
4.4 配置调试环境:Cortex-Debug + OpenOCD
调试配置在launch.json里。新建.vscode/launch.json:
{ "version": "0.2.0", "configurations": [ { "name": "Cortex Debug", "cwd": "${workspaceFolder}", "executable": "./build/led_demo.elf", "request": "launch", "type": "cortex-debug", "servertype": "openocd", "configFiles": [ "interface/stlink.cfg", "target/stm32f1x.cfg" ], "svdFile": "./STM32F103C8Tx.svd", "device": "STM32F103C8" } ] }其中svdFile是芯片的外设描述文件,VS Code 的调试器会读取它来显示每个外设寄存器的名字和位域含义。这个文件可以在 STM32CubeMX 的安装目录里找到,或者去芯片厂商官网下载。如果 SVD 文件能在调试时看到 USSART、GPIO 等寄存器值,这比用逻辑分析仪抓波形更直观。
4.5 让 IntelliSense 真正认识你的工程:compile_commands.json
很多人在 VS Code 里看代码时,发现#include "stm32f1xx_hal.h"会显示红色波浪线。原因是 IntelliSense 不知道头文件的搜索路径。
CMake 可以自动生成compile_commands.json。在CMakeLists.txt里加一行:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)或者在 VM 里缓存配置:
"C_Cpp.default.compileCommands": "${workspaceFolder}/build/compile_commands.json"重新 Configure 后,C/C++ 插件会读取这个文件,每个头文件搜索路径、宏定义就都知道了,波浪线自动消失,跳转、补全也会变准确。
4.6 把这几步整合成流程
以上配置完成后,日常工作流会非常顺手:
- 按
Ctrl + Shift + B编译。 - 按
Ctrl + Shift + P输Tasks: Run Task选flash烧录。 - 按
F5进入调试模式,在main函数里打断点、查看寄存器值。
5. AI 编程插件与嵌入式开发的组合玩法
文章标题里带有"AI 编程",所以单独用一节讲这部分。
AI 编程插件在 VS Code 里现在是标配了。像 Cline、Continue、Codeium、GitHub Copilot 都有各自的优点。嵌入式开发里,AI 能帮上忙的场景主要分三类:
5.1 代码生成与补全:从零写寄存器逻辑
AI 补全在对 HAL 库 API 不太熟时尤其好用。比如我想配置一个定时器输出 PWM,只需要在 main.c 里打一个注释:
/* Generate a 1kHz PWM on PA8 using TIM1_CH1 */AI 会自动生成:
TIM_OC_InitTypeDef sConfigOC = {0}; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); }这里有个前提:你的工程里已经有一点"示范代码"。AI 是根据你项目里已有的代码风格来推断输出格式。如果你全篇都是HAL_函数,它就会继续用HAL_;如果你自己写了寄存器版本,它也会跟着用寄存器方式。所以,开始用 AI 之前,先梳理一遍现有代码的写法风格,避免 AI 生成的内容和整个工程风格不一致。
5.2 代码解释与审查:比查手册快几倍
面对一段看不懂的驱动代码,我现在的习惯是先让 AI 解释,再翻手册验证。比如,我拿到一个不熟悉的传感器 SDK,几千行代码,AI 能快速给出函数调用关系图、主要数据结构定义、状态机逻辑。但必须强调:AI 的解释可能存在幻觉,不能全信,关键计算必须拿数据手册核对。
审查方面,AI 对低级错误很敏感,比如数组越界、未初始化变量、中断里调用阻塞函数。这些问题它一眼就能看出来,对提升代码质量的帮助很明显。
5.3 嵌入式场景下 AI 的使用边界
嵌入式开发和纯软件工程有一个显著区别:硬件互动。AI 不知道你的硬件原理图,也不知道某个引脚的电气特性。它会帮你写出"逻辑正确的代码",但逻辑正确不等于硬件能工作。
我举一个实际踩过的坑。AI 生成了一段驱动 WS2812B 灯带的代码,用的是 GPIO 翻转的软件实现,逻辑看着没问题。但 WS2812B 对时序要求非常严苛,每条数据位的信号持续时间要在几百纳秒级别,软件 GPIO 翻转在低主频下根本满足不了。最后还得改成 SPI + DMA 的方式。
所以在嵌入式领域,AI 是"资深副驾驶"而非"自动驾驶"。代码逻辑生成可以交给 AI,但硬件时序、资源约束、中断优先级、功耗管理这些判断必须人工把关。
5.4 给 AI 编程的提示词建议
- 给背景:告诉 AI 你用的芯片型号、HAL 库版本、内核频率。比如"STM32F407 @168MHz, using STM32CubeHAL v1.27",输出会精确很多。
- 给约束:明确告诉 AI 代码要在中断上下文执行还是普通任务上下文,能否使用动态内存分配(嵌入式里一般禁止),是否考虑低功耗。
- 给示例:直接把现有代码片段丢给它,让它按同样的风格继续。
- 要可验证的输出:要求 AI 生成的代码附带一个简短的测试用例或自检步骤,方便验证。
6. 避坑指南:这一节是你早晚会遇到的几类问题
环境配好不等于万事大吉,实际使用中总会遇到各种问题。这里把我踩过的一些坑集中整理出来,按出现频率排序。
6.1 OpenOCD 找不到目标芯片
报错内容类似:
Error: open failed in procedure 'program'排查步骤:
- 检查 ST-Link 是否被其他程序占用。特别是 STM32CubeProgrammer 或 Keil 如果后台开着,会占用 ST-Link 的资源,OpenOCD 就连接不上了。
- 检查 ST-Link 驱动是否正常。Windows 设备管理器里应该能看到
STMicroelectronics STLink dongle。 - 检查 SWD 接线。SCK、DIO、GND 三根线顺序别接错,ST-Link 的 SWD 接口丝印很小,容易插反。
- 芯片被读保护时也会导致连接失败。用 STM32CubeProgrammer 连接并解除读保护,或者用 OpenOCD 的
reset_config srst_only让 SWD 支持复位连接。
6.2 VS Code 终端里中文乱码
大多是因为 Windows 终端默认用 GBK 编码,而 GCC 输出 UTF-8。在.vscode/settings.json里强制设置:
"terminal.integrated.profiles.windows": { "PowerShell": { "source": "PowerShell", "env": { "PYTHONIOENCODING": "utf-8" } } }, "files.encoding": "utf8"但更省事的方案是在终端里执行:
chcp 65001这是把终端代码页切换为 UTF-8。另外建议在代码文件里不要写中文注释以外的特殊字符,减少编码带来的麻烦。
6.3 编译优化导致代码行为异常
VS Code 里默认 CMake 是 Debug 构建,优化等级可能是-Og或者-O0。但如果你想发布固件,开了-O2之后,某些依赖时序的代码可能会出问题。
举个典型例子:一个用软件延时的点灯程序,在-O0下完全正常,在-O2下灯不亮了。原因很可能是编译器把延时循环优化掉了。解决办法是查一下延时函数里有没有定义volatile变量,或者把关键延时函数加上__attribute__((optimize("O0")))。
6.4 调试时看不了全局变量
Cortex-Debug 插件有时会看不到全局变量的实时值。这不是插件 bug,而是编译器在优化模式下把变量放进了寄存器而不是内存。把变量声明为volatile,或者把构建类型切到 Debug,两者都能解决。
6.5 STM32CubeMX 生成的工程首次编译报错
经常遇到的问题是startup_stm32f103c8tx.s文件缺失。新版 CubeMX 生成的 CMake 工程默认会引用这个文件,但你打开的位置可能不对。
解决:在CMakeLists.txt里搜索startup,确认路径是${ProjDirPath}/startup_stm32f103c8tx.s还是Core/Src/startup_xxx.s。如果文件根本不存在,回到 CubeMX 里重新生成一遍,注意 Cubemx 的 MCU 型号和 package 版本要对应。
7. 日常工作流演示:从修改代码到调试一气呵成
这一节我完整演示一遍我平时的操作流程,让大家直观感受 VS Code + STM32 环境的高效之处。
假设我要在刚才的led_demo工程里增加一个按键控制 LED 的逻辑。
第一件事:打开 CubeMX,把 PA0 设为 GPIO_Input,重新生成代码。这时 CubeMX 不会覆盖你已经写好的main函数里的业务逻辑,它只会更新初始化部分。
回到 VS Code,Ctrl + Shift + B构建一次,确认没有语法错误。
然后在main函数的 while 循环加代码,先加这一行:
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET) { HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); HAL_Delay(100); }这个接口的名字是我从 HAL 库记忆里调出来的。如果记不准,在 VS Code 里输入HAL_GPIO_,插件会弹出所有可用函数,再结合@符号过滤出函数名。
加完代码后,Ctrl + S保存,Ctrl + Shift + B编译。
接下来Ctrl + Shift + P输入Tasks: Run Task,选flash。
等待 OpenOCD 烧录完成,复位板子。按下手指上的按键,LED 翻转。
如果需要进一步验证逻辑的时序,按F5启动调试。在HAL_GPIO_ReadPin那一行打断点,左侧调试面板能看到GPIOA->IDR寄存器值的变化。当按键按下时,第 0 位会变成 0。这一步能直观地确认硬件和代码之间是否真的连通了。
再来一个进阶场景:如果 LED 翻转间隔不稳定怎么办?
这种情况下我会先用逻辑分析仪抓 PA5 的波形,确认实际翻转周期。因为HAL_Delay(100)的精度依赖 SysTick 配置,而 SysTick 的时钟源可能走的是 HCLK 的 8 分频。所以要去 SystemClock_Config 里看 RCC 的 时钟配置是否正确。在 VS Code 里直接跳转到SystemClock_Config(),结合编译后生成的build/led_demo.map文件,可以快速核对各总线的时钟频率。这套联调流程,在 Keil 里做起来远没有这么顺手。
8. 一些补充:关于工程组织与多人协作
最后补充一点工程组织层面的经验。
当你开始用 VS Code 管理 STM32 工程后,建议把下面几类文件纳入版本管理:
- 所有源代码文件(Core、Drivers、App)
CMakeLists.txt.vscode/settings.json、launch.json、tasks.json.clang-format(格式化规则).gitignore
.gitignore需要排除以下内容:
build/ *.o *.elf *.bin *.hex *.map多人协作时,最理想的约定是:每个人本地安装 VS Code + arm-none-eabi-gcc + OpenOCD + CMake,工具版本尽量统一。我在实际项目里吃过版本不一致的亏——同事用 GCC 12 编译的固件能跑,我本地是 GCC 10,编译出来运行异常。后来排查半天,才发现是-fno-common这个默认行为在两个版本中发生了变化。所以,如果团队协作,强烈建议在CMakeLists.txt里显式指定工具链版本范围,或者直接提供一键式环境初始化脚本(比如用 vcpkg 仓库来锁定工具链版本)。
关于格式化,建议尽快配置.clang-format。我用的基底风格是 Google,但把ColumnLimit改成 120,IndentWidth改成 4,更贴合嵌入式代码的习惯。配置好之后,VS Code 里按Shift + Alt + F就能一键格式化。格式一致性对代码 review 的帮助非常大,尤其在多人同时维护同一份驱动代码时。
如果你愿意花一点时间把环境脚本化,还可以考虑把整个工具链做成 Docker 镜像。VS Code 的 Remote-Container 可以进入容器里开发,团队环境完全一致,再也不用担心"在我电脑上是好的"这种问题。Docker 容器里编译 STM32 工程是完全可行的,唯一需要注意的是 USB 设备的映射——要让容器直通宿主的 ST-Link,需要在启动容器时加上--device=/dev/bus/usb/xxx或者用一整套 privileged 配置。这个操作稍微有一点门槛,但对团队持续集成来说,值得投入。
我个人的习惯是:环境搭建这类事情,花一天时间把它做扎实,换来的是后续几个月开发效率的明显提升。VS Code 加 STM32 这套方案,本质上是把嵌入式开发"降维"成了现代软件工程的工作方式,代码补全、AI 辅助、自动化测试、持续集成都能顺势接进来。希望这篇文章能让你少踩几个我踩过的坑,顺利搭好属于自己的嵌入式开发环境。