μC/OS 之OSTCBInit()

OSTCBInit()

INT8U OSTCBInit(INT8U prio,OS_STK *ptos,OS_STK *pbos,INT16U id,INT16U stk_size,void *pext,INT16U opt)
/*该函数为TCB的初始化函数,返回一个INT8U型变量,含有9个参数*/
/*prio 表示任务的优先级也表示任务的标识符*/
/*ptos 表示堆栈初始化后栈顶的指针*/
/*pbos 表示栈底的指针*/
/*id 用于扩充任务数,μC/OSⅡ以后可能会用到,在这里只需将其设置为任务的优先级即可*/
/*stk_size分配的堆栈的大小,如果栈入口宽为4个字节,且stk_size=1000,则堆栈容量为4000字节*/
/*pext指向用户附加的数据域的指针,用来扩充TCB*/
/*opt用于设定OSTaskCreateExt()的选项,指定是否允许堆栈检验,是否堆栈清零,任务是否要进行浮点操作等等*/
/*OS_TASK_OPT_STK_CHK,OS_TASK_OPT_STK_CLR和OS_TASK_OPT_STK_SAVE_FP个占opt的一位*/
{   
   OS_TCB *ptcb;  /*建立一个指向TCB的指针*/
   
   OS_ENTER_CRITICAL();/*关中断,从空隙TCB池中选取一个TCB,选好后开中断*/
   ptcb=OSTCBFreeList;/*将ptcb指向空隙TCB链表的首节点*/
   if(ptcb!=(OS_TCB *)0)  /*如果首节点不为空,即还存在空闲的TCB的话,进行下面的操作*/
   {
      OSTCBFreeList=ptcb->OSTCBNext; /*将指向空闲链表首指点的指针,指向空闲链表中下一节点*/
      OS_EXIT_CRITICAL();/*选取空闲TCB完毕,开中断*/
      
      ptcb->OSTCBStkPtr=ptos;
      ptcb->OSTCBPrio  =(INT8U)prio; /*将优先级写入TCB*/
      ptcb->OSTCBStat  =OS_STAT_RDY; /*将任务准备运行状态写入TCB*/
      ptcb->OSTCBDly   =0;           /*任务运行延迟为0,即一旦进入就绪状态,系统调用马上可以运行*/
      
      
   #if OS_TASK_CREATE_EXT_EN         /*如果是扩展性任务的建立,则需将TCB中多写入如下的信息*/
      ptcb->OSTCBExtPtr   =pext;     /*将指向用户定义的数据域的指针填入TCB*/
      ptcb->OSTCBStkSize  =stk_size; /*将堆栈的大小填入TCB*/
      ptcb->OSTCBStkBottom=pbos;     /*将堆栈的栈底指针填入TCB*/
      ptcb->OSTCBOpt      =opt;      /*将选项的值填入TCB*/
      ptcb->OSTCBId       =id;       /*将id填入TCB,这里为任务的优先级*/
   #else
      pext                =pext;     
      stk_size            =stk_size;
      pbos                =pbos;
      opt                 =opt;
      id                  =id;
   #endif
      
      
   # if OS_TASK_DEL_EN
      ptcb->OSTCBDelReq   =OS_NO_ERR;
   #endif
   
       /*这部分是为填写就绪表,进入就绪状态做好准备*/ 
       ptcb->OSTCBY       =prio>>3;                /*将prio右移三位,即选取优先级的高三位*/
       ptcb->OSTCBBitY    =OSMapTbl[ptb->OSTCBY];  /*高三位转化为OSRdyGrp形式*/
       ptcb->OSTCBX       =prio&0x07;              /*求与操作,即选取优先级的第三位*/
       ptcb->OSTCBBitX    =OSMapTbl[ptb->OSTCBX];  /*低三位转化为OSRdyTbl形式*/
       
       
   #if OS_MBOX_EN||(OS_Q_EN&&(OS_MAX_QS>=2))||OS_SEM_EN
       ptcb->OSTCBEventPtr=(OS_EVENT *)0;
   #endif
       
       
   #if OS_MBOX_EN||(OS_Q_EN&&(OS_MAX_QS>=2))
       ptcb->OSTCBMsg     =(void*)0;
   #endif
       
       /*关中断的情况下,完成任务TCB之间的双向连接等*/
       OS_ENTER_CRITICAL();
       OSTCBPrioTbl[prio] =ptcb;                     /*将系统优先级表中对应的位填入对应TCB的指针*/
       
       ptcb->OSTCBNext    =OSTCBList;                /*将TCB的next指针连接到已有的任务上*/
       ptcb->OSTCBPrev    =(OS_TCB *)0;              /*将TCB的prev指针指为空*/
       if(OSTCBList!=(OS_TCB *)0)                    /*如果已经存在了任务,则将原有任务的TCB的prev指针执行新任务的TCB*/
       {
          OSTCBList->OSTCBPrev=ptcb;
       }
       OSTCBList          =ptcb;                     /*将任务列表的头指针指向新任务的TCB,以便后来的任务的链接操作*/
       
       OSRdyGrp          |=ptcb->OSTCBBitY;          /*将新任务写入就绪列表*/
       OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;
       OS_EXT_CRITICAL();
       
       return (OS_NO_ERR);                           /*TCB初始化成功,返回初始化成功对应的值*/
    else                                             /*如果没有空闲的TCB,则返回没有足够的TCB,初始化失败*/
    {
       OS_EXIT_CRITAL();                             /*注意关中断*/
       return(OS_NO_MORE_TCB);
      
       
小结:TCB的初始化做了哪些工作呢?
    ①对4个表的操作:空闲TCB链表,任务TCB链接,TCB优先级表,就绪表;
    ②对堆栈的操作:栈顶,栈底,栈长
    ③对优先级的操作:优先级写入,优先级转换
    ④其他的数据项的填写。
    
    TCB初始化的过程:
    ①首先查看空闲TCB链表,从中找出一个空的TCB,并更新TCB链表;如果没找到空闲TCB则返回失败;
    ②对一些基本数据项的填写,比如优先级,堆栈等;
    ③为工作尽快进入就绪状态,进行优先级的转换;
    ④更新三个表:任务优先级表;任务双向链表;就绪表。
    
注:对于未注释部分等待以后更新。

你可能感兴趣的:(工作,OS,ext,扩展,任务,FP)