2. Rust与嵌入式开发环境搭建:Rust工具链安装、目标平台配置(ARM Cortex-M)、使用cargo-generate创建项目
说实话,很多初学者在嵌入式开发上栽跟头,不是栽在代码逻辑上,而是栽在环境搭建上。工具链没配好,后面全是坑。我见过太多人花了一周时间折腾环境,最后发现是编译器版本不对。
这一章,咱们就把环境彻底搞定。ARM Cortex-M 平台,Rust 工具链,一步到位。
2.1 Rust 工具链安装
先装 Rust。这个简单,但有几个细节要注意。
核心命令:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
装完之后,检查一下版本:
rustc --version
cargo --version
rustup --version
我个人习惯用 rustup 管理多版本。为什么?因为嵌入式开发经常需要 nightly 版本。比如我们后面要用的 DMA 相关特性,有些还在 nightly 里。
小技巧: 如果你在公司网络环境下安装,记得先配好代理。我曾经在客户现场折腾了半天,最后发现是公司防火墙把下载给拦了。
2.2 目标平台配置:ARM Cortex-M
Rust 默认编译的是你当前电脑的架构。要编译 ARM Cortex-M 的代码,得先添加目标平台。
常用的 Cortex-M 目标有这些:
| 目标三元组 | 对应芯片 | 说明 |
|---|---|---|
thumbv6m-none-eabi |
Cortex-M0, M0+ | ARMv6-M 架构,无浮点 |
thumbv7m-none-eabi |
Cortex-M3 | ARMv7-M 架构,无浮点 |
thumbv7em-none-eabi |
Cortex-M4 | ARMv7E-M 架构,无浮点 |
thumbv7em-none-eabihf |
Cortex-M4F | 带硬件浮点 |
thumbv8m.main-none-eabi |
Cortex-M33 | ARMv8-M 架构 |
添加目标平台:
rustup target add thumbv7em-none-eabihf
嗯,这里要注意。如果你用的是 Cortex-M4 带 FPU 的芯片,比如 STM32F407,那就选 thumbv7em-none-eabihf。如果选错了,编译出来的程序可能跑不起来。
避坑指南: 我曾经帮一个同事调试,他用的 STM32F103(Cortex-M3),却加了 thumbv7em-none-eabihf 目标。结果链接器报了一堆奇怪的错误。后来改成 thumbv7m-none-eabi 就一切正常了。
2.3 安装必要的工具
除了 Rust 工具链,还需要几个嵌入式开发的必备工具:
- cargo-binutils:用于查看生成的二进制文件
- cargo-flash:烧录工具
- cargo-embed:调试和烧录一体化工具
- probe-rs:调试器驱动
安装命令:
cargo install cargo-binutils
cargo install cargo-flash
cargo install cargo-embed
cargo install probe-rs --features cli
为什么推荐 probe-rs?因为它支持 JLink、ST-Link、DAPLink 等多种调试器,不用来回切换驱动。我在项目中用过很多调试器,probe-rs 的兼容性是最好的。
2.4 使用 cargo-generate 创建项目
手动创建嵌入式项目很繁琐。要写 .cargo/config.toml、memory.x、build.rs 等等。好在有 cargo-generate,可以基于模板一键生成。
先安装:
cargo install cargo-generate
然后创建项目:
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
这个模板包含了 Cortex-M 项目的基本骨架。生成后,目录结构是这样的:
my-project/
├── .cargo/
│ └── config.toml # 编译配置
├── src/
│ └── main.rs # 主程序
├── memory.x # 内存布局
├── build.rs # 构建脚本
├── Cargo.toml
└── openocd.cfg # 调试配置(可选)
关键文件说明:
.cargo/config.toml:指定目标平台和链接器memory.x:定义 Flash 和 RAM 的起始地址和大小build.rs:自动生成链接脚本
2.5 配置 memory.x
memory.x 是链接脚本的核心。它告诉链接器芯片的 Flash 和 RAM 在哪里。
以 STM32F407 为例:
MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 1024K
RAM : ORIGIN = 0x20000000, LENGTH = 128K
}
不同芯片的地址不同。比如 STM32F103C8T6 的 Flash 只有 64K,RAM 只有 20K。写错了程序就飞了。
个人经验: 我习惯在项目根目录放一个 memory.x 的注释版,把芯片型号和地址范围都写清楚。这样换芯片时直接改,不用翻数据手册。
2.6 编译与验证
配置完成后,编译验证一下:
cargo build --release
如果一切正常,你会看到类似这样的输出:
Compiling my-project v0.1.0
Finished release [optimized] target(s) in 2.34s
生成的二进制文件在 target/thumbv7em-none-eabihf/release/ 目录下。
可以用 cargo-size 查看大小:
cargo size --release
输出示例:
text data bss dec hex filename
1200 0 0 1200 4b0 my-project
只有 1.2KB!这就是嵌入式 Rust 的魅力——没有运行时开销。
2.7 本章知识体系
下面这张图总结了整个环境搭建的流程和关键节点:
2.8 常见问题与解决
环境搭建过程中,有几个问题经常遇到:
| 问题 | 原因 | 解决方法 |
|---|---|---|
链接器报错:LINKER 未定义 |
缺少 build.rs 或 memory.x |
检查项目模板是否完整 |
编译报错:target-cpu 不匹配 |
目标平台选错 | 确认芯片型号,重新添加目标 |
| 烧录失败:无法连接调试器 | 驱动未安装或调试器未识别 | 安装 probe-rs 驱动 |
| 程序跑飞:进入 HardFault | memory.x 配置错误 |
核对芯片数据手册的地址范围 |
避坑指南: 我曾经在 STM32F429 上配错了 Flash 大小,把 2MB 写成了 1MB。程序能烧录,但跑到后半段就死机。查了两天才发现是 memory.x 的问题。所以,每次改 memory.x 后,一定要用 cargo-size 确认一下。
2.9 小结
环境搭建是嵌入式开发的第一步,也是最容易出问题的一步。装好 Rust 工具链,配好目标平台,用 cargo-generate 创建项目,改好 memory.x,然后编译验证。每一步都确认无误,后面才能安心写代码。