基于ARM嵌入式系統(tǒng)開發(fā)8_第1頁
基于ARM嵌入式系統(tǒng)開發(fā)8_第2頁
基于ARM嵌入式系統(tǒng)開發(fā)8_第3頁
基于ARM嵌入式系統(tǒng)開發(fā)8_第4頁
基于ARM嵌入式系統(tǒng)開發(fā)8_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、C/OS-II中的任務(wù)管理 任務(wù)的狀態(tài)及其轉(zhuǎn)換正在運行的任務(wù),需要等待一段時間或需要等待一個事件發(fā)生再運行時,該任務(wù)就會把CPU的使用權(quán)讓給別的任務(wù)而使任務(wù)進(jìn)入等待狀態(tài)。 任務(wù)在沒有被配備任務(wù)控制塊或被剝奪了任務(wù)控制塊時的狀態(tài)叫做任務(wù)的睡眠狀態(tài) 系統(tǒng)為任務(wù)配備了任務(wù)控制塊且在任務(wù)就緒表中進(jìn)行了就緒登記,這時任務(wù)的狀態(tài)叫做就緒狀態(tài)。 處于就緒狀態(tài)的任務(wù)如果經(jīng)調(diào)度器判斷獲得了CPU的使用權(quán),則任務(wù)就進(jìn)入運行狀態(tài) 一個正在運行的任務(wù)一旦響應(yīng)中斷申請就會中止運行而去執(zhí)行中斷服務(wù)程序,這時任務(wù)的狀態(tài)叫做中斷服務(wù)狀態(tài) 前面談到,一個任務(wù)的任務(wù)控制塊的主要作用就是保存該任務(wù)的虛擬處理器的堆棧指針寄存器SP。

2、其實,隨著任務(wù)管理工作的復(fù)雜性的提高,它還應(yīng)該保存一些其他信息。任務(wù)控制塊任務(wù)在系統(tǒng)中的身份證 由于系統(tǒng)存在著多個任務(wù),于是系統(tǒng)如何來識別并管理一個任務(wù)就是一個需要解決的問題。識別一個任務(wù)的最直接的辦法是為每一個任務(wù)起一個名稱。 由于C/OS-II中的任務(wù)都有一個惟一的優(yōu)先級別,因此C/OS-II是用任務(wù)的優(yōu)先級來作為任務(wù)的標(biāo)識的。 所以,任務(wù)控制塊還要來保存該任務(wù)的優(yōu)先級別。另外,前面也談到,一個任務(wù)在不同的時刻還處于不同的狀態(tài),顯然,記錄了任務(wù)狀態(tài)的數(shù)據(jù)也應(yīng)該保存到任務(wù)控制塊中?;谏鲜鲈?,系統(tǒng)必須為每個任務(wù)創(chuàng)建一個保存與該任務(wù)有關(guān)的相關(guān)信息的數(shù)據(jù)結(jié)構(gòu),這個數(shù)據(jù)結(jié)構(gòu)就叫做該任務(wù)的任務(wù)控制

3、塊(TCB)。任務(wù)控制塊結(jié)構(gòu)的主要成員typedef struct os_tcb OS_STK OS_STK * *OSTCBStkPtrOSTCBStkPtr; /指向任務(wù)堆棧棧頂?shù)闹羔?INT8U INT8U OSTCBStatOSTCBStat;/任務(wù)的當(dāng)前狀態(tài)標(biāo)志 INT8U INT8U OSTCBPrioOSTCBPrio; /任務(wù)的優(yōu)先級別 OS_TCB; 任務(wù)控制塊是不是像我們?nèi)嗽谝粋€國家中的身份證?(其實,系統(tǒng)中的所有資源都應(yīng)該有身份證。)任務(wù)在內(nèi)存中的結(jié)構(gòu) 用戶任務(wù)代碼的用戶任務(wù)代碼的 一般結(jié)構(gòu)一般結(jié)構(gòu) void MyTask(void *pdata) for (;) 可以被

