一个 no_std Rust环境
嵌入式编程这个词被广泛用于许多不同的编程场景中。小到RAM和ROM只有KB的8位机(像是ST72325xx),大到一个具有32/64位4核Cortex-A53和1GB RAM的系统,比如树莓派(Model B 3+)。当编写代码时,取决于你的目标环境和用例,将会有不同的限制和局限。
通常嵌入式编程有两类:
主机环境
这类环境与一个常见的PC环境类似。意味着向你提供了一个系统接口E.G. POSIX,使你能和不同的系统进行交互,比如文件系统,网络,内存管理,进程,等等。标准库相应地依赖这些接口去实现它们的功能。sysroot可能限制你使用RAM/ROM,可能还有一些特别的硬件或者I/O。总之感觉像是在专用的PC环境上编程一样。
裸机环境
在一个裸机环境中,你的程序被加载前,不存在代码。没有系统提供的软件,我们不能加载标准库。相反地,该程序,以及它使用的crates只能使用硬件(裸机)去运行。使用no-std
可以防止rust读取标准库。标准库中与平台无关的部分在libcore中。libcore剔除了那些在一个嵌入式环境中非必要的东西。比如用于动态分配的内存分配器。如果你需要这些或者其它的某些功能,通常会有提供这些功能的crates。
libstd运行时
就像之前提到的,使用libstd需要一些系统集成,这不仅仅是因为libstd使用了一个公共的方法访问操作系统,它也提供了一个运行时环境。这个运行时环境,负责设置堆栈溢出保护,处理命令行参数,并在一个程序的主函数被激活前启动一个主线程。在一个no_std
环境中,这个运行时环境也是不可用的。
总结
#![no_std]
是一个crate层级的属性,它说明crate将连接至core-crate而不是std-crate。libcore crate是std crate的一个的子集,其与平台无关,它对程序将要运行的系统没有做要求。比如,它提供了像是floats,strings和切片的APIs,暴露了像是与原子操作和SIMD指令相关的处理器功能的APIs。然而,它缺少涉及到平台集成的那些APIs。由于这些特性,no_std和libcore代码可以用于任何引导程序(stage 0)像是bootloaders,固件或者内核。
概述
feature | no_std | std |
---|---|---|
heap (dynamic memory) | ✓ | |
collections (Vec, HashMap, etc) | * | ✓ |
stack overflow protection | ✘ | ✓ |
runs init code before main | ✘ | ✓ |
libstd available | ✘ | ✓ |
libcore available | ✓ | ✓ |
writing firmware, kernel, or bootloader code | ✓ | ✘ |
* 只有在你使用了 alloc
crate 和设置了一个适合的分配器,比如alloc-cortex-m后有效。
** 只有在你使用了 collections
crate 并配置了一个全局默认的分配器后有效。