新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > μC/OS-II的內(nèi)核結(jié)構(gòu)

μC/OS-II的內(nèi)核結(jié)構(gòu)

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

盡的解釋。

OSSched()的所有代碼都屬臨界段代碼。在尋找進(jìn)入就緒態(tài)的優(yōu)先級(jí)最高的任務(wù)過程

中,為防止中斷服務(wù)子程序把一個(gè)或幾個(gè)任務(wù)的就緒位置位,中斷是被關(guān)掉的。為縮短切

換時(shí)間,OSSched()全部代碼都可以用匯編語言寫。為增加可讀性,可移植性和將匯編語言

代碼最少化,OSSched()是用C寫的。

3.6 給調(diào)度器上鎖和開鎖(LockingandUnLockingtheScheduler)

給調(diào)度器上鎖函數(shù)OSSchedlock()(程序清單L3.9)用于禁止任務(wù)調(diào)度,直到任務(wù)完

成后調(diào)用給調(diào)度器開鎖函數(shù)OSSchedUnlock()為止,(程序清單L3.10)。調(diào)用

OSSchedlock()的任務(wù)保持對(duì)CPU的控制權(quán),盡管有個(gè)優(yōu)先級(jí)更高的任務(wù)進(jìn)入了就緒態(tài)。然

而,此時(shí)中斷是可以被識(shí)別的,中斷服務(wù)也能得到(假設(shè)中斷是開著的)。OSSchedlock()

和OSSchedUnlock()必須成對(duì)使用。變量OSLockNesting跟蹤OSSchedLock()函數(shù)被調(diào)用的

次數(shù),以允許嵌套的函數(shù)包含臨界段代碼,這段代碼其它任務(wù)不得干預(yù)。μC/OS-Ⅱ允許嵌

套深度達(dá)255層。當(dāng)OSLockNesting等于零時(shí),調(diào)度重新得到允許。函數(shù)OSSchedLock()和

OSSchedUnlock()的使用要非常謹(jǐn)慎,因?yàn)樗鼈冇绊?mu;C/OS-Ⅱ?qū)θ蝿?wù)的正常管理。

當(dāng)OSLockNesting減到零的時(shí)候,OSSchedUnlock()調(diào)用OSSched[L3.10(2)]。

OSSchedUnlock()是被某任務(wù)調(diào)用的,在調(diào)度器上鎖的期間,可能有什么事件發(fā)生了并使一

個(gè)更高優(yōu)先級(jí)的任務(wù)進(jìn)入就緒態(tài)。

調(diào)用OSSchedLock()以后,用戶的應(yīng)用程序不得使用任何能將現(xiàn)行任務(wù)掛起的系統(tǒng)調(diào)用。也就是說,用戶程序不得調(diào)用OSMboxPend()、OSQPend()、OSSemPend()、OSTaskSuspend

(OS_PR1O_SELF)、OSTimeDly()或OSTimeDlyHMSM(),直到OSLockNesting回零為止。因?yàn)檎{(diào)度器上了鎖,用戶就鎖住了系統(tǒng),任何其它任務(wù)都不能運(yùn)行。

當(dāng)?shù)蛢?yōu)先級(jí)的任務(wù)要發(fā)消息給多任務(wù)的郵箱、消息隊(duì)列、信號(hào)量時(shí)(見第6章任務(wù)間通訊和同步),用戶不希望高優(yōu)先級(jí)的任務(wù)在郵箱、隊(duì)列和信號(hào)量沒有得到消息之前就取得了CPU的控制權(quán),此時(shí),用戶可以使用禁止調(diào)度器函數(shù)。

程序清單 L3.9 給調(diào)度器上鎖

voidOSSchedLock(void)

{

if(OSRunning==TRUE){

OS_ENTER_CRITICAL();

OSLockNesting++;

OS_EXIT_CRITICAL();

}

}

程序清單L3.10給調(diào)度器開鎖.

voidOSSchedUnlock(void)

{

if(OSRunning==TRUE){

OS_ENTER_CRITICAL();

if(OSLockNesting>0){

OSLockNesting--;

if((OSLockNesting|OSIntNesting)==0){(1)

OS_EXIT_CRITICAL();

OSSched();(2)

}else{

OS_EXIT_CRITICAL();

}

}else{

OS_EXIT_CRITICAL();

}

}

}

3.7 空閑任務(wù)(IdleTask)

μC/OS-Ⅱ總是建立一個(gè)空閑任務(wù),這個(gè)任務(wù)在沒有其它任務(wù)進(jìn)入就緒態(tài)時(shí)投入運(yùn)行。這個(gè)空閑任務(wù)[OSTaskIdle()]永遠(yuǎn)設(shè)為最低優(yōu)先級(jí),即OS_LOWEST_PRI0??臻e任務(wù)OSTaskIdle()什么也不做,只是在不停地給一個(gè)32位的名叫OSIdleCtr的計(jì)數(shù)器加1,統(tǒng)計(jì)任務(wù)(見3.08節(jié),統(tǒng)計(jì)任務(wù))使用這個(gè)計(jì)數(shù)器以確定現(xiàn)行應(yīng)用軟件實(shí)際消耗的CPU時(shí)間。程序清單L3.11是空閑任務(wù)的代碼。在計(jì)數(shù)器加1前后,中斷是先關(guān)掉再開啟的,因?yàn)?位以及大多數(shù)16位微處理器的32位加1需要多條指令,要防止高優(yōu)先級(jí)的任務(wù)或中斷服務(wù)子程序從中打入??臻e任務(wù)不可能被應(yīng)用軟件刪除。

