//任务控制块初始化 //描述:这个函数是uCOS-II内部函数,在建立任务时调用的初始化任务控制块OS_TCB函数,含7个参数,查看OSTaskCreate()和OSTaskCreateExt() //初始化任务控制块TCB(优先级指针,堆栈指针,栈底指针,任务标志符,堆栈容量,扩展指针,选择项) INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt) { #if OS_CRITICAL_METHOD == 3 //中断函数被设定为模式3 OS_CPU_SR cpu_sr; #endif OS_TCB *ptcb; //定义一个PCB变量 OS_ENTER_CRITICAL(); //关闭中断 ptcb = OSTCBFreeList; //分配一个空任务控制块给ptcb if (ptcb != (OS_TCB *)0) { //如果缓冲池有空余TCB,这个TCB被初始化 OSTCBFreeList = ptcb->OSTCBNext; //指向TCB的双向链接的后链接 OS_EXIT_CRITICAL(); //打开中断 ptcb->OSTCBStkPtr = ptos; //指向当前TCB的栈顶指针(输入的数据) ptcb->OSTCBPrio = (INT8U)prio; //保存当前TCB的优先级别(输入的数据) ptcb->OSTCBStat = OS_STAT_RDY; //设定当前TCB的状态字(内容为(准备完毕)) ptcb->OSTCBDly = 0; //允许任务等待的最大字节节拍为0 #if OS_TASK_CREATE_EXT_EN > 0 //允许生成OSTaskCreateExt()函数 ptcb->OSTCBExtPtr = pext; //指向用户定义的任务控制块(扩展指针) ptcb->OSTCBStkSize = stk_size; //设定堆栈的容量 ptcb->OSTCBStkBottom = pbos; //指向堆栈栈底的指针 ptcb->OSTCBOpt = opt; //保存OS_TCB的选择项 ptcb->OSTCBId = id; //保存任务标志符 #else //否则使用旧的参数 pext = pext; //扩展指针 stk_size = stk_size; //堆栈的容量 pbos = pbos; //栈底的指针 opt = opt; //选择项 id = id; //任务标志符 #endif #if OS_TASK_DEL_EN > 0 //允许生成OSTaskDel()函数代码函数 ptcb->OSTCBDelReq = OS_NO_ERR; //如果可以删除任务本身,可以从每个OS_TCB中节省出一个布尔量 #endif ptcb->OSTCBY = prio >> 3; //对一些参数提前运算,为了节省CPU的操作事件 ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY]; ptcb->OSTCBX = prio & 0x07; ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX]; #if OS_EVENT_EN > 0 //如果不打算在应用程序中使用各类事件 ptcb->OSTCBEventPtr = (OS_EVENT *)0; //OS_TCB中OSTCBEventPtr就不会出现 #endif //针对的事件为信号量,互斥型信号量,消息邮箱,消息队列,当满足版本大于2.51且事件标志允许且有最大事件标志及允许删除任务 #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0) ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; //则向事件标志节点的指针被初始化为空指针 #endif #if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0)) ptcb->OSTCBMsg = (void *)0; //满足以上条件,指向传递给任务的消息指针为0空指针 #endif #if OS_VERSION >= 204 //如果版本大于2.04 OSTCBInitHook(ptcb); //允许使用OSTCBInitHook(ptcb)函数,可对其加代码 #endif //主要增加OS_TCB扩展,浮点运算,MMU寄存器,与任务相关内容,调用此程序时中断开着的 OSTaskCreateHook(ptcb); //调用户建立任务钩子程序 OS_ENTER_CRITICAL(); OSTCBPrioTbl[prio] = ptcb; ptcb->OSTCBNext = OSTCBList; //链接到任务控制块链接串 ptcb->OSTCBPrev = (OS_TCB *)0; if (OSTCBList != (OS_TCB *)0) { OSTCBList->OSTCBPrev = ptcb; } OSTCBList = ptcb; //让该任务进入就绪表 OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */ OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); //打开中断 return (OS_NO_ERR); //调用成功,最后让此函数返回到调用函数[OSTaskCreate()或OSTaskCreateExt()函数], //返回值表示分配到任务控块,并初始化了 } OS_EXIT_CRITICAL(); //打开中断 return (OS_NO_MORE_TCB); //没有更多的任务控制块被分配,将无法创建新的任务 }