嵌入式开发
问题
Rust 在嵌入式场景有什么优势?no_std 是什么?
答案
Rust 的零成本抽象和内存安全使其成为嵌入式开发的理想选择——没有 GC、可控的内存布局、编译时消除空指针。
no_std 环境
no_std 意味着不使用标准库(std),只使用核心库(core)和可选的内存分配库(alloc):
src/main.rs
#![no_std] // 不链接标准库
#![no_main] // 不使用标准入口点
use core::panic::PanicInfo;
// 必须提供 panic handler
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
// 嵌入式入口点(以 cortex-m 为例)
#[cortex_m_rt::entry]
fn main() -> ! {
// 点亮一个 LED
let peripherals = stm32f4xx_hal::pac::Peripherals::take().unwrap();
// ... 硬件操作
loop {}
}
std vs no_std 可用功能
| 功能 | std | core | alloc |
|---|---|---|---|
| 基本类型、Trait | ✅ | ✅ | ✅ |
Option/Result | ✅ | ✅ | ✅ |
Vec/String/Box | ✅ | ❌ | ✅ |
HashMap | ✅ | ❌ | ❌ |
| 文件 IO | ✅ | ❌ | ❌ |
| 网络 | ✅ | ❌ | ❌ |
| 线程 | ✅ | ❌ | ❌ |
Embassy 异步嵌入式框架
Embassy 把 Rust 的 async/await 带到嵌入式:
#[embassy_executor::main]
async fn main(_spawner: embassy_executor::Spawner) {
let p = embassy_stm32::init(Default::default());
let mut led = Output::new(p.PB7, Level::High, Speed::Low);
loop {
led.set_high();
Timer::after_millis(500).await; // 异步等待,不阻塞
led.set_low();
Timer::after_millis(500).await;
}
}
Embassy 的零成本异步不需要 RTOS,任务切换在编译时完成。
常见面试问题
Q1: 为什么 Rust 适合嵌入式开发?
答案:
- 零成本抽象:高级 API 编译后与手写 C 一样高效
- 内存安全:编译时消除空指针、缓冲区溢出等嵌入式常见 Bug
- 没有 GC:可预测的内存行为,无 STW 暂停
no_std:可以在几 KB RAM 的 MCU 上运行- 类型系统:用 Typestate 模式在编译时防止硬件误操作