μC/OS-II的內(nèi)核結(jié)構(gòu)
圖3.1任務(wù)的狀態(tài)
本文引用地址:http://2s4d.com/article/201610/305744.htm正在運(yùn)行的任務(wù)可以通過調(diào)用兩個(gè)函數(shù)之一將自身延遲一段時(shí)間,這兩個(gè)函數(shù)是OSTimeDly()或OSTimeDlyHMSM()。這個(gè)任務(wù)于是進(jìn)入等待狀態(tài),等待這段時(shí)間過去,下一個(gè)優(yōu)先級(jí)最高的、并進(jìn)入了就緒態(tài)的任務(wù)立刻被賦予了CPU的控制權(quán)。等待的時(shí)間過去以后,系統(tǒng)服務(wù)函數(shù)OSTimeTick()使延遲了的任務(wù)進(jìn)入就緒態(tài)(見3.10節(jié),時(shí)鐘節(jié)拍)。
正在運(yùn)行的任務(wù)期待某一事件的發(fā)生時(shí)也要等待,手段是調(diào)用以下3個(gè)函數(shù)之一:
OSSemPend(),OSMboxPend(),或OSQPend()。調(diào)用后任務(wù)進(jìn)入了等待狀態(tài)(WAITING)。當(dāng)任務(wù)因等待事件被掛起(Pend),下一個(gè)優(yōu)先級(jí)最高的任務(wù)立即得到了CPU的控制權(quán)。當(dāng)事件發(fā)生了,被掛起的任務(wù)進(jìn)入就緒態(tài)。事件發(fā)生的報(bào)告可能來自另一個(gè)任務(wù),也可能來自中斷服務(wù)子程序。
正在運(yùn)行的任務(wù)是可以被中斷的,除非該任務(wù)將中斷關(guān)了,或者μC/OS-Ⅱ?qū)⒅袛嚓P(guān)了。被中斷了的任務(wù)就進(jìn)入了中斷服務(wù)態(tài)(ISR)。響應(yīng)中斷時(shí),正在執(zhí)行的任務(wù)被掛起,中斷服務(wù)子程序控制了CPU的使用權(quán)。中斷服務(wù)子程序可能會(huì)報(bào)告一個(gè)或多個(gè)事件的發(fā)生,而使一個(gè)或多個(gè)任務(wù)進(jìn)入就緒態(tài)。在這種情況下,從中斷服務(wù)子程序返回之前,μC/OS-Ⅱ要判定,被中斷的任務(wù)是否還是就緒態(tài)任務(wù)中優(yōu)先級(jí)最高的。如果中斷服務(wù)子程序使一個(gè)優(yōu)先級(jí)更高的任務(wù)進(jìn)入了就緒態(tài),則新進(jìn)入就緒態(tài)的這個(gè)優(yōu)先級(jí)更高的任務(wù)將得以運(yùn)行,否則原來被中斷了的任務(wù)才能繼續(xù)運(yùn)行。當(dāng)所有的任務(wù)都在等待事件發(fā)生或等待延遲時(shí)間結(jié)束,μC/OS-Ⅱ執(zhí)行空閑任務(wù)(idletask),執(zhí)行OSTaskIdle()函數(shù)。
3.3 任務(wù)控制塊(TaskControlBlocks,OS _TCBs)
一旦任務(wù)建立了,任務(wù)控制塊OS _TCBs將被賦值(程序清單3.3)。任務(wù)控制塊是一個(gè)數(shù)據(jù)結(jié)構(gòu),當(dāng)任務(wù)的CPU使用權(quán)被剝奪時(shí),μC/OS-Ⅱ用它來保存該任務(wù)的狀態(tài)。當(dāng)任務(wù)重新得到CPU使用權(quán)時(shí),任務(wù)控制塊能確保任務(wù)從當(dāng)時(shí)被中斷的那一點(diǎn)絲毫不差地繼續(xù)執(zhí)行。OS _TCBs全部駐留在RAM中。讀者將會(huì)注意到筆者在組織這個(gè)數(shù)據(jù)結(jié)構(gòu)時(shí),考慮到了各成員的邏輯分組。任務(wù)建立的時(shí)候,OS _TCBs就被初始化了(見第四章任務(wù)管理)。
程序清單 L3.3μC/OS-II任務(wù)控制塊.
typedefstructos_tcb{
OS_STK*OSTCBStkPtr;
#ifOS_TASK_CREATE_EXT_EN
void*OSTCBExtPtr;
OS_STK*OSTCBStkBottom;
INT32UOSTCBStkSize;
INT16UOSTCBOpt;
INT16UOSTCBId;
#endif
structos_tcb*OSTCBNext;
structos_tcb*OSTCBPrev;
#if(OS_Q_EN(OS_MAX_QS>=2))||OS_MBOX_EN||OS_SEM_EN
OS_EVENT*OSTCBEventPtr;
#endif
#if(OS_Q_EN(OS_MAX_QS>=2))||OS_MBOX_EN
void*OSTCBMsg;
#endif
INT16UOSTCBDly;
INT8UOSTCBStat;
INT8UOSTCBPrio;
INT8UOSTCBX;
INT8UOSTCBY;
INT8UOSTCBBitX;
INT8UOSTCBBitY;
#ifOS_TASK_DEL_EN
BOOLEANOSTCBDelReq;
#endif
}OS_TCB;
.OSTCBStkPtr 是指向當(dāng)前任務(wù)棧頂?shù)闹羔槨?mu;C/OS-Ⅱ允許每個(gè)任務(wù)有自己的棧,尤為重
要的是,每個(gè)任務(wù)的棧的容量可以是任意的。有些商業(yè)內(nèi)核要求所有任務(wù)棧的容量都一
樣,除非用戶寫一個(gè)復(fù)雜的接口函數(shù)來改變之。這種限制浪費(fèi)了RAM,當(dāng)各任務(wù)需要的棧
空間不同時(shí),也得按任務(wù)中預(yù)期棧容量需求最多的來分配??臻g。OSTCBStkPtr是OS_TCB
數(shù)據(jù)結(jié)構(gòu)中唯一的一個(gè)能用匯編語言來處置的變量(在任務(wù)切換段的代碼Context-
switchingcode之中,)把OSTCBStkPtr放在數(shù)據(jù)結(jié)構(gòu)的最前面,使得從匯編語言中處理
這個(gè)變量時(shí)較為容易。
.OSTCBExtPtr 指向用戶定義的任務(wù)控制塊擴(kuò)展。用戶可以擴(kuò)展任務(wù)控制塊而不必修改μ
C/OS-Ⅱ的源代碼。.OSTCBExtPtr只在函數(shù)OstaskCreateExt()中使用,故使用時(shí)要將
OS_TASK_CREAT_EN設(shè)為1,以允許建立任務(wù)函數(shù)的擴(kuò)展。例如用戶可以建立一個(gè)數(shù)據(jù)結(jié)
構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)包含每個(gè)任務(wù)的名字,或跟蹤某個(gè)任務(wù)的執(zhí)行時(shí)間,或者跟蹤切換到某
個(gè)任務(wù)的次數(shù)(見例3)。注意,筆者將這個(gè)擴(kuò)展指針變量放在緊跟著堆棧指針的位置,
為的是當(dāng)用戶需要在匯編語言中處理這個(gè)變量時(shí),從數(shù)據(jù)結(jié)構(gòu)的頭上算偏移量比較方便。
.OSTCBStkBottom 是指向任務(wù)棧底的指針。如果微處理器的棧指針是遞減的,即棧存儲(chǔ)器
從高地址向低地址方向分配,則OSTCBStkBottom指向任務(wù)使用的??臻g的最低地址。類似
地,如果微處理器的棧是從低地址向高地址遞增型的,則OSTCBStkBottom指向任務(wù)可以使
用的??臻g的最高地址。函數(shù)OSTaskStkChk()要用到變量OSTCBStkBottom,在運(yùn)行中檢驗(yàn)
??臻g的使用情況。用戶可以用它來確定任務(wù)實(shí)際需要的棧空間。這個(gè)功能只有當(dāng)用戶在
任務(wù)建立時(shí)允許使用OSTaskCreateExt()函數(shù)時(shí)才能實(shí)現(xiàn)。這就要求用戶將
OS_TASK_CREATE_EXT_EN設(shè)為1,以便允許該功能。
.OSTCBStkSize 存有棧中可容納的指針元數(shù)目而不是用字節(jié)(Byte)表示的棧容量總數(shù)。
也就是說,如果棧中可以保存1,000個(gè)入口地址,每個(gè)地址寬度是32位的,則實(shí)際棧容量
是4,000字節(jié)。同樣是1,000個(gè)入口地址,如果每個(gè)地址寬度是16位的,則總棧容量只有
2,000字節(jié)。在函數(shù)OSStakChk()中要調(diào)用OSTCBStkSize。同理,若使用該函數(shù)的話,要將
OS_TASK_CREAT_EXT_EN設(shè)為1。
.OSTCBOpt 把“選擇項(xiàng)”傳給OSTaskCreateExt(),只有在用戶將OS_TASK_CREATE_EXT_EN
設(shè)為1時(shí),這個(gè)變量才有效。μC/OS-Ⅱ目前只支持3個(gè)選擇項(xiàng)(見uCOS_II.H):
OS_TASK_OTP_STK_CHK,OS_TASK_OPT_STK_CLR和OS_TASK_OPT_SAVE_FP。
OS_TASK_OTP_STK_CHK用于告知TaskCreateExt(),在任務(wù)建立的時(shí)候任務(wù)棧檢驗(yàn)功能得
到了允許。OS_TASK_OPT_STK_CLR表示任務(wù)建立的時(shí)候任務(wù)棧要清零。只有在用戶需要有
棧檢驗(yàn)功能時(shí),才需要將棧清零。如果不定義OS_TASK_OPT_STK_CLR,而后又建立、刪除
評(píng)論