μC/OS-II的任務管理
{
本文引用地址:http://www.ex-cimer.com/article/201610/305743.htmOS_TCB*ptcb;
OS_ENTER_CRITICAL();
ptcb=OSTCBFreeList;(1)
if(ptcb!=(OS_TCB*)0){(2)
OSTCBFreeList=ptcb->OSTCBNext;
OS_EXIT_CRITICAL();
ptcb->OSTCBStkPtr=ptos;(3)
ptcb->OSTCBPrio=(INT8U)prio;
ptcb->OSTCBStat=OS_STAT_RDY;
ptcb->OSTCBDly=0;
#ifOS_TASK_CREATE_EXT_EN
ptcb->OSTCBExtPtr=pext;
ptcb->OSTCBStkSize=stk_size;
ptcb->OSTCBStkBottom=pbos;
ptcb->OSTCBOpt=opt;
ptcb->OSTCBId=id;
#else
pext=pext;
stk_size=stk_size;
pbos=pbos;
opt=opt;
id=id;
#endif
#ifOS_TASK_DEL_EN
ptcb->OSTCBDelReq=OS_NO_ERR;
#endif
ptcb->OSTCBY=prio>>3;
ptcb->OSTCBBitY=OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX=prio0x07;
ptcb->OSTCBBitX=OSMapTbl[ptcb->OSTCBX];
#ifOS_MBOX_EN||(OS_Q_EN(OS_MAX_QS>=2))||OS_SEM_EN
ptcb->OSTCBEventPtr=(OS_EVENT*)0;
#endif
#ifOS_MBOX_EN||(OS_Q_EN(OS_MAX_QS>=2))
ptcb->OSTCBMsg=(void*)0;
#endif
OS_ENTER_CRITICAL();(4)
OSTCBPrioTbl[prio]=ptcb;(5)
ptcb->OSTCBNext=OSTCBList;
ptcb->OSTCBPrev=(OS_TCB*)0;
if(OSTCBList!=(OS_TCB*)0){
OSTCBList->OSTCBPrev=ptcb;
}
OSTCBList=ptcb;
OSRdyGrp|=ptcb->OSTCBBitY;(6)
OSRdyTbl[ptcb->OSTCBY]|=ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return(OS_NO_ERR);(7)
}else{
OS_EXIT_CRITICAL();
return(OS_NO_MORE_TCB);
}
}
當OSTCBInit()需要將OS_TCB插入到已建立任務的OS_TCB的雙向鏈表中時[L4.2(5)],它就禁止中斷[L4.2(4)]。該雙向鏈表開始于OSTCBList,而一個新任務的OS_TCB常常被插入到鏈表的表頭。最后,該任務處于就緒狀態(tài)[L4.2(6)],并且OSTCBInit()向它的調用者[OSTaskCreate()]返回一個代碼表明OS_TCB已經(jīng)被分配和初始化了[L4.2(7)]。
現(xiàn)在,我可以繼續(xù)討論OSTaskCreate()(程序清單 L4.1)函數(shù)了。從OSTCBInit()返回后,OSTaskCreate()要檢驗返回代碼[L4.1(7)],如果成功,就增加OSTaskCtr[L4.1(8)],
OSTaskCtr用于保存產(chǎn)生的任務數(shù)目。 如果OSTCBInit()返回失敗, 就置OSTCBPrioTbl[prio]
的入口為0[L4.1(12)]以放棄該任務的優(yōu)先級。然后,OSTaskCreate()調用
OSTaskCreateHook()[L4.1(9)],OSTaskCreateHook()是用戶自己定義的函數(shù),用來擴展OSTaskCreate()的功能。例如,用戶可以通過OSTaskCreateHook()函數(shù)來初始化和存儲浮點寄存器、MMU寄存器的內容,或者其它與任務相關的內容。一般情況下,用戶可以在內存中存儲一些針對用戶的應用程序的附加信息。OSTaskCreateHook()既可以在OS_CPU_C.C中定義(如果OS_CPU_HOOKS_EN置1),也可以在其它地方定義。注意,OSTaskCreate()在調用OSTaskCreateHook()時,中斷是關掉的,所以用戶應該使OSTaskCreateHook()函數(shù)中的代碼盡量簡化,因為這將直接影響中斷的響應時間。OSTaskCreateHook()在被調用時會收到指向任務被建立時的OS_TCB的指針。 這意味著該函數(shù)可以訪問OS_TCB數(shù)據(jù)結構中的所有成員。
如果OSTaskCreate()函數(shù)是在某個任務的執(zhí)行過程中被調用(即OSRunning置為True[L4.1(10)]),則任務調度函數(shù)會被調用[L4.1(11)]來判斷是否新建立的任務比原來的任務有更高的優(yōu)先級。如果新任務的優(yōu)先級更高,內核會進行一次從舊任務到新任務的任務切換。如果在多任務調度開始之前(即用戶還沒有調用OSStart()),新任務就已經(jīng)建立了,則任務調度函數(shù)不會被調用。
4.1建立任務,OSTaskCreateExt()
用OSTaskCreateExt()函數(shù)來建立任務會更加靈活,但會增加一些額外的開銷。
OSTaskCreateExt()函數(shù)的代碼如程序清單L4.3所示。
我們可以看到OSTaskCreateExt()需要九個參數(shù)!前四個參數(shù)(task,pdata,ptos和prio)與OSTaskCreate()的四個參數(shù)完全相同,連先后順序都一樣。這樣做的目的是為了使用戶能夠更容易地將用戶的程序從OSTaskCreate()移植到OSTaskCreateExt()上去。
id參數(shù)為要建立的任務創(chuàng)建一個特殊的標識符。 該參數(shù)在μC/OS以后的升級版本中可能會用到,但在μC/OS-Ⅱ中還未使用。這個標識符可以擴展μC/OS-Ⅱ功能,使它可以執(zhí)行的任務數(shù)超過目前的64個。但在這里,用戶只要簡單地將任務的id設置成與任務的優(yōu)先級一樣的值就可以了。
pbos是指向任務的堆棧棧底的指針,用于堆棧的檢驗。
stk _size用于指定堆棧成員數(shù)目的容量。也就是說,如果堆棧的入口寬度為4字節(jié)寬,那么stk _size為10000是指堆棧有40000個字節(jié)。該參數(shù)與pbos一樣,也用于堆棧的檢驗。
pext是指向用戶附加的數(shù)據(jù)域的指針,用來擴展任務的OS_TCB。例如,用戶可以為每個任務增加一個名字(參看實例3),或是在任務切換過程中將浮點寄存器的內容儲存到這個附加數(shù)據(jù)域中,等等。
opt用于設定OSTaskCreateExt()的選項,指定是否允許堆棧檢驗,是否將堆棧清零,任務是否要進行浮點操作等等。 μCOS_Ⅱ.H文件中有一個所有可能選項(OS_TASK_OPT_STK_CHK,OS_TASK_OPT_STK_CLR和OS_TASK_OPT_SAVE_FP)的常數(shù)表。每個選項占有opt的一位, 并通過該位的置位來選定(用戶在使用時只需要將以上OS_TASK_OPT_???選項常數(shù)進行位或(OR)操作就可以了)。
程序清單 L4.3 OSTaskCreateExt()
INT8UOSTaskCreateExt(void(*task)(void*pd),
void*pdata,
OS_STK*ptos,
INT8Uprio,
INT16Uid,
OS_STK*pbos,
INT32Ustk_size,
void*pext,
INT16Uopt)
{
void*psp;
INT8Uerr;
評論