为微控制器编译
现在让我们谈谈嵌入式系统。当涉及到为微控制器编译 Rust 代码时,情况与普通桌面系统略有不同。微控制器通常不运行像 Linux 或 Windows 这样的完整操作系统。相反,它们在一个最小的环境中运行,通常根本没有操作系统。这被称为裸机(bare-metal)环境。
Rust 通过其 no_std 模式支持这种设置。在普通的 Rust 程序中,标准库(std)处理文件系统、线程、堆分配和 I/O 等事务。但在裸机微控制器上,这些都不存在。因此,我们不使用 std,而是使用一个小得多的 core 库,它只提供基本的构建块。
Pico 2 的目标三元组
Raspberry Pi Pico 2(RP2350 芯片),正如你已经知道的那样,它是独特的;它包含可选择的 ARM Cortex-M33 和 Hazard3 RISC-V 核心。你可以选择使用哪种处理器架构。
ARM Cortex-M33 目标
对于 ARM 模式,我们必须使用目标 [thumbv8m.main-none-eabi](https://doc.rust-lang.org/nightly/rustc/platform-support/thumbv8m.main-none-eabi.html):
让我们分解一下:
- 架构(Architecture)(thumbv8m.main):Cortex-M33 使用用于 ARMv8-M 架构的 ARM Thumb-2 指令集。
- 供应商(Vendor)(none):没有特定的供应商指定。
- 操作系统(OS)(none):没有操作系统 - 它是裸机的。
- 二进制接口(ABI)(eabi):嵌入式应用二进制接口(Embedded Application Binary Interface),嵌入式 ARM 系统的标准调用约定。
要安装并使用此目标:
rustup target add thumbv8m.main-none-eabi
cargo build --target thumbv8m.main-none-eabi
RISC-V Hazard3 目标
对于 RISC-V 模式,使用目标: riscv32imac-unknown-none-elf
让我们分解一下:
- 架构(Architecture)(riscv32imac):具有 I(整数)、M(乘法/除法)、A(原子)和 C(压缩)指令集的 32 位 RISC-V。
- 供应商(Vendor)(unknown):没有特定的供应商。
- 操作系统(OS)(none):没有操作系统 - 它是裸机的。
- 格式(Format)(elf):ELF(可执行和可链接格式),嵌入式系统中常用的对象文件格式。
要安装并使用此目标:
rustup target add riscv32imac-unknown-none-elf
cargo build --target riscv32imac-unknown-none-elf
在我们的练习中,我们将主要使用 ARM 模式。像 panic-probe 这样的一些 crate 在 RISC-V 模式下无法工作。
Cargo 配置
在快速开始中,你可能已经注意到我们在运行 cargo 命令时从未手动传递 --target 标志。那么它是如何知道要为哪个目标构建的呢?这是因为目标已经在 .cargo/config.toml 文件中配置好了。
这个文件允许你存储与 cargo 相关的设置,包括默认使用哪个目标。要为 ARM 模式下的 Pico 2 设置它,请在你的项目根目录中创建一个 .cargo 文件夹,并添加一个包含以下内容的 config.toml 文件:
[build]
target = "thumbv8m.main-none-eabihf"
现在你不必每次都传递 --target。Cargo 将自动使用此设置。