我目前正在开发一个使用 RTOS (micrium) 在 STM32 微控制器中开发应用程序的项目。
是否有任何工具可以计算 RTOS 应用程序中特定线程的堆栈使用情况?
2 回答
没有我知道的工具。但是,估计堆栈使用情况的两种简单方法一直对我有用。
用 0x55 或 0xAA 之类的值填充所有 RAM。让程序运行足够长的时间,同时使用设备的所有选项以获得最大的代码执行覆盖率。停止(在某些调试器下),并检查 RAM 是否有上述值被覆盖。这应该给你一个很好的近似值。这在有或没有操作系统的情况下都有效。
稍微修改操作系统,以便在任务切换时记录到某个全局变量(数组),并为每个任务通过与同一任务的先前值进行比较找到的最低堆栈指针。在 [1] 中运行应用程序足够长的时间后,检查计数器。尽管不能保证在任务切换发生的那一刻,您将拥有用于该任务的最大堆栈,但从统计上讲,经过足够长的时间并假设抢先切换,您将设法记录足够准确的值。
如果您使用 GCC 或 clang编译器开关会为每个函数-fstack-usage
生成一个堆栈帧大小。您需要将该信息与链接器生成的调用图信息相结合,以从特定函数开始找到最深的堆栈使用情况。从 开始main()
,任务入口点和 ISR 将为您提供该线程的最坏情况使用情况。
正如这里所讨论的,使用这里的 Perl 脚本,已经为您完成了创建这样一个工具的工作,这是很有帮助的。
ARM 的armcc
编译器 v5 及更早版本(v6 为 clang/llvm)内置了此功能,并且可以在链接映射中包含详细的堆栈分析,包括最坏情况的调用路径和非确定性堆栈使用的警告(由于递归或调用-例如通过函数指针返回)。armcc
例如,如果您使用 Keil ARM MDK,您可能正在使用。同样对于多线程系统(任务/ISR),您需要查看线程入口点的堆栈使用情况。
另请注意,在 ARM Cortex-M 上,“系统堆栈”由main()
线程和所有 ISR 共享,如果您使用 ISR 抢占优先级,则多个中断可能同时处于活动状态。因此,理论上最坏情况下的堆栈使用量是可能main()
同时发生的每个 ISR 的堆栈使用量之和。虽然保持 ISR 简短明了是一种很好的做法,但请注意第三方代码。例如,ST 的 USB 库在 ISR 上下文中运行整个 USB 设备堆栈!