嵌入式软件的调用树

有没有人知道一些工具来为C应用程序创建一个将在微控制器(Cortex-M3)上运行的调用树? 它可以从源代码(非理想),目标代码(首选解决方案)或运行时(可接受)生成。 我看过gprof,但是仍然有很多东西需要它才能在嵌入式系统上运行。

另外一个好处是该工具还可以提供最大堆栈深度。

更新:解决方案最好是免费的。

实现此目的的一个好方法是使用ARM链接器(armlink)的--callgraph选项,它是RVCT的一部分( 免费)。

有关详细信息 – 调用图文档 。

我从其中一条评论中意识到,您正在寻找基于gcc的解决方案,但事实并非如此。 但它可能仍然有用。

从源代码中,即使您尚未使用Doxygen来记录代码,也可以使用Doxygen和GraphViz 。 可以对其进行配置,使其包含所有函数和方法,无论它们是否具有文档注释。 安装AT&T Graphviz后,Doxygen将包含大多数function和方法的调用和调用图。

从目标代码,我没有一个现成的答案。 我认为这将是高度依赖于目标的,因为即使存在调试信息,它也必须解析目标代码以查找调用和其他堆栈用户。 在最坏的情况下,这种方法似乎需要有效地模拟目标。

在目标硬件上的运行时,您的选择将部分取决于存在何种嵌入式操作系统,以及它如何管理每个线程的堆栈。

一种常见的方法是将每个堆栈初始化为一个看似不太可能通常存储在自动变量中的已知值。 然后,中断处理程序或线程可以检查堆栈并测量近似的高水位线。

即使没有预先填充堆栈并且稍后将其移动以寻找足迹,中断也可以仅对堆栈指针的当前值(对于每个线程)进行采样并保持其最大观察范围的记录。 这将需要存储每个线程SP的副本,并且中断处理程序不需要做很多工作来维护信息。 当然,它必须访问所有活动线程的已保存状态。

我不知道一个明确这样做的工具。

如果您碰巧使用Micrium的 μC/ OS-II作为您的操作系统,您可以查看他们的μC/ Probe产品。 我自己没有使用它,但它声称允许连接的PC近乎实时地观察程序和操作系统状态信息。 如果需要,它可以适应另一个RTOS,我不会感到惊讶。

从源代码调用图表是没有问题的,如上面提到的编译器或doxygen可以从源代码生成此信息。 大多数现代编译器都可以生成一个调用图,作为编译过程的一部分。

在以前的嵌入式项目中,我使用模式填充该堆栈并运行任务。 检查堆栈破坏我的模式的点。 使用模式重新加载堆栈并运行下一个任务。 这使你的代码非常ssslloowww ….但是是免费的。 它并不完全准确,因为所有数据都在整个时间超时,并且代码在error handling程序中花费了大量时间。

在某些处理器上,您可以获得一个跟踪窗格,以便您可以监视代码封面,如果您的处理器需要全速运行以进行测试,那么您也可以监控代码封面,并且您也不能使用已检测的代码 不幸的是,这些类型的工具非常昂贵。 如果你有钱,看看Green Hills Time机器 。 这使得所有类型的调试更容易。

我没有用过这些,但你知道吗:

  • calltree
  • cflow

由于他们分析源代码,因此他们不计算堆栈深度。

注意,Doxygen可以做“调用图”和“调用者图”但我相信这些是按function的,并且只显示每个函数中一定数量的“跳”的树。

编译器工具可以支持堆栈深度和/或调用树生成。 例如,对于Renesas micros,有一个名为Call Walker的实用程序。

我的calltree图生成器,使用cscope和dot在bash中实现。

可以生成上游调用者,下游调用者和函数之间的调用关联的图。 您可以将其设置为以多种方式查看图形,包括xfig,.png查看器和动态点可视化工具“zgrviewer”。

http://toolchainguru.blogspot.com/2011/03/c-calltrees-in-bash-revisited.html

看看StackAnalyzer 。

只是一个想法。 是否可以在虚拟机(如Valgrind)中运行它并获取堆栈样本?

带CDT的Eclipse具有C / C ++索引,并将显示调用图。 据我所知,您不需要在Eclipse中构建以使索引器工作,只需确保所有源文件都在项目中。

它工作得非常好。

Visual Studio会做类似的(但它不是免费的)。 我使用Visual Studio来处理嵌入式项目; 使用makefile项目我可以完成除VS IDE中的调试之外的所有工作。

我已经在另一个关于嵌入式开发的讨论中提出了这种方法,但如果你真的需要一个调用图,以及堆栈使用信息,以及所有这些免费,我个人会考虑使用开源模拟器来模拟整个事物,而通过向模拟器本身添加一些钩子来获取此数据来检测目标代码。

我不熟悉这个特定的目标,但是有大量的开源ARM仿真器可用(freshmeat,sourceforge,google),你可能最感兴趣的是与call / ret和push / pop相关的操作码? 例如,查看skyeye 。

因此,即使您发现扩展编译器或模拟器以提供此信息并不简单,仍应该可以创建一个简单的脚本以查找入口点和所有调用/ rets,以及相关的操作码堆叠使用情况。

当然,关于堆栈使用的唯一可靠信息将来自运行时检测,最好是运行所有重要的代码路径。

一个非常轻松的工具: 埃及

使用了解: http : //www.scitools.com/

它不是免费的,并且在源代码(不是运行时)上运行,但是它可以工作,它运行良好,而且它得到了很好的支持。

它会告诉你比你想知道的代码更多的东西。

我知道这是一个非常古老的问题,但是有人可能会因为同样的问题而偶然发现这个问题……

我最近尝试了一个Python脚本,它分析应用程序的汇编程序版本,提取堆栈使用情况和调用树,并报告最大堆栈使用情况。 在我的构建系统中,我然后使用它来创建一个完全相同大小的堆栈。

我只在小型应用程序上使用它,但它似乎适用于AVR8,MSP430和Cortex-M3。 显然,存在严格的限制:没有间接调用(没有函数指针,没有虚函数),没有递归,使用堆栈的汇编程序指令模式仅限于我在GCC输出中找到的内容。 如果不满足这些限制,脚本将报告错误。

Python源代码是24k,免费(增强许可证),速度不是很快,而且还在开发中。 如果您有兴趣,请与我联系。