4、中斷的用戶代碼;可以被中斷的用戶代碼; OS_ENTER_CRITICAL( );/進(jìn)入臨界段(關(guān)中斷)進(jìn)入臨界段(關(guān)中斷) 不可以被中斷的用戶代碼;不可以被中斷的用戶代碼; OS_EXIT_CRITICAL( ); /退出臨界段(開中斷)退出臨界段(開中斷) 可以被中斷的用戶代碼;可以被中斷的用戶代碼; 臨界段臨界段無限循無限循環(huán)環(huán)于是可以這樣說,C/OS-II任務(wù)的代碼結(jié)構(gòu)是一個可以帶有臨界段的無限循環(huán)。 系統(tǒng)提供的空閑任務(wù) 在多任務(wù)系統(tǒng)運行時,系統(tǒng)經(jīng)常會在某個時間內(nèi)無用戶任務(wù)可運行而處于所謂的空閑狀態(tài),為了使CPU在沒有用戶任務(wù)可執(zhí)行的時候有事可做,C/OS-II提供了一個叫做空閑任務(wù)O

5、STaskIdle( )的系統(tǒng)任務(wù) void OSTaskIdle(void* pdata)# if OS_CRITICAL_METHOD = = 3OS_CPU_SR cpu_sr;#endif pdata = pdata;/防止某些編譯器報錯for(;)OS_ENTER_CRITICAL( );/關(guān)閉中斷OSdleCtr+;/計數(shù)OS_EXIT_CRITICAL( );/開放中斷 空閑任務(wù)只是做了一個計數(shù)工作注意!空閑任務(wù)中沒有調(diào)用任務(wù)延時函數(shù)C/OS-II規(guī)定,一個用戶應(yīng)用程序必須使用這個空閑任務(wù),而且這個任務(wù)是不能用軟件來刪除的 系統(tǒng)提供的另一個任務(wù) 統(tǒng)計任務(wù)C/OS-II提供的另一個

6、系統(tǒng)任務(wù)是統(tǒng)計任務(wù)OSTaskStat( )。這個統(tǒng)計任務(wù)每秒計算一次CPU在單位時間內(nèi)被使用的時間,并把計算結(jié)果以百分比的形式存放在變量OSCPUsage中,以便應(yīng)用程序通過訪問它來了解CPU的利用率,所以這個系統(tǒng)任務(wù)OSTaskStat( )叫做統(tǒng)計任務(wù) 任務(wù)的優(yōu)先權(quán) 及優(yōu)先級別 C/OS_II 把任務(wù)的優(yōu)先權(quán)分為64個優(yōu)先級別,每一個級別都用一個數(shù)字來表示。數(shù)字0表示任務(wù)的優(yōu)先級別最高,數(shù)字越大則表示任務(wù)的優(yōu)先級別越低 用戶可以根據(jù)應(yīng)用程序的需要,在文件OS_CFG.H中通過給表示最低優(yōu)先級別的常數(shù)OS_LOWEST_PRIO賦值的方法,來說明應(yīng)用程序中任務(wù)優(yōu)先級別的數(shù)目。該常數(shù)一旦被定

7、義,則意味著系統(tǒng)中可供使用的優(yōu)先級別為:0,1,2,OS_LOWEST_PRIO,共OS_LOWEST_PRIO+1個 固定地,系統(tǒng)總是把最低優(yōu)先級別OS_LOWEST_PRIO自動賦給空閑任務(wù)。如果應(yīng)用程序中還使用了統(tǒng)計任務(wù),系統(tǒng)則會把優(yōu)先級別OS_LOWEST_PRIO-1自動賦給統(tǒng)計任務(wù),因此用戶任務(wù)可以使用的優(yōu)先級別是:0,1,2OS_LOWEST_PRIO-2,共OS_LOWEST_PRIO-1個 任 務(wù) 堆 棧 保存CPU寄存器中的內(nèi)容及存儲任務(wù)私有數(shù)據(jù)的需要,每個任務(wù)都應(yīng)該配有自己的堆棧,任務(wù)堆棧是任務(wù)的重要的組成部分 在應(yīng)用程序中定義任務(wù)堆棧的棧區(qū)非常簡單,即定義一個OS_ST

