其他
开发嵌入式/no_std…
在 embedded/no_std Rust 项目中,按无堆、实时、资源受限、中断安全和外设所有权约束设计数据结构、并发与外设访问。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 48/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 53/100 ×0.15
适用场景
开发嵌入式/no_std Rust(MC通用
解决思路
- 开发前查看 .cargo/config.toml 获取目标配置。
- 无堆 -> 栈分配 -> 使用 heapless,禁用 Box/Vec。
- 无 std -> 只用 core -> 使用 #![no_std]。
- 实时 -> 可预测时序 -> 不做动态分配。
- 资源受限 -> 最小内存 -> 使用静态缓冲区。
- 硬件安全 -> 安全外设访问 -> 使用 HAL + ownership。
- 中断安全 -> ISR 不阻塞 -> 使用原子、临界区。
- 无动态分配规则:不能使用堆(无 allocator),原因是确定性内存、无 OOM,Rust 实现用 heapless::Vec<T, N>、数组。
- 中断安全规则:共享状态必须中断安全,因为 ISR 可能随时抢占,Rust 实现用 Mutex<RefCell<T>> + 临界区。
- 硬件所有权规则:外设必须有清晰所有权,防止冲突访问,Rust 实现用 HAL 获取所有权、singletons。
- 需要 no_std 兼容数据结构时,用 heapless collections,静态定长如 heapless::Vec<T, N>。
- 需要中断安全状态时,用 Mutex<RefCell<Option<T>>> 和临界区。
- 需要外设所有权时,用 singleton pattern 和 RAII 管理硬件生命周期。
- 按层选择:PAC 用于寄存器访问,HAL 用于硬件抽象,Framework 用于并发,Traits 用于可移植驱动。
- 选择框架:RTIC 用于基于优先级的中断驱动应用;Embassy 用于异步复杂状态机;裸机手动用于简单应用。
- 使用关键 crate:cortex-m-rt 作 ARM runtime;panic-halt/panic-probe 作 panic handler;heapless 作 collections;embedded-hal 作 HAL traits;defmt 作 logging;probe-run 作 flash/debug。
- 设计模式 no_std setup:使用 #![no_std] + #![no_main]。
- 设计模式入口点:使用 #[entry] 或 embassy。
- 设计模式静态状态:使用 Mutex<RefCell<Option<T>>> 供 ISR 访问。
- 设计模式固定缓冲:使用 heapless::Vec<T, N> 避免堆。
- 静态外设代码:引入 use cortex_m::interrupt::{self, Mutex}; 和 use core::cell::RefCell;。
- 静态外设代码:声明 static LED: Mutex<RefCell<Option<Led>>> = Mutex::new(RefCell::new(None));。
- 静态外设代码:用 #[entry] fn main() -> ! { ... },通过 pac::Peripherals::take().unwrap() 获取外设,创建 Led::new(dp.GPIOA)。
- 静态外设代码:在 interrupt::free 临界区中用 LED.borrow(cs).replace(Some(led)) 保存外设。
- 静态外设代码:在 loop 中于 interrupt::free 临界区中用 if let Some(led) = LED.borrow(cs).borrow_mut().as_mut() { led.toggle(); } 操作外设。
- 常见错误修复:使用 Vec -> 改为 heapless::Vec。
- 常见错误修复:没有临界区 -> 用 Mutex + interrupt::free。
- 常见错误修复:在 ISR 中阻塞 -> 推迟到主循环。
- 常见错误修复:unsafe 操作外设 -> 用 HAL ownership。
- 实现映射:No heap -> Static collections -> heapless::Vec<T, N>;ISR safety -> Critical sections -> Mutex<RefCell<T>>;Hardware ownership -> Singleton -> take().unwrap();no_std -> Core-only -> #![no_std]、#![no_main]。
适用边界 · 注意事项
- 有 std 和堆可用的普通 Rust 应用,不需要 no_std 约束时。
- 非嵌入式、不关心实时性、内存上限或中断安全的场景。
- 没有 MCU/裸机目标或不需要外设所有权管理的开发场景。