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 本章知识体系

下面这张图总结了整个环境搭建的流程和关键节点:

Rust嵌入式环境搭建流程 Rust嵌入式环境搭建流程 安装 Rust 工具链 rustup / cargo / rustc 添加目标平台 thumbv7em-none-eabihf 安装辅助工具 probe-rs / cargo-flash cargo-generate 创建项目 配置 memory.x / .cargo/config.toml / build.rs cargo build --release 关键:目标平台必须与芯片型号匹配,否则编译出来的程序无法运行

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,然后编译验证。每一步都确认无误,后面才能安心写代码。