1. Rust嵌入式开发环境搭建:安装Rust工具链、配置交叉编译目标、使用probe-rs与调试器
嵌入式Rust开发,第一步就是搭环境。这事儿说难不难,说简单吧,坑也不少。我这些年帮团队搭建过不下二十次开发环境,从STM32到ESP32再到RISC-V,每次都能遇到点新花样。今天咱们就把这套流程捋清楚。
1.1 安装Rust工具链
如果你还没装Rust,直接用官方推荐的rustup。我个人习惯用这条命令:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
装完之后,确认一下版本:
rustc --version
cargo --version
rustup --version
嗯,这里要注意。如果你在Windows上开发,建议用WSL2或者直接装MSVC版本的toolchain。我曾经在Windows原生环境下折腾过一整天,最后发现是路径问题——Rust的链接器找不到某些库。后来切到WSL2,十分钟搞定。
1.2 配置交叉编译目标
嵌入式开发嘛,你的代码不是在x86上跑的。你得告诉Rust:我要给ARM Cortex-M编译,或者给RISC-V编译。这就是交叉编译目标。
先看看Rust支持哪些嵌入式目标:
rustup target list | grep thumb
你会看到一堆类似这样的:
| 目标三元组 | 适用架构 | 典型芯片 |
|---|---|---|
| thumbv6m-none-eabi | Cortex-M0, M0+ | STM32F0, nRF51822 |
| thumbv7m-none-eabi | Cortex-M3 | STM32F1, LPC1768 |
| thumbv7em-none-eabi | Cortex-M4, M7 | STM32F4, nRF52840 |
| thumbv8m.main-none-eabi | Cortex-M33, M55 | STM32L5, nRF5340 |
安装目标很简单,比如我要给STM32F407(Cortex-M4)编译:
rustup target add thumbv7em-none-eabi
你想想看,这一步其实就是在你的Rust工具链里加了一套标准库的交叉编译版本。没有它,你的代码连链接都过不去。
1.3 安装probe-rs与调试器
环境搭好了,怎么把程序烧进去?怎么调试?probe-rs就是干这个的。它支持J-Link、ST-Link、DAPLink等常见调试器,而且纯Rust实现,不需要装OpenOCD那种庞然大物。
安装probe-rs:
cargo install probe-rs --features cli
装完之后,接上你的调试器,运行:
probe-rs list
如果看到类似下面的输出,说明调试器被识别了:
Probing target via JTAG
Debug probe found:
STLink V3 (VID: 0x0483, PID: 0x374e, Serial: 003F001F3138511438383133)
我刚开始用probe-rs时,遇到一个很诡异的问题——ST-Link V2识别不到。折腾了半天,发现是固件版本太旧。升级到V2.J37.S7之后就好了。所以如果你遇到类似问题,先检查调试器固件。
1.4 创建并烧录第一个嵌入式Rust项目
环境都齐了,咱们来跑个Hello World——不过嵌入式世界的Hello World是点灯。
创建一个新项目:
cargo new --bin blinky
cd blinky
编辑Cargo.toml,添加依赖:
[package]
name = "blinky"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m-rt = "0.7"
cortex-m-semihosting = "0.5"
panic-halt = "0.2"
[[bin]]
name = "blinky"
path = "src/main.rs"
在项目根目录创建.cargo/config.toml,指定交叉编译器和链接脚本:
[target.thumbv7em-none-eabi]
rustflags = ["-C", "link-arg=-Tlink.x"]
[build]
target = "thumbv7em-none-eabi"
然后写个最简单的main.rs:
#![no_std]
#![no_main]
use panic_halt as _;
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
loop {}
}
编译:
cargo build
烧录:
probe-rs run --chip STM32F407VGTx target/thumbv7em-none-eabi/debug/blinky
1.5 知识体系总览
下面这张图把整个环境搭建的脉络理清楚了。你照着这个流程走,基本不会迷路。
1.6 常见问题与排查
搭环境这件事,一次过是运气,踩坑才是常态。我整理了几个高频问题:
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| probe-rs list找不到调试器 | 驱动未安装 / 权限不足 | Linux下添加udev规则;Windows下装Zadig驱动 |
| 编译报错"file not found for link.x" | 缺少链接脚本或memory.x | 检查.cargo/config.toml路径,或使用cortex-m-quickstart模板 |
| 烧录后芯片不运行 | 启动文件配置错误 / 时钟未初始化 | 检查vector table地址,确认boot引脚电平 |
| GDB连接后无法单步 | 优化级别过高 / 调试符号缺失 | debug模式编译,或加-C debuginfo=2 |
1.7 开发环境验证清单
环境搭完,别急着写代码。先跑一遍这个清单,确认每个环节都通了:
- 工具链验证:rustc --version 和 cargo --version 能正常输出
- 交叉编译目标:rustup target list --installed 包含你的目标三元组
- 调试器识别:probe-rs list 能看到你的调试器型号和序列号
- 编译测试:cargo build --release 能生成elf文件,没有链接错误
- 烧录测试:probe-rs run 能把程序烧进去,芯片开始运行
- 调试测试:probe-rs gdb 能启动GDB服务器,arm-none-eabi-gdb能连接并打断点
这六步都过了,恭喜你,环境算是稳了。后面咱们就可以开始真正玩SPI和I2C了。