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 连接上去调试。

我的建议: 新手优先用probe-rs。它跟Rust生态集成得更好,命令行也更简洁。openocd虽然功能强大,但配置起来比较繁琐。等你熟悉了嵌入式Rust开发流程,再回头研究openocd也不迟。

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 知识结构总览

下面这张图帮你理清整个开发环境的关系:

嵌入式Rust开发环境结构图 嵌入式Rust开发环境结构 Rust工具链 嵌入式目标 调试工具 rustup cargo thumbv7em -none-eabihf thumbv7m -none-eabi probe-rs openocd 硬件调试器(ST-Link / J-Link / DAPLink) 通过SWD或JTAG接口连接目标芯片 目标芯片(Cortex-M4F / M7 等) 说明: rustup管理Rust版本,cargo负责构建和依赖,嵌入式目标指定交叉编译架构,调试工具负责烧录和调试。

这张图把整个环境分成了四层:工具链、目标、调试器、芯片。你从上往下走一遍,环境就搭好了。

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 极慢:第一次编译会下载并编译所有依赖,耐心等。之后增量编译会快很多。
避坑指南: 我曾经在Windows上用openocd调试STM32F4,结果一直报错“Error: unable to find a matching CMSIS-DAP device”。折腾了两天,最后发现是ST-Link的固件版本太旧。更新固件后一切正常。所以,如果你遇到类似问题,先检查调试器固件。