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