高效的开发基于FreeRTOS的固件需要理解任务、中断和内核之间的交互以及时间序列。
Tracealyzer支持基于FreeRTOS应用的可视化分析,它提供了30多种相互关联的视图,观测软件运行时行为。
我们基于一个案例解析Tracealyzer如何帮助用户解决实际问题。本例中, 用户在ARM Cortex-M4微控制器上运行了FreeRTOS+TCP/IP+Flash文件系统的应用。系统中包含多个任务,一个Server任务用于响应网络请求,一个Logger文件缓冲任务。网络请求的响应时间一直不理想,最近一次构建,响应时间更加恶化。
为了解决响应时间问题,他们比较了两个版本的源代码,找不到任何明显的原因导致响应时间变长。代码有许多小的变化,但并没有增加新的功能。因此,用户决定使用Tracealyzer来比较新旧版本的运行时行为。
在相似的条件下记录两个版本的运行过程。使用Actor Statistics Report视图进行比较 (图1A和图1B),视图中提供了时间统计信息,如CPU使用情况、执行次数、任务优先级和响应时间信息。
图 1A
图1B
Statistics Report显示,新代码版本中Server任务的响应时间(Response time)增加大约50%。而执行时间(Execution time)新版本中仅增长约7%。由此得出的结论,较长响应时间的主要原因一定是其他任务的干扰,但是哪个任务?
为了确定哪些任务干扰了Server任务,单击Statistics Report中的极端值。跟踪到主视图中相应的位置,可以看到更多执行细节,打开Tracealyzer的并行实例,可以很容易地比较并发现差异。
由于Server任务执行了多个服务,因此我们添加了两个用户事件 (标记为ServerLog)来标记接收和应答请求,如图2A和2B所示,图例的缩放级别相同,可以清楚地看到新版本中响应时间更长,Logger任务抢占了Server任务11次,而旧版本中抢占只有6次。
图2A
图2B
此外,我们看到Logger任务的优先级高于Server任务,因此日志记录的服务调用会抢占Server任务。
因此,新版本中似乎添加了新的日志记录调用,导致Logger任务更多地干扰Server任务。为了查看记录的内容,我们在日志任务中添加了一个User Event,在跟踪视图中显示所有日志消息。可以看到除了Server之外的其他任务生成的日志消息,例如ADC_0任务。为了查看向日志任务发送消息的所有任务,我们使用Tracealyzer的通信流图,如图3所示。通信流图显示了跟踪的任务和中断对消息队列、信号量和其他内核对象执行的所有操作,展示了上层应用程序设计以及运行时依赖关系。
图3
在本例中,通信流图显示有五个任务发送日志消息。通过双击图中的LoggerQueue节点,可以打开Kernel Object History视图,查看该消息队列上的所有操作(图4)。正如预期的那样,我们看到Logger任务频繁地接收消息,每次接收一条消息,并且在每个消息之后被阻塞,如Event列中的红色指示灯所示。
图4
应用可能没有必要将日志消息一条接一条地写入文件。如果提升Server任务的调度优先级高于Logger任务,那么Server能够更快地响应,日志消息可以被缓冲在LoggerQueue队列中,直到Server和其他高优先级任务完成,Logger任务恢复执行并批量处理所有缓冲消息。
测试的结果如图5所示。Server任务的最高响应时间现在只有5.4 ms,比早期版本(5.7 ms)还要快,Logger任务收到一条消息后不会立即抢占Server任务,而是在Server完成后批量处理所有挂起的消息。
图5
我们还可以查看消息队列操作的事件标签,并且正如预期的那样,多个xQueueSend调用,没有引起阻塞或任务抢占。仍然有一些由A/D转换任务引起的抢占,但这不再导致Logger任务的额外激活。
问题解决了!更多关于Tracealyzer的技术文档,请关注BMR微信公号。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !