对初始化函数OSInit()的理解

我们在学习uCOSII的时候每一个main()函数总有一个初始化函数OSInit(),说明初始化是非常重要的,那么初始化到底做了那些工作呢,说简单点就是把系统恢复到默认值,让我们来详细看一下代码:
要看代码首先要从整体上了解初始化后的数据结构,如图:
对初始化函数OSInit()的理解_第1张图片
void  OSInit (void)
{
    OSInitHookBegin();                                           /* 如果版本号超过204u则调用此函数Call port specific initialization code   */

    OS_InitMisc();                                               /* 初始化一些基本的参数Initialize miscellaneous variables       */

    OS_InitRdyList();                                            /* 初始化任务就绪表Initialize the Ready List                */

    OS_InitTCBList();                                            /* 初始化任务控制块链表Initialize the free list of OS_TCBs      */

    OS_InitEventList();                                          /* 初始化事件链表Initialize the free list of OS_EVENTs    */

#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
    OS_FlagInit();                                               /* 初始化事件标志Initialize the event flag structures     */
#endif

#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
    OS_MemInit();                                                /* 初始化内存Initialize the memory manager            */
#endif

#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
    OS_QInit();                                                  /* 初始化队列Initialize the message queue structures  */
#endif

    OS_InitTaskIdle();                                           /* 创建空闲任务Create the Idle Task                     */
#if OS_TASK_STAT_EN > 0
    OS_InitTaskStat();                                           /* 创建统计任务Create the Statistic Task                */
#endif

#if OS_TMR_EN > 0
    OSTmr_Init();                                                /* 初始化时间管理控制器Initialize the Timer Manager             */
#endif

    OSInitHookEnd();                                             /* Call port specific init. code            */

#if OS_DEBUG_EN > 0
    OSDebugInit();
#endif
}
从这么多的初始化中我们着重讲一下任务就绪表和任务控制块的初始化,首先看任务就绪表的初始化:
static  void  OS_InitRdyList (void)				/*任务就绪表的初始化函数*/
{
    INT8U    i;
#if OS_LOWEST_PRIO <= 63
    INT8U   *prdytbl;						/*任务就绪表指针*/
#else
    INT16U  *prdytbl;
#endif


    OSRdyGrp      = 0;                                     /* 清除任务就绪表Clear the ready list                     */
    prdytbl       = &OSRdyTbl[0];
    for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
        *prdytbl++ = 0;						/*将所有的任务就绪表清除*/
    }

    OSPrioCur     = 0;						/*当前正在运行的的任务优先级别清0*/
    OSPrioHighRdy = 0;						/*具有最高优先级别的任务就绪表的优先级清0*/

    OSTCBHighRdy  = (OS_TCB *)0;				/*指向最高优先级的就绪任务控制块的指针清0*/
    OSTCBCur      = (OS_TCB *)0;				/*指向正在运行就绪任务控制块的指针清0*/
}
static  void  OS_InitTCBList (void)					/*任务控制块链表的初始化函数*/
{
    INT8U    i;
    OS_TCB  *ptcb1;							/*指向任务控制块的指针1*/
    OS_TCB  *ptcb2;							/*指向任务控制块的指针2*/


    OS_MemClr((INT8U *)&OSTCBTbl[0],     sizeof(OSTCBTbl));      /* 清除所有的任务控制块Clear all the TCBs                 */
    OS_MemClr((INT8U *)&OSTCBPrioTbl[0], sizeof(OSTCBPrioTbl));  /* 清除所有的优先级列表Clear the priority table           */
    ptcb1 = &OSTCBTbl[0];					/*ptcb1指向任务控制块链表中的第一个任务控制块*/
    ptcb2 = &OSTCBTbl[1];					/*ptcb2指向任务控制块链表中的第一个任务控制块*/
    for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {  /* 初始化空的任务控制块链表Init. list of free TCBs            */
        ptcb1->OSTCBNext = ptcb2;
#if OS_TASK_NAME_SIZE > 1					/*如果不知道任务的名称*/
        ptcb1->OSTCBTaskName[0] = '?';                           /* Unknown name                       */
        ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
        ptcb1++;
        ptcb2++;
    }
    ptcb1->OSTCBNext = (OS_TCB *)0;                              /* 最后一个任务控制块置为空Last OS_TCB                        */
#if OS_TASK_NAME_SIZE > 1
    ptcb1->OSTCBTaskName[0] = '?';                               /* Unknown name                       */
    ptcb1->OSTCBTaskName[1] = OS_ASCII_NUL;
#endif
    OSTCBList               = (OS_TCB *)0;                       /* 将统计任务的控制块置为空TCB lists initializations          */
    OSTCBFreeList           = &OSTCBTbl[0];			/*将空闲任务的控制块置为空*/
}

从这么多代码的分析中我们可以看出这些函数基本上是按照上图所示进行初始化的,所以这也就启示:我们不光要了解具体的过程,从整体上把握函数的功能,这样我们才能够有放矢地的学习uVOSII。

你可能感兴趣的:(uCOSII)