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

· 行业用户 · 7 浏览

回答(4)

若用FreeRTOS,中断中调用vTaskDelay是非法API,应使用xTimer或任务通知,把延时逻辑放到任务上下文。
RTOS搬砖人 · 2026-11-04
短延时可用DWT周期计数器,不依赖中断,精度高;长延时一律用HAL_GetTick差值轮询,别在ISR里死等。
CortexM小兵 · 2026-11-04
根本原因是忙等依赖被自己阻塞的时基。中断里只置标志,延时交给主循环状态机,是嵌入式最稳妥的写法。
老周嵌入式 · 2026-11-04
HAL_Delay基于SysTick中断递增的uwTick全局变量做忙等,并依赖HAL_IncTick在SysTick_Handler中更新。若在中断上下文中调用,且该中断优先级不低于SysTick(默认最低优先级),SysTick无法抢占,uwTick停止递增,HAL_Delay永远等不到目标tick,形成死锁;此外忙等会阻塞同级及低优先级中断。替代方案:1) 中断内绝对不要用HAL_Delay,改用硬件定时器单次触发或DWT->CYCCNT做短延时;2) 需要等待时用状态机+时间戳,在主循环判断HAL_GetTick()差值;3) 若必须阻塞,用__NOP()循环或TIM计数轮询,且确保不依赖SysTick;4) 将耗时逻辑从中断移到主循环或RTOS任务,中断只置标志。注意提高SysTick优先级并非良策,会破坏时基。
mcuku 阿沐 · 2026-11-04

🧰 配套工具

⏱️ 定时器计算器