2. 开发环境搭建:安装Rust工具链与嵌入式目标
说实话,嵌入式Rust开发的第一步,往往就把不少人挡在门外。不是Rust本身难,而是工具链的配置确实有点绕。我刚开始接触时也踩过不少坑——明明照着教程一步步来,结果编译出来的二进制烧进去就是跑不起来。
这一节,咱们就把环境彻底搭好。你跟着我走一遍,保证后面写驱动时不会因为工具链问题卡壳。
2.1 安装Rust工具链:rustup与cargo
Rust的工具链管理工具叫rustup。它负责安装、切换、更新Rust编译器(rustc)和包管理器(cargo)。说白了,rustup就是Rust世界的“版本管家”。
安装命令很简单(Linux/macOS/WSL):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Windows用户可以去官网下载rustup-init.exe。我个人习惯用WSL2做嵌入式开发,因为调试工具在Linux下更顺手。
安装完成后,验证一下:
rustup --version
cargo --version
rustc --version
如果都正常输出版本号,说明工具链装好了。
~/.cargo/config.toml 中添加:
[source.crates-io]
replace-with = 'ustc'
[source.ustc]
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
我当年没配镜像,下个依赖等了半小时……嗯,别学我。
2.2 添加嵌入式目标:thumbv7em-none-eabihf
Rust默认安装的是宿主机的目标(比如x86_64-unknown-linux-gnu)。但嵌入式开发需要交叉编译——你的代码要在ARM Cortex-M这类芯片上跑。
常用的嵌入式目标有这几个:
| 目标三元组 | 适用架构 | 浮点支持 | 典型芯片 |
|---|---|---|---|
thumbv6m-none-eabi |
Cortex-M0, M0+, M1 | 无 | STM32F0, nRF51822 |
thumbv7m-none-eabi |
Cortex-M3 | 无 | STM32F1, LPC1768 |
thumbv7em-none-eabi |
Cortex-M4, M7(无FPU) | 软件模拟 | STM32F4(某些型号) |
thumbv7em-none-eabihf |
Cortex-M4F, M7(有FPU) | 硬件浮点 | STM32F407, nRF52840 |
thumbv8m.main-none-eabi |
Cortex-M33, M55 | 可选 | STM32U5, LPC55S69 |
咱们课程主要用thumbv7em-none-eabihf,因为大多数Cortex-M4F开发板都支持硬件浮点,性能更好。添加目标:
rustup target add thumbv7em-none-eabihf
验证是否添加成功:
rustup target list --installed
你应该能看到 thumbv7em-none-eabihf 在列表中。
eabi 和 eabihf 的区别。后者明确启用了硬件浮点单元(FPU)。如果你用错了目标,编译出来的代码可能无法正确执行浮点运算——我曾经在这个问题上折腾了一下午,最后发现是目标选错了。
2.3 安装调试工具:probe-rs 与 openocd
代码写好了,怎么烧进去?怎么调试?这就轮到调试工具上场了。
2.3.1 probe-rs(推荐)
probe-rs 是Rust生态里最流行的调试工具。它原生支持Rust,不需要GDB,直接通过USB调试器(如ST-Link、J-Link、DAPLink)烧录和调试。
安装方式:
cargo install probe-rs --features cli
安装完成后,连接你的开发板,运行:
probe-rs list
如果能看到调试器信息,说明环境通了。
我个人非常喜欢probe-rs的一点是,它可以直接用 cargo run 烧录程序,不需要额外配置。后面写驱动时,你会感受到这种“一键烧录”的爽快。
2.3.2 openocd(备选)
openocd 是更传统的调试工具,支持各种调试器和芯片。如果你用J-Link或者某些冷门调试器,openocd可能是更好的选择。
安装方式(Ubuntu/Debian):
sudo apt install openocd
macOS:
brew install openocd
Windows用户可以去官网下载安装包。
使用openocd时,通常需要写一个配置文件指定调试器和芯片。比如对于STM32F4 + ST-Link:
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
启动后,它会监听GDB端口(默认3333),然后你可以用 gdb-multiarch 连接上去调试。
2.4 验证环境:编译一个空项目
环境搭没搭好,跑个空项目就知道了。创建一个新的Rust项目:
cargo new --bin blinky
cd blinky
在 Cargo.toml 中添加依赖:
[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:
[build]
target = "thumbv7em-none-eabihf"
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip STM32F407VGTx"
然后写一个最简单的 src/main.rs:
#![no_std]
#![no_main]
use panic_halt as _;
use cortex_m_rt::entry;
#[entry]
fn main() -> ! {
loop {}
}
编译:
cargo build
如果编译通过,没有报错,说明你的工具链和目标配置完全正确。
cortex-m-rt 之类的依赖,检查一下网络或者镜像配置。我第一次编译时卡在依赖下载上,后来发现是DNS解析问题——换成 8.8.8.8 就好了。
2.5 知识结构总览
下面这张图帮你理清整个开发环境的关系:
这张图把整个环境分成了四层:工具链、目标、调试器、芯片。你从上往下走一遍,环境就搭好了。
2.6 常见问题与避坑
- 编译报错“linker not found”:缺少ARM链接器。安装
gcc-arm-none-eabi即可:sudo apt install gcc-arm-none-eabi。 - probe-rs 找不到调试器:检查USB权限。Linux下需要添加udev规则,或者用
sudo运行(不推荐)。 - openocd 启动后卡住:可能是调试器驱动问题。Windows下需要安装Zadig驱动,把ST-Link换成WinUSB。
- cargo build 极慢:第一次编译会下载并编译所有依赖,耐心等。之后增量编译会快很多。