该任务的目的是统计运行时间的,OSTaskStat()
如果定义了宏OS_TASK_STAT_EN那么就会建立这个任务
- /*
- *********************************************************************************************************
- * INITIALIZATION
- * CREATING THE STATISTIC TASK
- *
- * Description: This function creates the Statistic Task.
- *
- * Arguments : none
- *
- * Returns : none
- *********************************************************************************************************
- */
- #if OS_TASK_STAT_EN > 0
- static void OS_InitTaskStat (void)
- {
- #if OS_TASK_NAME_SIZE > 7
- INT8U err;
- #endif
- #if OS_TASK_CREATE_EXT_EN > 0
- #if OS_STK_GROWTH == 1
- (void)OSTaskCreateExt(OS_TaskStat,
- (void *)0, /* No args passed to OS_TaskStat()*/
- &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* 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 - 1], /* 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 == 1
- (void)OSTaskCreate(OS_TaskStat,
- (void *)0, /* No args passed to OS_TaskStat()*/
- &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* 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_SIZE > 14
- OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"uC/OS-II Stat", &err);
- #else
- #if OS_TASK_NAME_SIZE > 7
- OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"OS-Stat", &err);
- #endif
- #endif
- }
- #endif
那么这个任务中的主要执行依然是建立任务的函数OSTaskCreateExt或者OSTaskCreate
建立时关联执行程序函数名OS_TaskStat
没有参数传递第二个参数为NULL
堆栈栈顶为数组的最后一个元素OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1]
优先级#define OS_TASK_STAT_PRIO (OS_LOWEST_PRIO - 1) /* Statistic task priority */
我们可以看到这个计数任务的优先级是倒数第二的,只比空闲程序高一级
然后是没有开发的ID,我们看到空闲任务的id是65535,这个计数程序是65534,以后ID有这么多,优先级也有这么多咯?还是有可能多任务处于同一优先级?
然后是堆栈栈底,数组第一个元素的地址
然后是堆栈元素个数
然后是指向附加数据域的指针,为NULL
最后使能堆栈检查和清空的功能
使用nameset函数将任务的TCB中的name数组改成相应的名字就结束了,下面我们来看看OSTaskStat函数
- /*
- *********************************************************************************************************
- * STATISTICS TASK
- *
- * Description: This task is internal to uC/OS-II and is used to compute some statistics about the
- * multitasking environment. Specifically, OS_TaskStat() computes the CPU usage.
- * CPU usage is determined by:
- *
- * OSIdleCtr
- * OSCPUUsage = 100 * (1 - ------------) (units are in %)
- * OSIdleCtrMax
- *
- * Arguments : parg this pointer is not used at this time.
- *
- * Returns : none
- *
- * Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the
- * next higher priority, OS_TASK_IDLE_PRIO-1.
- * 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0.
- * 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the
- * maximum value for the idle counter.
- *********************************************************************************************************
- */
- #if OS_TASK_STAT_EN > 0
- void OS_TaskStat (void *p_arg)
- {
- INT32U run;
- INT32U max;
- INT8S usage;
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
- p_arg = p_arg; /* Prevent compiler warning for not using 'parg' */
- while (OSStatRdy == OS_FALSE) {
- OSTimeDly(2 * OS_TICKS_PER_SEC / 10); /* Wait until statistic task is ready */
- }
- max = OSIdleCtrMax / 100L;
- for (;;) {
- OS_ENTER_CRITICAL();
- OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */
- run = OSIdleCtr;
- OSIdleCtr = 0L; /* Reset the idle counter for the next second */
- OS_EXIT_CRITICAL();
- if (max > 0L) {
- usage = (INT8S)(100L - run / max);
- if (usage >= 0) { /* Make sure we don't have a negative percentage */
- OSCPUUsage = usage;
- } else {
- OSCPUUsage = 0;
- }
- } else {
- OSCPUUsage = 0;
- max = OSIdleCtrMax / 100L;
- }
- OSTaskStatHook(); /* Invoke user definable hook */
- #if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)
- OS_TaskStatStkChk(); /* Check the stacks for each task */
- #endif
- OSTimeDly(OS_TICKS_PER_SEC / 10); /* Accumulate OSIdleCtr for the next 1/10 second */
- }
- }
- #endif
顺便说一句,以前总是看到用pdata=pdata
不理解是干啥用的,百度说是避免警告的产生,如果不使用这个指针的话,想一想如果不使用为什么要传递到子函数?
在stat子函数里面,检查布尔型标志位OSStatRdy是否为0,如果为0则进行
取得idle寄存器一秒钟内的最大值/100
OSTimeDly(2 * OS_TICKS_PER_SEC / 10);延时0.2个秒(大概是这个意思吧,一秒有多少个时间片的宏)
如果就绪标志位ok了
进入一个死循环,关中断,取得idle寄存器的值
重置idle计数寄存器的值
开中断
取得100-run/max idle寄存器上一秒种的数值除以最大值/100(直接算出整数位百分比)
给OSCPUUsage变量赋值cpu的使用率
进入自定义函数OSTaskStatHook()
如果ext使能且stkchk使能,那么执行
- /*
- *********************************************************************************************************
- * CHECK ALL TASK STACKS
- *
- * Description: This function is called by OS_TaskStat() to check the stacks of each active task.
- *
- * Arguments : none
- *
- * Returns : none
- *********************************************************************************************************
- */
- #if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)
- void OS_TaskStatStkChk (void)
- {
- OS_TCB *ptcb;
- OS_STK_DATA stk_data;
- INT8U err;
- INT8U prio;
- for (prio = 0; prio <= OS_TASK_IDLE_PRIO; prio++) {
- err = OSTaskStkChk(prio, &stk_data);
- if (err == OS_NO_ERR) {
- ptcb = OSTCBPrioTbl[prio];
- if (ptcb != (OS_TCB *)0) { /* Make sure task 'ptcb' is ... */
- if (ptcb != (OS_TCB *)1) { /* ... still valid. */
- #if OS_TASK_PROFILE_EN > 0
- #if OS_STK_GROWTH == 1
- ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom + ptcb->OSTCBStkSize;
- #else
- ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom - ptcb->OSTCBStkSize;
- #endif
- ptcb->OSTCBStkUsed = stk_data.OSUsed; /* Store the number of bytes used */
- #endif
- }
- }
- }
- }
- }
- #endif
OS_TaskStatStkChk对每一个任务进行堆栈检查,具体的检查过程
- /*
- *********************************************************************************************************
- * STACK CHECKING
- *
- * Description: This function is called to check the amount of free memory left on the specified task's
- * stack.
- *
- * Arguments : prio is the task priority
- *
- * p_stk_data is a pointer to a data structure of type OS_STK_DATA.
- *
- * Returns : OS_NO_ERR upon success
- * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
- * (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
- * OS_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP
- * OS_TASK_OPT_ERR if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
- * OS_ERR_PDATA_NULL if 'p_stk_data' is a NULL pointer
- *********************************************************************************************************
- */
- #if OS_TASK_CREATE_EXT_EN > 0
- INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data)
- {
- OS_TCB *ptcb;
- OS_STK *pchk;
- INT32U free;
- INT32U size;
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
- #if OS_ARG_CHK_EN > 0
- if (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */
- if (prio != OS_PRIO_SELF) {
- return (OS_PRIO_INVALID);
- }
- }
- if (p_stk_data == (OS_STK_DATA *)0) { /* Validate 'p_stk_data' */
- return (OS_ERR_PDATA_NULL);
- }
- #endif
- p_stk_data->OSFree = 0; /* Assume failure, set to 0 size */
- p_stk_data->OSUsed = 0;
- OS_ENTER_CRITICAL();
- if (prio == OS_PRIO_SELF) { /* See if check for SELF */
- prio = OSTCBCur->OSTCBPrio;
- }
- ptcb = OSTCBPrioTbl[prio];
- if (ptcb == (OS_TCB *)0) { /* Make sure task exist */
- OS_EXIT_CRITICAL();
- return (OS_TASK_NOT_EXIST);
- }
- if (ptcb == (OS_TCB *)1) {
- OS_EXIT_CRITICAL();
- return (OS_TASK_NOT_EXIST);
- }
- if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */
- OS_EXIT_CRITICAL();
- return (OS_TASK_OPT_ERR);
- }
- free = 0;
- size = ptcb->OSTCBStkSize;
- pchk = ptcb->OSTCBStkBottom;
- OS_EXIT_CRITICAL();
- #if OS_STK_GROWTH == 1
- while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */
- free++;
- }
- #else
- while (*pchk-- == (OS_STK)0) {
- free++;
- }
- #endif
- p_stk_data->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */
- p_stk_data->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */
- return (OS_NO_ERR);
- }
- #endif
好困啊,明天再看这个栈检查函数!
阅读(2194) | 评论(0) | 转发(0) |