默认情况下,Tracealyzer记录器库能够追踪记录两种信息:RTOS内核事件例如上下文切换,和应用程序事件,例如调试日志记录、状态转换和变量值等等。后者通过对vTracePrint()函数的调用被记录为“用户事件”。从Tracealyzer V4.2.9版本开始,增加了记录器扩展方式来跟踪用户应用程序。记录器扩展方式可以帮助用户实现中间件、驱动程序API等重要功能函数调用的跟踪。针对Amazon FreeRTOS中的“Secure Socket”API函数的跟踪示例如上图所示。
使用Tracealyzer记录器扩展功能,不需要对目标函数代码进行任何修改,仅需在应用程序源代码文件中添加#include “trcExtensions.h”这一预处理行,其余部分由预处理程序和跟踪记录器,根据记录器扩展文件中的定义处理。trcExtensions.h头文件中将包含所使用的记录器扩展文件。
不同于用户事件记录,记录器旨在对API调用进行系统跟踪。记录器扩展功能包含两个组成部分,即具有目标端定义的头文件和具有主机端元数据的XML文件。XML文件中包含API函数的名称、使所用变量的数据类型和API所处事件分组的名称等,这些信息将告知Tracealyzer如何解析事件,如作为I/O操作。通过这种方式,Tracealyzer能够理解事件含义并将其包含在相关关联视图例如I/O视图中。
Tracealyzer记录器扩展是自包含的,自包含指扩展头文件可以独立编译,而无需依赖额外的内容。故易于集成,便于分发。因此嵌入式软件供应商可以针对自己的产品,开发并提供自定义的Tracealyzer扩展库,而无需在现有的代码库中集成工具代码。而且来自于不同供应商的扩展可以在同一系统内自由组合而不会引起冲突。
如何使用预先定义的记录器扩展文件? 在Tracealyzer的安装目录下提供了一些记录器扩展文件示例。另外需要注意的是目前Tracealyzer V4.2.9版本仅支持流模式,暂不支持快照模式。 请参考Tracealyzer用户手册在项目中集成跟踪记录器库,配置为流模式,并且使用Tracealyzer v4.2.9以上版本。
Tracealyzer包含两个Amazon FreeRTOS扩展示例,能够对aws_secure_sockets.h和aws_wifi.h这两个头文件中下列函数的调用进行跟踪。示例用到的记录器扩展文件可以在Tracealyzer4\FreeRTOS\TraceRecorder\include和Tracealyzer 4\cfg目录下找到。
跟踪Amazon FreeRTOS 的操作步骤如下: 1、打开trcExtensions.h头文件并将TRC_CFG_EXTENSION_COUNT设置为2 2、搜索应用中所有包含#include “aws_secure_sockets.h”或#include “aws_wifi.h”的源文件 3、除了包含硬件相关的的源文件例如aws_secure_sockets.c和aws_wifi.c外,在上述搜索到的其他文件中,添加头文件包含语句#include “trcExtensions.h”。示例: #include ... #include "aws_secure_sockets.h" /* 要跟踪的API */ #include "trcExtensions.h" /* 在跟踪API之后,或最后*/ 4、重新编译应用程序,并在流模式下启用Tracealyzer跟踪,新增的函数调用事件会出现在跟踪记录中。 5、如果遇到“duplicate definitions”重复定义或类似的编译错误,则很可能是在aws_secure_sockets.c和aws_wifi.c(或它们包含的头文件)中也包含了trcExtensions.h。将这种情况下的#include语句删除。
记录器扩展实现原理 Tracealyzer扩展通常是针对特定的API进行的,例如,一组相关的函数,如设备驱动程序或中间件库,或应用程序的特定模块。Tracealyzer对于这些API的跟踪功能依赖于扩展头文件中的预处理定义,它重新定义所跟踪函数的函数名,进而引用加入跟踪功能后重新封装的函数。
Tracealyzer记录器扩展的具体工作原理如下: (1) 首先在扩展头文件中对要跟踪的API函数名进行了重定义,例如: #define api_func api_func_trace 函数重定义后,预处理器将会把对api_func 函数的引用变为对api_func _trace函数的引用。api_func _trace ()是在扩展头文件中定义的小型内联函数,函数声明与原函数api_func一致,只是在名称中添加了后缀“_trace”。 (2) 在函数api_func_trace()中,将调用跟踪记录器库函数来保存相关的调用事件。 (3) 下图更清晰的演示了加入记录器扩展后的调用逻辑: (4) 如虚线箭头所示,在应用程序application.c文件中,调用了名为api_func()的函数。这是应用程序中的调用关系。
(5) 实线部分的两个箭头表示Tracealyzer工作时实际的函数调用逻辑,由于在记录器扩展头文件中进行了预处理定义,对于api_func()函数的调用将替换为对api_func_trace()函数的调用。在api_func_trace()函数中,完成了如下工作: |