μC/OS-Ⅱ初始化

来源:互联网 发布:淘宝产品简介模板 编辑:程序博客网 时间:2024/05/16 09:18

在调用μC/OS-Ⅱ的任何其它服务之前,μC/OS-Ⅱ要求用户首先调用系统初始化函数OSIint()。OSIint()初始化μC/OS-Ⅱ所有的变量和数据结构(见OS_CORE.C)。

OSInit()建立空闲任务idle task,这个任务总是处于就绪态的。空闲任务OSTaskIdle()的优先级总是设成最低,即OS_LOWEST_PRIO。如果统计任务允许OS_TASK_STAT_EN和任务建立扩展允许都设为1,则OSInit()还得建立统计任务OSTaskStat()并且让其进入就绪态。OSTaskStat的优先级总是设为OS_LOWEST_PRIO-1

F3.7表示调用OSInit()之后,一些μC/OS-Ⅱ变量和数据结构之间的关系。其解释是基于以下假设的:

在文件OS_CFG.H中,OS_TASK_STAT_EN是设为1的。

在文件OS_CFG.H中,OS_LOWEST_PRIO是设为63的。

在文件OS_CFG.H中, 最多任务数OS_MAX_TASKS是设成大于2的。

以上两个任务的任务控制块(OS_TCBs)是用双向链表链接在一起的。OSTCBList指向这个链表的起始处。当建立一个任务时,这个任务总是被放在这个链表的起始处。换句话说,OSTCBList总是指向最后建立的那个任务。链的终点指向空字符NULL(也就是零)。

因为这两个任务都处在就绪态,在就绪任务表OSRdyTbl[]中的相应位是设为1的。还有,因为这两个任务的相应位是在OSRdyTbl[]的同一行上,即属同一组,故OSRdyGrp中只有1位是设为1的。

μC/OS-Ⅱ还初始化了4个空数据结构缓冲区,如图F3.8所示。每个缓冲区都是单向链表,允许μC/OS-Ⅱ从缓冲区中迅速得到或释放一个缓冲区中的元素。注意,空任务控制块在空缓冲区中的数目取决于最多任务数OS_MAX_TASKS,这个最多任务数是在OS_CFG.H文件中定义的。μC/OS-Ⅱ自动安排总的系统任务数OS_N_SYS_TASKS(见文件μC/OS-Ⅱ.H)。控制块OS_TCB的数目也就自动确定了。当然,包括足够的任务控制块分配给统计任务和空闲任务。指向空事件表OSEventFreeList和空队列表OSFreeList的指针将在第6章,任务间通讯与同步中讨论。指向空存储区的指针表OSMemFreeList将在第7章存储管理中讨论。

