是否有人可以提供一个清晰的建议方法,在今天的32位嵌入式处理器中适用于所有情况?
最好的情况是你的代码使用静态堆栈(没有递归调用)。然后您可以通过以下方式评估最大堆栈使用量:
但即使这样,如果可能的话,您仍希望有一种方法来检测并处理堆栈溢出,以增强鲁棒性,尤其是在项目的开发阶段。一些检测溢出的方法:
一旦检测到,您就需要处理它。我不知道有多少种方法可以优雅地从堆栈溢出中恢复代码,因为一旦发生,您的程序逻辑几乎肯定会失效。所以你能做的只有:
嵌入式堆栈溢出可能是由于递归函数失控引起的,也可能是由于指针误用(虽然这可以被认为是另一种类型的错误),以及使用不足的堆栈进行正常系统操作。换句话说,如果您不对堆栈使用情况进行分析,那么它可能会在缺陷或错误情况之外发生。
在您能够“处理”堆栈溢出之前,您必须先确定它。一个好的方法是在初始化期间加载堆栈,并监视运行时消失的模式数量。通过这种方式,您可以确定堆栈达到的最高点。
模式检查算法应该按照堆栈增长的相反方向执行。因此,如果堆栈从0x1000增长到0x2000,则您的模式检查可以从0x2000开始以提高效率。如果您的模式是0xAA,而0x2000处的值包含除0xAA之外的其他内容,则说明您可能已经溢出了一些内容。
您还应考虑在堆栈之后立即放置一个空的RAM缓冲区,以便在检测到溢出时可以关闭系统而不会丢失数据。如果您的堆栈紧随堆或SRAM数据,则识别溢出将意味着您已经遭受了破坏。您的缓冲区将为您提供更长时间的保护。在32位微控制器上,您应该有足够的RAM来提供至少一个小缓冲区。
当调用栈过大时,例如递归函数嵌套层数太多时,会发生堆栈溢出。
通过在栈后放置已知数据来检测堆栈溢出,如果栈增长过多并覆盖了它,就可以检测到它。
有一些静态源代码分析工具,如GnatStack、AbsInt的StackAnalyzer和Bound-T,可以用于确定或猜测最大运行时堆栈大小。