μ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则返回失败; ②对一些基本数据项的填写,比如优先级,堆栈等; ③为工作尽快进入就绪状态,进行优先级的转换; ④更新三个表:任务优先级表;任务双向链表;就绪表。 注:对于未注释部分等待以后更新。