在实时系统中每个delay的任务依靠时间tick函数来减少TCB中delay项的值,当其减到0时,进入就绪态
任务调度的时候就会考虑就绪态的任务,所以tick函数应该算所操作系统的核心函数
点击(此处)折叠或打开
- /*
- *********************************************************************************************************
- * PROCESS SYSTEM TICK
- *
- * Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known
- * as a 'clock tick'). This function should be called by the ticker ISR but, can also be
- * called by a high priority task.
- *
- * Arguments : none
- *
- * Returns : none
- *********************************************************************************************************
- */
-
- void OSTimeTick (void)
- {
- OS_TCB *ptcb;
- #if OS_TICK_STEP_EN > 0
- BOOLEAN step;
- #endif
- #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
- OS_CPU_SR cpu_sr = 0;
- #endif
-
-
-
- #if OS_TIME_TICK_HOOK_EN > 0
- OSTimeTickHook(); /* Call user definable hook */
- #endif
- #if OS_TIME_GET_SET_EN > 0
- OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
- OSTime++;
- OS_EXIT_CRITICAL();
- #endif
- if (OSRunning == OS_TRUE) {
- #if OS_TICK_STEP_EN > 0
- switch (OSTickStepState) { /* Determine whether we need to process a tick */
- case OS_TICK_STEP_DIS: /* Yes, stepping is disabled */
- step = OS_TRUE;
- break;
-
- case OS_TICK_STEP_WAIT: /* No, waiting for uC/OS-View to set ... */
- step = OS_FALSE; /* .. OSTickStepState to OS_TICK_STEP_ONCE */
- break;
-
- case OS_TICK_STEP_ONCE: /* Yes, process tick once and wait for next ... */
- step = OS_TRUE; /* ... step command from uC/OS-View */
- OSTickStepState = OS_TICK_STEP_WAIT;
- break;
-
- default: /* Invalid case, correct situation */
- step = OS_TRUE;
- OSTickStepState = OS_TICK_STEP_DIS;
- break;
- }
- if (step == OS_FALSE) { /* Return if waiting for step command */
- return;
- }
- #endif
- ptcb = OSTCBList; /* Point at first TCB in TCB list */
- while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) { /* Go through all TCBs in TCB list */
- OS_ENTER_CRITICAL();
- if (ptcb->OSTCBDly != 0) { /* No, Delayed or waiting for event with TO */
- if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
- /* Check for timeout */
- if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
- ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */
- ptcb->OSTCBPendTO = OS_TRUE; /* Indicate PEND timeout */
- } else {
- ptcb->OSTCBPendTO = OS_FALSE;
- }
-
- if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended?*/
- OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */
- OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
- }
- }
- }
- ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
- OS_EXIT_CRITICAL();
- }
- }
- }
如其题目所介绍的,它应当是时钟tick中断调用的函数,每当调用这个函数都会把OSTCBList中的所有任务遍历一遍,进行delay--的操作
第一步,调用用户自己定义的hook函数,用户可以在每个时间片中间加入自己的操作
第二步,关中断,给OSTime++,OSTime是当开启TIME_GET_SET_EN时的系统以时间片为单位的计时,开中断
第三步,标志位OSRuning如果为true,那么判断是否是step模式的tick,step有三种状态,disabile,wait和once,在wait下直接return函数,不进行tick原本应当进行的代码,如果once执行一次就置为wait,如果disable那么相当于不进行wait,直接执行tick遍历OSTCBList。
第四步,只要prio不是idleprio,那么判断delay是否为0,
是不是在等待某种信号,OS_STAT_PEND_ANY,如果是,因为等待超时,所以不再等待某种信号,
清除标志位。
第五步,如果OS_STAT_SUSPEND位为0,那么将任务在就绪表中的位置置1
第六步,将指向TCB的指针指向下一个数据块ptcb = ptcb->OSTCBNext;开始下一轮while循环