统计UCOSII每个任务堆栈使用大小、剩余大小、使用率、优先级、任务名等信息
统计UCOSII任务堆栈使用情况
一、统计任务堆栈使用情况
说明:
- 主要统计任务优先级、任务堆栈使用大小、任务堆栈剩余大小、任务堆栈使用、以及任务名称。
- 想要实现任务堆栈的统计必须使用OSTaskCreateExt()创建任务,且OS_TASK_CREATE_EXT_EN置1。
#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */
#if OS_TASK_CREATE_EXT_EN > 0u
INT8U OSTaskCreateExt (void (*task)(void *p_arg),
void *p_arg,
OS_STK *ptos,
INT8U prio,
INT16U id,
OS_STK *pbos,
INT32U stk_size,
void *pext,
INT16U opt);
#endif
- 任务堆栈的统计最终使用OSTaskStkChk()函数来实现。
- 宏OS_TASK_STAT_STK_CHK_EN和OS_TASK_CREATE_EXT_EN都置1,OSTaskStkChk()才有效。
#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task */
#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */
#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)
INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data);
#endif
/**********************************************************************************************************************************************
* 函数名 : vAppTask_DebugInfo
* 描 述 : 任务堆栈信息
**********************************************************************************************************************************************/
static void vAppTask_DebugInfo(void)
{
OS_TCB *ptcb;
OS_STK_DATA stkDat;
ptcb = &OSTCBTbl[0];//Table TCB
printf("************************************ App Task Debug Info ***********************************\r\n");
printf(" Prio Used Free Per TaskName\r\n");
while (ptcb != NULL)
{
OSTaskStkChk(ptcb->OSTCBPrio, &stkDat);//Check task stack
printf(" %2d %5d %5d %02d%% %s\r\n", ptcb->OSTCBPrio, stkDat.OSUsed, stkDat.OSFree, (stkDat.OSUsed * 100)/(stkDat.OSUsed + stkDat.OSFree), ptcb->OSTCBTaskName);
ptcb = ptcb->OSTCBPrev;//Previous TCB list
}
printf("\r\n");
}
二、任务名相关说明
- 设置任务名称需要将宏OS_TASK_NAME_EN置1
#define OS_TASK_NAME_EN 1u /* Enable task names */
- 设置任务名称的函数为OSTaskNameSet()
// prio : 任务优先级
// pname : 任务名字
// perr : 错误代码
void OSTaskNameSet (INT8U prio, INT8U *pname, INT8U *perr)
三、设置任务名源码
/**********************************************************************************************************
* ASSIGN A NAME TO A TASK
*
* Description: This function is used to set the name of a task.
*
* Arguments : prio is the priority of the task that you want the assign a name to.
*
* pname is a pointer to an ASCII string that contains the name of the task.
*
* perr is a pointer to an error code that can contain one of the following values:
*
* OS_ERR_NONE if the requested task is resumed
* OS_ERR_TASK_NOT_EXIST if the task has not been created or is assigned to a Mutex
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
* OS_ERR_PRIO_INVALID if you specified an invalid priority:
* A higher value than the idle task or not OS_PRIO_SELF.
* OS_ERR_NAME_SET_ISR if you called this function from an ISR
*
* Returns : None
**********************************************************************************************************/
#if OS_TASK_NAME_EN > 0u
void OSTaskNameSet (INT8U prio,
INT8U *pname,
INT8U *perr)
{
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
if (perr == (INT8U *)0) {
OS_SAFETY_CRITICAL_EXCEPTION();
return;
}
#endif
#if OS_ARG_CHK_EN > 0u
if (prio > OS_LOWEST_PRIO) { /* Task priority valid ? */
if (prio != OS_PRIO_SELF) {
*perr = OS_ERR_PRIO_INVALID; /* No */
return;
}
}
if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
*perr = OS_ERR_PNAME_NULL; /* Yes */
return;
}
#endif
if (OSIntNesting > 0u) { /* See if trying to call from an ISR */
*perr = OS_ERR_NAME_SET_ISR;
return;
}
OS_ENTER_CRITICAL();
if (prio == OS_PRIO_SELF) { /* See if caller desires to set it's own name */
prio = OSTCBCur->OSTCBPrio;
}
ptcb = OSTCBPrioTbl[prio];
if (ptcb == (OS_TCB *)0) { /* Does task exist? */
OS_EXIT_CRITICAL(); /* No */
*perr = OS_ERR_TASK_NOT_EXIST;
return;
}
if (ptcb == OS_TCB_RESERVED) { /* Task assigned to a Mutex? */
OS_EXIT_CRITICAL(); /* Yes */
*perr = OS_ERR_TASK_NOT_EXIST;
return;
}
ptcb->OSTCBTaskName = pname;
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
}
#endif
四、任务堆栈使用情况输出打印效果
说明
- uC/OS-II Idle为空闲任务。
- uC/OS-II Stat为统计任务。
- uC/OS-II Tmr为软件定时器任务。
- 空闲任务为系统自动创建任务且为必须创建的任务,空闲任务的优先级最低。
- 软件定时器任务优先级最高,且软件定时器任务可通过宏定义来决定是否创建。
- 宏OS_TMR_EN为1,则创建软件定时器任务。
- 宏OS_TASK_STAT_EN为1,则创建统计任务。
************************************ App Task Debug Info ***********************************
Prio Used Free Per TaskName
63 15 113 11% uC/OS-II Idle
62 21 107 16% uC/OS-II Stat
0 25 103 19% uC/OS-II Tmr
5 66 14 82% Start
10 66 34 66% USART3
9 27 73 27% USART2
11 27 73 27% IWDG
12 52 48 52% Queue
3 27 73 27% Debug
五、系统自动创建空闲任务
/**********************************************************************************************************
* INITIALIZATION
* CREATING THE IDLE TASK
*
* Description: This function creates the Idle Task.
*
* Arguments : none
*
* Returns : none
**********************************************************************************************************/
static void OS_InitTaskIdle (void)
{
#if OS_TASK_NAME_EN > 0u
INT8U err;
#endif
#if OS_TASK_CREATE_EXT_EN > 0u
#if OS_STK_GROWTH == 1u
(void)OSTaskCreateExt(OS_TaskIdle,
(void *)0, /* No arguments passed to OS_TaskIdle() */
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],/* Set Top-Of-Stack */
OS_TASK_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[0], /* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#else
(void)OSTaskCreateExt(OS_TaskIdle,
(void *)0, /* No arguments passed to OS_TaskIdle() */
&OSTaskIdleStk[0], /* Set Top-Of-Stack */
OS_TASK_IDLE_PRIO, /* Lowest priority level */
OS_TASK_IDLE_ID,
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],/* Set Bottom-Of-Stack */
OS_TASK_IDLE_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack */
#endif
#else
#if OS_STK_GROWTH == 1u
(void)OSTaskCreate(OS_TaskIdle,
(void *)0,
&OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1u],
OS_TASK_IDLE_PRIO);
#else
(void)OSTaskCreate(OS_TaskIdle,
(void *)0,
&OSTaskIdleStk[0],
OS_TASK_IDLE_PRIO);
#endif
#endif
#if OS_TASK_NAME_EN > 0u
OSTaskNameSet(OS_TASK_IDLE_PRIO, (INT8U *)(void *)"uC/OS-II Idle", &err);
#endif
}
六、系统自动创建爱你统计任务
/**********************************************************************************************************
* INITIALIZATION
* CREATING THE STATISTIC TASK
*
* Description: This function creates the Statistic Task.
*
* Arguments : none
*
* Returns : none
**********************************************************************************************************/
#if OS_TASK_STAT_EN > 0u
static void OS_InitTaskStat (void)
{
#if OS_TASK_NAME_EN > 0u
INT8U err;
#endif
#if OS_TASK_CREATE_EXT_EN > 0u
#if OS_STK_GROWTH == 1u
(void)OSTaskCreateExt(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1u], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO, /* One higher than the idle task */
OS_TASK_STAT_ID,
&OSTaskStatStk[0], /* Set Bottom-Of-Stack */
OS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#else
(void)OSTaskCreateExt(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[0], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO, /* One higher than the idle task */
OS_TASK_STAT_ID,
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1u], /* Set Bottom-Of-Stack */
OS_TASK_STAT_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
#endif
#else
#if OS_STK_GROWTH == 1u
(void)OSTaskCreate(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1u], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO); /* One higher than the idle task */
#else
(void)OSTaskCreate(OS_TaskStat,
(void *)0, /* No args passed to OS_TaskStat()*/
&OSTaskStatStk[0], /* Set Top-Of-Stack */
OS_TASK_STAT_PRIO); /* One higher than the idle task */
#endif
#endif
#if OS_TASK_NAME_EN > 0u
OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)(void *)"uC/OS-II Stat", &err);
#endif
}
#endif
七、系统自动创建软件定时器任务
/**********************************************************************************************************
* INITIALIZE THE TIMER MANAGEMENT TASK
*
* Description: This function is called by OSTmrInit() to create the timer management task.
* * Arguments : none
*
* Returns : none
**********************************************************************************************************/
#if OS_TMR_EN > 0u
static void OSTmr_InitTask (void)
{
#if OS_TASK_NAME_EN > 0u
INT8U err;
#endif
#if OS_TASK_CREATE_EXT_EN > 0u
#if OS_STK_GROWTH == 1u
(void)OSTaskCreateExt(OSTmr_Task,
(void *)0, /* No arguments passed to OSTmrTask() */
&OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u], /* Set Top-Of-Stack */
OS_TASK_TMR_PRIO,
OS_TASK_TMR_ID,
&OSTmrTaskStk[0], /* Set Bottom-Of-Stack */
OS_TASK_TMR_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */
#else
(void)OSTaskCreateExt(OSTmr_Task,
(void *)0, /* No arguments passed to OSTmrTask() */
&OSTmrTaskStk[0], /* Set Top-Of-Stack */
OS_TASK_TMR_PRIO,
OS_TASK_TMR_ID,
&OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u], /* Set Bottom-Of-Stack */
OS_TASK_TMR_STK_SIZE,
(void *)0, /* No TCB extension */
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear stack */
#endif
#else
#if OS_STK_GROWTH == 1u
(void)OSTaskCreate(OSTmr_Task,
(void *)0,
&OSTmrTaskStk[OS_TASK_TMR_STK_SIZE - 1u],
OS_TASK_TMR_PRIO);
#else
(void)OSTaskCreate(OSTmr_Task,
(void *)0,
&OSTmrTaskStk[0],
OS_TASK_TMR_PRIO);
#endif
#endif
#if OS_TASK_NAME_EN > 0u
OSTaskNameSet(OS_TASK_TMR_PRIO, (INT8U *)(void *)"uC/OS-II Tmr", &err);
#endif
}
#endif