2. Rust与嵌入式环境搭建:安装Rust工具链、配置嵌入式目标、使用cargo-generate创建项目

好,咱们正式开始动手。这一章的目标很明确——把电脑变成一台能编译嵌入式Rust代码的机器。我见过不少新手卡在这一步,不是工具链装错版本,就是目标配置漏了关键项。别急,跟着我的节奏来,半小时内你就能跑通第一个嵌入式Rust项目。

2.1 安装Rust工具链

先装Rust本身。我个人习惯用官方推荐的rustup,它不仅是安装器,更是版本管理器。你想想看,以后可能要同时维护多个项目,有的用stable,有的用nightly,rustup一键切换,省心。

核心命令:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

安装完成后,重启终端或执行 source $HOME/.cargo/env 使环境变量生效。

验证安装:

rustc --version
cargo --version
rustup --version

输出类似这样就算成了:

rustc 1.77.0 (a36d4b6f1 2024-03-22)
cargo 1.77.0 (1d6b6c0e3 2024-03-22)
rustup 1.27.0 (1.26.0)

小技巧:如果你在Windows上开发,建议用WSL2(Ubuntu 22.04 LTS)。我之前在原生Windows下折腾过一阵,链接脚本和工具链路径总出幺蛾子。换了WSL2后,世界清净了。

2.2 配置嵌入式目标(thumbv7em-none-eabihf)

为什么是这个目标?说白了,thumbv7em-none-eabihf 对应的是ARM Cortex-M4/M7内核,带硬件浮点单元(FPU)。咱们课程用的STM32F4系列,正是这个架构。

添加目标:

rustup target add thumbv7em-none-eabihf

查看已安装的目标列表:

rustup target list --installed

你应该能看到 thumbv7em-none-eabihf 在列表中。

目标三元组 适用内核 浮点支持 典型芯片
thumbv6m-none-eabi Cortex-M0/M0+/M1 无 STM32F0
thumbv7m-none-eabi Cortex-M3 无 STM32F1
thumbv7em-none-eabi Cortex-M4/M7 软浮点 STM32F4(无FPU版本)
thumbv7em-none-eabihf Cortex-M4/M7 硬浮点 STM32F4(有FPU版本)

注意:千万别选错目标。我曾经帮一个同事排查编译问题,折腾了两小时,最后发现他配的是 thumbv7m-none-eabi(Cortex-M3),而芯片是STM32F407(Cortex-M4)。目标不匹配,链接阶段直接报错。

2.3 安装cargo-generate

cargo-generate 是一个项目生成工具,能从GitHub模板仓库快速创建新项目。咱们用它来拉取嵌入式Rust的标准项目模板。

安装命令:

cargo install cargo-generate

这个过程会编译一些依赖,大概需要3-5分钟。趁这个时间,你可以去泡杯咖啡。

提速建议:如果你网络环境不太好,可以预先设置cargo镜像源。在 ~/.cargo/config.toml 中添加:

[source.crates-io]
replace-with = 'ustc'

[source.ustc]
registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"

中科大的镜像,速度稳得很。

2.4 使用cargo-generate创建项目

模板我用的是 rust-embedded/cortex-m-quickstart,这是官方维护的快速启动模板,包含了链接脚本、内存布局、启动代码等基础设施。

创建项目:

cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart \
    --name my-dma-project

命令执行后,会交互式询问一些问题:

  • Project Name: 默认就是 my-dma-project
  • Target: 选择 thumbv7em-none-eabihf
  • MCU: 输入 STM32F407(咱们课程用的芯片)

生成后的目录结构:

my-dma-project/
├── .cargo/
│   └── config.toml      # cargo配置,指定目标、链接器
├── src/
│   └── main.rs          # 主程序入口
├── memory.x             # 内存布局文件(Flash、RAM大小)
├── build.rs             # 构建脚本
├── Cargo.toml           # 项目依赖配置
├── openocd.cfg          # OpenOCD调试配置
└── .gitignore

2.5 验证编译

进入项目目录,尝试编译:

cd my-dma-project
cargo build

如果一切顺利,你会看到类似这样的输出:

Compiling my-dma-project v0.1.0 (/path/to/my-dma-project)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.34s

生成的ELF文件在 target/thumbv7em-none-eabihf/debug/my-dma-project。

验证要点:

  • 确认编译目标正确:thumbv7em-none-eabihf
  • 确认没有链接错误(undefined reference等)
  • 确认生成的文件大小合理(空项目一般在10KB以内)

2.6 常见问题与避坑

问题1:链接器找不到

错误信息:error: linker `arm-none-eabi-gcc` not found

解决方案:安装ARM GCC工具链。

# Ubuntu/Debian
sudo apt install gcc-arm-none-eabi

# macOS
brew install arm-none-eabi-gcc

# Windows (WSL2)
sudo apt install gcc-arm-none-eabi

问题2:内存布局不匹配

错误信息:error: L6235E: More than one section matches selector

原因:memory.x 中的Flash/RAM大小与芯片实际不符。

解决方案:检查芯片手册,修改 memory.x 中的值。以STM32F407VG为例:

MEMORY
{
  FLASH : ORIGIN = 0x08000000, LENGTH = 1024K
  RAM   : ORIGIN = 0x20000000, LENGTH = 128K
}

我的经验:第一次编译嵌入式Rust项目时,我卡在链接器配置上整整半天。后来发现是 .cargo/config.toml 中的 runner 配置写错了。如果你用OpenOCD调试,runner 应该指向 arm-none-eabi-gdb,而不是 gdb-multiarch。细节决定成败啊。

2.7 本章知识体系

下面这张图概括了咱们搭建的环境全貌:

Rust嵌入式开发环境搭建流程 Rust嵌入式开发环境搭建流程 Rust工具链 rustup / rustc / cargo 嵌入式目标 thumbv7em-none-eabihf 项目模板 cargo-generate 生成的项目结构 .cargo/config.toml | src/main.rs | memory.x build.rs | Cargo.toml | openocd.cfg .gitignore 验证:cargo build 生成 target/thumbv7em-none-eabihf/debug/xxx 💡 核心要点:工具链 → 目标配置 → 项目生成 → 编译验证,四步走通嵌入式Rust开发环境 常见坑:目标选错、链接器缺失、memory.x不匹配

2.8 小结

到这一步,你的开发环境已经搭好了。我们完成了:

  • 安装Rust工具链(rustup + cargo)
  • 添加嵌入式目标 thumbv7em-none-eabihf
  • 安装 cargo-generate 并创建项目
  • 成功编译第一个嵌入式Rust程序