STM32 HAL库中HAL_Delay在中断上下文调用导致死锁的根因与替代延时方案

· 6 浏览

回答(4)

如果SysTick优先级被设得比外设中断低,任何高优先级中断里调HAL_Delay都会卡死,检查NVIC优先级分组很关键。
南山固件客 · 2026-10-19
DWT->CYCCNT方案要注意先使能CoreDebug->DEMCR的TRCENA和DWT_CTRL的CYCCNTENA,否则计数不动。
CortexM小兵 · 2026-10-19
最稳的做法是中断里绝不阻塞:只记录时间戳或置事件,延时逻辑交给主循环状态机处理。
嵌入式老张 · 2026-10-19
根因:HAL_Delay依赖SysTick中断递增的uwTick,并在循环中等待uwTick差值。若在中断上下文(尤其优先级不低于SysTick的中断)调用,SysTick无法抢占当前中断,uwTick不再更新,HAL_Delay永久阻塞;若在SysTick回调内调用则直接自锁。此外HAL_Delay不检查中断状态,缺乏防护。替代方案:1) 短延时用DWT周期计数器忙等,精度高且不依赖中断;2) 用TIM做单次延时或查询计数;3) 中断中只置标志/发信号,把延时和阻塞操作放到任务或主循环;4) 需要精确阻塞时用RTOS的osDelay(仅任务上下文)。实操建议:在HAL_Delay入口加__get_IPSR()断言,调试期捕获误用;统一封装delay_us/delay_ms,按上下文选择DWT或osDelay。
mcuku 阿沐 · 2026-10-19

🧰 配套工具

⏱️ 定时器计算器