μC/OS-II的任務(wù)管理
這樣,OSTaskDel()就能處理中斷服務(wù)了,但由于它增加了 OSLockNesting,ISR執(zhí)行完后會(huì)返回到被中斷任務(wù),從而繼續(xù)任務(wù)的刪除工作。注意OSTaskDel()此時(shí)還沒(méi)有完全完成刪除任務(wù)的工作,因?yàn)樗€需要從TCB鏈中解開(kāi)OS_TCB,并將OS_TCB返回到空閑OS_TCB表中。
另外需要注意的是,筆者在調(diào)用OS_EXIT_CRITICAL()函數(shù)后,馬上調(diào)用了OSDummy()[L4.11(12)],該函數(shù)并不會(huì)進(jìn)行任何實(shí)質(zhì)性的工作。這樣做只是因?yàn)橄氪_保處理器在中斷允許的情況下至少執(zhí)行一個(gè)指令。對(duì)于許多處理器來(lái)說(shuō),執(zhí)行中斷允許指令會(huì)強(qiáng)制CPU禁止中斷直到下個(gè)指令結(jié)束!Intel80x86和ZilogZ-80處理器就是如此工作的。開(kāi)中斷后馬上關(guān)中斷就等于從來(lái)沒(méi)開(kāi)過(guò)中斷,當(dāng)然這會(huì)增加中斷的響應(yīng)時(shí)間。因此調(diào)用OSDummy()確保在再次禁止中斷之前至少執(zhí)行了一個(gè)調(diào)用指令和一個(gè)返回指令。當(dāng)然,用戶可以用宏定義將OSDummy()定義為一個(gè)空操作指令(譯者注:例如MC68HC08指令中的NOP指令) ,這樣調(diào)用OSDummy()就等于執(zhí)行了一個(gè)空操作指令,會(huì)使OSTaskDel()的執(zhí)行時(shí)間稍微縮短一點(diǎn)。但筆者認(rèn)為這種宏定義是沒(méi)價(jià)值的,因?yàn)樗鼤?huì)增加移植μCOS-Ⅱ的工作量。
現(xiàn)在,OSTaskDel()可以繼續(xù)執(zhí)行刪除任務(wù)的操作了。在OSTaskDel()重新關(guān)中斷后,它通過(guò)鎖定嵌套計(jì)數(shù)器(OSLockNesting)減一以重新允許任務(wù)調(diào)度[L4.11(13)]。接著,OSTaskDel()調(diào)用用戶自定義的OSTaskDelHook()函數(shù)[L4.11(14)],用戶可以在這里刪除或
釋放自定義的TCB附加數(shù)據(jù)域。 然后, OSTaskDel()減少μCOS-Ⅱ的任務(wù)計(jì)數(shù)器。 OSTaskDel()
簡(jiǎn)單地將指向被刪除的任務(wù)的OS_TCB的指針指向NULL[L4.11(15)],從而達(dá)到將OS_TCB從優(yōu)先級(jí)表中移除的目的。再接著,OSTaskDel()將被刪除的任務(wù)的OS_TCB從OS_TCB雙向鏈表中移除[L4.11(16)]。 注意,沒(méi)有必要檢驗(yàn)ptcb->OSTCBNext==0的情況, 因?yàn)镺STaskDel()不能刪除空閑任務(wù),而空閑任務(wù)就處于鏈表的末端(ptcb->OSTCBNext==0)。接下來(lái),OS_TCB返回到空閑OS_TCB表中,并允許其它任務(wù)的建立[L4.11(17)]。最后,調(diào)用任務(wù)調(diào)度程序來(lái)查看在OSTaskDel()重新允許中斷的時(shí)候[L4.11(11)],中斷服務(wù)子程序是否曾使更高優(yōu)先級(jí)的任務(wù)處于就緒狀態(tài)[L4.11(18)]。
4.5請(qǐng)求刪除任務(wù),OSTaskDelReq()
有時(shí)候,如果任務(wù)A擁有內(nèi)存緩沖區(qū)或信號(hào)量之類(lèi)的資源,而任務(wù)B想刪除該任務(wù),這些資源就可能由于沒(méi)被釋放而丟失。在這種情況下,用戶可以想法子讓擁有這些資源的任務(wù)在使用完資源后,先釋放資源,再刪除自己。用戶可以通過(guò)OSTaskDelReq()函數(shù)來(lái)完成該功能。
發(fā)出刪除任務(wù)請(qǐng)求的任務(wù)(任務(wù)B)和要?jiǎng)h除的任務(wù)(任務(wù)A)都需要調(diào)用OSTaskDelReq()函數(shù)。任務(wù)B的代碼如程序清單L4.12所示。任務(wù)B需要決定在怎樣的情況下請(qǐng)求刪除任務(wù)[L4.12(1)]。換句話說(shuō),用戶的應(yīng)用程序需要決定在什么樣的情況下刪除任務(wù)。如果任務(wù)需要被刪除,可以通過(guò)傳遞被刪除任務(wù)的優(yōu)先級(jí)來(lái)調(diào)用OSTaskDelReq()[L4.12(2)]。如果要被刪除的任務(wù)不存在(即任務(wù)已被刪除或是還沒(méi)被建立),OSTaskDelReq()返回OS_TASK_NOT_EXIST。如果OSTaskDelReq()的返回值為OS_NO_ERR,則表明請(qǐng)求已被接受但任務(wù)還沒(méi)被刪除。用戶可能希望任務(wù)B等到任務(wù)A刪除了自己以后才繼續(xù)進(jìn)行下面的工作,這時(shí)用戶可以象筆者一樣,通過(guò)讓任務(wù)B延時(shí)一定時(shí)間來(lái)達(dá)到這個(gè)目的[L4.12(3)]。筆者延時(shí)了一個(gè)時(shí)鐘節(jié)拍。如果需要,用戶可以延時(shí)得更長(zhǎng)一些。當(dāng)任務(wù)A完全刪除自己后,[L4.12(2)]中的返回值成為0S_TASK_NOT_EXIST,此時(shí)循環(huán)結(jié)束[L4.12(4)]。
程序清單 L4.12 請(qǐng)求刪除其它任務(wù)的任務(wù)(任務(wù)B)
voidRequestorTask(void*pdata)
{
INT8Uerr;
pdata=pdata;
for(;;){
/* 應(yīng)用程序代碼 */
if('TaskToBeDeleted()' 需要被刪除){(1)
while(OSTaskDelReq(TASK_TO_DEL_PRIO)!=OS_TASK_NOT_EXIST){(2)
OSTimeDly(1);(3)
}
}
/*應(yīng)用程序代碼*/(4)
}
}
程序清單 L4.13 需要?jiǎng)h除自己的任務(wù)(任務(wù)A)
voIDTaskToBeDeleted(void*pdata)
{
INT8Uerr;
pdata=pdata;
for(;;){
/*應(yīng)用程序代碼*/
If(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ){(1)
釋放所有占用的資源;(2)
釋放所有動(dòng)態(tài)內(nèi)存;
OSTaskDel(OS_PRIO_SELF);(3)
}else{
/*應(yīng)用程序代碼*/
}
}
}
需要?jiǎng)h除自己的任務(wù)(任務(wù)A)的代碼如程序清單L4.13所示。在OS_TAB中存有一個(gè)標(biāo)志,任務(wù)通過(guò)查詢(xún)這個(gè)標(biāo)志的值來(lái)確認(rèn)自己是否需要被刪除。這個(gè)標(biāo)志的值是通過(guò)調(diào)用OSTaskDelReq(OS_PRIO_SELF)而得到的。當(dāng)OSTaskDelReq()返回給調(diào)用者OS_TASK_DEL_REQ[L4.13(1)]時(shí),則表明已經(jīng)有另外的任務(wù)請(qǐng)求該任務(wù)被刪除了。在這種情況下,被刪除的任務(wù)會(huì)釋放它所擁有的所用資源[L4.13(2)],并且調(diào)用OSTaskDel(OS_PRIO_SELF)來(lái)刪除自己[L4.13(3)]。前面曾提到過(guò),任務(wù)的代碼沒(méi)有被真正的刪除,而只是μC/OS-Ⅱ不再理會(huì)該任務(wù)代碼,換句話說(shuō),就是任務(wù)的代碼不會(huì)再運(yùn)行了。
但是,用戶可以通過(guò)調(diào)用OSTaskCreate()或OSTaskCreateExt()函數(shù)重新建立該任務(wù)。OSTaskDelReq()的代碼如程序清單L4.14所示。通常OSTaskDelReq()需要檢查臨界條件。首先,如果正在刪除的任務(wù)是空閑任務(wù),OSTaskDelReq()會(huì)報(bào)錯(cuò)并返回[L4.14(1)]。接著,它要保證調(diào)用者請(qǐng)求刪除的任務(wù)的優(yōu)先級(jí)是有效的[L4.14(2)]。如果調(diào)用者就是被刪除任務(wù)本身,存儲(chǔ)在OS_TCB中的標(biāo)志將會(huì)作為返回值[L4.14(3)]。如果用戶用優(yōu)先級(jí)而不是OS_PRIO_SELF指定任務(wù),并且任務(wù)是存在的[L4.14(4)],OSTaskDelReq()就會(huì)設(shè)置任務(wù)的內(nèi)部標(biāo)志[L4.14(5)]。如果任務(wù)不存在,OSTaskDelReq()則會(huì)返回OS_TASK_NOT_EXIST,表明任務(wù)可能已經(jīng)刪除自己了[L4.14(6)]。
程序清單 L4.14 OSTaskDelReq().
INT8UOSTaskDelReq(INT8Uprio)
{
BOOLEANstat;
INT8Uerr;
OS_TCB*ptcb;
if(prio==OS_IDLE_PRIO){(1)
return(OS_TASK_DEL_IDLE);
}
if(prio>=OS_LOWEST_PRIOprio!=OS_PRIO_SELF){
評(píng)論