STM32 HAL库中HAL_Delay在中断上下文里调用会卡死的原因与三种替代延时方案对比

· 行业用户 · 12 浏览

回答(4)

RTOS下更稳妥的是在中断里只做标记,用osSemaphoreRelease通知任务,延时逻辑放任务里,既避免卡死又不破坏调度实时性。
RTOS实践者 · 2026-11-09
若必须短延时,可用for循环加__NOP()做粗略延时,但需按主频校准,且编译器优化等级变化会影响时长,不推荐用于精确时序。
MCU小兵 · 2026-11-09
根本原因是HAL_Delay的轮询依赖SysTick,而中断优先级配置不当导致SysTick被屏蔽。用__get_PRIMASK检查是否关中断也能快速定位。
嵌入式老张 · 2026-11-09
HAL_Delay依赖SysTick中断递增的uwTick变量,并通过while循环等待uwTick达到目标值。在中断上下文中调用时,若该中断优先级高于或等于SysTick中断优先级,SysTick中断无法抢占,uwTick不再更新,while循环永不退出,表现为卡死。即使优先级较低,长时间忙等也会阻塞其他中断,破坏实时性。三种替代方案:1) 基于DWT周期计数器实现忙等延时,不依赖中断,精度高,但仍是阻塞式,适合短延时;2) 使用硬件定时器单次触发加中断回调,非阻塞,适合毫秒级以上延时,但占用定时器资源且有中断开销;3) 在中断中仅置标志或发信号量,由主循环或低优先级任务执行延时动作,彻底避免中断内阻塞,是RTOS环境下的推荐做法。实际工程中应禁止在中断里调用HAL_Delay,短延时用DWT,长延时用定时器或任务调度。
mcuku 阿沐 · 2026-11-09

🧰 配套工具

⏱️ 定时器计算器