8、K類型的一個數(shù)組并在創(chuàng)建一個任務(wù)時把這個數(shù)組的地址賦給該任務(wù)就可以了。例如: /定義堆棧的長度#defineTASK_STK_SIZE 512/定義一個數(shù)組來作為任務(wù)堆棧OS_STK TaskStkTASK_STK_SIZE;typedef unsigned int OS_STK;/這是系統(tǒng)定義的一個數(shù)據(jù)類型 void main(void)OSTaskCreate(MyTask, /任務(wù)的指針&MyTaskAgu, /傳遞給任務(wù)的參數(shù)& MyTaskStkMyTaskStkN-1,/任務(wù)堆棧棧頂?shù)刂?0/任務(wù)的優(yōu)先級別);在創(chuàng)建用戶任務(wù)時,要傳遞任務(wù)的堆棧指針和任務(wù)優(yōu)先級別使用

9、函數(shù)OSTaskCreate( )創(chuàng)建任務(wù)時,一定要注意所使用的處理器對堆棧增長方向的支持是向上的還是向下的 任務(wù)堆棧的初始化應(yīng)用程序在創(chuàng)建一個新任務(wù)的時候,必須把在系統(tǒng)啟動這個任務(wù)時CPU各寄存器所需要的初始數(shù)據(jù)(任務(wù)指針、任務(wù)堆棧指針、程序狀態(tài)字等等),事先存放在任務(wù)的堆棧中 C/OS-II在創(chuàng)建任務(wù)函數(shù)OSTaskCreate( )中通過調(diào)用任務(wù)堆棧初始化函數(shù)OSTaskStkInit( )來完成任務(wù)堆棧初始化工作的 它的原型如下: OS_STK *OSTaskStkInit(void (*task)(void *pd), void *pdato, OS_STK *ptos, INT16

10、U opt);由于各種處理器的寄存器及對堆棧的操作方式不盡相同,因此該函數(shù)需要用戶在進(jìn)行C/OS-II的移植時,按所使用的處理器由用戶來編寫。實現(xiàn)這個函數(shù)的具體細(xì)節(jié),參考有關(guān)C/OS-II移植的文檔 其實,任務(wù)堆棧的初始化就是對該任務(wù)的虛擬處理器的初始化(復(fù)位)。 任務(wù)控制塊(OS_TCB)及任務(wù)控制塊鏈表C/OS-II用來記錄任務(wù)的堆棧指針、任務(wù)的當(dāng)前狀態(tài)、任務(wù)的優(yōu)先級別等一些與任務(wù)管理有關(guān)的屬性的表就叫做任務(wù)控制塊 任務(wù)控制塊就相當(dāng)于是一個任務(wù)的身份證,沒有任務(wù)控制塊的任務(wù)是不能被系統(tǒng)承認(rèn)和管理的 任務(wù)控制塊結(jié)構(gòu)的主要成員typedef struct os_tcb OS_STK *OSTC

11、BStkPtr; /指向任務(wù)堆棧棧頂?shù)闹羔?struct os_tcb *OSTCBNext;/指向后一個任務(wù)控制塊的指針 struct os_tcb *OSTCBPrev; /指向前一個任務(wù)控制塊的指針 INT16U OSTCBDly; /任務(wù)等待的時限(節(jié)拍數(shù)) INT8U OSTCBStat; /任務(wù)的當(dāng)前狀態(tài)標(biāo)志 INT8U OSTCBPrio; /任務(wù)的優(yōu)先級別 OS_TCB; 任務(wù)控制塊鏈表空任務(wù)控制塊鏈表當(dāng)應(yīng)用程序調(diào)用函數(shù)OSTaskCreate( )創(chuàng)建一個任務(wù)時,這個函數(shù)會調(diào)用系統(tǒng)函數(shù)OSTCBInit ( )來為任務(wù)控制塊進(jìn)行初始化。這個函數(shù)首先為被創(chuàng)建任務(wù)從空任務(wù)控制塊鏈

12、表獲取一個任務(wù)控制塊,然后用任務(wù)的屬性對任務(wù)控制塊各個成員進(jìn)行賦值,最后再把這個任務(wù)控制塊鏈入到任務(wù)控制塊鏈表的頭部 當(dāng)進(jìn)行系統(tǒng)初始化時,初始化函數(shù)會按用戶提供的任務(wù)數(shù)為系統(tǒng)創(chuàng)建具有相應(yīng)數(shù)量的任務(wù)控制塊并把它們鏈接為一個鏈表。由于這些任務(wù)控制塊還沒有對應(yīng)的任務(wù),故這個鏈表叫做空任務(wù)塊鏈表。即相當(dāng)于是一些空白的身份證。 任務(wù)就緒表及任務(wù)調(diào)度 多任務(wù)操作系統(tǒng)的核心工作就是任務(wù)調(diào)度。 所謂調(diào)度,就是通過一個算法在多個任務(wù)中確定該運行的任務(wù),做這項工作的函數(shù)就叫做調(diào)度器。 C/OS_II進(jìn)行任務(wù)調(diào)度的思想是 “近似地每時每刻總是讓優(yōu)先級最高的就緒任務(wù)處于運行狀態(tài)” 。為了保證這一點,它在系統(tǒng)或用戶任務(wù)

