新聞中心

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

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

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

在前面的章節(jié)中,筆者曾說過任務(wù)可以是一個無限的循環(huán),也可以是在一次執(zhí)行完畢后被刪除掉。這里要注意的是,任務(wù)代碼并不是被真正的刪除了,而只是μC/OS-Ⅱ不再理會該任務(wù)代碼,所以該任務(wù)代碼不會再運(yùn)行。任務(wù)看起來與任何C函數(shù)一樣,具有一個返回類型和一個參數(shù),只是它從不返回。任務(wù)的返回類型必須被定義成void型。在本章中所提到的函數(shù)可以在OS_TASK文件中找到。如前所述,任務(wù)必須是以下兩種結(jié)構(gòu)之一:

本文引用地址:http://2s4d.com/article/201610/305743.htm

voidYourTask(void*pdata)

{

for(;;){

/* 用戶代碼 */

調(diào)用μC/OS-Ⅱ的服務(wù)例程之一:

OSMboxPend();

OSQPend();

OSSemPend();

OSTaskDel(OS_PRIO_SELF);

OSTaskSuspend(OS_PRIO_SELF);

OSTImeDly();

OSTimeDlyHMSM();

/* 用戶代碼 */

}

}

voidYourTask(void*pdata)

{

/* 用戶代碼 */

OSTaskDel(OS_PRIO_SELF);

}

本章所講的內(nèi)容包括如何在用戶的應(yīng)用程序中建立任務(wù)、 刪除任務(wù)、 改變?nèi)蝿?wù)的優(yōu)先級、掛起和恢復(fù)任務(wù),以及獲得有關(guān)任務(wù)的信息。

μC/OS-Ⅱ可以管理多達(dá)64個任務(wù),并從中保留了四個最高優(yōu)先級和四個最低優(yōu)先級的任務(wù)供自己使用,所以用戶可以使用的只有56個任務(wù)。任務(wù)的優(yōu)先級越高,反映優(yōu)先級的值則越低。在最新的μC/OS-Ⅱ版本中,任務(wù)的優(yōu)先級數(shù)也可作為任務(wù)的標(biāo)識符使用。

4.0 建立任務(wù),OSTaskCreate()

想讓μC/OS-Ⅱ管理用戶的任務(wù),用戶必須要先建立任務(wù)。用戶可以通過傳遞任務(wù)地址和其它參數(shù)到以下兩個函數(shù)之一來建立任務(wù):OSTaskCreate()或OSTaskCreateExt()。

OSTaskCreate()與μC/OS是向下兼容的, OSTaskCreateExt()是 OSTaskCreate()的擴(kuò)展版本,提供了一些附加的功能。用兩個函數(shù)中的任何一個都可以建立任務(wù)。任務(wù)可以在多任務(wù)調(diào)度開始前建立,也可以在其它任務(wù)的執(zhí)行過程中被建立。在開始多任務(wù)調(diào)度(即調(diào)用OSStart())前,用戶必須建立至少一個任務(wù)。任務(wù)不能由中斷服務(wù)程序(ISR)來建立。

OSTaskCreate()的代碼如程序清單L4.1所述。從中可以知道,OSTaskCreate()需要四個參數(shù): task是任務(wù)代碼的指針, pdata是當(dāng)任務(wù)開始執(zhí)行時傳遞給任務(wù)的參數(shù)的指針, ptos是分配給任務(wù)的堆棧的棧頂指針(參看4.02,任務(wù)堆棧),prio是分配給任務(wù)的優(yōu)先級。

程序清單 L4.1 OSTaskCreate()

INT8UOSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,

INT8Uprio)

{

void*psp;

INT8Uerr;

if(prio>OS_LOWEST_PRIO){(1)

return(OS_PRIO_INVALID);

}

OS_ENTER_CRITICAL();

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

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

OS_EXIT_CRITICAL();(4)

psp=(void*)OSTaskStkInit(task,pdata,ptos,0);(5)

err=OSTCBInit(prio,psp,(void*)0,0,0,(void*)0,0);(6)

if(err==OS_NO_ERR){(7)

OS_ENTER_CRITICAL();

OSTaskCtr++;(8)

OSTaskCreateHook(OSTCBPrioTbl[prio]);(9)

OS_EXIT_CRITICAL();

if(OSRunning){(10)

OSSched();(11)

}

}else{

OS_ENTER_CRITICAL();

OSTCBPrioTbl[prio]=(OS_TCB*)0;(12)

OS_EXIT_CRITICAL();

}

return(err);

}else{

OS_EXIT_CRITICAL();

return(OS_PRIO_EXIST);

}

}

