如何确定嵌入式系统中的最大堆栈使用量?

Dav*_*ary 10 embedded code-analysis static-analysis keil

当我给Keil编译器提供"--callgraph"选项时,它会静态计算出我的"最大堆栈使用率".

唉,今天它给了我一个"最大堆栈使用= 284字节+未知(没有堆栈大小的函数......)"消息,以及"没有堆栈信息的函数"列表.

奈杰尔琼斯说,递归在嵌入式系统中是一个非常糟糕的主意("计算你的堆栈大小" 2009),所以我一直小心不要在这段代码中做任何相互递归的函数.

另外,我确保我的中断处理程序都没有重新启用中断,直到它们最终从中断返回指令,所以我不需要担心重入中断处理程序.

如果没有递归或重入中断处理程序,它应该能够静态地确定最大堆栈使用情况.(所以大多数答案 如何确定最大堆栈使用量? 不适用).我的理解是,处理"--callgraph"选项的软件首先找到每个中断处理程序在没有被更高优先级的中断打断时的最大堆栈深度,以及main()函数的最大堆栈深度.不打断 然后它将它们全部加起来以找到总(最坏情况)最大堆栈深度.当main()后台任务在被最低优先级中断中断时处于最大深度时会发生这种情况,并且当该中断被下一个最低优先级中断中断时,该中断处于其最大深度,依此类推.

我怀疑处理--callgraph的软件对"无堆栈信息的功能"列表中的小型汇编语言函数感到困惑.该--callgraph文档似乎暗示我需要手动计算(或作出保守估计),他们多少堆栈使用-他们是很短的,所以这应该是简单的-然后"使用汇编语言框架指令用于描述代码如何使用堆栈的代码." 其中之一是初始启动代码,在跳转到main()之前将堆栈重置为零 - 因此,实际上,这会消耗零堆栈.另一个是"故障"中断处理程序,它锁定在一个无限循环中,直到我循环上电 - 假设这消耗零堆栈是安全的.

我正在使用Keil uVision V4.20.03.0来编译LM3S1968 ARM Cortex-M3的代码.

那么我如何使用"框架指令"来告诉处理"--callgraph"的软件这些函数使用了多少堆栈?或者是否有更好的方法来确定最大堆栈使用量?

(有关针对gcc编译器的几乎相同的问题,请参阅如何使用gcc确定嵌入式系统中的最大堆栈使用量.)

Cli*_*ord 3

在链接器选项中使用 --info=stack。然后,映射文件将包含具有外部链接的所有函数的堆栈使用情况。

在单任务环境中,main() 的堆栈使用情况将为您提供总需求。如果您使用的是 RTOS(例如 RTX),其中每个任务都有自己的堆栈,那么您需要查看所有任务入口点的堆栈使用情况,然后为任务上下文添加更多内容(在 RTX 的情况下为 64 字节)贮存。

这里描述了适用于 Keil 以及更普遍的这种技术和其他技术