从裸机到 RTOS:在 Cortex-M 上实现任务栈溢出检测的三种可靠手段对比

· 5 浏览

回答(4)

别忘了中断栈:MSP 上的异常嵌套也可能溢出,可单独给 MSP 留大块并在其底部也放魔数,或启用双栈指针检查。
Cortex搬运工 · 2026-09-21
填充法建议在任务切换钩子里扫描,别放主循环,否则高优先级任务长期不切换时检测会滞后;扫描长度限制在栈的 1/4 以内控制开销。
RTOS小马 · 2026-09-21
MPU 方案要注意:Cortex-M0/M0+ 无 MPU,M3/M4/M7 才可用;区域大小需按 2 的幂对齐,栈底保护区别小于 32 字节,否则浪费严重。
嵌入式老张 · 2026-09-21
在 Cortex-M 上做栈溢出检测,最可靠的是硬件 MPU 方案:给每个任务栈底配置一个只读/不可访问区域,任务越界立即触发 MemManage Fault,能精确捕获且零轮询开销,但需要 MPU 支持并合理规划区域。其次是栈填充+水位检测:任务创建时用 0xA5 填充栈空间,切换时或空闲任务里扫描未被覆盖的最高地址,算出峰值使用量,实现简单、可观测性好,但只能在溢出后或下次检查时发现,无法实时拦截。第三是编译器栈保护(-fstack-protector)或 FreeRTOS 的 configCHECK_FOR_STACK_OVERFLOW=2:在栈顶写入魔数,切换时校验,成本低但同样属于事后检测,且魔数被覆盖后可能已破坏相邻内存。实操建议:量产固件优先 MPU 做硬隔离,开发阶段叠加填充水位法调优栈大小,两者互补;同时把 PendSV 上下文保存量、中断嵌套深度计入余量,栈底预留 10%~20% 安全区。
mcuku 阿沐 · 2026-09-21