13、調(diào)用系統(tǒng)函數(shù)及執(zhí)行中斷服務(wù)程序結(jié)束時總是調(diào)用調(diào)度器,來確定應(yīng)該運行的任務(wù)并運行它 。C/OS_II進(jìn)行任務(wù)調(diào)度的依據(jù)就是任務(wù)就緒表 為了能夠使系統(tǒng)清楚地知道,系統(tǒng)中哪些任務(wù)已經(jīng)就緒,哪些還沒有就緒,C/OS_II在RAM中設(shè)立了一個記錄表,系統(tǒng)中的每個任務(wù)都在這個表中占據(jù)一個位置,并用這個位置的狀態(tài)(1或者0)來表示任務(wù)是否處于就緒狀態(tài),這個表就叫做任務(wù)就緒狀態(tài)表,簡稱叫任務(wù)就緒表 任務(wù)就緒表就是一個二維數(shù)組OSRdyTbl 為加快訪問任務(wù)就緒表的速度,系統(tǒng)定義了一個變量OSRdyGrp來表明就緒表每行中是否存在就緒任務(wù)。OSRdyTbl 1/0 1/0 1/0 1/0 1/0 1/0 1/0

14、 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/01/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0OSRdyGrp D7 D6 D5 D4 D3 D2 D1 D0 1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0任務(wù)就緒表的示意圖012345

15、67xy01234567OSRdyGrp D7 D6 D5 D4 D3 D2 D1 D0 11110000prio=29D7 D6 D5 D4 D3 D2 D1 D0 1D7 D6 D5 D4 D3 D2 D1 D0 1OSRdyTbl3 把prio為29的任務(wù)置為就緒狀態(tài)YXOSRdyGrp | =OSMapTblprio3; OSRdyTblprio3 | = OSMapTblprio&0 x07; 在程序中,可以用類似下面的代碼把優(yōu)先級別為prio的任務(wù)置為就緒狀態(tài): OSRdyGrp | =OSMapTblprio3;OSRdyGrp | =OSMapTblprio3;OSRd

16、yTblprio3 | = OSMapTblprio&0 x07;OSRdyTblprio3 | = OSMapTblprio&0 x07;如果要使一個優(yōu)先級別為prio的任務(wù)脫離就緒狀態(tài)則可使用如下類似代碼:if(OSRdyTblprio3&=if(OSRdyTblprio3&=OSMapTblprio&0 x07)=OSMapTblprio&0 x07)=0)0)OSRdyGrp&=OSRdyGrp&=OSMapTblprio3;OSMapTblprio3; OSRdyGrp D7 D6 D5 D4 D3 D2 D1 D0 1

17、1110000prio=29D7 D6 D5 D4 D3 D2 D1 D0 1D7 D6 D5 D4 D3 D2 D1 D0 1OSRdyTbly x = OSUnMapTalOSRdyTbly; 11000000000000y = OSUnMapTalOSRdyGrp; 圖5-6 在就緒表中查找最高優(yōu)先級別任務(wù)的過程從任務(wù)就緒表中獲取優(yōu)先級別最高的就緒任務(wù)可用如下類似的代碼: y = OSUnMapTalOSRdyGrp; /D5、D4、D3位x = OSUnMapTalOSRdyTbly; /D2、D1、D0位prio = (y3)+x;/優(yōu)先級別 或 y = OSUnMapTblOSRd

18、yGrp;prio = (INT8U)(y 3) + OSUnMapTblOSRdyTbly);優(yōu)先級判定表OSUnMapTbl256(os_core.c)INT8UconstOSUnMapTbl=0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2

19、,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1

