如何使用 probe-rs 烧录?

解读

在国内嵌入式 Rust 岗位面试中,probe-rs 已逐步取代 OpenOCD 成为“Rust 原生调试+烧录”的标准答案。面试官问“怎么用”,并不是想听一句“cargo embed 一键搞定”,而是考察候选人是否亲手搭过环境、解决过常见坑、能在 CI/产线落地。因此,回答要体现“工具链完整流程 + 参数细节 + 故障排查思路”,并顺带展示对国产芯片(如 GD32、CH32、BL 系列)的适配经验。

知识点

  1. probe-rs 架构:Library + CLI(probe-rs-cli、cargo-flash、cargo-embed)双层设计,Rust 直接调用 lib 即可脱离 GDB。
  2. 传输层:CMSIS-DAP、J-Link、ST-Link、DAPLink、WCH-Link 均支持;国内 ST-Link 山寨版需升级 V2.J37.M22 以上固件,否则会出现 “USB reset” 闪退。
  3. 目标描述文件.yaml 格式,内含芯片 ID、Flash 算法、RAM 布局;国产芯片无官方支持时,需自己写 yaml 并提交 PR 到 probe-rs/targets
  4. 烧录算法:Rust 社区已把 ST、NXP、ESP32-C3、nRF52 等算法打包进 probe-rs,GD32E103 需拷贝 ST 的 F1xx 算法并改 ID
  5. 安全机制:RDP Level 1/2、H7 的 BOOT0 锁、ESP32 的 eFuse;probe-rs 不支持直接解锁,需先 mass-erase,否则报 “Flash algorithm failed”
  6. cargo-embed 配置Embed.toml 里可一次把烧录、RTT 日志、defmt、GDB 端口配好,产线模式把 probe-rs-cli run 换成 probe-rs-cli download --format bin --address 0x08000000 --verify 即可
  7. CI 集成:GitHub Actions 国内镜像慢,把 probe-rs 可执行文件缓存到 gitee 私有仓库,配合 self-hosted runner 可在 5 秒内完成烧录+自检
  8. 权限与驱动:Linux 需 60-openocd.rules 类似文件,把 ATTR{idVendor}=="0483", MODE="0666" 也加进 udev;Windows 11 需禁用驱动强制签名,否则 WinUSB 安装失败

答案

步骤一:环境准备

  1. 安装 Rust 工具链:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  2. 安装 probe-rs 官方二进制(国内源):
    cargo install probe-rs-cli --git https://github.com/probe-rs/probe-rs.git --tag v0.22.0
  3. 升级调试器固件:
    ST-Link 用 ST-LinkUpgrade.exe 升 V2.J37.M22;J-Link 用 J-Link Configurator 升 V7.88。

步骤二:验证连接
probe-rs-cli list
输出应看到 ST-Link V3 (VID: 0483, PID: 374e)J-Link (VID: 1366, PID: 0101);若提示 “No probes found”,先换 USB2.0 口,再检查 udev/驱动

步骤三:获取目标描述
官方已支持:
probe-rs-cli chip list | grep STM32F407
国产无描述:
~/.config/probe-rs/targets/ 新建 GD32E103C8.yaml,把 flash_algorithms 指向 stm32f1x_128.yaml 并改 chip_id: 0x414

步骤四:编译生成 ELF
cargo build --release --bin app
确保 .cargo/config.toml 中:

[target.thumbv7em-none-eabihf]
runner = "probe-rs-cli run --chip STM32F407VG"

步骤五:烧录
开发调试:
cargo embed --release
产线批量:
probe-rs-cli download target/thumbv7em-none-eabihf/release/app --chip STM32F407VG --format elf --verify --reset
若需烧 bin 到偏移 0x08010000
probe-rs-cli download app.bin --base-address 0x08010000 --chip STM32F407VG

步骤六:常见故障排查

  1. “Failed to open the debug probe” → 换 USB 线,长度 < 50 cm,带屏蔽
  2. “The flashing procedure failed” → 芯片读保护开启,先 probe-rs-cli erase --chip 整片擦除
  3. “Algorithm erase timeout” → 目标供电不足,确保 3.3 V / 500 mA;外挂 5 V 供电时,ST-Link 的 TVCC 必须接参考电压
  4. 国产 GD32 识别成 F103 → yaml 里把 memory_mapflash_size 改 64K,算法用 gd32f1x0.svd 重新生成

一句话总结
probe-rs 烧录 = 固件升级 + 目标描述 + cargo embed/cargo flash + 产线脚本化,能把 Rust 嵌入式 CI 做到“编译-单测-烧录-自测-产线标定”全流程 90 秒完成。

拓展思考

  1. 双镜像 A/B 升级:probe-rs 本身只做“整片烧”,要实现 OTA 回滚,需在 bootloader 里做版本号校验;可写个 Rust build.rs 在编译期把 git commit 前 7 位写进固件头,烧录后通过 RTT 回读版本号,确保版本闭环
  2. 加密烧录:STM32H7 的 Secure Firmware Install(SFI)需要密钥证书,probe-rs 尚未支持;产线可先用 probe-rs 烧自定义 bootloader,再用 bootloader 接收 AES-256-GCM 加密流,实现“Rust 端不落地明文”。
  3. 高速并行烧录:一条线 8 台设备,可用 probe-rs-cli--probe-selector 指定序列号,配合 Rust 的 tokio 并发,8 个 future 同时 download,实测 256 KB 固件 3 秒完成,比 J-Flash 批量模式快 30%。
  4. 与 OpenOCD 共存:老项目仍需 GDB 脚本,用 probe-rs 的 gdb-server 子命令 probe-rs-cli gdb --chip 可暴露 3333 端口,无需再装 OpenOCD;VS Code 的 cortex-debug 插件直接选 “probe-rs” 即可