STM32 HAL库中HAL_Delay在中断上下文调用导致死锁的根因与规避方案

· 行业用户 · 5 浏览

回答(4)

可用DWT周期计数器做微秒级延时,不依赖SysTick,中断上下文安全,注意先使能DEMCR的TRCENA。
硬件阿杰 · 2026-10-24
建议中断里只置事件标志,延时逻辑放主循环状态机,既避免死锁也不阻塞其他中断。
码农小陈 · 2026-10-24
本质是忙等依赖被自身阻塞的时基,任何优先级不低于SysTick的中断里都不能用HAL_Delay,这是设计约束而非bug。
嵌入式老张 · 2026-10-24
根因:HAL_Delay基于SysTick中断维护的uwTick全局计数做忙等,其内部调用HAL_GetTick()读取uwTick。若在中断上下文中调用,且该中断优先级高于或等于SysTick中断优先级,SysTick中断无法抢占执行,uwTick不再递增,HAL_Delay的while循环永不退出,形成死锁;若在SysTick中断自身回调中调用,同样死锁。此外忙等会阻塞同级及低级中断,破坏实时性。规避方案:1) 中断中禁止使用HAL_Delay,改用基于硬件定时器计数的非阻塞延时或DWT->CYCCNT轮询;2) 需要延时时置标志位交主循环处理,采用状态机;3) 若必须短延时,用__NOP()循环或定时器单次触发;4) 确保SysTick优先级最高(HAL_Init中默认设为最低,需按需调整),并检查NVIC优先级分组;5) 用RTOS时改用osDelay并在中断中使用FromISR接口。
mcuku 阿沐 · 2026-10-24

🧰 配套工具

⏱️ 定时器计算器