20、,0,2,0,1,0;舉例:舉例: 如如OSRdyGrpOSRdyGrp的值為的值為00101000B00101000B,即,即0X280X28,則查得,則查得OSUnMapTblOSRdyGrpOSUnMapTblOSRdyGrp的值的值是是3 3,它相應(yīng)于,它相應(yīng)于OSRdyGrpOSRdyGrp中的中的第第3 3位置位置1 1; 如如OSRdyTbl3OSRdyTbl3的值是的值是11100100B11100100B,即,即0XE40XE4,則查,則查OSUnMapTblOSRdyTbl3OSUnMapTblOSRdyTbl3的的值是值是2 2,則進(jìn)入就緒態(tài)的最高,則進(jìn)入就緒態(tài)的最高任務(wù)

21、優(yōu)先級任務(wù)優(yōu)先級 Prio=3Prio=3* *8+2=268+2=26 小結(jié)系統(tǒng)通過查找任務(wù)就緒表來獲取待運行任務(wù)的優(yōu)先級優(yōu)先級任務(wù)切換過程獲得待運行任務(wù)的任務(wù)控制塊恢復(fù)待運行任務(wù)的運行環(huán)境處理器的PC=任務(wù)堆棧中的斷點地址處理器的SP=任務(wù)塊中保存的SP如何獲得待運行任務(wù)的任務(wù)控制塊?根據(jù)就緒表獲得待運行任務(wù)的任務(wù)控制塊指針其實,調(diào)度器在進(jìn)行調(diào)度時,在這個位置還要進(jìn)行一下判斷:究竟是待運行任務(wù)是否為當(dāng)前任務(wù),如果是,則不切換;如果不是才切換,而且還要保存被中止任務(wù)的運行環(huán)境。1 任務(wù)切換宏 OS_TASK_SW( ) 任務(wù)切換就是中止正在運行的任務(wù)(當(dāng)前任務(wù)),轉(zhuǎn)而去運行另外一個任務(wù)的操作

