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 本章知识体系
下面这张图概括了咱们搭建的环境全貌:
2.8 小结
到这一步,你的开发环境已经搭好了。我们完成了:
- 安装Rust工具链(rustup + cargo)
- 添加嵌入式目标
thumbv7em-none-eabihf - 安装
cargo-generate并创建项目 - 成功编译第一个嵌入式Rust程序