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

· 6 浏览

回答(4)

RTOS项目直接禁用HAL_Delay,统一封装为任务级延时;ISR里需要定时就交给软件定时器或消息队列,别在中断里忙等。
RTOS搬砖人 · 2026-10-20
用DWT->CYCCNT做us级延时最省事,初始化时使能DEMCR的TRCENA和CYCCNT,注意计数器回绕,适合ISR内几十us以内。
Coder小马 · 2026-10-20
本质是优先级反转:高优先级中断里等一个永远进不来的低优先级中断。把SysTick设最低优先级只是避免死锁,不解决阻塞问题,ISR里仍不应延时。
嵌入式老张 · 2026-10-20
HAL_Delay依赖SysTick中断递增的全局变量uwTick,并在循环中等待uwTick差值。若在中断上下文中调用,且该中断优先级不低于SysTick(通常SysTick优先级最低),SysTick中断无法抢占当前中断,uwTick不再更新,形成死锁;即使优先级允许,也会长时间占用中断,破坏实时性。替代方案:1) 短延时用DWT周期计数器或NOP循环,基于CPU主频计算;2) 精确微秒延时用硬件定时器单次计数轮询;3) 中断中只置标志或发信号量,延时逻辑放到主循环或RTOS任务;4) RTOS下用osDelay,禁止在ISR中调用阻塞API。建议将SysTick优先级设为最低,并在代码规范中禁止ISR调用HAL_Delay。
mcuku 阿沐 · 2026-10-20

🧰 配套工具

⏱️ 定时器计算器