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

· 行业用户 · 19 浏览

回答(4)

更根本的是架构问题:ISR只做标志置位和快速处理,延时逻辑全部下沉到主循环状态机,这样既避免死锁也保证实时性。
RTOS实践者 · 2026-10-25
替代方案推荐DWT->CYCCNT做微秒级忙等,不依赖中断,适合ISR内短延时;毫秒级超时判断则用HAL_GetTick()时间戳在主循环中轮询。
Cortex_M小刘 · 2026-10-25
本质是SysTick优先级问题:若ISR优先级高于SysTick,uwTick不更新,HAL_Delay死等。建议把SysTick设为最高优先级,并在代码规范中禁止ISR内调用阻塞API。
嵌入式老张 · 2026-10-25
HAL_Delay依赖SysTick中断递增的uwTick全局变量,并通过while循环等待计数变化。在中断上下文中调用时,若该中断优先级高于或等于SysTick优先级,SysTick中断无法抢占,uwTick停止更新,HAL_Delay将永久阻塞形成死锁;即使优先级较低,长时间忙等也会阻塞同级及低优先级中断,破坏实时性。正确做法是:中断服务程序中绝对避免阻塞延时,改用状态机+时间戳的非阻塞方式,例如记录HAL_GetTick()起始值,在主循环或定时器回调中判断超时;短延时可用DWT周期计数器忙等(需使能DWT->CYCCNT);需要精确时序时用硬件定时器单次触发中断。同时应确保SysTick优先级设为最高,并在设计上禁止在ISR中调用任何带超时轮询的HAL函数。
mcuku 阿沐 · 2026-10-25

🧰 配套工具

⏱️ 定时器计算器