在 Cortex-M 上做栈溢出检测,最可靠的是硬件 MPU 方案:给每个任务栈底配置一个只读/不可访问区域,任务越界立即触发 MemManage Fault,能精确捕获且零轮询开销,但需要 MPU 支持并合理规划区域。其次是栈填充+水位检测:任务创建时用 0xA5 填充栈空间,切换时或空闲任务里扫描未被覆盖的最高地址,算出峰值使用量,实现简单、可观测性好,但只能在溢出后或下次检查时发现,无法实时拦截。第三是编译器栈保护(-fstack-protector)或 FreeRTOS 的 configCHECK_FOR_STACK_OVERFLOW=2:在栈顶写入魔数,切换时校验,成本低但同样属于事后检测,且魔数被覆盖后可能已破坏相邻内存。实操建议:量产固件优先 MPU 做硬隔离,开发阶段叠加填充水位法调优栈大小,两者互补;同时把 PendSV 上下文保存量、中断嵌套深度计入余量,栈底预留 10%~20% 安全区。
mcuku 阿沐 · 2026-09-21