新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II的任務管理

        μC/OS-II的任務管理

        作者: 時間:2016-10-08 來源:網絡 收藏

        (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改變任務的優先級,OSTaskChangePrio()

        在用戶建立任務的時候會分配給任務一個優先級。在程序運行期間,用戶可以通過調用OSTaskChangePrio()來改變任務的優先級。換句話說,就是μC/OS-Ⅱ允許用戶動態的改變任務的優先級。

        OSTaskChangePrio()的代碼如程序清單L4.15所示。用戶不能改變空閑任務的優先級[L4.15(1)],但用戶可以改變調用本函數的任務或者其它任務的優先級。為了改變調用本函數的任務的優先級,用戶可以指定該任務當前的優先級或OS_PRIO_SELF,

        OSTaskChangePrio()會決定該任務的優先級。用戶還必須指定任務的新(即想要的)優先級。因為μC/OS-Ⅱ不允許多個任務具有相同的優先級,所以OSTaskChangePrio()需要檢驗新優先級是否是合法的(即不存在具有新優先級的任務)[L4.15(2)]。如果新優先級是合法的,μC/OS-Ⅱ通過將某些東西儲存到OSTCBPrioTbl[newprio]中保留這個優先級[L4.15(3)]。如此就使得OSTaskChangePrio()可以重新允許中斷,因為此時其它任務已經不可能建立擁有該優先級的任務,也不能通過指定相同的新優先級來調用OSTaskChangePrio()。接下來OSTaskChangePrio()可以預先計算新優先級任務的OS_TCB中的某些值[L4.15(4)]。而這些值用來將任務放入就緒表或從該表中移除(參看3.04,就緒表)。

        接著,OSTaskChangePrio()檢驗目前的任務是否想改變它的優先級[L4.15(5)]。然后,TaskChangePrio()檢查想要改變優先級的任務是否存在[L4.15(6)]。很明顯,如果要改變優先級的任務就是當前任務,這個測試就會成功。但是,如果OSTaskChangePrio()想要改變優先級的任務不存在,它必須將保留的新優先級放回到優先級表OSTCBPrioTbl[]中[L4.15(17)],并返回給調用者一個錯誤碼。

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

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

        接著,OSTaskChangePrio()將指向任務OS_TCB的指針存到OSTCBPrioTbl[]中[L4.15(13)]。 新的優先級被保存在OS_TCB中[L4.15(14)], 重新計算的值也被保存在OS_TCB中[L4.15(15)]。OSTaskChangePrio()完成了關鍵性的步驟后,在新的優先級高于舊的優先級或新的優先級高于調用本函數的任務的優先級情況下,任務調度程序就會被調用[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);



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 高台县| 岳池县| 吕梁市| 东辽县| 都昌县| 麻江县| 来宾市| 灵石县| 鄄城县| 信阳市| 唐河县| 措勤县| 渭源县| 台中县| 玛曲县| 巴楚县| 宣汉县| 河南省| 博客| 高雄县| 略阳县| 茶陵县| 静安区| 西宁市| 永州市| 蛟河市| 中江县| 宁安市| 黔西县| 安徽省| 渭南市| 文安县| 沐川县| 视频| 滨海县| 龙海市| 陆河县| 宜宾市| 察隅县| 隆子县| 潼南县|