统计UCOSII每个任务堆栈使用大小、剩余大小、堆栈使用率、优先级、任务名

主要统计任务优先级、任务堆栈使用大小、任务堆栈剩余大小、任务堆栈使用率、以及任务名称。(任务堆栈使用率 不同于 CPU使用率)该任务统计的是实时的栈使用情况,不是最大的。

一、统计任务堆栈使用情况

想要实现任务堆栈的统计必须使用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

OSTaskCreateExt()函数的使用:

OSTaskCreateExt()建立任务_*fzfw的博客-CSDN博客

任务堆栈的统计最终使用OSTaskStkChk()函数来实现。要想使得OSTaskStkChk()有效,必须将宏OS_TASK_STAT_STK_CHK_ENOS_TASK_CREATE_EXT_EN都置1,堆栈检测任务OSTaskStkChk()才有效。

#define OS_TASK_STAT_STK_CHK_EN   1u   //    从统计任务中检查任务堆栈使能                  
#define OS_TASK_CREATE_EXT_EN     1u   //   OSTaskCreateExt()使能                       

#if (OS_TASK_STAT_STK_CHK_EN > 0u) && (OS_TASK_CREATE_EXT_EN > 0u)
        OS_TaskStatStkChk();                     //配置允许时,进行堆栈检测                   
#endif

二、任务名相关说明
设置任务名称需要将宏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,则创建统计任务。

printf使用前,需要对 fputc 函数进行重定向,这样可以使其发送到指定的串口。当选上”Use MicroLIB”这是KEIL自带的一个简易的库,例如你用printf函数的时候,就会从串口1 输出字符串,直接默认定向到串口1。只要在任意一个运行的任务中调用该函数就可以了。

/**********************************************************************************************************************************************
 * 函数名 : vAppTask_DebugInfo
 * 描  述 : 任务堆栈信息  
 **********************************************************************************************************************************************/
static void vAppTask_DebugInfo(void)
{
    OS_TCB *ptcb;       //定义一个任务控制块,结构体指针
    OS_STK_DATA stkDat;   //定义堆栈结构体变量         
    ptcb = &OSTCBTbl[0];//将指针指向任务表的第一个任务

    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");
}
************************************ 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值