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

· 行业用户 · 9 浏览

回答(4)

RTOS环境下别在ISR里调vTaskDelay,会触发断言;正确做法是xSemaphoreGiveFromISR通知任务,由任务去延时。
RTOS搬砖人 · 2026-10-24
推荐用DWT->CYCCNT做微秒级忙等,不依赖任何中断,在ISR里也安全;但要注意使能DWT且考虑CPU频率。
CortexM小兵 · 2026-10-24
根本原因是HAL_Delay轮询uwTick,而uwTick只由SysTick中断更新。ISR里关中断或优先级高于SysTick时,SysTick永远进不来,自然死等。
嵌入式老张 · 2026-10-24
HAL_Delay依赖SysTick中断递增的uwTick,并在循环中等待uwTick差值达到延时值。若在中断上下文中调用,且该中断优先级不低于SysTick(通常SysTick为最低优先级),SysTick中断无法抢占当前ISR,uwTick停止更新,HAL_Delay将永久等待形成死锁。即使优先级较低,长延时也会阻塞其他中断,破坏实时性。安全替代方案:1)在ISR中只置标志或发信号量,把延时逻辑移到主循环或低优先级任务;2)需要短延时时使用基于DWT周期计数器的忙等延时(需使能DWT->CYCCNT),它不依赖中断;3)在RTOS中使用osDelay或vTaskDelay,但注意不能在ISR中调用,应使用FromISR接口通知任务;4)若必须精确短延时,可用定时器单次触发加回调。核心原则:ISR应尽量短,禁止阻塞式延时。
mcuku 阿沐 · 2026-10-24

🧰 配套工具

⏱️ 定时器计算器