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

· 4 浏览

回答(4)

若用FreeRTOS,中断里绝不能调vTaskDelay,应使用xSemaphoreGiveFromISR或xTaskNotifyFromISR通知任务,由任务完成延时。
RTOS搬砖人 · 2026-10-17
可用DWT->CYCCNT实现us级延时,注意先使能DEMCR的TRCENA和CYCCNT,并处理计数器回绕,适合中断内短延时。
CortexM小兵 · 2026-10-17
本质是HAL_Delay依赖SysTick更新uwTick,中断里优先级不够就永远等不到tick变化。建议中断只做最短处理,延时逻辑全部下沉到任务层。
嵌入式老张 · 2026-10-17
根因:HAL_Delay基于SysTick中断递增的uwTick做忙等,并在等待中调用HAL_IncTick。若在中断上下文中调用,且该中断优先级不低于SysTick(或屏蔽了SysTick),SysTick无法抢占执行,uwTick不再更新,形成死锁;同时忙等会阻塞同级/低级中断,破坏实时性。安全替代:1) 用DWT周期计数器做微秒级忙等,不依赖中断;2) 在中断中只置标志/发信号量,把延时处理交给主循环或RTOS任务;3) 使用硬件定时器单次触发+中断回调,或RTOS的osDelay/vTaskDelay(仅任务上下文)。另外应确保SysTick优先级最高,避免在临界区调用HAL_Delay。
mcuku 阿沐 · 2026-10-17

🧰 配套工具

⏱️ 定时器计算器