新聞中心

μC/OS-II的任務(wù)管理

作者: 時(shí)間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

(2)

return(OS_PRIO_INVALID);

}

if(prio==OS_PRIO_SELF){(3)

OS_ENTER_CRITICAL();

stat=OSTCBCur->OSTCBDelReq;

OS_EXIT_CRITICAL();

return(stat);

}

else{

OS_ENTER_CRITICAL();

if((ptcb=OSTCBPrioTbl[prio])!=(OS_TCB*)0){(4)

ptcb->OSTCBDelReq=OS_TASK_DEL_REQ;(5)

err=OS_NO_ERR;

}else{

err=OS_TASK_NOT_EXIST;(6)

}

OS_EXIT_CRITICAL();

return(err);

}

}

4.6改變?nèi)蝿?wù)的優(yōu)先級(jí),OSTaskChangePrio()

在用戶建立任務(wù)的時(shí)候會(huì)分配給任務(wù)一個(gè)優(yōu)先級(jí)。在程序運(yùn)行期間,用戶可以通過調(diào)用OSTaskChangePrio()來改變?nèi)蝿?wù)的優(yōu)先級(jí)。換句話說,就是μC/OS-Ⅱ允許用戶動(dòng)態(tài)的改變?nèi)蝿?wù)的優(yōu)先級(jí)。

OSTaskChangePrio()的代碼如程序清單L4.15所示。用戶不能改變空閑任務(wù)的優(yōu)先級(jí)[L4.15(1)],但用戶可以改變調(diào)用本函數(shù)的任務(wù)或者其它任務(wù)的優(yōu)先級(jí)。為了改變調(diào)用本函數(shù)的任務(wù)的優(yōu)先級(jí),用戶可以指定該任務(wù)當(dāng)前的優(yōu)先級(jí)或OS_PRIO_SELF,

OSTaskChangePrio()會(huì)決定該任務(wù)的優(yōu)先級(jí)。用戶還必須指定任務(wù)的新(即想要的)優(yōu)先級(jí)。因?yàn)?mu;C/OS-Ⅱ不允許多個(gè)任務(wù)具有相同的優(yōu)先級(jí),所以O(shè)STaskChangePrio()需要檢驗(yàn)新優(yōu)先級(jí)是否是合法的(即不存在具有新優(yōu)先級(jí)的任務(wù))[L4.15(2)]。如果新優(yōu)先級(jí)是合法的,μC/OS-Ⅱ通過將某些東西儲(chǔ)存到OSTCBPrioTbl[newprio]中保留這個(gè)優(yōu)先級(jí)[L4.15(3)]。如此就使得OSTaskChangePrio()可以重新允許中斷,因?yàn)榇藭r(shí)其它任務(wù)已經(jīng)不可能建立擁有該優(yōu)先級(jí)的任務(wù),也不能通過指定相同的新優(yōu)先級(jí)來調(diào)用OSTaskChangePrio()。接下來OSTaskChangePrio()可以預(yù)先計(jì)算新優(yōu)先級(jí)任務(wù)的OS_TCB中的某些值[L4.15(4)]。而這些值用來將任務(wù)放入就緒表或從該表中移除(參看3.04,就緒表)。

接著,OSTaskChangePrio()檢驗(yàn)?zāi)壳暗娜蝿?wù)是否想改變它的優(yōu)先級(jí)[L4.15(5)]。然后,TaskChangePrio()檢查想要改變優(yōu)先級(jí)的任務(wù)是否存在[L4.15(6)]。很明顯,如果要改變優(yōu)先級(jí)的任務(wù)就是當(dāng)前任務(wù),這個(gè)測(cè)試就會(huì)成功。但是,如果OSTaskChangePrio()想要改變優(yōu)先級(jí)的任務(wù)不存在,它必須將保留的新優(yōu)先級(jí)放回到優(yōu)先級(jí)表OSTCBPrioTbl[]中[L4.15(17)],并返回給調(diào)用者一個(gè)錯(cuò)誤碼。

現(xiàn)在, OSTaskChangePrio()可以通過插入NULL指針將指向當(dāng)前任務(wù)OS_TCB的指針從優(yōu)先級(jí)表中移除了[L4.15(7)]。這就使得當(dāng)前任務(wù)的舊的優(yōu)先級(jí)可以重新使用了。接著,我們檢驗(yàn)一下OSTaskChangePrio()想要改變優(yōu)先級(jí)的任務(wù)是否就緒[L4.15(8)]。如果該任務(wù)處于就緒狀態(tài),它必須在當(dāng)前的優(yōu)先級(jí)下從就緒表中移除[L4.15(9)],然后在新的優(yōu)先級(jí)下插入到就緒表中[L4.15(10)]。這兒需要注意的是,OSTaskChangePrio()所用的是重新計(jì)算的值[L4.15(4)]將任務(wù)插入就緒表中的。

