一、概述
在使用FreeRtos进行开发的过程中,我们通常需要了解系统的运行状态、内存、CPU使用情况等信息,来确保系统能够长期稳定的运行。FreeRtos提供了许多这样的接口,我们也可以通过阅读FreeRtos相关的源代码自己编写需要的Debug接口。
通常我们需要用到的一些系统信息为:
- 当前任务的剩余内存;
- 当前任务历史最小内存;
- 系统总的剩余内存;
- 系统运行的总时间;
- 单个任务的运行时间;
- 每个任务占用的CPU时间;
二、获取系统信息的相关函数
2.1、vTaskList
函数原型:void vTaskList( char * pcWriteBuffer );
函数功能:获取系统中所有任务的任务名、任务状态、优先级、最小剩余堆栈、创建序号相关信息;
使用示例:
void PrintSysInfo(void)
{
char *buf = NULL;
char *fmt = "======================================\r\n\
name\tstatus\tpri\tmin-stack\tnum\r\n\
======================================\r\n";
buf = pvPortMalloc(512);
if(NULL == buf)return;
sprintf(buf,"%s",fmt);
vTaskList(buf+strlen(fmt));
d_printf("%s\r\n",buf);
vPortFree(buf);
}
打印结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0watrBnC-1612168202907)(en-resource://database/622:1)]
status表示任务的运行状态,有五种:
- x 运行状态
- R Redy就绪状态
- B Block阻塞状态
- S Suspend挂起状态
- D Deletedr任务已经被删除
min-stack表示系统历史剩余最小堆栈,单位是字,比如33表示33*4=132byte。这个值越接近于0,任务内存溢出的可能性就越大;FreeRtos在创建任务的时候会将分配给任务的内存全部初始化为0xa5,如果某段内存被使用过,那么其中的值就会被改变,FreeRtos获取内存剩余空间的源码如下:
static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
{
uint32_t ulCount = 0U;
/*任务的内存在任务创建时会被填充为tskSTACK_FILL_BYTE,在任务运行时会被填充为其它内容*/
while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE )
{
pucStackByte -= portSTACK_GROWTH;
ulCount++;
}
/*返回值的单位为字而不是字节*/
ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
return ( configSTACK_DEPTH_TYPE ) ulCount;
}
num表示任务创建的序号,一般按照任务的创建顺序编号。
2.2、vTaskGetRunTimeStats
函数原型: void vTaskGetRunTimeStats( char * pcWriteBuffer );
函数功能:获取每个任务的运行时间,并统计每个任务占用CPU的时间;
示例:
void PrintSysTimeInfo(void)
{
#if configGENERATE_RUN_TIME_STATS
char *buf = NULL;
char *fmt = "======================================\r\n\
任务名\t运行时间\tcpu占用率\r\n\
======================================\r\n";
buf = pvPortMalloc(512);
if(NULL == buf)return;
sprintf(buf,"%s",fmt);
vTaskGetRunTimeStats(buf+strlen(fmt));
d_printf("%s\r\n",buf);
vPortFree(buf);
#endif
}
打印结果:
从结果中可以看出,系统中一共有四个任务,其中空闲任务IDLE运行的时间最长,为10902ms,占用了98%的CPU执行时间。
FreeRtos默认是不支持这个功能的,如果想要使用这个功能,就需要自己使用硬件定时器来实现。使用前应该实现以下三个宏:
#define configGENERATE_RUN_TIME_STATS 1//打开运行时间统计功能
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS configureTimerForRunTimeStats//初始化硬件定时器
#define portGET_RUN_TIME_COUNTER_VALUE getRunTimeCounterValue//获取定时器的计数值
2.3、uxTaskGetStackHighWaterMark
函数原型:UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
函数功能:获取指定任务历史最小剩余堆栈,返回的值越小,任务越容易内存溢出
2.4、eTaskGetState
函数原型:eTaskState eTaskGetState( TaskHandle_t xTask );
函数功能:获取任务状态
2.5、uxTaskPriorityGet
函数原型:UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask )
函数功能:获取任务优先级
2.6、xTaskGetTickCount
函数原型:TickType_t xTaskGetTickCount( void )
函数功能:获取任务的系统节拍数,用户可以根据这个值计算系统运行的总时间,但是需要注意TickType_t的数据类型,当系统时钟节拍是1ms时,系统运行一个多月后时间会溢出。
2.7、uxTaskGetTaskNumber
函数原型:UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask )
函数功能:获取任务创建的序号,任务在创建时通常会按照创建顺序给任务一个编码,比如第一个创建的任务序号为1,第二个为2,以此类推。这个值也可以通过vTaskSetTaskNumber函数来修改。
FreeRtos带注释源码Gitee地址:https://gitee.com/zBlackShadow/FreeRtos10.4.3.git