新聞中心

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

        μC/OS-II的任務管理

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

        這樣,OSTaskDel()就能處理中斷服務了,但由于它增加了 OSLockNesting,ISR執(zhí)行完后會返回到被中斷任務,從而繼續(xù)任務的刪除工作。注意OSTaskDel()此時還沒有完全完成刪除任務的工作,因為它還需要從TCB鏈中解開OS_TCB,并將OS_TCB返回到空閑OS_TCB表中。

        另外需要注意的是,筆者在調(diào)用OS_EXIT_CRITICAL()函數(shù)后,馬上調(diào)用了OSDummy()[L4.11(12)],該函數(shù)并不會進行任何實質(zhì)性的工作。這樣做只是因為想確保處理器在中斷允許的情況下至少執(zhí)行一個指令。對于許多處理器來說,執(zhí)行中斷允許指令會強制CPU禁止中斷直到下個指令結(jié)束!Intel80x86和ZilogZ-80處理器就是如此工作的。開中斷后馬上關(guān)中斷就等于從來沒開過中斷,當然這會增加中斷的響應時間。因此調(diào)用OSDummy()確保在再次禁止中斷之前至少執(zhí)行了一個調(diào)用指令和一個返回指令。當然,用戶可以用宏定義將OSDummy()定義為一個空操作指令(譯者注:例如MC68HC08指令中的NOP指令) ,這樣調(diào)用OSDummy()就等于執(zhí)行了一個空操作指令,會使OSTaskDel()的執(zhí)行時間稍微縮短一點。但筆者認為這種宏定義是沒價值的,因為它會增加移植μCOS-Ⅱ的工作量。

        現(xiàn)在,OSTaskDel()可以繼續(xù)執(zhí)行刪除任務的操作了。在OSTaskDel()重新關(guān)中斷后,它通過鎖定嵌套計數(shù)器(OSLockNesting)減一以重新允許任務調(diào)度[L4.11(13)]。接著,OSTaskDel()調(diào)用用戶自定義的OSTaskDelHook()函數(shù)[L4.11(14)],用戶可以在這里刪除或

        釋放自定義的TCB附加數(shù)據(jù)域。 然后, OSTaskDel()減少μCOS-Ⅱ的任務計數(shù)器。 OSTaskDel()

        簡單地將指向被刪除的任務的OS_TCB的指針指向NULL[L4.11(15)],從而達到將OS_TCB從優(yōu)先級表中移除的目的。再接著,OSTaskDel()將被刪除的任務的OS_TCB從OS_TCB雙向鏈表中移除[L4.11(16)]。 注意,沒有必要檢驗ptcb->OSTCBNext==0的情況, 因為OSTaskDel()不能刪除空閑任務,而空閑任務就處于鏈表的末端(ptcb->OSTCBNext==0)。接下來,OS_TCB返回到空閑OS_TCB表中,并允許其它任務的建立[L4.11(17)]。最后,調(diào)用任務調(diào)度程序來查看在OSTaskDel()重新允許中斷的時候[L4.11(11)],中斷服務子程序是否曾使更高優(yōu)先級的任務處于就緒狀態(tài)[L4.11(18)]。

        4.5請求刪除任務,OSTaskDelReq()

        有時候,如果任務A擁有內(nèi)存緩沖區(qū)或信號量之類的資源,而任務B想刪除該任務,這些資源就可能由于沒被釋放而丟失。在這種情況下,用戶可以想法子讓擁有這些資源的任務在使用完資源后,先釋放資源,再刪除自己。用戶可以通過OSTaskDelReq()函數(shù)來完成該功能。

        發(fā)出刪除任務請求的任務(任務B)和要刪除的任務(任務A)都需要調(diào)用OSTaskDelReq()函數(shù)。任務B的代碼如程序清單L4.12所示。任務B需要決定在怎樣的情況下請求刪除任務[L4.12(1)]。換句話說,用戶的應用程序需要決定在什么樣的情況下刪除任務。如果任務需要被刪除,可以通過傳遞被刪除任務的優(yōu)先級來調(diào)用OSTaskDelReq()[L4.12(2)]。如果要被刪除的任務不存在(即任務已被刪除或是還沒被建立),OSTaskDelReq()返回OS_TASK_NOT_EXIST。如果OSTaskDelReq()的返回值為OS_NO_ERR,則表明請求已被接受但任務還沒被刪除。用戶可能希望任務B等到任務A刪除了自己以后才繼續(xù)進行下面的工作,這時用戶可以象筆者一樣,通過讓任務B延時一定時間來達到這個目的[L4.12(3)]。筆者延時了一個時鐘節(jié)拍。如果需要,用戶可以延時得更長一些。當任務A完全刪除自己后,[L4.12(2)]中的返回值成為0S_TASK_NOT_EXIST,此時循環(huán)結(jié)束[L4.12(4)]。

        程序清單 L4.12 請求刪除其它任務的任務(任務B)

        voidRequestorTask(void*pdata)

        {

        INT8Uerr;

        pdata=pdata;

        for(;;){

        /* 應用程序代碼 */

        if('TaskToBeDeleted()' 需要被刪除){(1)

        while(OSTaskDelReq(TASK_TO_DEL_PRIO)!=OS_TASK_NOT_EXIST){(2)

        OSTimeDly(1);(3)

        }

        }

        /*應用程序代碼*/(4)

        }

        }

        程序清單 L4.13 需要刪除自己的任務(任務A)

        voIDTaskToBeDeleted(void*pdata)

        {

        INT8Uerr;

        pdata=pdata;

        for(;;){

        /*應用程序代碼*/

        If(OSTaskDelReq(OS_PRIO_SELF)==OS_TASK_DEL_REQ){(1)

        釋放所有占用的資源;(2)

        釋放所有動態(tài)內(nèi)存;

        OSTaskDel(OS_PRIO_SELF);(3)

        }else{

        /*應用程序代碼*/

        }

        }

        }

        需要刪除自己的任務(任務A)的代碼如程序清單L4.13所示。在OS_TAB中存有一個標志,任務通過查詢這個標志的值來確認自己是否需要被刪除。這個標志的值是通過調(diào)用OSTaskDelReq(OS_PRIO_SELF)而得到的。當OSTaskDelReq()返回給調(diào)用者OS_TASK_DEL_REQ[L4.13(1)]時,則表明已經(jīng)有另外的任務請求該任務被刪除了。在這種情況下,被刪除的任務會釋放它所擁有的所用資源[L4.13(2)],并且調(diào)用OSTaskDel(OS_PRIO_SELF)來刪除自己[L4.13(3)]。前面曾提到過,任務的代碼沒有被真正的刪除,而只是μC/OS-Ⅱ不再理會該任務代碼,換句話說,就是任務的代碼不會再運行了。

        但是,用戶可以通過調(diào)用OSTaskCreate()或OSTaskCreateExt()函數(shù)重新建立該任務。OSTaskDelReq()的代碼如程序清單L4.14所示。通常OSTaskDelReq()需要檢查臨界條件。首先,如果正在刪除的任務是空閑任務,OSTaskDelReq()會報錯并返回[L4.14(1)]。接著,它要保證調(diào)用者請求刪除的任務的優(yōu)先級是有效的[L4.14(2)]。如果調(diào)用者就是被刪除任務本身,存儲在OS_TCB中的標志將會作為返回值[L4.14(3)]。如果用戶用優(yōu)先級而不是OS_PRIO_SELF指定任務,并且任務是存在的[L4.14(4)],OSTaskDelReq()就會設置任務的內(nèi)部標志[L4.14(5)]。如果任務不存在,OSTaskDelReq()則會返回OS_TASK_NOT_EXIST,表明任務可能已經(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){



        關(guān)鍵詞:

        評論


        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 临邑县| 黄浦区| 古丈县| 渑池县| 平和县| 嘉黎县| 历史| 舒城县| 元阳县| 广平县| 铁力市| 长宁区| 肇州县| 公主岭市| 寿宁县| 荥阳市| 海城市| 沽源县| 阿坝| 通城县| 商河县| 固阳县| 潼南县| 合肥市| 类乌齐县| 安化县| 正镶白旗| 丽江市| 阜城县| 湛江市| 新和县| 全南县| 萨迦县| 孝义市| 丽水市| 岳西县| 阳信县| 金乡县| 通城县| 开封市| 乐清市|