μC/OS 之OSTCBInit()

来源:互联网 发布:光猫telnet端口被关闭 编辑:程序博客网 时间:2024/04/29 14:20
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则返回失败;    ②对一些基本数据项的填写,比如优先级,堆栈等;    ③为工作尽快进入就绪状态,进行优先级的转换;    ④更新三个表:任务优先级表;任务双向链表;就绪表。    注:对于未注释部分等待以后更新。

原创粉丝点击