Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434019
  • 博文数量: 103
  • 博客积分: 1455
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-15 22:17
文章分类

全部博文(103)

文章存档

2013年(4)

2012年(99)

我的朋友

分类: LINUX

2012-11-11 19:50:03

该任务的目的是统计运行时间的,OSTaskStat()
如果定义了宏OS_TASK_STAT_EN那么就会建立这个任务

点击(此处)折叠或打开

  1. /*
  2. *********************************************************************************************************
  3. * INITIALIZATION
  4. * CREATING THE STATISTIC TASK
  5. *
  6. * Description: This function creates the Statistic Task.
  7. *
  8. * Arguments : none
  9. *
  10. * Returns : none
  11. *********************************************************************************************************
  12. */

  13. #if OS_TASK_STAT_EN > 0
  14. static void OS_InitTaskStat (void)
  15. {
  16. #if OS_TASK_NAME_SIZE > 7
  17.     INT8U err;
  18. #endif


  19. #if OS_TASK_CREATE_EXT_EN > 0
  20.     #if OS_STK_GROWTH == 1
  21.     (void)OSTaskCreateExt(OS_TaskStat,
  22.                           (void *)0, /* No args passed to OS_TaskStat()*/
  23.                           &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
  24.                           OS_TASK_STAT_PRIO, /* One higher than the idle task */
  25.                           OS_TASK_STAT_ID,
  26.                           &OSTaskStatStk[0], /* Set Bottom-Of-Stack */
  27.                           OS_TASK_STAT_STK_SIZE,
  28.                           (void *)0, /* No TCB extension */
  29.                           OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
  30.     #else
  31.     (void)OSTaskCreateExt(OS_TaskStat,
  32.                           (void *)0, /* No args passed to OS_TaskStat()*/
  33.                           &OSTaskStatStk[0], /* Set Top-Of-Stack */
  34.                           OS_TASK_STAT_PRIO, /* One higher than the idle task */
  35.                           OS_TASK_STAT_ID,
  36.                           &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Bottom-Of-Stack */
  37.                           OS_TASK_STAT_STK_SIZE,
  38.                           (void *)0, /* No TCB extension */
  39.                           OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); /* Enable stack checking + clear */
  40.     #endif
  41. #else
  42.     #if OS_STK_GROWTH == 1
  43.     (void)OSTaskCreate(OS_TaskStat,
  44.                        (void *)0, /* No args passed to OS_TaskStat()*/
  45.                        &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1], /* Set Top-Of-Stack */
  46.                        OS_TASK_STAT_PRIO); /* One higher than the idle task */
  47.     #else
  48.     (void)OSTaskCreate(OS_TaskStat,
  49.                        (void *)0, /* No args passed to OS_TaskStat()*/
  50.                        &OSTaskStatStk[0], /* Set Top-Of-Stack */
  51.                        OS_TASK_STAT_PRIO); /* One higher than the idle task */
  52.     #endif
  53. #endif

  54. #if OS_TASK_NAME_SIZE > 14
  55.     OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"uC/OS-II Stat", &err);
  56. #else
  57. #if OS_TASK_NAME_SIZE > 7
  58.     OSTaskNameSet(OS_TASK_STAT_PRIO, (INT8U *)"OS-Stat", &err);
  59. #endif
  60. #endif
  61. }
  62. #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函数

点击(此处)折叠或打开

  1. /*
  2. *********************************************************************************************************
  3. * STATISTICS TASK
  4. *
  5. * Description: This task is internal to uC/OS-II and is used to compute some statistics about the
  6. * multitasking environment. Specifically, OS_TaskStat() computes the CPU usage.
  7. * CPU usage is determined by:
  8. *
  9. * OSIdleCtr
  10. * OSCPUUsage = 100 * (1 - ------------) (units are in %)
  11. * OSIdleCtrMax
  12. *
  13. * Arguments : parg this pointer is not used at this time.
  14. *
  15. * Returns : none
  16. *
  17. * Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the
  18. * next higher priority, OS_TASK_IDLE_PRIO-1.
  19. * 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0.
  20. * 3) You MUST have at least a delay of 2/10 seconds to allow for the system to establish the
  21. * maximum value for the idle counter.
  22. *********************************************************************************************************
  23. */

  24. #if OS_TASK_STAT_EN > 0
  25. void OS_TaskStat (void *p_arg)
  26. {
  27.     INT32U run;
  28.     INT32U max;
  29.     INT8S usage;
  30. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  31.     OS_CPU_SR cpu_sr = 0;
  32. #endif



  33.     p_arg = p_arg; /* Prevent compiler warning for not using 'parg' */
  34.     while (OSStatRdy == OS_FALSE) {
  35.         OSTimeDly(2 * OS_TICKS_PER_SEC / 10); /* Wait until statistic task is ready */
  36.     }
  37.     max = OSIdleCtrMax / 100L;
  38.     for (;;) {
  39.         OS_ENTER_CRITICAL();
  40.         OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */
  41.         run = OSIdleCtr;
  42.         OSIdleCtr = 0L; /* Reset the idle counter for the next second */
  43.         OS_EXIT_CRITICAL();
  44.         if (max > 0L) {
  45.             usage = (INT8S)(100L - run / max);
  46.             if (usage >= 0) { /* Make sure we don't have a negative percentage */
  47.                 OSCPUUsage = usage;
  48.             } else {
  49.                 OSCPUUsage = 0;
  50.             }
  51.         } else {
  52.             OSCPUUsage = 0;
  53.             max = OSIdleCtrMax / 100L;
  54.         }
  55.         OSTaskStatHook(); /* Invoke user definable hook */
  56. #if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)
  57.         OS_TaskStatStkChk(); /* Check the stacks for each task */
  58. #endif
  59.         OSTimeDly(OS_TICKS_PER_SEC / 10); /* Accumulate OSIdleCtr for the next 1/10 second */
  60.     }
  61. }
  62. #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使能,那么执行

