如何使用Tracealyzer分析FreeRTOS内存使用情况?

浏览:1828来源:本站时间:2021-07-09

FreeRTOS在创建任务、信号量和消息队列等内核对象时支持两种内存分配方式,动态内存和静态内存。当使用动态内存时,任务所需要的内存空间在运行过程中动态申请,当系统heap内存空间不足时任务将会创建失败。

那么如何掌握系统内存的使用情况呢?对于系统内存的使用情况,FreeRTOS提供了如下两个API函数,用户可以在完成系统任务等内核对象的创建工作后调用这些API来了解heap内存的使用情况。

• xPortGetFreeHeapSize()

获取当前未分配的内存堆大小

• xPortGetMinimumEverFreeHeapSize()

获取未分配内存堆的历史最小值,即内存堆的最大使用量

但是上面调用API函数的形式存在如下问题:

1)仅能了解整体的系统内存使用情况,难以针对每个任务进行更细致的分析

2)难以发现可能存在的内存泄露风险,小的内存泄露在长时间的运行后可能导致严重后果

此时可以借助RTOS的可视化分析工具Tracealyzer来更清晰直观的掌握系统内存的使用情况。如何将Tracealyzer添加到项目工程中请参考之前的这篇文章(点击最下方的“阅读原文”)

下面我们将介绍如何使用Tracealyzer来分析系统内存的使用情况。

在演示实验中创建了3个任务,Start_task、Test_task和Led_task。

1、其中Start_task负责创建Test_task和Led_task,并在完成这两个任务的创建工作后将自己删除。

2、在Test_task中,指针变量p和np先分别被分配了200字节的内存,随后指针p被np指针重新赋值,最后调用vPortFree函数释放了np指针所对应的内存空间。

最开始p和np指针分别指向200字节的内存空间,执行p=np后,两个指针均指向了np所对应的内存空间,结果是p之前所指向的内存位置变成了孤立的内存,该内存无法被释放,因为没有指向该内存的指针,从而导致了200字节的内存泄漏。


3、在Led_task中,利用递增变量count多次调用pvPortMalloc函数来演示对内存空间的使用


使用流模式或者快照模式开启Tracealyzer跟踪后,通过views->Memory Heap Utilization打开heap内存跟踪视图。

在Memory Heap Utilization窗口中,横坐标代表时间轴,纵坐标数值代表heap空间使用量,当调用pvPortMalloc函数申请heap空间时,曲线会向上增长,当调用free函数释放空间时,曲线会下降。曲线上的每一个节点对应一次内存申请或者释放操作。双击该节点,可以关联到该操作所对应的函数代码位置。

图片

在Memory Heap Utilization窗口的右侧,会显示系统中存在的任务,不同任务通过不同的颜色来进行区分,用户可以勾选所想要查看的任务:

•  红色曲线代表Test任务,Test任务调用了vPortFree函数释放了np指针所对应的内存空间,但是p指针所对应的内存空间成为了孤立的内存,即发生了内存泄漏。因此在对指针赋值前,需要确保该指针所对应的内存位置不会成为孤立的。

•  绿色曲线代表LED任务,在LED任务中多次调用了pvPortMalloc函数,每次内存空间申请对应曲线上的一个节点。

•  深绿色曲线代表Start任务,Start任务在创建Test和Led任务时需要申请这两个任务所使用的任务堆栈和TCB的空间,对应曲线的4个增长节点。

除了显示每个任务的heap内存使用情况,还可以利用上方的标签切换显示系统整体的heap内存空间使用情况,可以帮助用户了解系统的最大heap使用量在什么时间段,以及系统整体的heap空间增长情况。

图片

如上图所示,系统整体的heap空间在最初阶段达到一个最高点之后回落,随后又随时间不断进行增长直至超过了最开始的最大heap空间使用量。如果系统中存在类似的情况,则可能是存在内存泄漏的问题,随着时间的增长,内存泄漏最终将耗尽heap空间导致系统出错。

当系统中可能存在内存泄漏时,可以通过views->Object History->system heap窗口,通过show Remaining Only选项过滤掉所有已经释放了的内存空间,方便用户迅速定位可能发生内存泄漏的位置。

图片

借助RTOS的可视化分析工具Tracealyzer,用户可以更清晰直观的掌握系统中内存的使用情况,进而开发出更高质量的代码。

京ICP备:京ICP备05011254号-1 版权归北京麦克泰软件技术有限公司所有
北京麦克泰软件技术有限公司