2.获取任务信息并格式化 获取每个任务的状态信息使用的是API函数uxTaskGetSystemState(),该函数定义为:
UBaseType_tuxTaskGetSystemState(
TaskStatus_t * constpxTaskStatusArray,
const UBaseType_tuxArraySize,
unsigned long * constpulTotalRunTime );
函数uxTaskGetSystemState()向TaskStatus_t结构体填充相关信息,系统中每一个任务的信息都可以填充到TaskStatus_t结构体数组中,数组大小由uxArraySize指定。结构体TaskStatus_t定义如下:
typedef struct xTASK_STATUS
{
/* 任务句柄*/
TaskHandle_t xHandle;
/* 指针,指向任务名*/
const signed char *pcTaskName;
/*任务ID,是一个独一无二的数字*/
UBaseType_t xTaskNumber;
/*填充结构体时,任务当前的状态(运行、就绪、挂起等等)*/
eTaskState eCurrentState;
/*填充结构体时,任务运行(或继承)的优先级。*/
UBaseType_t uxCurrentPriority;
/* 当任务因继承而改变优先级时,该变量保存任务最初的优先级。仅当configUSE_MUTEXES定义为1有效。*/
UBaseType_t uxBasePriority;
/* 分配给任务的总运行时间。仅当宏configGENERATE_RUN_TIME_STATS为1时有效。*/
unsigned long ulRunTimeCounter;
/* 从任务创建起,堆栈剩余的最小数量,这个值越接近0,堆栈溢出的可能越大。 */
unsigned short usStackHighWaterMark;
}TaskStatus_t;
注意,这个函数仅用来调试用,调用此函数会挂起所有任务,直到函数结束后才恢复挂起的任务,因此任务可能被挂起很长时间。在文件FreeRTOSConfig.h中,宏configUSE_TRACE_FACILITY必须设置为1,此函数才有效。 由于我们不使用动态内存分配策略,所以实现定义了最大任务个数并预先分配好了存储任务状态信息的数组:
#defineMAX_TASK_NUM 5
TaskStatus_tpxTaskStatusArray[MAX_TASK_NUM];
正确调用函数uxTaskGetSystemState()后,任务的信息会被放在TaskStatus_t结构体中,我们需要将这些信息格式化为容易阅读的形式,并共通过串口打印到屏幕。完成这些功能的函数叫做get_task_state(),代码如下所示:
/*获取OS任务信息*/
voidget_task_state(int32_t argc,void *cmd_arg)
{
const chartask_state[]={'r','R','B','S','D'};
volatile UBaseType_t uxArraySize, x;
uint32_t ulTotalRunTime,ulStatsAsPercentage;
/* 获取任务总数目 */
uxArraySize = uxTaskGetNumberOfTasks();
if(uxArraySize>MAX_TASK_NUM)
{
MY_DEBUGF(CMD_LINE_DEBUG,("当前任务数量过多!\n"));
}
/*获取每个任务的状态信息 */
uxArraySize = uxTaskGetSystemState(pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
#if (configGENERATE_RUN_TIME_STATS==1)
MY_DEBUGF(CMD_LINE_DEBUG,("任务名 状态 ID 优先级 堆栈 CPU使用率\n"));
/* 避免除零错误 */
if( ulTotalRunTime > 0 )
{
/* 将获得的每一个任务状态信息部分的转化为程序员容易识别的字符串格式 */
for( x = 0; x < uxArraySize; x++ )
{
char tmp[128];
/* 计算任务运行时间与总运行时间的百分比。*/
ulStatsAsPercentage =(uint64_t)(pxTaskStatusArray[ x ].ulRunTimeCounter)*100 / ulTotalRunTime;
if( ulStatsAsPercentage > 0UL )
{
sprintf(tmp,"%-12s%-6c%-6d%-8d%-8d%d%%",pxTaskStatusArray[ x].pcTaskName,task_state[pxTaskStatusArray[ x ].eCurrentState],
pxTaskStatusArray[ x ].xTaskNumber,pxTaskStatusArray[ x].uxCurrentPriority,
pxTaskStatusArray[ x ].usStackHighWaterMark,ulStatsAsPercentage);
}
else
{
/* 任务运行时间不足总运行时间的1%*/
sprintf(tmp,"%-12s%-6c%-6d%-8d%-8dt<1%%",pxTaskStatusArray[x ].pcTaskName,task_state[pxTaskStatusArray[ x ].eCurrentState],
pxTaskStatusArray[ x ].xTaskNumber,pxTaskStatusArray[ x].uxCurrentPriority,
pxTaskStatusArray[ x ].usStackHighWaterMark);
}
MY_DEBUGF(CMD_LINE_DEBUG,("%s\n",tmp));
}
}
MY_DEBUGF(CMD_LINE_DEBUG,("任务状态: r-运行 R-就绪 B-阻塞 S-挂起 D-删除\n"));
#endif //#if (configGENERATE_RUN_TIME_STATS==1)
}
|