获取一个空闲TCB c 1 2 3 OS_TCB *ptcb; OS_ENTER_CRITICAL(); ptcb = OSTCBFreeList; 这条语句是将一个指向空闲任务列表的指针(OSTCBFreeList)赋值给一个名为 ptcb的指针变量。 在RTOS中,任务控制块(TCB)通常被保存在一个链表中,以便在需要创建新 任务时能够快速获取一个空闲的TCB。OSTCBFreeList就是这个链表的头指针, 它指向第一个空闲的TCB。 因此,这条语句的作用是将OSTCBFreeList指向的第一个空闲TCB的地址赋值给 ptcb变量,以便在后续的代码中使用。如果OSTCBFreeList的值是0(即空指 针),则ptcb也会被赋值为0,表示没有可用的空闲TCB。 因此,接下来就要用 if 语句判断,是否有空闲TCB if(ptcb != (OS_TCB*)0 ){ OSTCBFreeList = ptcb->OSTCBNext; OS_EXIT_CRITICAL(); //...... 如果此时ptcb不为空,即有空闲tcb,就把ptcb移除OSTCBFreeList 给tcb装上东西 //初始化tcb ptcb->OSTCBStkPtr= ptos; ptcb->OSTCBPrio = (INT8U)prio; ptcb->OSTCBStat = OS_STAT_RDY; ptcb->OSTCBDly = 0; pext = pext; stk_size = stk_size; pbos = pbos; opt = opt; id = id; OSTCBStkPtr:任务堆栈指针,指向该任务的堆栈顶部。 OSTCBPrio:任务优先级,用于确定该任务在优先级调度中的执行顺序。 OSTCBStat:任务状态,用于表示该任务当前的状态,例如“运行”、“阻塞”或“准 备就绪”等。 OSTCBDly:任务延迟时间,用于表示该任务当前需要延迟的时间。 pext、stk_size、pbos、opt、id:一些其他选项,例如任务的扩展属性、堆栈大 小、堆栈底部指针、选项标志和任务ID等。 ptcb->OSTCBY = prio >> 3; ptcb->OSTCBBitY=OSMapTbl[ptcb->OSTCBY]; ptcb->OSTCBX =prio & 0x07; ptcb->OSTCBBitX=OSMapTbl[ptcb->OSTCBX]; 将优先级存储到tcb里面 取高三位(右移三位),放在OSTCBY 设置OSTCBY的掩码,掩码计算放在OSMapTbl里 取低三位,取掩码 把tcb插入到各种表、图里 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; OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX; OS_EXIT_CRITICAL(); return (OS_NO_ERR); } OS_EXIT_CRITICAL(); return (OS_NO_MORE_TCB);} 插OSTCBPrioTbl,prio为索引 插OSTCBList(头插) 更新rdyGrp、rdyTbl 做完后,返回(OS_NO_ERR) 如果前面最开始 if(ptcb != (OS_TCB*)0 ) 判断为假,就返回 (OS_NO_MORE_TCB) 临界区总结 进入临界区:一次或两次 每次修改全局变量都要进入 具体来说,在本函数是修改OSTCBFreeList(第一次)和修改OSTCBList、 OSTCBPrioTbl、rdyGrp、rdyTbl(第二次,没有空闲tcb则不进入)