/***********************************************************************************************************                                             INITIALIZATION** Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to*              creating any uC/OS-II object and, prior to calling OSStart().** Arguments  : none** Returns    : none**********************************************************************************************************/void  OSInit (void) reentrant{    INT16U     i;    INT8U     *prdytbl;    OS_TCB    *ptcb1;    OS_TCB    *ptcb2;#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 1)    OS_EVENT  *pevent1;    OS_EVENT  *pevent2;#endif#if OS_VERSION >= 204    OSInitHookBegin();                                           /* Call port specific initialization code   */#endif#if OS_TIME_GET_SET_EN > 0       OSTime        = 0L;                                          /* Clear the 32-bit system clock            */#endif    OSIntNesting  = 0;                                           /* Clear the interrupt nesting counter      */    OSLockNesting = 0;                                           /* Clear the scheduling lock counter        */    OSTaskCtr     = 0;                                           /* Clear the number of tasks                */    OSRunning     = FALSE;                                       /* Indicate that multitasking not started   */    OSIdleCtr     = 0L;                                          /* Clear the 32-bit idle counter            */#if (OS_TASK_STAT_EN > 0) && (OS_TASK_CREATE_EXT_EN > 0)    OSIdleCtrRun  = 0L;    OSIdleCtrMax  = 0L;    OSStatRdy     = FALSE;                                       /* Statistic task is not ready              */#endif    OSCtxSwCtr    = 0;                                           /* Clear the context switch counter         */    OSRdyGrp      = 0x00;                                        /* Clear the ready list                     */    prdytbl       = &OSRdyTbl[0];    for (i = 0; i < OS_RDY_TBL_SIZE; i++) {        *prdytbl++ = 0x00;    }    OSPrioCur     = 0;    OSPrioHighRdy = 0;    OSTCBHighRdy  = (OS_TCB *)0;                                 /* TCB Initialization                       */    OSTCBCur      = (OS_TCB *)0;    OSTCBList     = (OS_TCB *)0;    for (i = 0; i < (OS_LOWEST_PRIO + 1); i++) {                 /* Clear the priority table                 */        OSTCBPrioTbl[i] = (OS_TCB *)0;    }    ptcb1 = &OSTCBTbl[0];    ptcb2 = &OSTCBTbl[1];    for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {  /* Init. list of free TCBs                  */        ptcb1->OSTCBNext = ptcb2;        ptcb1++;        ptcb2++;    }    ptcb1->OSTCBNext = (OS_TCB *)0;                              /* Last OS_TCB                              */    OSTCBFreeList    = &OSTCBTbl[0];                            //把OSTCBTbl做成一个链表#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0)    #if OS_MAX_EVENTS == 1                                           OSEventFreeList              = &OSEventTbl[0];               /* Only have ONE event control block        */    OSEventFreeList->OSEventType = OS_EVENT_TYPE_UNUSED;    OSEventFreeList->OSEventPtr  = (OS_EVENT *)0;    #else    pevent1 = &OSEventTbl[0];    pevent2 = &OSEventTbl[1];    for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {                  /* Init. list of free EVENT control blocks  */        pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;        pevent1->OSEventPtr  = pevent2;        pevent1++;        pevent2++;    }    pevent1->OSEventType = OS_EVENT_TYPE_UNUSED;    pevent1->OSEventPtr  = (OS_EVENT *)0;    OSEventFreeList      = &OSEventTbl[0];    #endif#endif#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)    OS_FlagInit();                                               /* Initialize the event flag structures     */#endif#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)    OS_QInit();                                                  /* Initialize the message queue structures  */#endif#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)    OS_MemInit();                                                /* Initialize the memory manager            */#endif    /* ------------------------------------- CREATION OF 'IDLE' TASK --------------------------------------- */#if OS_TASK_CREATE_EXT_EN > 0    #if OS_STK_GROWTH == 1    (void)OSTaskCreateExt(OS_TaskIdle,                          (void *)0,                                 /* No arguments passed to OS_TaskIdle() */                          &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Top-Of-Stack                     */                          OS_IDLE_PRIO,                              /* Lowest priority level                */                          OS_TASK_IDLE_ID,                          &OSTaskIdleStk[0],                         /* Set Bottom-Of-Stack                  */                          OS_TASK_IDLE_STK_SIZE,                          (void *)0,                                 /* No TCB extension                     */                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */    #else    (void)OSTaskCreateExt(OS_TaskIdle,                          (void *)0,                                 /* No arguments passed to OS_TaskIdle() */                          &OSTaskIdleStk[0],                         /* Set Top-Of-Stack                     */                          OS_IDLE_PRIO,                              /* Lowest priority level                */                          OS_TASK_IDLE_ID,                          &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], /* Set Bottom-Of-Stack                  */                          OS_TASK_IDLE_STK_SIZE,                          (void *)0,                                 /* No TCB extension                     */                          OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);/* Enable stack checking + clear stack  */    #endif#else    #if OS_STK_GROWTH == 1    (void)OSTaskCreate(OS_TaskIdle,                       (void *)0,                       &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1],                       OS_IDLE_PRIO);    #else    (void)OSTaskCreate(OS_TaskIdle,                       (void *)0,                       &OSTaskIdleStk[0],                       OS_IDLE_PRIO);    #endif#endif    /* ------------------------------- CREATION OF 'STATISTIC' TASK ---------------------------------- */#if OS_TASK_STAT_EN > 0    #if OS_TASK_CREATE_EXT_EN > 0        #if OS_STK_GROWTH == 1        (void)OSTaskCreateExt(OS_TaskStat,                              (void *)0,                                   /* No args passed to OS_TaskStat()*/                              &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],   /* Set Top-Of-Stack               */                              OS_STAT_PRIO,                                /* One higher than the idle task  */                              OS_TASK_STAT_ID,                              &OSTaskStatStk[0],                           /* Set Bottom-Of-Stack            */                              OS_TASK_STAT_STK_SIZE,                              (void *)0,                                   /* No TCB extension               */                              OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */        #else        (void)OSTaskCreateExt(OS_TaskStat,                              (void *)0,                                   /* No args passed to OS_TaskStat()*/                              &OSTaskStatStk[0],                           /* Set Top-Of-Stack               */                              OS_STAT_PRIO,                                /* One higher than the idle task  */                              OS_TASK_STAT_ID,                              &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],   /* Set Bottom-Of-Stack            */                              OS_TASK_STAT_STK_SIZE,                              (void *)0,                                   /* No TCB extension               */                              OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);  /* Enable stack checking + clear  */        #endif    #else        #if OS_STK_GROWTH == 1        (void)OSTaskCreate(OS_TaskStat,                           (void *)0,                                      /* No args passed to OS_TaskStat()*/                           &OSTaskStatStk[OS_TASK_STAT_STK_SIZE - 1],      /* Set Top-Of-Stack               */                           OS_STAT_PRIO);                                  /* One higher than the idle task  */        #else        (void)OSTaskCreate(OS_TaskStat,                           (void *)0,                                      /* No args passed to OS_TaskStat()*/                           &OSTaskStatStk[0],                              /* Set Top-Of-Stack               */                           OS_STAT_PRIO);                                  /* One higher than the idle task  */        #endif    #endif#endif#if OS_VERSION >= 204    OSInitHookEnd();                                                       /* Call port specific init. code  */#endif}


0 0