NRF52832开发日志——线程信息(CPU使用率,栈空间等)输出

分类: NRF52832开发日志 |
在运行RTOS的嵌入式系统中,获取每个线程的CPU使用率,栈空间使用情况,堆空间使用情况对于配置其基本参数和进行各种优化调试是至关重要的。FreeRTOS提供了相关的接口,我们只需稍加改动即可很方便将其用起来。
要开启相关功能,首先freertos_config.h里面,把下面这些宏开起来。
此外还要提供两个回调函数,先这里把函数名加到宏定义里面去。
http://s11/mw690/002VF2gAzy76fJB0H229a&690
要提供的俩函数用来做时间测定的,这个在计算线程运行时间,CPU使用率时是必须的。原理就是任务切入和切出时候记录时间戳,由此即可得到每次线程运行时间并用于计算了。这里我们就用用于操作系统的RTC1的Counter作为时间基准。
http://s14/mw690/002VF2gAzy76fJB3rRzbd&690
任何时候,调用uxTaskGetSystemState()函数即可获取相关信息,会被拷贝到用户提供的内存空间中供访问。但FreeRTOS只提供线程运行时间总数,不计算CPU使用率。这个就只能我们自己来完成。
要提供的俩函数用来做时间测定的,这个在计算线程运行时间,CPU使用率时是必须的。原理就是任务切入和切出时候记录时间戳,由此即可得到每次线程运行时间并用于计算了。这里我们就用用于操作系统的RTC1的Counter作为时间基准。
http://s14/mw690/002VF2gAzy76fJB3rRzbd&690
任何时候,调用uxTaskGetSystemState()函数即可获取相关信息,会被拷贝到用户提供的内存空间中供访问。但FreeRTOS只提供线程运行时间总数,不计算CPU使用率。这个就只能我们自己来完成。
下面是其提供的主要信息,包括句柄,线程名称,状态,优先级,运行总时间,最小剩余栈空间。
http://s15/mw690/002VF2gAzy76fK9ivfM4e&690
由此我再其基础上再加入一个CPU使用率和一个CPU平均使用率,也就是T_SYS_Thread_State_t里面内容。
http://s15/mw690/002VF2gAzy76fK9ivfM4e&690
由此我再其基础上再加入一个CPU使用率和一个CPU平均使用率,也就是T_SYS_Thread_State_t里面内容。
整机系统的信息结构体,T_SYS_State_t还包括整机CPU使用率,平均使用率,任务数量,各处内存堆占用比例。
http://s11/mw690/002VF2gAzy76fK9gqMy3a&690
以我的习惯是必然要开启一个线程来专门干统计的事情,SW_SYS_State_Init()负责创建线程,分配空间等任务。
http://s5/mw690/002VF2gAzy76fK9Uek4e4&690
这个就是线程实际运行的函数了。从代码可以看出每0.5s生成一次统计信息,基本也就是各种调用FreeRTOS的API了。不过也有很大一段是自己写的,也就是各个线程的状态统计。
http://s9/mw690/002VF2gAzy76fKax1lmc8&690
之前实测发现,uxTaskGetSystemState()每次返回的线程顺序都不同(若还存在增减就变化更大了)。因此为了计算CPU使用率还得花一点功夫,得按照句柄找到上次保存的里面对应的线程的才能进行计算。
http://s11/mw690/002VF2gAzy76fK9gqMy3a&690
以我的习惯是必然要开启一个线程来专门干统计的事情,SW_SYS_State_Init()负责创建线程,分配空间等任务。
http://s5/mw690/002VF2gAzy76fK9Uek4e4&690
这个就是线程实际运行的函数了。从代码可以看出每0.5s生成一次统计信息,基本也就是各种调用FreeRTOS的API了。不过也有很大一段是自己写的,也就是各个线程的状态统计。
http://s9/mw690/002VF2gAzy76fKax1lmc8&690
之前实测发现,uxTaskGetSystemState()每次返回的线程顺序都不同(若还存在增减就变化更大了)。因此为了计算CPU使用率还得花一点功夫,得按照句柄找到上次保存的里面对应的线程的才能进行计算。
计算方式也很简单,(这次总运行时间-上次总运行时间)/(这次CPU总运行时间-上次CPU总运行时间)。此外还有计算CPU的使用率的。严格上来讲CPU使用率永远是100%,总有个IDLE任务会填满CPU的使用时间,虽然其实那时候CPU根本就没干活。所以除去IDLE以外的线程的CPU使用率才是我们关心的,计算时候很简单直接1-IDLE就是了。CPU使用率关系到CPU性能是否足够保证任务响应时间,以及低功耗优化,也是非常重要的。
http://s4/mw690/002VF2gAzy76fKaVfvtb3&690
同样也是上面原因,因为每次线程位置不同其实阅读起来会很费劲,因此最好方式是再排个序,就按照句柄大小来排序啦。
http://s5/mw690/002VF2gAzy76fKbg9Za24&690
这些都搞完之后,打开调试器的Watch直接阅读相关结构体数组就可以了。当然喜欢串口方式的话,也可以额外再写代码输出出来。不过个人感觉没必要,就酱紫很方便了。
http://s4/mw690/002VF2gAzy76fKaVfvtb3&690
同样也是上面原因,因为每次线程位置不同其实阅读起来会很费劲,因此最好方式是再排个序,就按照句柄大小来排序啦。
http://s5/mw690/002VF2gAzy76fKbg9Za24&690
这些都搞完之后,打开调试器的Watch直接阅读相关结构体数组就可以了。当然喜欢串口方式的话,也可以额外再写代码输出出来。不过个人感觉没必要,就酱紫很方便了。
这里现在可以看出来,CPU使用率是0.2%,非常低所以功耗也很低。内存使用状况42.9%,还是ok的。sys_task的栈空间使用情况usStackHighWaterMark,即最小栈空间是170字节,说明栈分配多了,可以稍微缩减一些。
这里FreeRTOS的内存分配没有按照线程来进行区分,只能看到总使用状况,有时候内存紧张需要优化时候也比较麻烦,不好确定究竟谁是大头。后面有空的话,我也会考虑将相关功能增加进来。
http://s16/mw690/002VF2gAzy76fJBW2ar2f&690
http://s16/mw690/002VF2gAzy76fJBW2ar2f&690