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

    }

}

 

 

 

 

你可能感兴趣的:(源码分析)