ucos-II 时间管理源码分析

ucos-II 的时间管理非常简单,其的核心主要在于理解两个变量和一个函数。

一个是全局变量 OS_EXT  volatile  INT32U  OSTime 表示系统时间;另外一个是每个任务的OS_TCB变量中的成员OSTCBDly用来处理任务的延时;

函数OSTimeTick被定义在core.c文件中,它需要在系统启动时被挂载在一个定时器里(根据CPU的不同,在操作系统的移植代码里实现),在这个函数里完成对上述两个变量的修改,如下:

  • 系统时间变量OSTime累加;
  • 遍历任务列表中的每个任务结构体变量,如果OS_TCB变量中的OSTCBDly不为0,则递减该变量;如果该变量为0,且该任务也是因为延时被挂起,则将该任务置于任务就绪队列中。
        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 != 0u) {/* No, Delayed or waiting for event with TO     */
                ptcb->OSTCBDly--; /* Decrement nbr of ticks to end of delay       */
                if (ptcb->OSTCBDly == 0u) { /* Check for timeout                            */

                    if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
                        ptcb->OSTCBStat  &= (INT8U)~(INT8U)OS_STAT_PEND_ANY; /* Yes, Clear status flag   */
                        ptcb->OSTCBStatPend = OS_STAT_PEND_TO;                 /* Indicate PEND timeout    */
                    } else {
                        ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
                    }

                    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                */

内核剩下的时间管理功能主要是提供一些应用调用的API,如时间延时、系统时间获取等。定义在OS_TIME.c文件中,都比较简单。这里列举函数OSTimeDly:

完成对一个任务的延时:void  OSTimeDly (INT32U ticks),若入参tick数不为0,将当前任务清除接续队列,设置其OSTimeDly变量后,调用OS_Sched。

void  OSTimeDly (INT32U ticks)
{
    INT8U      y;
    if (OSIntNesting > 0u) {/* See if trying to call from an ISR  /
        return;
    }
    if (OSLockNesting > 0u) { /* See if called with scheduler locked */
        return;
    }
    if (ticks > 0u) {/* 0 means no delay! */
        OS_ENTER_CRITICAL();
        y            =  OSTCBCur->OSTCBY;        /* Delay current task */
        OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0u) {
            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
        }
        OSTCBCur->OSTCBDly = ticks;  /* Load ticks in TCB */
        OS_EXIT_CRITICAL();
        OS_Sched(); /* Find next task to run! */
    }
}

 

 

 

 

posted @ 2013-01-27 20:51  Fredric_2013  阅读(719)  评论(0编辑  收藏  举报