直接回答:中断随时抢占主程序,共享可变数据若在多步操作中途被中断改写,就会产生撕裂状态——与多线程数据竞争本质相同,只是“线程”换成了中断上下文。Rust 的做法:共享数据包进 cortex_m::interrupt::Mutex<RefCell>(注意这是单核临界区语义,不是 std::sync::Mutex),访问必须先进入 critical section(interrupt::free 临时关中断)拿到借用。
展开解析:原理拆解:单核 MCU 上没有真并行,竞争只来自抢占,所以关中断这个极短窗口内独占访问就是安全的——临界区内不可再做长操作或触发中断依赖的动作(如等待标志位),否则死锁或中断延迟超标。cortex-m Mutex 的实现就是基于这个前提:它给的是临界区内的 & 借用,离开临界区即失效,类型系统强制你没法把引用带出去。更优的模式是 RTIC(Real-Time Interrupt-driven Concurrency):编译期做优先级天花板分析(priority ceiling),声明资源和优先级后框架静态证明无死锁无数据竞争,高优先级任务可抢占低优先级,共享资源自动加天花板锁,连临界区都不用手写。常见错误:在临界区里做 IO 导致中断丢失;用 static mut 裸共享(编译器都要求 unsafe 了就该警觉);忘了外设寄存器本身也是共享状态——对同一外设的多处访问同样需要同步或抽象所有权归一。
追问方向:优先级反转在单核 MCU 上如何发生?RTIC 的静态分析能证明什么、不能证明什么?
(约 470 字)