当我为 Keil 编译器提供“--callgraph”选项时,它会为我静态计算确切的“最大堆栈使用量”。
唉,今天它给了我一个“最大堆栈使用量 = 284 字节 + 未知(没有堆栈大小的函数...)”消息,以及一个“没有堆栈信息的函数”列表。
Nigel Jones 说递归在嵌入式系统中是一个非常糟糕的主意(“计算堆栈大小” 2009),所以我一直小心不要在这段代码中创建任何相互递归的函数。
另外,我确保我的中断处理程序在最后的中断返回指令之前都不会重新启用中断,所以我不需要担心可重入中断处理程序。
如果没有递归或重入中断处理程序,它应该能够静态确定最大堆栈使用量。(所以大多数关于 如何确定最大堆栈使用量的答案? 不适用)。我的理解是,处理“--callgraph”选项的软件首先找到每个中断处理程序没有被更高优先级中断中断时的最大堆栈深度,以及main()函数的最大堆栈深度。没有中断。然后它将它们全部加起来以找到总(最坏情况)最大堆栈深度。当 main() 后台任务在其被最低优先级中断中断时处于其最大深度时,会发生这种情况,而当它被下一个最低优先级中断中断时,该中断处于其最大深度,依此类推。
我怀疑处理 --callgraph 的软件对“没有堆栈信息的函数”列表中的小型汇编语言函数感到困惑。--callgraph文档似乎暗示我需要手动计算(或保守估计)它们使用了多少堆栈——它们很短,所以应该很简单——然后“在汇编语言中使用框架指令代码来描述您的代码如何使用堆栈。” 其中之一是在跳转到 main() 之前将堆栈重置为零的初始启动代码——因此,实际上,这消耗了零堆栈。另一个是“故障”中断处理程序,它锁定在无限循环中,直到我重新启动电源——假设这消耗零堆栈是安全的。
我正在使用 Keil uVision V4.20.03.0 为 LM3S1968 ARM Cortex-M3 编译代码。
那么如何使用“框架指令”来告诉处理“--callgraph”的软件这些函数使用了多少堆栈呢?还是有更好的方法来确定最大堆栈使用量?
(请参阅如何使用 gcc 确定嵌入式系统中的最大堆栈使用量?对于针对 gcc 编译器的几乎相同的问题。)