点击(此处)折叠或打开

  1. /*
  2. *********************************************************************************************************
  3. * CHECK ALL TASK STACKS
  4. *
  5. * Description: This function is called by OS_TaskStat() to check the stacks of each active task.
  6. *
  7. * Arguments : none
  8. *
  9. * Returns : none
  10. *********************************************************************************************************
  11. */

  12. #if (OS_TASK_STAT_STK_CHK_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)
  13. void OS_TaskStatStkChk (void)
  14. {
  15.     OS_TCB *ptcb;
  16.     OS_STK_DATA stk_data;
  17.     INT8U err;
  18.     INT8U prio;


  19.     for (prio = 0; prio <= OS_TASK_IDLE_PRIO; prio++) {
  20.         err = OSTaskStkChk(prio, &stk_data);
  21.         if (err == OS_NO_ERR) {
  22.             ptcb = OSTCBPrioTbl[prio];
  23.             if (ptcb != (OS_TCB *)0) { /* Make sure task 'ptcb' is ... */
  24.                 if (ptcb != (OS_TCB *)1) { /* ... still valid. */
  25. #if OS_TASK_PROFILE_EN > 0
  26.                     #if OS_STK_GROWTH == 1
  27.                     ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom + ptcb->OSTCBStkSize;
  28.                     #else
  29.                     ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom - ptcb->OSTCBStkSize;
  30.                     #endif
  31.                     ptcb->OSTCBStkUsed = stk_data.OSUsed; /* Store the number of bytes used */
  32. #endif
  33.                 }
  34.             }
  35.         }
  36.     }
  37. }
  38. #endif

 
OS_TaskStatStkChk对每一个任务进行堆栈检查,具体的检查过程

点击(此处)折叠或打开

  1. /*
  2. *********************************************************************************************************
  3. * STACK CHECKING
  4. *
  5. * Description: This function is called to check the amount of free memory left on the specified task's
  6. * stack.
  7. *
  8. * Arguments : prio is the task priority
  9. *
  10. * p_stk_data is a pointer to a data structure of type OS_STK_DATA.
  11. *
  12. * Returns : OS_NO_ERR upon success
  13. * OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed
  14. * (i.e. > OS_LOWEST_PRIO) or, you have not specified OS_PRIO_SELF.
  15. * OS_TASK_NOT_EXIST if the desired task has not been created or is assigned to a Mutex PIP
  16. * OS_TASK_OPT_ERR if you did NOT specified OS_TASK_OPT_STK_CHK when the task was created
  17. * OS_ERR_PDATA_NULL if 'p_stk_data' is a NULL pointer
  18. *********************************************************************************************************
  19. */
  20. #if OS_TASK_CREATE_EXT_EN > 0
  21. INT8U OSTaskStkChk (INT8U prio, OS_STK_DATA *p_stk_data)
  22. {
  23.     OS_TCB *ptcb;
  24.     OS_STK *pchk;
  25.     INT32U free;
  26.     INT32U size;
  27. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  28.     OS_CPU_SR cpu_sr = 0;
  29. #endif



  30. #if OS_ARG_CHK_EN > 0
  31.     if (prio > OS_LOWEST_PRIO) { /* Make sure task priority is valid */
  32.         if (prio != OS_PRIO_SELF) {
  33.             return (OS_PRIO_INVALID);
  34.         }
  35.     }
  36.     if (p_stk_data == (OS_STK_DATA *)0) { /* Validate 'p_stk_data' */
  37.         return (OS_ERR_PDATA_NULL);
  38.     }
  39. #endif
  40.     p_stk_data->OSFree = 0; /* Assume failure, set to 0 size */
  41.     p_stk_data->OSUsed = 0;
  42.     OS_ENTER_CRITICAL();
  43.     if (prio == OS_PRIO_SELF) { /* See if check for SELF */
  44.         prio = OSTCBCur->OSTCBPrio;
  45.     }
  46.     ptcb = OSTCBPrioTbl[prio];
  47.     if (ptcb == (OS_TCB *)0) { /* Make sure task exist */
  48.         OS_EXIT_CRITICAL();
  49.         return (OS_TASK_NOT_EXIST);
  50.     }
  51.     if (ptcb == (OS_TCB *)1) {
  52.         OS_EXIT_CRITICAL();
  53.         return (OS_TASK_NOT_EXIST);
  54.     }
  55.     if ((ptcb->OSTCBOpt & OS_TASK_OPT_STK_CHK) == 0) { /* Make sure stack checking option is set */
  56.         OS_EXIT_CRITICAL();
  57.         return (OS_TASK_OPT_ERR);
  58.     }
  59.     free = 0;
  60.     size = ptcb->OSTCBStkSize;
  61.     pchk = ptcb->OSTCBStkBottom;
  62.     OS_EXIT_CRITICAL();
  63. #if OS_STK_GROWTH == 1
  64.     while (*pchk++ == (OS_STK)0) { /* Compute the number of zero entries on the stk */
  65.         free++;
  66.     }
  67. #else
  68.     while (*pchk-- == (OS_STK)0) {
  69.         free++;
  70.     }
  71. #endif
  72.     p_stk_data->OSFree = free * sizeof(OS_STK); /* Compute number of free bytes on the stack */
  73.     p_stk_data->OSUsed = (size - free) * sizeof(OS_STK); /* Compute number of bytes used on the stack */
  74.     return (OS_NO_ERR);
  75. }
  76. #endif

好困啊,明天再看这个栈检查函数!
 
 
 
 
 
 
阅读(2226) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~