02-no_std
no_std)2 分钟阅读
译文 · 基于 The Embedded Rust Book
no_std
原文链接: https://doc.rust-lang.org/stable/embedded-book/intro/no-std.html
“嵌入式编程”这一术语涵盖了非常广泛的编程类别。 从只有几 KB RAM 与 ROM 的 8 位 MCU(如 ST72325xx), 到像 Raspberry Pi(Model B 3+)这样拥有 32/64 位 4 核 Cortex-A53 @ 1.4 GHz 与 1GB RAM 的系统。根据目标与用例的不同,编写代码时会面临不同的限制。
嵌入式编程大体有两类:
托管环境(Hosted Environments)
这类环境接近普通 PC 环境。 这意味着你会得到某种系统接口(例如 POSIX), 它提供与文件系统、网络、内存管理、线程等各类系统交互的原语。 标准库通常依赖这些原语来实现其功能。 你也可能有某种 sysroot,以及对 RAM/ROM 使用的限制,或许还有一些特殊硬件或 I/O。 整体感觉就像在专用 PC 环境上编码。
裸机环境(Bare Metal Environments)
在裸机环境中,在你的程序之前没有任何代码被加载。
没有操作系统提供的软件,我们就无法加载标准库。
程序及其所用的 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 的平台无关子集,
不对程序将运行其上的系统做任何假设。
因此,它为浮点数、字符串与切片等语言原语提供 API,也暴露原子操作与 SIMD 指令等处理器特性。
但它缺少任何涉及平台集成的 API。
正因这些特性,no_std 与 libcore 代码可用于任何引导(stage 0)代码,
如引导加载程序、固件或内核。
概览
| 功能 | no_std | std |
|---|---|---|
| 堆(动态内存) | * | ✓ |
| 集合(Vec、BTreeMap 等) | ** | ✓ |
| 栈溢出保护 | ✘ | ✓ |
| 在 main 前运行初始化代码 | ✘ | ✓ |
| 可用 libstd | ✘ | ✓ |
| 可用 libcore | ✓ | ✓ |
| 编写固件、内核或引导加载程序代码 | ✓ | ✘ |
* 仅当你使用 alloc crate,并使用合适的分配器(如 alloc-cortex-m)时。
** 仅当你使用 collections crate 并配置全局默认分配器时。
** 由于缺少安全的随机数生成器,HashMap 与 HashSet 不可用。