嵌入式Rust通过外设句柄清除定时器中断及相关问题排查
编译错误问题解决
你最初遇到的#[interrupt]属性找不到的错误,是因为导入的cortex_m::interrupt是提供临界区能力的模块,不是中断定义属性宏。你后续调整导入的方向是正确的,需要从你使用的stm32g0 PAC包中导入interrupt属性宏,注意避免和cortex_m::interrupt模块重名即可,你拆分导入free和Mutex的写法已经解决了名字冲突问题。
Mutex封装全局外设的写法正确性
你参考嵌入式Rust手册写的Mutex<RefCell<Option<外设>>>的全局共享写法是完全正确的,这是无HAL裸机开发时共享外设的标准实现,不需要依赖任何HAL crate即可正常使用。
ISR中if let判断为false、中断循环触发的原因及解决
核心原因
你遇到的问题是两个常见的裸机开发错误共同导致的:
- 第一是外设所有权逻辑错误:你修改为使用TIM2后,没有同步修改全局
G_TIM的类型,也没有将p.TIM2的所有权存入G_TIM,导致G_TIM的值始终为None,if let判断自然永远失败。如果你同步修改了G_TIM类型,那另一个可能的错误是你先取了定时器的引用用于配置,再尝试移动所有权到全局变量,导致外设实例被意外释放,全局变量最终存入None。 - 第二是中断开启时机错误:你在代码中先执行
NVIC::unmask开启了定时器中断,之后才配置定时器、将外设实例存入全局变量。如果定时器在全局变量赋值完成前就触发了中断,G_TIM此时还是None,无法清除中断标志位,就会导致中断循环触发。
修复方案
按以下步骤调整代码即可:
- 统一外设类型,全程使用同一定时器,不要混用TIM2和TIM3的定义:
// 全局变量修改为对应你使用的定时器类型,这里以TIM2为例 static G_TIM: Mutex<RefCell<Option<stm32g071::TIM2>>> = Mutex::new(RefCell::new(None));
- 调整初始化顺序,先完成定时器配置、全局变量赋值,最后再开启NVIC中断,避免中断提前触发:
#[entry] fn main() -> ! { let p = stm32g071::Peripherals::take().unwrap(); let rcc_r = &p.RCC; // 直接拿到定时器的所有权,不要提前取引用导致所有权转移失败 let tim2 = p.TIM2; // 开定时器时钟 rcc_r.apbenr1.write(|w| w.tim2en().set_bit()); // 配置定时器参数 prepare_timer2(&tim2); // 先将定时器实例存入全局变量 free(|cs| { G_TIM.borrow(cs).replace(Some(tim2)); }); // 所有准备工作完成后,最后再开启NVIC中断 unsafe { NVIC::unmask(Interrupt::TIM2); }; loop {} } // 定时器配置函数对应修改为TIM2的参数 fn prepare_timer2(tim2_r_handle: &TIM2) { tim2_r_handle.cr1.write(|w| w.cen().clear_bit()); tim2_r_handle.psc.write(|w| unsafe { w.psc().bits(16000) }); tim2_r_handle.arr.write(|w| unsafe { w.arr_l().bits(100) }); tim2_r_handle.egr.write(|w| w.ug().set_bit()); tim2_r_handle.dier.write(|w| w.uie().set_bit()); tim2_r_handle.cr1.write(|w| w.cen().set_bit()); }
- 调整ISR逻辑,和你C语言的实现对齐,先判断中断标志位再清除,简化引用获取写法:
#[interrupt] fn TIM2() { free(|cs| { // 直接用as_mut获取可变引用,不需要手动调用deref_mut if let Some(tim2) = G_TIM.borrow(cs).borrow_mut().as_mut() { // 先读SR寄存器判断更新中断是否触发,和C逻辑完全一致 if tim2.sr.read().uif().bit_is_set() { // 清除更新中断标志位 tim2.sr.write(|w| w.uif().clear_bit()); } } }); }
内容的提问来源于stack exchange,提问作者dunajski
相关产品推荐
相关产品推荐

