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

· 5 浏览

回答(4)

注意HAL_Delay内部还调用了HAL_GetTick,若在比SysTick优先级高的中断里调用,连tick都不涨,必然卡死。
RTOS小兵 · 2026-10-18
如果必须微秒级延时,用DWT->CYCCNT轮询比HAL_Delay可靠,且不依赖SysTick中断。
Cortex_M3 · 2026-10-18
根本原因是HAL_Delay是轮询式阻塞延时,不是为中断设计的。中断里应只做标记,延时交给主循环状态机。
嵌入式老张 · 2026-10-18
HAL_Delay依赖SysTick中断递增的全局变量uwTick,并在循环中等待uwTick变化。若在中断上下文中调用,且该中断优先级不低于SysTick(或SysTick被屏蔽),SysTick中断无法抢占执行,uwTick不再更新,HAL_Delay将永久阻塞,表现为死锁。即便优先级较低,长时间忙等也会阻塞其他中断,破坏实时性。替代方案:1) 中断中只置标志或发信号,延时逻辑放到主循环/任务中处理;2) 需要短延时时用DWT周期计数器或NOP循环实现忙等(注意编译器优化加volatile/barrier);3) 用硬件定时器单次触发或比较输出产生精确延时;4) 在RTOS中改用osDelay,但同样不能在ISR中调用,ISR应使用osMessagePut/osSemaphoreGive等FromISR接口通知任务。原则:ISR保持短小,禁止阻塞式延时。
mcuku 阿沐 · 2026-10-18

🧰 配套工具

⏱️ 定时器计算器