UCOS-II几个重要的函数使用详解

 void OSInit (void)
{
    INT16U i;
     /*****/
     /*****/
    OSTime        = 0L;                                    /* Clear the 32-bit system clock            */
    OSIntNesting  = 0;   /**中断嵌套层数计数,>0时候禁止任务调度***/ /* Clear the interrupt nesting counter      */
    OSLockNesting = 0;   /**锁定嵌套计数器,>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            */
    OSCtxSwCtr    = 0;      /* 统计计数器=任务切换的次数,Clear the context switch counter         */
    OSRdyGrp      = 0;       /*任务就绪组,任何时候只有一个bit位是置1的,和优先级有关 Clear the ready list                     */
    for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
        OSRdyTbl[i] = 0;     /**每个任务的就绪任务表**/
    }
               
    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;        /**全部的控制模块清成空闲状态**/
    }
    /**任务链表数组--**/   
    for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) {  /* Init. list of free TCBs            */
        OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i + 1];   /**将任务链表的TCB地址记录**/
    }
    OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS - 1].OSTCBNext = (OS_TCB *)0;    /* Last OS_TCB             */
    OSTCBFreeList                                         = &OSTCBTbl[0];     /**空任务块控制指针:初始化时候指向的是第一个任务**/
                                                                                                  /*第一个任务是系统任务--空闲任务,还有一个统计任务(OS_N_SYS_TASKS=2时)**/

/**事件链表数组***/
    for (i = 0; i < (OS_MAX_EVENTS - 1); i++) {            /* Init. list of free EVENT control blocks  */
        OSEventTbl[i].OSEventPtr = (OS_EVENT *)&OSEventTbl[i + 1];
    }
    OSEventTbl[OS_MAX_EVENTS - 1].OSEventPtr = (OS_EVENT *)0;/**最后的事件表**/
    OSEventFreeList                          = &OSEventTbl[0];   
 
#if OS_STK_GROWTH == 1                      /***由高地址向低地址方向***/
 
    OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], OS_IDLE_PRIO);

#else                                      /****栈的方向由低地址到高地址***/
    OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[0], OS_IDLE_PRIO);    //  mand by jk 2007-8-16
//          OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], OS_IDLE_PRIO);
#endif
              
}

void OSSemPend (OS_EVENT *pevent, INT16U timeout,

INT8U *err)reentrant
INT8U OSSemPost (OS_EVENT *pevent)reentrant

消息通信函数:OSSemPend(A)期待A事件的发生,如果事件A还没有发生,那么就被挂起(pending)等待,并且下一个优先级获得CPU的控制权,进行下一个任务。相应的OSSemPost();就是通知给OSSemPend()事件发生了,那么如果在下一个任务中执行了OSSemPost(A),则上面的任务就知道了事件A的发生,那么系统将CPU控制权交给了原来的优先级更高的任务运行。相应的函数有
OSFlagPend(),OSSemPend(),OSMutexPend(),OSMboxPend(),OSQPend()都是peng挂起等待某个事件的产生,否则进入到等待状态。
例子:
  void TaskA()
   {
    
OSSemPend(Event,5,err);  //A任务等待系统里面Event事件的发生
     }
  void TaskB()
   {
   
OSSemPost(Event);            //B事件告示了Event事件的发生
 }
/***以下为内核中最重要的几个函数***/
INT8U OSTaskCreate(void (*task)(void *pd)reentrant,//任务函数
             void *dataptr,  //任务中需要使用的数据参数:万能指针类型
             OS_STK *ptos,   //任务栈顶指针:指向一开始申请的堆栈数组
             INT8U prio)reentrant // 定义任务的优先级
{
            void *psp;  //堆栈任务指针
            INT8U err;
   
   if(prio>OS_LOWEST_PRIO) {       //确保优先级在合法使用区域内
     return (OS_PRIO_INVALID)
}            //优先级错误则返回一个不合法的优先级错误代码
    
  OS_ENTER_CRITICAL();//进入临界区域--关中断
   if(OSTCBPrioTbl[prio]==(OS_TCB *)0)   ///**是否有清空当前任务块的优先级链表**/
           {
               
OSTCBPrioTbl[prio]==(OS_TCB *)1;
                //提升系统性能,先开中断,离开临界区
                OS_EXIT_CRITICAL();
                //初始化任务堆栈,包含了任务执行首地址,数据,堆栈顶
                /**初始化堆栈:在建立的堆栈区域存放相应的内容**/
                psp=(void *)OSTaskStkInit(task,dataptr,ptos,0);
                //初始化TCB任务控制模块函数:
               err=OSTCBInit(prio,psp,(void *)0,0,0,(void *)0,0);
                 if (err == OS_NO_ERR)
                     {            /**没有error:说明建立的任务控制模块一切正常**/
                    OS_ENTER_CRITICAL();
                    OSTaskCtr++;                /**增加任务数**/
                    OSTaskCreateHook(OSTCBPrioTbl[prio]);        /**当OSTaskCreateHook( )被调用的时,它会收到指向已建立任务的任务控制块的指针,这样就可以调用里面的所有成员**/  /* Call user defined hook                   */
                    OS_EXIT_CRITICAL();
                    if (OSRunning) {             
                        OSSched();    /****/
                    }
                } else {
                    OS_ENTER_CRITICAL();
                    OSTCBPrioTbl[prio] = (OS_TCB *)0;
                    OS_EXIT_CRITICAL();
                }
                return (err);
           }
    else {
        OS_EXIT_CRITICAL();
        return (OS_PRIO_EXIST);
    }
}