如果任務(wù)已經(jīng)就緒,它可能會(huì)正在等待一個(gè)信號(hào)量、一封郵件或是一個(gè)消息隊(duì)列。如果OSTCBEventPtr非空(不等于NULL)[L4.15(8)],OSTaskChangePrio()就會(huì)知道任務(wù)正在等待以上的某件事。如果任務(wù)在等待某一事件的發(fā)生,OSTaskChangePrio()必須將任務(wù)從事件控制塊(參看6.00,事件控制塊)的等待隊(duì)列(在舊的優(yōu)先級(jí)下)中移除。并在新的優(yōu)先級(jí)下將事件插入到等待隊(duì)列中[L4.15(12)]。 任務(wù)也有可能正在等待延時(shí)的期滿(參看第五章-任務(wù)管理)或是被掛起(參看4.07,掛起任務(wù),OSTaskSuspend())。在這些情況下,從L4.15(8)到L4.15(12)這幾行可以略過。

接著,OSTaskChangePrio()將指向任務(wù)OS_TCB的指針存到OSTCBPrioTbl[]中[L4.15(13)]。 新的優(yōu)先級(jí)被保存在OS_TCB中[L4.15(14)], 重新計(jì)算的值也被保存在OS_TCB中[L4.15(15)]。OSTaskChangePrio()完成了關(guān)鍵性的步驟后,在新的優(yōu)先級(jí)高于舊的優(yōu)先級(jí)或新的優(yōu)先級(jí)高于調(diào)用本函數(shù)的任務(wù)的優(yōu)先級(jí)情況下,任務(wù)調(diào)度程序就會(huì)被調(diào)用[L4.15(16)]。

程序清單 L4.15 OSTaskChangePrio().

INT8UOSTaskChangePrio(INT8Uoldprio,INT8Unewprio)

{

OS_TCB*ptcb;

OS_EVENT*pevent;

INT8Ux;

INT8Uy;

INT8Ubitx;

INT8Ubity;

if((oldprio>=OS_LOWEST_PRIOoldprio!=OS_PRIO_SELF)||(1)

newprio>=OS_LOWEST_PRIO){

return(OS_PRIO_INVALID);

}

OS_ENTER_CRITICAL();

if(OSTCBPrioTbl[newprio]!=(OS_TCB*)0){(2)

OS_EXIT_CRITICAL();

return(OS_PRIO_EXIST);

}else{

OSTCBPrioTbl[newprio]=(OS_TCB*)1;(3)

OS_EXIT_CRITICAL();

y=newprio>>3;(4)

bity=OSMapTbl[y];

x=newprio0x07;

bitx=OSMapTbl[x];

OS_ENTER_CRITICAL();

if(oldprio==OS_PRIO_SELF){(5)

oldprio=OSTCBCur->OSTCBPrio;

}

if((ptcb=OSTCBPrioTbl[oldprio])!=(OS_TCB*)0){(6)

OSTCBPrioTbl[oldprio]=(OS_TCB*)0;(7)

if(OSRdyTbl[ptcb->OSTCBY]ptcb->OSTCBBitX){(8)

if((OSRdyTbl[ptcb->OSTCBY]=~ptcb->OSTCBBitX)==0){(9)

OSRdyGrp=~ptcb->OSTCBBitY;

}

OSRdyGrp|=bity;(10)

OSRdyTbl[y]|=bitx;

}else{

if((pevent=ptcb->OSTCBEventPtr)!=(OS_EVENT*)0){(11)

if((pevent->OSEventTbl[ptcb->OSTCBY]=

~ptcb->OSTCBBitX)==0){

pevent->OSEventGrp=~ptcb->OSTCBBitY;

}

pevent->OSEventGrp|=bity;(12)

pevent->OSEventTbl[y]|=bitx;

}

}

OSTCBPrioTbl[newprio]=ptcb;(13)

ptcb->OSTCBPrio=newprio;(14)

ptcb->OSTCBY=y;(15)

ptcb->OSTCBX=x;

ptcb->OSTCBBitY=bity;

ptcb->OSTCBBitX=bitx;

OS_EXIT_CRITICAL();

OSSched();(16)

return(OS_NO_ERR);



關(guān)鍵詞:

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