OSTaskCreate()一開始先檢測分配給任務(wù)的優(yōu)先級是否有效[L4.1(1)]。任務(wù)的優(yōu)先級必須在0到OS_LOWEST_PRIO之間。接著,OSTaskCreate()要確保在規(guī)定的優(yōu)先級上還沒有建立任務(wù)[L4.1(2)]。在使用μC/OS-Ⅱ時,每個任務(wù)都有特定的優(yōu)先級。如果某個優(yōu)先級是空閑的,μC/OS-Ⅱ通過放置一個非空指針在OSTCBPrioTbl[]中來保留該優(yōu)先級[L4.1(3)]。

這就使得OSTaskCreate()在設(shè)置任務(wù)數(shù)據(jù)結(jié)構(gòu)的其他部分時能重新允許中斷[L4.1(4)]。然后,OSTaskCreate()調(diào)用OSTaskStkInit()[L4.1(5)],它負(fù)責(zé)建立任務(wù)的堆棧。該函數(shù)是與處理器的硬件體系相關(guān)的函數(shù),可以在OS_CPU_C.C文件中找到。有關(guān)實現(xiàn)OSTaskStkInit()的細(xì)節(jié)可參看第8章——移植μC/OS-Ⅱ。如果已經(jīng)有人在你用的處理器上成功地移植了μC/OS-Ⅱ,而你又得到了他的代碼,就不必考慮該函數(shù)的實現(xiàn)細(xì)節(jié)了。

OSTaskStkInit()函數(shù)返回新的堆棧棧頂(psp),并被保存在任務(wù)的0S_TCB中。 注意用戶得將傳遞給OSTaskStkInit()函數(shù)的第四個參數(shù)opt置0,因為OSTaskCreate()與OSTaskCreateExt()不同,它不支持用戶為任務(wù)的創(chuàng)建過程設(shè)置不同的選項,所以沒有任何選項可以通過opt參數(shù)傳遞給OSTaskStkInit()。

μC/OS-Ⅱ支持的處理器的堆棧既可以從上(高地址)往下(低地址)遞減也可以從下往上遞增。用戶在調(diào)用OSTaskCreate()的時候必須知道堆棧是遞增的還是遞減的(參看所用處理器的OS_CPU.H中的OS_STACK_GROWTH),因為用戶必須得把堆棧的棧頂傳遞給OSTaskCreate(), 而棧頂可能是堆棧的最高地址(堆棧從上往下遞減), 也可能是最低地址(堆棧從下往上長)。

一旦OSTaskStkInit()函數(shù)完成了建立堆棧的任務(wù),OSTaskCreate()就調(diào)用OSTCBInit()[L4.1(6)],從空閑的OS_TCB池中獲得并初始化一個OS_TCB。OSTCBInit()的代碼如程序清單L4.2所示,它存在于0S_CORE.C文件中而不是OS_TASK.C文件中。

OSTCBInit()函數(shù)首先從OS_TCB緩沖池中獲得一個OS_TCB[L4.2(1)],如果OS_TCB池中有空閑的OS_TCB[L4.2(2)],它就被初始化[L4.2(3)]。注意一旦OS_TCB被分配,該任務(wù)的創(chuàng)建者就已經(jīng)完全擁有它了,即使這時內(nèi)核又創(chuàng)建了其它的任務(wù),這些新任務(wù)也不可能對已分配的OS_TCB作任何操作,所以O(shè)STCBInit()在這時就可以允許中斷,并繼續(xù)初始化OS_TCB的數(shù)據(jù)單元。

程序清單 L4.2 OSTCBInit()

INT8UOSTCBInit(INT8Uprio,OS_STK*ptos,OS_STK*pbos,INT16Uid,

INT16Ustk_size,void*pext,INT16Uopt)


上一頁 1 2 3 4 5 6 7 8 9 下一頁

關(guān)鍵詞:

評論


相關(guān)推薦

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

關(guān)閉