不用从新闻稿的角度去看这个标题,真正让嵌入式开发者兴奋的点在于:ST(意法半导体)把自家整套开发工具链放到了 Linux 平台上,并且免费。过去很多用 STM32 的工程师要么在 Windows 下用 Keil、IAR,要么折腾虚拟机跑 Windows 环境,而现在从代码生成、编译、烧录到调试,在 Linux 原生的桌面环境下就能全流程跑通。这篇内容我结合自己长期在 Linux 下做 STM32 和嵌入式 Linux 开发的实操经验,把 ST 这套免费工具链的选型思路、安装配置、实战流程和踩坑记录一次说清楚,希望能帮你省掉自己摸索的时间。
1. ST 免费开发工具全景:不止一个 IDE 那么简单
很多人一听到 ST 的免费工具,第一反应就是 STM32CubeIDE。确实,这是 ST 官方主推的集成开发环境,但如果你只把它当成一个“能写代码的软件”,那就太小看 ST 这套布局了。我在 Linux 下实际使用下来,ST 的免费工具链覆盖了项目开发全生命周期,从芯片初始化配置、代码生成、编译构建、烧录调试到运行时监控,每一环都有对应的工具,而且全部对 Linux 用户开放。
1.1 核心工具矩阵与定位
先给大家理一下 ST 这套工具链的组成,每一款工具的定位和作用我在表格里做了梳理:
| 工具名称 | 核心功能 | Linux 支持情况 | 适用场景 |
|---|---|---|---|
| STM32CubeMX | 图形化芯片配置、引脚分配、中间件选择、代码生成 | 官方提供 Linux 版 | 项目初期快速搭建工程骨架 |
| STM32CubeIDE | 基于 Eclipse 的完整 IDE,集成编译、调试、分析 | 官方提供 Linux 版 | 日常开发调试主战场 |
| STM32CubeProgrammer | 烧录、加密、选项字节配置 | 提供 Linux 命令行版和 GUI 版 | 量产烧录、固件更新 |
| STM32CubeMonitor | 实时变量监控、波形显示 | 提供 Linux 版 | 调试时的数据可视化分析 |
| STM32CubeCLT | 命令行工具集,含编译器和调试服务器 | Linux 原生支持 | CI/CD 自动化构建场景 |
重点提一下 STM32CubeCLT 这个工具。很多工程师容易忽略它,但在 Linux 环境下这恰恰是价值最大的工具之一。它把编译器(arm-none-eabi-gcc 工具链)、调试器(OpenOCD 或 ST-LINK GDB server)、烧录工具全部打包成命令行版本,这意味着你可以完全脱离图形界面做构建和烧录。我个人的习惯是:日常小改动用 IDE,但一旦涉及持续集成、批量编译、自动化测试,全部切换到 CLI 工具链。加上 STM32CubeMX 可以在命令行模式下做工程生成,整条流水线就能完全脚本化,这在 Windows 生态下很难做到这么干净。
1.2 为什么说“Linux 原生支持”是件事儿
这里要展开说一下 Linux 原生支持到底意味着什么。很多厂家说“支持 Linux”其实就是给一个阉割版的功能或者只提供命令行接口,但 ST 这次是把完整的桌面级体验搬到了 Linux 上。STM32CubeIDE 基于 Eclipse 框架,原生运行在 X11/Wayland 环境下,调试视图、断点管理、变量监视这些功能和 Windows 版完全一致。STM32CubeMX 的图形化引脚配置界面在 Linux 下也跑得很流畅,你可以用鼠标拖拽配置引脚,实时看到芯片封装的引脚状态变化。
更深一层的是,Linux 环境对嵌入式开发本身就有天然优势。比如你用 STM32 做产品,往往还要配合 Linux 主机做上位机通信、协议联调,甚至直接用树莓派或定制 ARM 板做带 Linux 系统的产品。如果开发工具跑在 Windows 上,你需要在两套系统间来回切换;现在所有工具都在 Linux 下,工作流是连续的:STM32 的代码在 Linux 主机上编译烧录,同时同一个 Linux 系统还能跑 QT 上位机开发、交叉编译 Linux 内核,这种“一机搞定”的体验,在 ST 这套工具全面支持 Linux 前是不敢想的。
2. Linux 环境下的工具链选型与安装要点
我自己的主力开发机是 Ubuntu 22.04 LTS,这一节以这个环境为例,但大部分内容对 Debian、Arch、Fedora 同样适用。先说明一点:不建议在 Linux 下用 Windows 虚拟机跑 STM32CubeIDE,性能损耗大,而且 USB 透传 ST-Link 经常出问题,体验非常糟糕。ST 原生工具在 Linux 下跑得足够好,没必要绕路。
2.1 安装前必须处理的系统依赖
Linux 下安装工具链最容易翻车的不是软件本身,而是系统依赖缺失。STM32CubeIDE 和 STM32CubeProgrammer 依赖两部分东西:一是 Java 运行环境(JRE),二是若干图形界面库。
先说 Java 环境。STM32CubeIDE 5.x 版本要求 Java 17 或更高,而 STM32CubeMX 6.10 版本要求 Java 17 以上。Ubuntu 22.04 自带的 OpenJDK 是 11,直接跑会报版本不兼容错误。我的建议是安装 OpenJDK 17,不要用 Oracle JDK,尽量用发行版仓库自带的版本,省去手动配置 JAVA_HOME 的麻烦:
sudo apt update sudo apt install openjdk-17-jre openjdk-17-jdk java -version看到输出里有 “openjdk version 17.0.x” 就说明 Java 环境OK了。
然后是图形库依赖。STM32CubeIDE 基于 Eclipse,底层依赖 GTK 库。如果你用的是最小化安装的 Ubuntu Server 或者剪裁过的桌面环境,需要补装:
sudo apt install libgtk-3-0 libwebkit2gtk-4.0-37 libcanberra-gtk-module libcanberra-gtk3-module这里有个特别容易踩的坑:如果用 Wayland 会话,STM32CubeIDE 的某些版本在调试时偶发界面卡死,建议 Ubuntu 用户在登录界面选择 “Ubuntu on Xorg” 会话再使用 STM32CubeIDE。虽然 Ubuntu 默认推荐 Wayland,但嵌入式 IDE 这类重型 Java 应用在 X11 下的兼容性更成熟,实测跑了几个月没有出过问题。
2.2 从 STM32CubeMX 到 IDE 的完整安装路径
ST 的 Linux 安装包基本都是压缩包或 .sh 脚本,不需要 apt 管理。STM32CubeMX 和 STM32CubeIDE 在 ST 官网注册后能下载 Linux 版本。安装步骤我整理成了一套固定流程:
第一步,把下载好的压缩包解压到自定义目录,我习惯放在/opt下,这样所有用户都可以调用:
sudo mkdir -p /opt/stm32cube sudo tar -xzf en.stm32cubemx-lin-v6.10.0.tar.gz -C /opt/stm32cube/ sudo tar -xzf en.stm32cubeide-lin-v1.13.0.tar.gz -C /opt/stm32cube/解压完成后,目录结构会像这样:
/opt/stm32cube/ ├── STM32CubeMX/ └── STM32CubeIDE/注意 STM32CubeMX 的安装包解压后还需要运行安装脚本才能完成注册:
cd /opt/stm32cube/STM32CubeMX ./SetupSTM32CubeMX-6.10.0这个过程会把必要的文件复制到用户目录,并在~/.stm32cubemx或者~/.config下创建配置文件夹。首次启动 STM32CubeMX 会提示选择工作目录,这个目录专门存放你的工程,建议放到独立目录,比如~/stm32-workspace,方便后续 IDE 统一管理。
STM32CubeIDE 则不同,它解压后可以直接运行启动脚本:
cd /opt/stm32cube/STM32CubeIDE ./stm32cubeide第一次启动会创建 workspace 目录,同时会询问是否需要安装固件包——这一步建议先跳过,等设置了国内镜像源后再下载,速度会快很多。固件包是 STM32CubeMX 生成代码时必需的芯片支持库,以 STM32F4 系列为例,它包含 HAL 驱动、CMSIS 核心文件和中间件组件,后续生成代码时会自动调用。
2.3 STM32CubeCLT 的安装与验证
如果你有自动化构建需求,STM32CubeCLT 是必须安装的。它不像 IDE 那样有图形界面,安装方式更轻量。ST 官方提供了 Linux 安装说明,核心思路是安装到/opt/stm32cubeclt目录:
sudo mkdir -p /opt/stm32cubeclt sudo tar -xzf en.stm32cubeclt-lin-v1.15.0.tar.gz -C /opt/stm32cubeclt/装完后检查工具是否可用:
/opt/stm32cubeclt/STM32CubeProgrammer/bin/STM32_Programmer.sh --version /opt/stm32cubeclt/STM32CubeCLT/arm-none-eabi-gcc/bin/arm-none-eabi-gcc --version /opt/stm32cubeclt/STM32CubeCLT/bin/stutil如果版本信息都能正确输出,说明工具链装好了。安装完记得把工具目录加到 PATH 环境变量,建议写入~/.bashrc:
export PATH=$PATH:/opt/stm32cubeclt/STM32CubeCLT/bin:/opt/stm32cubeclt/STM32CubeProgrammer/bin export PATH=$PATH:/opt/stm32cube/STM32CubeIDE/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.12.3.rel1.linux64_1.0.0.202401161405/tools/bin第二行是 IDE 内置的 gcc-arm 工具链路径,实际版本号可能不同,以你安装目录为准。配置完执行source ~/.bashrc生效。
3. 从零到一的 Linux 开发流程实战
工具装完后,真正的价值体现在实际的开发流程中。这一节我完整走一个 STM32 项目从生成到烧录的流程,用的是很常用的 NUCLEO-F411RE 开发板。整个过程完全在 Linux 终端和 GUI 下完成,不涉及 Windows。
3.1 用 STM32CubeMX 生成工程骨架
STM32CubeMX 的图形化配置是项目开发的起点。打开软件后,选择芯片型号或者直接搜索开发板名称。以 NUCLEO-F411RE 为例,双击后会自动加载该开发板的默认配置(LED、串口、板载 ST-Link 等)。
引脚配置是最关键的环节。在 Pinout 视图中,你会看到芯片的封装图,用鼠标点击引脚就能切换功能。比如我要用 USART2 通信,在搜索框输入USART2,STM32CubeMX 会自动高亮并在引脚图上推荐可用的引脚组合,我只需要确认 Mode 为Asynchronous即可。这一步的好处是引脚冲突会被自动检测,如果 PA2 已经被其他外设占用,软件会提示冲突并给出替代方案。
配置完外设,还有两个常被忽视但非常重要的设置项:
一是 Project Manager 标签页里的 Toolchain/IDE 选项。这里可以选择生成STM32CubeIDE项目还是Makefile项目。如果你用的是 IDE,选择前者;如果你想用命令行纯 make 编译,选择后者。我一般生成 Makefile 项目,因为这样在 CI/CD 里最灵活,IDE 项目反而不方便脚本化处理。
二是代码生成器的Generate Under Root选项。默认情况下 STM32CubeMX 会在工程目录下创建Core、Drivers等子目录,但代码文件会和工程文件混在一起。建议勾选 “Generate Under Root”,让代码生成在独立的Core目录下,保持工程根目录干净。这个习惯在项目持续迭代、多人协作时特别重要。
配置完成后点击右上角的GENERATE CODE,选择工程保存路径,STM32CubeMX 会自动生成完整的初始化代码。生成完成后打开工程目录看看结构:
~/stm32-workspace/test_f411/ ├── Core/ │ ├── Inc/ │ ├── Src/ ├── Drivers/ ├── Makefile └── test_f411.ioc.ioc文件是 STM32CubeMX 的工程文件,后续所有修改都通过双击它进行。Makefile 是编译入口,稍后在命令行里直接运行make就能完成构建。
3.2 免 IDE 命令行编译与烧录
生成代码后,测试编译是否通过:
cd ~/stm32-workspace/test_f411 make -j$(nproc)这里-j$(nproc)是让编译使用全部 CPU 核心数,对于大工程能明显提速。首次编译会输出完整的编译日志,最后生成build/test_f411.elf和build/test_f411.bin两个文件。
编译通过后,连接 NUCLEO-F411RE 开发板,用lsusb检查板载 ST-Link 是否被识别:
lsusb | grep -i stlink输出结果类似Bus 001 Device 004: ID 0483:374b STMicroelectronics ST-LINK/V2就说明硬件识别正常。USB 识别不正常的情况我在第 4 节专门讲排查方法。
然后使用 STM32CubeProgrammer 的命令行烧录:
STM32_Programmer.sh -c port=SWD mode=HOTPLUG -w build/test_f411.elf -v命令拆解一下:-c port=SWD mode=HOTPLUG表示通过 ST-Link 的 SWD 接口连接,HOTPLUG 模式允许热插拔检测;-w表示写入;-v表示烧录后回读验证。如果所有操作正确,会看到类似Download verified successfully的输出。
如果你更习惯 OpenOCD 方式,ST 工具链里也有对应的调试服务器脚本:
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program build/test_f411.elf verify reset exit"这条命令会加载 ST-Link 接口配置和 STM32F4 目标配置,把固件写入并复位运行。OpenOCD 的灵活性体现在它可以和 GDB 配合做自动化测试,是 CI 流程的标配。
3.3 使用 GDB 和 IDE 做调试分析
命令行烧录完成后,调试环节我推荐两种方式。一种是 STM32CubeIDE 的图形化调试,另一种是 GDB + OpenOCD 的命令行调试。
如果选择 IDE,启动 STM32CubeIDE 后导入刚才生成的 Makefile 项目。File -> Import -> Existing Projects into Workspace,选择工程目录后即可导入。导入后先构建一次(Ctrl+B),再设置调试配置,在 Debug Configurations 里选择 STM32 Cortex-M C/C++ Application,指定编译生成的.elf文件,点击 Debug 按钮启动调试会话。IDE 会自动启动 ST-Link GDB server 并连接目标板,然后进入断点调试界面,可以逐行执行代码、查看寄存器、观察变量实时值。
命令行调试场景多数发生在自动化测试中。先启动 OpenOCD 作为 GDB server:
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg这个终端保持运行,OpenOCD 默认在 3333 端口监听 GDB 连接。再开一个新终端,用 arm-none-eabi-gdb 连接:
arm-none-eabi-gdb build/test_f411.elf (gdb) target remote :3333 (gdb) monitor reset halt (gdb) load (gdb) continue调试过程中最常用的几个命令我列一下:
break main:在 main 函数入口设置断点info registers:查看所有寄存器值print variable_name:打印某个变量的当前值step/next:单步执行,step 会进入函数内部,next 跳过函数调用x/8wx 0x20000000:查看内存地址 0x20000000 起 8 个字的数据
这套组合拳在排查硬件初始化问题时非常有用。比如系统跑飞了,你可以先用monitor reset halt让 CPU 停在复位向量处,再单步跟踪看看具体是哪条指令导致异常。
4. 常见问题与排查技巧实录
在 Linux 下用 ST 工具链开发,遇到的问题和 Windows 下有很大不同。这一节整理我实际踩过的坑和排查思路,覆盖面从 USB 权限、依赖库缺失到网络问题,都是高频场景。
4.1 USB 权限问题导致 ST-Link 无法识别
现象:开发板插上后,lsusb能看到设备,但 STM32CubeProgrammer 报错No ST-Link detected。
原因:Linux 默认的 udev 规则没有为 ST-Link 设备分配足够的访问权限,普通用户无法直接读设备。
排查与解决:ST 提供了 udev 规则文件。在/etc/udev/rules.d/下新建49-stlinkv2.rules:
sudo tee /etc/udev/rules.d/49-stlinkv2.rules << EOF SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE="0666", GROUP="dialout" SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374d", MODE="0666", GROUP="dialout" EOF然后重载规则并重新插拔设备:
sudo udevadm control --reload-rules sudo udevadm trigger0483:374b是 ST-Link/V2 的 USB ID,0483:374d是 ST-Link/V3 的。配置后把用户加到dialout组,再退出登录重新登录一次就生效了。
4.2 编译报错找不到头文件或链接器脚本
现象:执行make时报错fatal error: stm32f4xx_hal_conf.h: No such file or directory,或者链接阶段报cannot find -lstdc++。
原因:最常见的原因是 Makefile 里的编译器路径不对,或者软件包路径被修改后导致 HAL 库的引用关系断了。另一个原因是安装的 arm-none-eabi-gcc 版本过旧,不支持新式编译参数。
排查与解决:先在终端手动跑一次编译器测试:
arm-none-eabi-gcc --version如果显示版本低于 10.x,建议升级工具链。ST 的 STM32CubeIDE 内置的 gcc 版本通常是最新的,可以直接用它替换系统默认。如果版本没问题,检查 Makefile 中的C_INCLUDES变量,确认Drivers路径是否正确。一个最简单的绕过办法是重新用 STM32CubeMX 生成一次 Makefile,然后对比差异,很多时候是因为手动改过 Makefile 导致路径失效。
4.3 固件包下载卡死在 “Download” 阶段
现象:第一次在 STM32CubeMX 中打开某个芯片系列,需要下载对应的固件包(例如 STM32F4xx_FW_Package),但进度条长时间卡住不动,速度极慢。
原因:固件包存放在 ST 的海外服务器上,国内访问延迟极高,且下载过程中没有断点续传机制。
解决思路:一是手动下载固件包后拷贝到本地。到 ST 官网搜索 “STM32CubeF4”,下载最新版本压缩包,解压后放到~/STM32Cube/Repository/目录下。启动 STM32CubeMX 后它会自动识别到本地固件包。二是在 STM32CubeMX 的设置里把固件包更新源改成镜像。当前 ST 官网主要仓库地址不可选,但你的下载请求如果走代理或内网镜像会快很多。这里不建议手动修改软件内部仓库地址,容易出现版本匹配问题。
经验之谈:固件包我建议直接手动下载完整包,而不是依赖 IDE 的自动下载。因为自动下载失败后残留的临时文件不会自动清理,可能会导致后续下载反复失败。手动下载时按需选择,比如只做 F1、F4 系列的产品,就下载 STM32CubeF1、STM32CubeF4 两个包,其余不下载,省磁盘空间。
4.4 多版本工具链切换的坑
现象:系统里既有 STM32CubeIDE 自带的 gcc 编译器,又有自己单独安装的 arm-none-eabi-gcc,两者版本不一致,导致同一个工程在 IDE 内编译通过,在命令行编译报错。
原因:不同版本 gcc 的默认代码生成特性有差异,特别是 C 语言标准(如默认gnu11和gnu17的差异)、宏定义、浮点 ABI 支持等。如果命令行的编译器路径比 IDE 自带的旧,就可能出现头文件模板不匹配的问题。
解决思路:统一编译器版本。建议命令行编译使用 IDE 内置的 gcc,也就是我在 2.3 节加到 PATH 里的那个路径。具体做法是把 IDE 内置 gcc 的路径在PATH中放到/usr/bin之前,然后用which arm-none-eabi-gcc确认调用的是 IDE 版本。另外在 Makefile 里显式指定编译器全路径,避免隐式解析。不同 STM32CubeIDE 版本自带的 gcc 版本不同,尽量保持 IDE 和 CLT 的版本一致,避免工程文件跨版本迁移时出现诡异的编译错误。
提示:嵌入式工程对编译器的可复现性要求很高。建议在项目根目录放一个
toolchain.mk文件记录编译器版本和路径,团队成员统一使用同一套工具链,否则同样的代码可能在不同人机器上行为不一致。
4.5 自定义时钟树配置导致的启动失败
现象:CubeMX 里配置好 PLL 倍频、切换系统时钟源后,生成代码烧录到板子,程序运行异常,LED 不闪或串口数据乱码。
原因:时钟树配置与芯片实际支持频率不一致,或外部晶振(HSE)与代码里配置的不匹配。比如 NUCLEO 板上用的是 8MHz 晶振,如果你的配置里填的是 25MHz,PLL 倍频后会超出主频上限,导致内核跑飞。
排查与解决:连接 ST-Link 用 STM32CubeMonitor 的虚谱仪功能监控寄存器实时值,或者简单粗暴地先把时钟配置改回内部 HSI 振荡器(16MHz),确认基础功能正常后再逐步切换外设和时钟源。还有一种常用手段是用 STM32CubeProgrammer 的-r参数读取复位原因寄存器:
STM32_Programmer.sh -c port=SWD mode=HOTPLUG -r 0x40000000 0x10如果读出RCC->CSR的值里有复位标志位,能辅助判断是不是看门狗复位或上电复位。实践中最省事的做法是回到 CubeMX 重新生成代码,但生成前把 System Clock 的输入值和分频系数都核对一遍。
5. 让 Linux 开发体验更进一步的建议
工具链能跑通和用得好之间,还隔着一条“工作流打磨”的距离。这里分享几个提升效率的实用建议,都是亲测有效的细节。
5.1 用脚本封装常用操作
频繁敲一长串烧录命令容易出错,我习惯在项目根目录建立一个Makefile.local,把烧录和调试指令封装为 make 目标:
flash: STM32_Programmer.sh -c port=SWD mode=HOTPLUG -w build/$(TARGET).elf -v debug: openocd -f interface/stlink.cfg -f target/stm32f4x.cfg \ -c "program build/$(TARGET).elf verify reset exit" -c "shutdown"这样每次烧录只要make flash,编译加烧录一条命令make && make flash,非常顺手。TARGET 变量在编译时确定,比如这里的test_f411。
5.2 把 openocd 和 gdb 做成 tmux 分屏
如果你经常做命令行调试,会发现调试服务器和 gdb 客户端两个终端来回切换很烦人。我推荐用 tmux 开两个分屏,左边跑 OpenOCD,右边跑 gdb,这样可以同时看目标板日志和调试会话:
tmux new -s debug # Ctrl-b % 分屏,左侧跑 openocd,右侧跑 gdb这种调试方式在无头服务器上格外有用,不用桌面环境也能完全控制嵌入式设备。
5.3 用好 git 做嵌入式版本管理
嵌入式工程的.ioc文件是文本 XML,非常适合纳入 git 版本管理。每次修改完工程配置后生成代码,提交时把Core/、Drivers/和.ioc一起提交。这里有个关键点:CubeMX 生成的代码会被它的代码生成器覆盖,如果你在生成的代码里手动修改,下次生成时会被覆盖掉,所以要么把自定义逻辑都放到USER CODE BEGIN和USER CODE END注释块之间(CubeMX 生成时保留这些区块),要么就尽量在Core/Src之外的目录建立自己的业务代码文件,避免被覆盖。
我在实际项目里是把Core/Src/main.c、Core/Src/stm32f4xx_it.c这类原生成文件里的改动压缩到最小,自己业务逻辑全部放到App/目录下自己创建的 C 文件。CubeMX 只管初始化代码,业务代码和硬件抽象分离,这样升级 HAL 库或重新生成工程时不会杀得乱七八糟。
5.4 监控资源:用 perf 和 systemtap 分析性能
嵌入式开发偶尔得解决性能瓶颈问题。在 Linux 主机上开发时,你可以用 perf 工具收集程序的运行特征,再结合 STM32CubeMonitor 做数据可视化分析。不过有个前提:目标芯片要开启 DWT(Data Watchpoint and Trace)单元的周期计数寄存器(DWT->CYCCNT),这是 Cortex-M3/M4 内核自带的性能计数器。在代码初始化阶段加上:
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CYCCNT = 0; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;之后就能通过DWT->CYCCNT读取 CPU 运行的时钟周期数,在分析冷启动时间、中断响应延迟时非常有用,而且对运行性能零开销。配合 STM32CubeMonitor 的实时变量监控,可以不用中断程序就能观察全局变量变化趋势。
6. 聊聊我对 ST 免费工具链在 Linux 生态中的观察
从行业角度看,ST 这次对 Linux 的全面支持绝不是一个孤立事件。STM32 系列芯片在 IoT、工业控制、消费电子领域有着庞大的装机量,而 Linux 在嵌入式开发和云计算基础设施领域处于绝对主导地位。ST 主动向 Linux 用户开放全链路工具,本质上是在顺应整个开发者生态向 Linux 迁徙的趋势。
我更关注的是这种变化给开发者带来的实际影响。以前团队成员有人用 Windows、有人用 macOS、有人用 Linux,同一套代码在不同平台上编译结果偶尔不一致,CI/CD 构建只能用 Windows server 跑。现在全团队统一到 Linux 环境后,工具链可复现性大幅提升,编译构建、单元测试、静态检查这些环节都自动化跑起来了。对我这种长期用 Linux 的开发者来说,能在本机完成从原理图、代码到烧录验证的全流程,再也不用开虚拟机或者找一台 Windows 机器了,效率提升是实打实的。
当然,这套工具链在 Linux 下还有一些细节需要打磨,比如某些 STM32 系列的图形化配置界面响应速度不及 Windows 版,ST-Link 的虚拟串口在 Linux 下需要单独配置 modemmanager 禁用规则等等。不过总体而言,ST 在 Linux 生态中的工具链支持已经进入成熟可用阶段,值得每个嵌入式开发者认真对待。