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
}


/*消息通信函数:OSSemPend(A)期待A事件的发生,如果事件A还没有发生,那么就被挂起(pending)等待,并且下一个优先级获得CPU的控制权,进行下一个任务。相应的OSSemPost();就是通知给OSSemPend()事件发生了,那么如果在下一个任务中执行了OSSemPost(A),则上面的任务就知道了事件A的发生,那么系统将CPU控制权交给了原来的优先级更高的任务运行。相应的函数有OSFlagPend(),OSSemPend(),OSMutexPend(),OSMboxPend(),OSQPend()都是peng挂起等待某个事件的产生,否则进入到等待状态。*/
void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)reentrant
INT8U OSSemPost (OS_EVENT *pevent)reentrant
/*--例子:*/
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( )被调用时,它会收到指向已建立任务的任务控制块的指针,这样就可调用里面所有成员*/ 
    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);
    }
}

粽子糖果 发表于11-19 14:33 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

粽子糖果
粽子糖果(总统)
金币:41623个|学分:51975个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号