22、,當(dāng)然這個任務(wù)應(yīng)該是就緒任務(wù)中優(yōu)先級別最高的那個任務(wù) 先保護(hù)被中止任務(wù)的斷點數(shù)據(jù)后恢復(fù)待運行任務(wù)的斷點數(shù)據(jù)不要企圖用PUSH和POP指令來使程序計數(shù)器PC壓棧和出棧,因為沒有這樣的指令。只好變通一下了。中斷動作和過程調(diào)用指令可以使PC壓棧;中斷返回指令可以使PC出棧。因此任務(wù)切換OSCtxSw(OSCtxSw( )必定是一個中斷服務(wù)程序。需要由宏OS_TASK_SW( ) 來引發(fā)一次中斷或者一次調(diào)用來使OSCtxSw(OSCtxSw( )執(zhí)行任務(wù)切換工作調(diào)度時機(jī)很容易想到的調(diào)度時機(jī)就是定時調(diào)度。對于實時系統(tǒng)來說,應(yīng)該盡可能地實現(xiàn)即時調(diào)度。用函數(shù)OSTaskCreate( ) 創(chuàng)建任務(wù) 應(yīng)用程序

23、通過調(diào)用OSTaskCreate( ) 函數(shù)來創(chuàng)建一個任務(wù),OSTaskCreate( )函數(shù)的原型如下: INT8U OSTaskCreate ( void (*task)(void *pd),/指向任務(wù)的指針 void *pdata, /傳遞給任務(wù)的參數(shù) OS_STK *ptos, /指向任務(wù)堆棧棧頂?shù)闹羔?INT8U prio/任務(wù)的優(yōu)先級) 創(chuàng)建任務(wù) 的一般方法 一般來說,任務(wù)可以在調(diào)用函數(shù)OSStart( )啟動任務(wù)調(diào)度之前來創(chuàng)建,也可以在任務(wù)中來創(chuàng)建。但是,C/OS-II有一個規(guī)定:在調(diào)用啟動任務(wù)函數(shù)OSStart( )之前,必須已經(jīng)創(chuàng)建了至少一個任務(wù)。因此,人們習(xí)慣上在調(diào)用函數(shù)O

24、SStart( )之前先創(chuàng)建一個任務(wù),并賦予它最高的優(yōu)先級別,從而使它成為起始任務(wù)。然后在這個起始任務(wù)中,再創(chuàng)建其他各任務(wù)。如果要使用系統(tǒng)提供的統(tǒng)計任務(wù),則統(tǒng)計任務(wù)的初始化函數(shù)也必須在這個起始任務(wù)中來調(diào)用 void main(void)OSInit( );/對C/OS-II進(jìn)行初始化OSTaskCreate (TaskStart,);/創(chuàng)建任務(wù)TaskStartOSStart( );/開始多任務(wù)調(diào)度 void TaskStart(void*pdata)/在這個位置安裝并啟動C/OS-II的時鐘OSStatInit( );/初始化統(tǒng)計任務(wù)/在這個位置創(chuàng)建其他任務(wù)for(;)起始任務(wù)TaskSta

25、rt的代碼 C/OS-II的初始化在使用C/OS-II的所有服務(wù)之前,必須要調(diào)用C/OS-II的初始化函數(shù)OSInit( )對C/OS-II自身的運行環(huán)境進(jìn)行初始化。 函數(shù)OSInit( )將對C/OS-II的所有的全局變量和數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化,同時創(chuàng)建空閑任務(wù)OSTaskIdle,并賦之以最低的優(yōu)先級別和永遠(yuǎn)的就緒狀態(tài)。如果用戶應(yīng)用程序還要使用統(tǒng)計任務(wù)的話(常數(shù)OS_TASK_STAT_EN=1),則OSInit( )還要以優(yōu)先級別為OS_LOWEST_PRIO-1來創(chuàng)建統(tǒng)計任務(wù) 初始化函數(shù)OSInit( )對數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化時,主要要創(chuàng)建包括空任務(wù)控制塊鏈表在內(nèi)的5個空數(shù)據(jù)緩沖區(qū)。同時,

26、為了可以快速地查詢?nèi)蝿?wù)控制塊鏈表中的各個元素,初始化函數(shù)OSInit( )還要創(chuàng)建一個數(shù)組OSTCBPrioTblOS_LOWEST_PRIO + 1,在這個數(shù)組中,按任務(wù)的優(yōu)先級別的順序把任務(wù)控制塊的指針存放在了對應(yīng)的元素中 C/OS-II的啟動C/OS-II進(jìn)行任務(wù)的管理是從調(diào)用啟動函數(shù)OSStart( )開始的,當(dāng)然其前提條件是在調(diào)用該函數(shù)之前至少創(chuàng)建了一個用戶任務(wù) 第第3 3章章 C/OS-C/OS-的中斷和時鐘的中斷和時鐘 本章主要內(nèi)容:C/OS-II系統(tǒng) 響應(yīng)中斷的過程C/OS-II系統(tǒng)響應(yīng)中斷的過程為:系統(tǒng)接收到中斷請求后,這時如果CPU處于中斷允許狀態(tài)(即中斷是開放的),系統(tǒng)就

27、會中止正在運行的當(dāng)前任務(wù),而按照中斷向量的指向轉(zhuǎn)而去運行中斷服務(wù)子程序;當(dāng)中斷服務(wù)子程序的運行結(jié)束后,系統(tǒng)將會根據(jù)情況返回到被中止的任務(wù)繼續(xù)運行或者轉(zhuǎn)向運行另一個具有更高優(yōu)先級別的就緒任務(wù)。注意!中斷服務(wù)子程序運行結(jié)束之后,系統(tǒng)將會根據(jù)情況進(jìn)行一次任務(wù)調(diào)度去運行優(yōu)先級別最高的就緒任務(wù),而并不是一定要接續(xù)運行被中斷的任務(wù)的。中斷請求關(guān)閉中斷轉(zhuǎn)到中斷向量保存CPU寄存器通知內(nèi)核退出ISRISR給任務(wù)發(fā)信號中斷返回恢復(fù)CPU寄存器中斷響應(yīng)中斷恢復(fù)中斷恢復(fù)任務(wù)響應(yīng)時間任務(wù)響應(yīng)時間中斷的響應(yīng)過程無新高級任務(wù)則返回原任務(wù)通知內(nèi)核退出ISR恢復(fù)CPU寄存器中斷返回有新高級任務(wù)則運行高級任務(wù)通知內(nèi)核進(jìn)入ISR