程序清單L3.11μC/OS-Ⅱ的空閑任務(wù).

voidOSTaskIdle(void*pdata)

{

pdata=pdata;

for(;;){

OS_ENTER_CRITICAL();

OSIdleCtr++;

OS_EXIT_CRITICAL();

}

}

3.8 統(tǒng)計(jì)任務(wù)

μC/OS-Ⅱ有一個(gè)提供運(yùn)行時(shí)間統(tǒng)計(jì)的任務(wù)。這個(gè)任務(wù)叫做OSTaskStat(),如果用戶將系統(tǒng)定義常數(shù)OS_TASK_STAT_EN(見文件OS_CFG.H)設(shè)為1,這個(gè)任務(wù)就會(huì)建立。一旦得到了允許,OSTaskStat()每秒鐘運(yùn)行一次(見文件OS_CORE.C),計(jì)算當(dāng)前的CPU利用率。換句話說,OSTaskStat()告訴用戶應(yīng)用程序使用了多少CPU時(shí)間,用百分比表示,這個(gè)值放在一個(gè)有符號(hào)8位整數(shù)OSCPUsage中,精讀度是1個(gè)百分點(diǎn)。

如果用戶應(yīng)用程序打算使用統(tǒng)計(jì)任務(wù),用戶必須在初始化時(shí)建立一個(gè)唯一的任務(wù),在這個(gè)任務(wù)中調(diào)用OSStatInit()(見文件OS_CORE.C)。換句話說,在調(diào)用系統(tǒng)啟動(dòng)函數(shù)OSStart()之前,用戶初始代碼必須先建立一個(gè)任務(wù),在這個(gè)任務(wù)中調(diào)用系統(tǒng)統(tǒng)計(jì)初始化函數(shù)OSStatInit(),然后再建立應(yīng)用程序中的其它任務(wù)。程序清單L3.12是統(tǒng)計(jì)任務(wù)的示意性代碼。

程序清單L3.12初始化統(tǒng)計(jì)任務(wù).

voidmain(void)

{

OSInit();/* 初始化uC/OS-II(1)*/

/* 安裝uC/OS-II的任務(wù)切換向量 */

/* 創(chuàng)建用戶起始任務(wù)(為了方便討論,這里以TaskStart()作為起始任務(wù))(2)*/

OSStart();/* 開始多任務(wù)調(diào)度 (3)*/

}

voidTaskStart(void*pdata)

{

/* 安裝并啟動(dòng)uC/OS-II的時(shí)鐘節(jié)拍 (4)*/

OSStatInit();/* 初始化統(tǒng)計(jì)任務(wù) (5)*/

/* 創(chuàng)建用戶應(yīng)用程序任務(wù) */

for(;;){

/* 這里是TaskStart()的代碼!*/

}

}

因?yàn)橛脩舻膽?yīng)用程序必須先建立一個(gè)起始任務(wù)[TaskStart()],當(dāng)主程序main()調(diào)用系統(tǒng)啟動(dòng)函數(shù)OSStcnt()的時(shí)候,μC/OS-Ⅱ只有3個(gè)要管理的任務(wù):TaskStart()、OSTaskIdle()和OSTaskStat()。請(qǐng)注意,任務(wù)TaskStart()的名稱是無所謂的,叫什么名字都可以。因?yàn)?mu;C/OS-Ⅱ已經(jīng)將空閑任務(wù)的優(yōu)先級(jí)設(shè)為最低,即OS_LOWEST_PR10,統(tǒng)計(jì)任務(wù)的優(yōu)先級(jí)設(shè)為次低,OS_LOWEST_PR10-1。啟動(dòng)任務(wù)TaskStart()總是優(yōu)先級(jí)最高的任務(wù)。

圖F3.4解釋初始化統(tǒng)計(jì)任務(wù)時(shí)的流程。用戶必須首先調(diào)用的是μC/OS-Ⅱ中的系統(tǒng)初始化函數(shù)OSInit(),該函數(shù)初始化μC/OS-Ⅱ[圖F3.4(2)]。有的處理器(例如Motorola的MC68HC11),不需要“設(shè)置”中斷向量,中斷向量已經(jīng)在ROM中有了。用戶必須調(diào)用OSTaskCreat()或者OSTaskCreatExt()以建立TaskStart()[圖F3.4(3)]。進(jìn)入多任務(wù)的條件準(zhǔn)備好了以后,調(diào)用系統(tǒng)啟動(dòng)函數(shù)OSStart()。這個(gè)函數(shù)將使 TaskStart()開始執(zhí)行,因?yàn)門askStart()是優(yōu)先級(jí)最高的任務(wù)[圖F3.4(4)]]。



關(guān)鍵詞:

評(píng)論


相關(guān)推薦

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

關(guān)閉