ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明

有工程师调试代码发现一个问题,IAR中把堆栈设小了,导致堆栈溢出,进入hardfault。我检查了下,堆栈溢出这个事实是存在的,但是堆栈溢出的结果和现象和我以前对于ARM的理解不一样了。

以前的理解:堆栈栈底不停的PUSH,即使超出了stack的范围,哪怕是修改了和栈底相邻的变量的值,也不会立即产生hardfault或者发现程序异常,而是在pop回来或者其他程序开始取得相邻变量的值的时候发生错误。所以以前要去查hardfault发生错误的位置,或者是程序功能错误,是不太好查的。下面是IAR的一些经验之谈

Debugging a HardFault on Cortex-M | IAR Systems

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第1张图片

但是这次在IAR+LPC55调试过程中发现的hardfault出现情况是不同的,单步汇编代码能够看到感知一旦越界立即就会产生hardfault。

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第2张图片

因为LPC55是较新的ARMV8M内核,查阅cortex_m33_trm_的技术手册,可以看到想比以前多了两个寄存器,MSPLIM和PSPLIM,正是这两个寄存器限制了stack越界的行为。

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第3张图片

LPC55的初始化启动文件中明确设置了这个寄存器。

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第4张图片

现在描述下这个寄存器的实测行为:首先CFSR中的STKOF被置位了,这个就是stack overflow的标记

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第5张图片

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第6张图片

使用IAR的View > Fault exception viewer可以看到

ARMv8M 堆栈溢出情况说明-NXP LPC55为例说明_第7张图片

 

  1. DisableGlobalIRQ无法屏蔽这个hardfault行为的产生;
  2. 在第一次压栈,超过MSPLIM的时候,就产生hardfault,且没有压成功;
  3. 在hardfault_handler中,还会继续压栈,这时候不止没有压成功,还会从hardfault中跳出,直接将PC指征指向为一个非法地址;

这个设计的好处是大家不再会遭受堆栈溢出的痛苦了,但是我自己还是有一些遗留问题

遗留问题:

以前大家可能会在hardfault中加入一些处理程序,比如

  • 软件复位
  • 追踪堆栈压栈以确定产生hardfault的代码位置;
  • RTOS是如何处理这个问题的?

但是目前这种情况下,hardfault都无法正常进入,点解??

你可能感兴趣的:(嵌入式,nxp)