一个 no_std Rust 环境

嵌入式编程这个术语用于指代各种不同的编程类别。范围从编程只有几 KB RAM 和 ROM 的 8 位 MCU(如 ST72325xx),到像 Raspberry Pi (Model B 3+) 这样的系统,它拥有一个 32/64 位 4 核 Cortex-A53 @ 1.4 GHz 和 1GB RAM。根据你拥有的目标和用例类型,在编写代码时会有不同的限制/约束。

有两种通用的嵌入式编程分类

托管环境

这类环境接近于普通的 PC 环境。这意味着为你提供了一个系统接口 例如 POSIX,它为你提供了与各种系统交互的原语,如文件系统、网络、内存管理、线程等。标准库反过来通常依赖这些原语来实现其功能。你可能还有一些 sysroot 和对 RAM/ROM 使用的限制,以及一些特殊的硬件或 I/O。总的来说,感觉就像在专用的 PC 环境中进行编码。

裸机环境

在裸机环境中,你的程序之前没有加载任何代码。如果没有操作系统提供的软件,我们就无法加载标准库。相反,该程序及其使用的 crate 只能使用硬件(裸机)来运行。要阻止 rust 加载标准库,请使用 no_std。标准库中与平台无关的部分可以通过 libcore 获得。libcore 还排除了在嵌入式环境中不总是需要的东西。其中一件是用于动态内存分配的内存分配器。如果你需要这个或任何其他功能,通常会有 crate 提供这些功能。

libstd 运行时

如前所述,使用 libstd 需要某种系统集成,但这不仅是因为 libstd 只是提供了一种访问 OS 抽象的通用方法,它还提供了一个运行时。此运行时除其他外,负责设置堆栈溢出保护、处理命令行参数以及在调用程序的 main 函数之前生成主线程。此运行时在 no_std 环境中也无法使用。

总结

#![no_std] 是一个 crate 级别的属性,指示该 crate 将链接到 core-crate 而不是 std-crate。 libcore crate 反过来是 std crate 的一个与平台无关的子集,它对程序将在其上运行的系统不做任何假设。因此,它为语言原语(如浮点数、字符串和切片)以及暴露处理器特性(如原子操作和 SIMD 指令)的 API 提供了 API。但是,它缺少任何涉及平台集成的 API。由于这些特性,no_std 和 libcore 代码可以用于任何类型的引导(第 0 阶段)代码,如引导加载程序、固件或内核。

概览

特性no_stdstd
堆(动态内存)*
集合 (Vec, BTreeMap 等)**
堆栈溢出保护
在 main 之前运行初始化代码
libstd 可用
libcore 可用
编写固件、内核或引导加载程序代码

* 仅当您使用 alloc crate 并使用合适的分配器,例如 alloc-cortex-m 时。

** 仅当您使用 collections crate 并配置全局默认分配器时。

** 由于缺少安全的随机数生成器,HashMap 和 HashSet 不可用。

另请参阅