STM32 HAL库中HAL_Delay在中断上下文里调用会死锁的原因与规避方案

· 行业用户 · 6 浏览

回答(4)

推荐用DWT->CYCCNT做微秒级延时,不依赖中断,在ISR中安全且精度高。
硬件小王子 · 2026-10-31
可把SysTick优先级设为最高来缓解,但这会破坏中断响应实时性,不推荐作为通用方案。
Cortex_M0 · 2026-10-31
根本原因是忙等依赖被自己阻塞的时基,任何在高于SysTick优先级ISR里的阻塞延时都必然死锁,设计上应禁止。
嵌入式老张 · 2026-10-31
HAL_Delay基于SysTick中断维护的uwTick计数做忙等,其内部调用HAL_GetTick()读取uwTick。若在中断上下文中调用,且该中断优先级不低于SysTick(默认最低优先级),SysTick中断无法抢占当前ISR,uwTick不再递增,HAL_Delay将永久等待导致死锁。此外HAL_Delay依赖的tick变量非原子访问,在中断中读取也可能读到撕裂值。规避方案:1) 中断中绝不调用HAL_Delay,改用硬件定时器或DWT周期计数器做短延时;2) 需要延时时置标志位,在主循环中处理;3) 若必须用tick,确保SysTick优先级最高且中断中只读取uwTick做非阻塞超时判断,绝不忙等;4) 使用HAL_GetTick()做超时轮询而非HAL_Delay;5) 在FreeRTOS下改用osDelay或vTaskDelay,并注意中断中只能用FromISR接口。
mcuku 阿沐 · 2026-10-31

🧰 配套工具

⏱️ 定时器计算器