关于OSTaskCreate()函数内部调用的一些说明:
函数OSTCBInit(INT8U prio,OS_STK *ptos,OS_STK *pbos,INT16U id,INT16U stk_size,void *pext,INT16U opt)reentrant
分别为 优先级 栈顶指针 栈末尾 任务号 栈大小 用户使用堆栈区 任务扩展在OSTaskCreateExt()用

/**初始化最新创建的任务控制模块**
优先级、堆栈的起始地址、堆栈的结束地址、任务编号、任务堆栈大小....

****/
static OS_TCB *ptcb11;
INT8U OSTCBInit (INT8U prio,    
             OS_STK *ptos,
             OS_STK *pbos,
             INT16U id,
             INT16U stk_size,
             void *pext,
             INT16U opt)reentrant
{
    OS_ENTER_CRITICAL();
    ptcb11 = OSTCBFreeList;     /**首先赋值给空闲TCB指针**/                /* Get a free TCB from the free TCB list    */
    if (ptcb11 != (OS_TCB *)0)
        {   /**检查TCB是否为空**/
        OSTCBFreeList        = ptcb11->OSTCBNext;            /* Update pointer to free TCB list          */
        OS_EXIT_CRITICAL();
        ptcb11->OSTCBStkPtr    = ptos;                       /* Load Stack pointer in TCB                */
        ptcb11->OSTCBPrio      = (INT8U)prio;                /* Load task priority into TCB              */
        ptcb11->OSTCBStat      = OS_STAT_RDY;                /* Task is ready to run                     */
        ptcb11->OSTCBDly       = 0;                          /* Task is not delayed                      */

#if OS_TASK_CREATE_EXT_EN       
        ptcb11->OSTCBExtPtr    = pext;                       /* Store pointer to TCB extension           */
        ptcb11->OSTCBStkSize   = stk_size;                   /* Store stack size                         */
        ptcb11->OSTCBStkBottom = pbos;                       /* Store pointer to bottom of stack         */
        ptcb11->OSTCBOpt       = opt;                        /* Store task options                       */
        ptcb11->OSTCBId        = id;                         /* Store task ID                            */
#else
        pext                 = pext;                       /* Prevent compiler warning if not used     */
        stk_size             = stk_size;
        pbos                 = pbos;
        opt                  = opt;
        id                   = id;
#endif

#if OS_TASK_DEL_EN       
        ptcb11->OSTCBDelReq    = OS_NO_ERR;
#endif
        /**任务表的计算:当知优先级时就可以优先定义**/
        ptcb11->OSTCBY         = prio >> 3;                  /* Pre-compute X, Y, BitX and BitY          */
        ptcb11->OSTCBBitY      = OSMapTbl[ptcb11->OSTCBY];
        ptcb11->OSTCBX         = prio & 0x07;
        ptcb11->OSTCBBitX      = OSMapTbl[ptcb11->OSTCBX];

#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_Sem_EN
        ptcb11->OSTCBEventPtr  = (OS_EVENT *)0;              /* Task is not pending on an event          */
#endif

#if     OS_MBOX_EN || (OS_Q_EN && (OS_MAX_QS >= 2))
        ptcb11->OSTCBMsg       = (void *)0;                  /* No message received                      */
#endif

        OS_ENTER_CRITICAL();
/***加入TCB链表:前后插入法***/
        OSTCBPrioTbl[prio]   = ptcb11;
        ptcb11->OSTCBNext      = OSTCBList;                  /* Link into TCB chain                      */
        ptcb11->OSTCBPrev      = (OS_TCB *)0;
        if (OSTCBList != (OS_TCB *)0) {
            OSTCBList->OSTCBPrev = ptcb11;
        }
/**任务模块控制链表建立**/
        OSTCBList               = ptcb11;
/**任务成员变量:方便任务上下文切换**/
        OSRdyGrp               |= ptcb11->OSTCBBitY;         /* Make task ready to run                   */
        OSRdyTbl[ptcb11->OSTCBY] |= ptcb11->OSTCBBitX;
        OS_EXIT_CRITICAL();
        return (OS_NO_ERR);
    }
    else {
        OS_EXIT_CRITICAL();
        return (OS_NO_MORE_TCB);
    }
}
阅读更多
个人分类: 51ucos-II System
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