28、void OSIntEnter (void) if (OSRunning = TRUE) if (OSIntNesting 0) OSIntNesting-;/中斷嵌套層數(shù)計數(shù)器減一中斷嵌套層數(shù)計數(shù)器減一 if (OSIntNesting = 0) & (OSLockNesting = 0) OSIntExitY = OSUnMapTblOSRdyGrp; OSPrioHighRdy = (INT8U)(OSIntExitY OSTCBStkPtr;/SP指向待運行任務(wù)堆棧用出棧指令把用出棧指令把R1,R2,彈入彈入CPU的通用寄存器;的通用寄存器;RETI;/中斷返回,使PC指向待運

29、行任務(wù)應(yīng)用程序中的臨界段 在應(yīng)用程序中經(jīng)常有一些代碼段必須不受任何干擾地連續(xù)運行,這樣的代碼段叫做臨界段。因此,為了使臨界段在運行時不受中斷所打斷,在臨界段代碼前必須用關(guān)中斷指令使CPU屏蔽中斷請求,而在臨界段代碼后必須用開中斷指令解除屏蔽使得CPU可以響應(yīng)中斷請求 由于各廠商生產(chǎn)的CPU和C編譯器的關(guān)中斷和開中斷的方法和指令不盡相同,為增強(qiáng)C/OS-II的可移植性(即在C/OS-II的各個C函數(shù)中盡可能地不出現(xiàn)匯編語言代碼),C/OS-II用兩個宏來實現(xiàn)中斷的開放和關(guān)閉,而把與系統(tǒng)的硬件相關(guān)的關(guān)中斷和開中斷的指令分別封裝在這兩個宏中: OS_ENTER_CRITICAL( )OS_EXIT_

30、CRITICAL( ) 第一種方法最簡單,即直接使用處理器的開中斷和關(guān)中斷指令來實現(xiàn)宏,這時需要令常數(shù)OS_CRITICAL_METHOD=1。其示意性代碼為: #define OS_ENTER_CRITICAL( )asm(“DI”) 關(guān)中斷 #define OS_EXIT_CRITICAL( )asm(“EI”) 開中斷 第二種方法稍微復(fù)雜一些,但可以使CPU中斷允許標(biāo)志的狀態(tài),在臨界段前和臨界段后不發(fā)生改變。在宏OS_ENTER_CRITICAL( )中,把CPU的允許中斷標(biāo)志保持到堆棧中,然后再關(guān)閉中斷,這樣在臨界段結(jié)束時,即在調(diào)用宏OS_EXIT_CRITICAL( )時只要把堆棧中

31、保存的CPU允許中斷狀態(tài)恢復(fù)就可以了。這兩個宏的示意性代碼如下: #define OS_ENTER_CRITICAL( ) asm(“PUSHPSW”) /*通過保存程序狀態(tài)字來保存中 斷允許標(biāo)志*/asm(“DI”) /關(guān)中斷 #define OS_EXIT_CRITICAL( ) asm(“POPPSW”) /恢復(fù)中斷允許標(biāo)志 C/OS-II的系統(tǒng)時鐘C/OS-II與大多數(shù)計算機(jī)系統(tǒng)一樣,用硬件定時器產(chǎn)生一個周期為ms級的周期性中斷來實現(xiàn)系統(tǒng)時鐘,最小的時鐘單位就是兩次中斷之間相間隔的時間,這個最小時鐘單位叫做時鐘節(jié)拍(Time Tick)。硬件定時器以時鐘節(jié)拍為周期定時地產(chǎn)生中 斷 ,

32、該 中 斷 的 中 斷 服 務(wù) 程 序 叫 做OSTickISR( )。中斷服務(wù)程序通過調(diào)用函數(shù)OSTimeTick( )來完成系統(tǒng)在每個時鐘節(jié)拍時需要做的工作。void OSTickISR(void)保存CPU寄存器;調(diào)用OSIntEnter( );/記錄中斷嵌套層數(shù)if (OSIntNesting = = 1;OSTCBCur-OSTCBStkPtr = SP; /保存堆棧指針調(diào)用調(diào)用OSTimeTick( );/節(jié)拍處理清除中斷;開中斷;調(diào)用OSIntExit( );/中斷嵌套層數(shù)減一 恢復(fù)CPU寄存器;中斷返回; 這是系統(tǒng)時鐘中斷服務(wù)程序void OSTimeTick (void) OSTimeTickHook( ); OSTime+;/記錄節(jié)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論