版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、嵌入式實(shí)時(shí)操作系統(tǒng) C/OS-II講座,北 華 大 學(xué) 任 哲 2006 廣州,為什么要學(xué)習(xí)C/OS-II,一.凡從事嵌入式系統(tǒng)開(kāi)發(fā)工作的人,必須 對(duì)嵌入式操作系統(tǒng)有足夠的了解。 二.對(duì)于初學(xué)者,從C/OS-II開(kāi)始是個(gè)明智的選擇。 1. C/OS-II麻雀雖小,卻五臟基本全(它是個(gè)微內(nèi)核)。 2.可以學(xué)習(xí)實(shí)時(shí)系統(tǒng)的一些編程技巧。 3.可以把在學(xué)校中學(xué)到的操作系統(tǒng)抽象概念具體化。 4.具有很強(qiáng)的實(shí)用性。 5.學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)應(yīng)用的好例子。,講座的主要內(nèi)容,一.計(jì)算機(jī)操作系統(tǒng)的基本概念 二.操作系統(tǒng)中常用的數(shù)據(jù)結(jié)構(gòu) 三.并發(fā)操作系統(tǒng)的概念 四.任務(wù)的要素 五. C/OS-II的任務(wù)管理(任務(wù)調(diào)度)
2、六. C/OS-II的中斷和時(shí)鐘 七. C/OS-II的任務(wù)的同步與通信 八. C/OS-II的存儲(chǔ)管理 九.硬件抽象層和測(cè)試臺(tái),操作系統(tǒng)是一種為應(yīng)用程序提供服務(wù)的系統(tǒng)軟件,是一個(gè)完整計(jì)算機(jī)系統(tǒng)的有機(jī)組成部分。 從層次來(lái)看,操作系統(tǒng)位于計(jì)算機(jī)硬件之上,應(yīng)用軟件之下。所以也把它叫做應(yīng)用軟件的運(yùn)行平臺(tái)。,什么是計(jì)算機(jī)操作系統(tǒng) (Operating System,OS),它在計(jì)算機(jī)應(yīng)用程序與計(jì)算機(jī)硬件系統(tǒng)之間,屏蔽了計(jì)算機(jī)硬件工作的一些細(xì)節(jié),并對(duì)系統(tǒng)中的資源進(jìn)行有效的管理。 通過(guò)提供函數(shù)(應(yīng)用程序接口(API),從而使應(yīng)用程序的設(shè)計(jì)人員得以在一個(gè)友好的平臺(tái)上進(jìn)行應(yīng)用程序的設(shè)計(jì)和開(kāi)發(fā),大大地提高了應(yīng)用
3、程序的開(kāi)發(fā)效率。,計(jì)算機(jī)操作系統(tǒng)的作用,從用戶(hù)的角度來(lái)看,它就是一大堆函數(shù)(API和系統(tǒng)函數(shù)),用戶(hù)可以調(diào)用(普通調(diào)用或系統(tǒng)調(diào)用)它們來(lái)對(duì)系統(tǒng)資源進(jìn)行操作。,操作系統(tǒng),計(jì)算機(jī)操作系統(tǒng)的功能,處理器的管理,存儲(chǔ)管理,網(wǎng)絡(luò)和通信的管理,總之,需要一大堆表,操作系統(tǒng)中經(jīng)常使用 的數(shù)據(jù)結(jié)構(gòu)(數(shù)組),數(shù)組 1。同一數(shù)據(jù)類(lèi)型數(shù)據(jù)的集合; 2。占用連續(xù)內(nèi)存空間; 3。其中的所有元素名稱(chēng)都相同,但每個(gè)元素都有一個(gè)編號(hào); 4。元素名去掉編號(hào)(下標(biāo)),得到的是數(shù)組名,數(shù)組名是個(gè)指針。,int a10,a0,a1,a2,a3,a9,a,a+1,使用上的特點(diǎn): 1。分類(lèi)存放; 2。檢索速度快且恒定; 3。缺點(diǎn):占用連
4、續(xù)空間大,a+2,a+3,a+9,應(yīng)用:記錄同類(lèi)事物的表,操作系統(tǒng)中經(jīng)常使用 的數(shù)據(jù)結(jié)構(gòu)(位圖),位圖是數(shù)組的一種特殊應(yīng)用,a10 (可以記錄80個(gè)事物的狀態(tài)),a0,a1,a2,a3,a9,a,a+1,a+2,a+3,a+9,應(yīng)用:登記表,1/0,D7 D6 D5 D4 D3 D2 D1 D0,操作系統(tǒng)中經(jīng)常使用 的數(shù)據(jù)結(jié)構(gòu)(結(jié)構(gòu)),1。不同數(shù)據(jù)類(lèi)型數(shù)據(jù)的集合; 2。占用連續(xù)內(nèi)存空間;,struct Student int age; char*name; char sex; ;,使用上的特點(diǎn): 1。不分類(lèi)存放,但用來(lái)描述同一事物; 2。檢索速度快且恒定;,應(yīng)用:通訊錄中的一條記錄、 工具箱、
5、廚房等等,操作系統(tǒng)中經(jīng)常使用 的數(shù)據(jù)結(jié)構(gòu)(鏈表),struct Student Student*next int age; char*name; char sex; ;,1。同數(shù)據(jù)類(lèi)型數(shù)據(jù)的集合; 2。不占用連續(xù)內(nèi)存空間。,使用上的特點(diǎn): 1。分類(lèi)存放,但空間上不連續(xù)(不需要大量的連續(xù)存儲(chǔ)空間); 2。檢索速度慢,且耗費(fèi)的時(shí)間不固定;,應(yīng)用:存放大量的較大 的表,類(lèi)似檔案柜,操作系統(tǒng)中經(jīng)常使用 的數(shù)據(jù)結(jié)構(gòu)(隊(duì)列),按照先進(jìn)先出 的規(guī)則組織的數(shù)據(jù)結(jié)構(gòu) 可以用數(shù)組也可以用鏈 表來(lái)實(shí)現(xiàn),主要用于對(duì)象的排隊(duì),操作系統(tǒng)中經(jīng)常使用 的數(shù)據(jù)結(jié)構(gòu)(堆棧),按照先進(jìn)后出 規(guī)則組織的數(shù)據(jù)結(jié)構(gòu) 主要用數(shù)組來(lái)實(shí)現(xiàn),主
6、要用于 程序模塊的嵌套運(yùn)行,什么是多任務(wù)系統(tǒng),簡(jiǎn)單地說(shuō),就是能用一個(gè)處理器 并發(fā)(注意,不是同時(shí)! ) 地運(yùn)行多個(gè)程序的計(jì)算機(jī)管理系統(tǒng)。,并發(fā):由同一個(gè)處理器輪換地 運(yùn)行多個(gè)程序?;蛘哒f(shuō)是由多個(gè) 程序輪班地占用處理器這個(gè)資源。 且在占用這個(gè)資源期間,并不一 定能夠把程序運(yùn)行完畢。,并發(fā)過(guò)程 示意圖,處理器如何進(jìn)行程序的 切換?,程序的切換(兩句話(huà)),處理器是個(gè)傻瓜,PC讓它干啥,它就干啥。,PC是個(gè)指路器,它指向哪 兒,處理器就去哪兒。,從此可以知道,哪個(gè)程序占有了PC,哪個(gè)程序就占有了處理器。,深刻地理解PC是理解系統(tǒng) 進(jìn)行程序切換動(dòng)作的關(guān)鍵。,如何操作PC,指令: 不同的計(jì)算機(jī)類(lèi)型的指令是
7、不同的。,數(shù)據(jù)傳送指令 子程序返回指令(由堆 棧彈出) 中斷服務(wù)程序返回指令 (由堆棧彈出),小結(jié),系統(tǒng)是通過(guò)把待運(yùn)行程序的地址賦予程序計(jì)數(shù)器PC來(lái)實(shí)現(xiàn)程序的切換的。,任務(wù)代碼,任務(wù)堆棧,內(nèi)存,處理器,任務(wù)運(yùn)行時(shí)與 處理器之間的關(guān)系,處理器通過(guò)兩個(gè)指針寄存器(PC和SP)來(lái)與任務(wù)代碼和任務(wù)堆棧建立聯(lián)系并運(yùn)行它,寄存器組,運(yùn)行環(huán)境包括了兩部分:處理器中的運(yùn)行環(huán)境和內(nèi)存中的運(yùn)行環(huán)境,處理器,多任務(wù)時(shí)的問(wèn)題,?,當(dāng)有多個(gè)任務(wù)時(shí),處理器中的運(yùn)行環(huán)境應(yīng)該怎么辦?,寄存器組,程序運(yùn)行環(huán)境,多任務(wù)時(shí)任務(wù)與處理器 之間關(guān)系的處理,程序,在內(nèi)存中為每個(gè)任務(wù)創(chuàng)建一個(gè)虛擬的處理器(處理器部分的運(yùn)行環(huán)境,由操作系統(tǒng)的
8、調(diào)度器按某種規(guī)則來(lái)進(jìn)行這兩個(gè)復(fù)制工作,寄存器組,寄存器組,也就是說(shuō),任務(wù)的切換是 任務(wù)運(yùn)行環(huán)境的切換,虛擬處理器,虛擬處理器應(yīng)該存儲(chǔ)的主要信息: 1。程序的斷點(diǎn)地址(PC) 2。任務(wù)堆棧指針(SP) 3。程序狀態(tài)字寄存器(PSW) 4。通用寄存器內(nèi)容 5。函數(shù)調(diào)用信息(已存在于堆棧),另外再用一個(gè)數(shù)據(jù)結(jié)構(gòu)保存任務(wù)堆棧 指針(SP),這個(gè)數(shù)據(jù)結(jié)構(gòu)叫做任務(wù) 控制塊,它除了保存任務(wù)堆棧指針之 外還要負(fù)責(zé)保存任務(wù)其他信息。,這些內(nèi)容通常保存在任務(wù)堆棧中,這些內(nèi)容也常叫做任務(wù)的上下文。,任務(wù)控制塊是由操作系統(tǒng)另行構(gòu)造的一個(gè)數(shù)據(jù)結(jié)構(gòu),每個(gè)任務(wù)都有一個(gè)。,任務(wù)控制塊結(jié)構(gòu)的主要成員 typedef struc
9、t os_tcb OS_STK *OSTCBStkPtr; /指向任務(wù)堆棧棧頂?shù)闹羔?INT8U OSTCBStat;/任務(wù)的當(dāng)前狀態(tài)標(biāo)志 INT8U OSTCBPrio; /任務(wù)的優(yōu)先級(jí)別 OS_TCB;,其實(shí),程序切換的關(guān)鍵是 把程序的私有堆棧指針賦 予處理器的堆棧指針SP,實(shí)質(zhì)上系統(tǒng)是通過(guò)SP的切換 來(lái)實(shí)現(xiàn)程序的切換的。,要建立一個(gè)概念:具有 控制塊的程序才是一個(gè) 可以被系統(tǒng)所運(yùn)行的任務(wù)。 程序代碼、私有堆棧、任 務(wù)控制塊是任務(wù)的三要件。 任務(wù)控制塊提供了運(yùn)行環(huán) 境的存儲(chǔ)位置。,任務(wù)的基本概念,把一個(gè)大型任務(wù)分解成多個(gè)小任務(wù),然后在計(jì)算機(jī)中通過(guò)運(yùn)行這些小任務(wù),最終達(dá)到完成大任務(wù)的目的。
10、在C/OS-II中,與上述那些小任務(wù)對(duì)應(yīng)的程序?qū)嶓w就叫做“任務(wù)”(實(shí)質(zhì)上是一個(gè)線(xiàn)程),C/OS-II就是一個(gè)能對(duì)這些小任務(wù)的運(yùn)行進(jìn)行管理和調(diào)度的多任務(wù)操作系統(tǒng)。,從應(yīng)用程序設(shè)計(jì)的角度來(lái)看,C/OS-II的任務(wù)就是一個(gè)用戶(hù)編寫(xiě)的C函數(shù)和與之相關(guān)聯(lián)的一些數(shù)據(jù)結(jié)構(gòu)而構(gòu)成的一個(gè)實(shí)體。,任務(wù)切換過(guò)程,獲得待運(yùn)行任務(wù)的任務(wù)控制塊,如何獲得待運(yùn)行任務(wù)的任務(wù)控制塊?,小結(jié),一個(gè)完整的任務(wù)應(yīng)該有如下三部分: 任務(wù)代碼(程序) 任務(wù)的私有堆棧(用以保護(hù)運(yùn)行環(huán)境) 任務(wù)控制塊(提供私有堆棧也是虛擬處理器的位置) 這些都是任務(wù)方應(yīng)該提供的基本信息。,C/OS-II中 的任務(wù)管理,任務(wù)的狀態(tài)及其轉(zhuǎn)換,正在運(yùn)行的任務(wù),需
11、要等待一段時(shí)間或需要等待一個(gè)事件發(fā)生再運(yùn)行時(shí),該任務(wù)就會(huì)把CPU的使用權(quán)讓給別的任務(wù)而使任務(wù)進(jìn)入等待狀態(tài)。,任務(wù)在沒(méi)有被配備任務(wù)控制塊或被剝奪了任務(wù)控制塊時(shí)的狀態(tài)叫做任務(wù)的睡眠狀態(tài),系統(tǒng)為任務(wù)配備了任務(wù)控制塊且在任務(wù)就緒表中進(jìn)行了就緒登記,這時(shí)任務(wù)的狀態(tài)叫做就緒狀態(tài)。,處于就緒狀態(tài)的任務(wù)如果經(jīng)調(diào)度器判斷獲得了CPU的使用權(quán),則任務(wù)就進(jìn)入運(yùn)行狀態(tài),一個(gè)正在運(yùn)行的任務(wù)一旦響應(yīng)中斷申請(qǐng)就會(huì)中止運(yùn)行而去執(zhí)行中斷服務(wù)程序,這時(shí)任務(wù)的狀態(tài)叫做中斷服務(wù)狀態(tài),前面談到,一個(gè)任務(wù)的任務(wù)控制塊 的主要作用就是保存該任務(wù)的虛擬 處理器的堆棧指針寄存器SP。 其實(shí),隨著任務(wù)管理工作的復(fù)雜性 的提高,它還應(yīng)該保存一些其
12、他信 息。,任務(wù)控制塊任務(wù)在系統(tǒng)中的身份證,由于系統(tǒng)存在著多個(gè)任務(wù),于是 系統(tǒng)如何來(lái)識(shí)別并管理一個(gè)任務(wù)就是 一個(gè)需要解決的問(wèn)題。識(shí)別一個(gè)任務(wù) 的最直接的辦法是為每一個(gè)任務(wù)起一 個(gè)名稱(chēng)。 由于C/OS-II中的任務(wù)都有一個(gè) 惟一的優(yōu)先級(jí)別,因此C/OS-II是用 任務(wù)的優(yōu)先級(jí)來(lái)作為任務(wù)的標(biāo)識(shí)的。 所以,任務(wù)控制塊還要來(lái)保存該 任務(wù)的優(yōu)先級(jí)別。,另外,前面也談到,一個(gè)任務(wù)在 不同的時(shí)刻還處于不同的狀態(tài), 顯然,記錄了任務(wù)狀態(tài)的數(shù)據(jù)也 應(yīng)該保存到任務(wù)控制塊中。,基于上述原因,系統(tǒng)必須為每個(gè)任務(wù)創(chuàng)建 一個(gè)保存與該任務(wù)有關(guān)的相關(guān)信息的數(shù)據(jù) 結(jié)構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)就叫做該任務(wù)的任務(wù) 控制塊(TCB)。,任務(wù)控
13、制塊結(jié)構(gòu)的主要成員 typedef struct os_tcb OS_STK *OSTCBStkPtr; /指向任務(wù)堆棧棧頂?shù)闹羔?INT8U OSTCBStat;/任務(wù)的當(dāng)前狀態(tài)標(biāo)志 INT8U OSTCBPrio; /任務(wù)的優(yōu)先級(jí)別 OS_TCB;,任務(wù)控制塊是不是像 我們?nèi)嗽谝粋€(gè)國(guó)家中 的身份證?(其實(shí), 系統(tǒng)中的所有資源 都應(yīng)該有身份證。),任務(wù)在內(nèi)存中的結(jié)構(gòu),用戶(hù)任務(wù)代碼的 一般結(jié)構(gòu),void MyTask(void *pdata) for (;) 可以被中斷的用戶(hù)代碼; OS_ENTER_CRITICAL( );/進(jìn)入臨界段(關(guān)中斷) 不可以被中斷的用戶(hù)代碼; OS_EXIT_CR
14、ITICAL( ); /退出臨界段(開(kāi)中斷) 可以被中斷的用戶(hù)代碼; ,臨界段,無(wú)限循環(huán),于是可以這樣說(shuō),C/OS-II任務(wù)的代碼結(jié)構(gòu)是一個(gè)可以帶有臨界段的無(wú)限循環(huán)。,系統(tǒng)提供的空閑任務(wù),在多任務(wù)系統(tǒng)運(yùn)行時(shí),系統(tǒng)經(jīng)常會(huì)在某個(gè)時(shí)間內(nèi)無(wú)用戶(hù)任務(wù)可運(yùn)行而處于所謂的空閑狀態(tài),為了使CPU在沒(méi)有用戶(hù)任務(wù)可執(zhí)行的時(shí)候有事可做,C/OS-II提供了一個(gè)叫做空閑任務(wù)OSTaskIdle( )的系統(tǒng)任務(wù),void OSTaskIdle(void* pdata) # if OS_CRITICAL_METHOD = = 3 OS_CPU_SR cpu_sr; #endif pdata = pdata;/防止某些編譯
15、器報(bào)錯(cuò) for(;) OS_ENTER_CRITICAL( );/關(guān)閉中斷 OSdleCtr+;/計(jì)數(shù) OS_EXIT_CRITICAL( );/開(kāi)放中斷 ,空閑任務(wù)只是做了一個(gè)計(jì)數(shù)工作,注意!空閑任務(wù)中沒(méi)有調(diào)用任務(wù)延時(shí)函數(shù),C/OS-II規(guī)定,一個(gè)用戶(hù)應(yīng)用程序必須使用這個(gè)空閑任務(wù),而且這個(gè)任務(wù)是不能用軟件來(lái)刪除的,系統(tǒng)提供的另一個(gè)任務(wù) 統(tǒng)計(jì)任務(wù),C/OS-II提供的另一個(gè)系統(tǒng)任務(wù)是統(tǒng)計(jì)任務(wù)OSTaskStat( )。這個(gè)統(tǒng)計(jì)任務(wù)每秒計(jì)算一次CPU在單位時(shí)間內(nèi)被使用的時(shí)間,并把計(jì)算結(jié)果以百分比的形式存放在變量OSCPUsage中,以便應(yīng)用程序通過(guò)訪(fǎng)問(wèn)它來(lái)了解CPU的利用率,所以這個(gè)系統(tǒng)任務(wù)OS
16、TaskStat( )叫做統(tǒng)計(jì)任務(wù),任務(wù)的優(yōu)先權(quán) 及優(yōu)先級(jí)別,C/OS_II 把任務(wù)的優(yōu)先權(quán)分為64個(gè)優(yōu)先級(jí)別,每一個(gè)級(jí)別都用一個(gè)數(shù)字來(lái)表示。數(shù)字0表示任務(wù)的優(yōu)先級(jí)別最高,數(shù)字越大則表示任務(wù)的優(yōu)先級(jí)別越低,用戶(hù)可以根據(jù)應(yīng)用程序的需要,在文件OS_CFG.H中通過(guò)給表示最低優(yōu)先級(jí)別的常數(shù)OS_LOWEST_PRIO賦值的方法,來(lái)說(shuō)明應(yīng)用程序中任務(wù)優(yōu)先級(jí)別的數(shù)目。該常數(shù)一旦被定義,則意味著系統(tǒng)中可供使用的優(yōu)先級(jí)別為:0,1,2,OS_LOWEST_PRIO,共OS_LOWEST_PRIO+1個(gè),固定地,系統(tǒng)總是把最低優(yōu)先級(jí)別OS_LOWEST_PRIO自動(dòng)賦給空閑任務(wù)。如果應(yīng)用程序中還使用了統(tǒng)計(jì)任
17、務(wù),系統(tǒng)則會(huì)把優(yōu)先級(jí)別OS_LOWEST_PRIO-1自動(dòng)賦給統(tǒng)計(jì)任務(wù),因此用戶(hù)任務(wù)可以使用的優(yōu)先級(jí)別是:0,1,2OS_LOWEST_PRIO-2,共OS_LOWEST_PRIO-1個(gè),任 務(wù) 堆 棧,保存CPU寄存器中的內(nèi)容及存儲(chǔ)任務(wù)私有數(shù)據(jù)的需要,每個(gè)任務(wù)都應(yīng)該配有自己的堆棧,任務(wù)堆棧是任務(wù)的重要的組成部分,在應(yīng)用程序中定義任務(wù)堆棧的棧區(qū)非常簡(jiǎn)單,即定義一個(gè)OS_STK類(lèi)型的一個(gè)數(shù)組并在創(chuàng)建一個(gè)任務(wù)時(shí)把這個(gè)數(shù)組的地址賦給該任務(wù)就可以了。 例如: /定義堆棧的長(zhǎng)度 #defineTASK_STK_SIZE 512 /定義一個(gè)數(shù)組來(lái)作為任務(wù)堆棧 OS_STK TaskStkTASK_STK_
18、SIZE;,typedef unsigned int OS_STK; /這是系統(tǒng)定義的一個(gè)數(shù)據(jù)類(lèi)型,void main(void) OSTaskCreate( MyTask, /任務(wù)的指針 ,在創(chuàng)建用戶(hù)任務(wù)時(shí),要傳遞任務(wù)的堆棧指針和任務(wù)優(yōu)先級(jí)別,使用函數(shù)OSTaskCreate( )創(chuàng)建任務(wù)時(shí),一定要注意所使用的處理器對(duì)堆棧增長(zhǎng)方向的支持是向上的還是向下的,任務(wù)堆棧的初始化,應(yīng)用程序在創(chuàng)建一個(gè)新任務(wù)的時(shí)候,必須把在系統(tǒng)啟動(dòng)這個(gè)任務(wù)時(shí)CPU各寄存器所需要的初始數(shù)據(jù)(任務(wù)指針、任務(wù)堆棧指針、程序狀態(tài)字等等),事先存放在任務(wù)的堆棧中,C/OS-II在創(chuàng)建任務(wù)函數(shù)OSTaskCreate( )中通過(guò)調(diào)
19、用任務(wù)堆棧初始化函數(shù)OSTaskStkInit( )來(lái)完成任務(wù)堆棧初始化工作的,它的原型如下: OS_STK *OSTaskStkInit( void (*task)(void *pd), void *pdato, OS_STK *ptos, INT16U opt );,由于各種處理器的寄存器及對(duì)堆棧的操作方式不盡相同,因此該函數(shù)需要用戶(hù)在進(jìn)行C/OS-II的移植時(shí),按所使用的處理器由用戶(hù)來(lái)編寫(xiě)。實(shí)現(xiàn)這個(gè)函數(shù)的具體細(xì)節(jié),將在本書(shū)有關(guān)C/OS-II移植的章節(jié)中做進(jìn) 一步的介紹,其實(shí),任務(wù)堆棧的初始化就是對(duì)該任務(wù)的虛擬處理器的初始化(復(fù)位)。,任務(wù)控制塊 (OS_TCB) 及任務(wù)控制塊鏈表,C/O
20、S-II用來(lái)記錄任務(wù)的堆棧指針、任務(wù)的當(dāng)前狀態(tài)、任務(wù)的優(yōu)先級(jí)別等一些與任務(wù)管理有關(guān)的屬性的表就叫做任務(wù)控制塊,任務(wù)控制塊就相當(dāng)于是一個(gè)任務(wù)的身份證,沒(méi)有任務(wù)控制塊的任務(wù)是不能被系統(tǒng)承認(rèn)和管理的,任務(wù)控制塊結(jié)構(gòu)的主要成員 typedef struct os_tcb OS_STK *OSTCBStkPtr; /指向任務(wù)堆棧棧頂?shù)闹羔?struct os_tcb *OSTCBNext;/指向后一個(gè)任務(wù)控制塊的指針 struct os_tcb *OSTCBPrev; /指向前一個(gè)任務(wù)控制塊的指針 INT16U OSTCBDly; /任務(wù)等待的時(shí)限(節(jié)拍數(shù)) INT8U OSTCBStat;/任務(wù)的當(dāng)前
21、狀態(tài)標(biāo)志 INT8U OSTCBPrio; /任務(wù)的優(yōu)先級(jí)別 OS_TCB;,任務(wù)控制塊鏈表,空任務(wù)控制塊鏈表,當(dāng)應(yīng)用程序調(diào)用函數(shù)OSTaskCreate( )創(chuàng)建一個(gè)任務(wù)時(shí),這個(gè)函數(shù)會(huì)調(diào)用系統(tǒng)函數(shù)OSTCBInit ( )來(lái)為任務(wù)控制塊進(jìn)行初始化。這個(gè)函數(shù)首先為被創(chuàng)建任務(wù)從空任務(wù)控制塊鏈表獲取一個(gè)任務(wù)控制塊,然后用任務(wù)的屬性對(duì)任務(wù)控制塊各個(gè)成員進(jìn)行賦值,最后再把這個(gè)任務(wù)控制塊鏈入到任務(wù)控制塊鏈表的頭部,當(dāng)進(jìn)行系統(tǒng)初始化時(shí),初始化函數(shù)會(huì)按用戶(hù)提供的任務(wù)數(shù)為系統(tǒng)創(chuàng)建具有相應(yīng)數(shù)量的任務(wù)控制塊并把它們鏈接為一個(gè)鏈表。 由于這些任務(wù)控制塊還沒(méi)有對(duì)應(yīng)的任務(wù),故這個(gè)鏈表叫做空任務(wù)塊鏈表。即相當(dāng)于是一些空白
22、的身份證。,任務(wù)就緒表 及 任務(wù)調(diào)度,多任務(wù)操作系統(tǒng)的核心工作就是任務(wù)調(diào)度。 所謂調(diào)度,就是通過(guò)一個(gè)算法在多個(gè)任務(wù)中確定該運(yùn)行的任務(wù),做這項(xiàng)工作的函數(shù)就叫做調(diào)度器。 C/OS_II進(jìn)行任務(wù)調(diào)度的思想是 “近似地每時(shí)每刻總是讓優(yōu)先級(jí)最高的就緒任務(wù)處于運(yùn)行狀態(tài)” 。為了保證這一點(diǎn),它在系統(tǒng)或用戶(hù)任務(wù)調(diào)用系統(tǒng)函數(shù)及執(zhí)行中斷服務(wù)程序結(jié)束時(shí)總是調(diào)用調(diào)度器,來(lái)確定應(yīng)該運(yùn)行的任務(wù)并運(yùn)行它 。,C/OS_II進(jìn)行任務(wù)調(diào)度的依據(jù)就是任務(wù)就緒表,為了能夠使系統(tǒng)清楚地知道,系統(tǒng)中哪些任務(wù)已經(jīng)就緒,哪些還沒(méi)有就緒,C/OS_II在RAM中設(shè)立了一個(gè)記錄表,系統(tǒng)中的每個(gè)任務(wù)都在這個(gè)表中占據(jù)一個(gè)位置,并用這個(gè)位置的狀態(tài)(
23、1或者0)來(lái)表示任務(wù)是否處于就緒狀態(tài),這個(gè)表就叫做任務(wù)就緒狀態(tài)表,簡(jiǎn)稱(chēng)叫任務(wù)就緒表,任務(wù)就緒表就是一個(gè)二維數(shù)組OSRdyTbl ,為加快訪(fǎng)問(wèn)任務(wù)就緒表的 速度,系統(tǒng)定義了一個(gè)變 量OSRdyGrp來(lái)表明就緒表 每行中是否存在就緒任務(wù)。,OSRdyTbl ,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0
24、1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,1/0 1/0 1/0 1/0 1/0 1/0 1/0 1/0,OSRdyGrp,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ù)就緒表的示意圖,0,1,2,3,4,5,6,7,x,y,0,1,2,3,4,5,6,7,OSRdyGrp,D7 D6 D5 D4 D3 D2 D1 D0,1,1,1,1,0,0,0,0,prio=29,D7 D6 D5 D4 D3 D2 D1 D0,1,D7 D6 D5 D4 D3 D2 D1 D
25、0,1,OSRdyTbl3 ,把prio為29的任務(wù)置為就緒狀態(tài),Y,X,OSRdyGrp | =OSMapTblprio3;,OSRdyTblprio3 | = OSMapTblprio,在程序中,可以用類(lèi)似下面的代碼把優(yōu)先級(jí)別為prio的任務(wù)置為就緒狀態(tài): OSRdyGrp | =OSMapTblprio3; OSRdyTblprio3 | = OSMapTblprio,OSRdyGrp,D7 D6 D5 D4 D3 D2 D1 D0,1,1,1,1,0,0,0,0,prio=29,D7 D6 D5 D4 D3 D2 D1 D0,1,D7 D6 D5 D4 D3 D2 D1 D0,1,OS
26、RdyTbly ,x = OSUnMapTalOSRdyTbly;,1,1,0,0,0,0,0,0,0,0,0,0,0,0,y = OSUnMapTalOSRdyGrp;,圖5-6 在就緒表中查找最高優(yōu)先級(jí)別任務(wù)的過(guò)程,從任務(wù)就緒表中獲取優(yōu)先級(jí)別最高的就緒任務(wù)可用如下類(lèi)似的代碼: y = OSUnMapTalOSRdyGrp; /D5、D4、D3位 x = OSUnMapTalOSRdyTbly; /D2、D1、D0位 prio = (y3)+x;/優(yōu)先級(jí)別 或 y = OSUnMapTblOSRdyGrp; prio = (INT8U)(y 3) + OSUnMapTblOSRdyTbly)
27、;,優(yōu)先級(jí)判定表OSUnMapTbl256(os_core.c),INT8U const OSUnMapTbl = 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,
28、 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, 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,
29、 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, 0, 2, 0, 1, 0 ;,舉例: 如OSRdyGrp的值為00101000B,即0X28,則查得OSUnMapTblOSRdyGrp的值是3,它相應(yīng)于OSRdyGrp中的第
30、3位置1; 如OSRdyTbl3的值是11100100B,即0XE4,則查OSUnMapTblOSRdyTbl3的值是2,則進(jìn)入就緒態(tài)的最高任務(wù)優(yōu)先級(jí) Prio=3*8+2=26,小結(jié),系統(tǒng)通過(guò)查找任務(wù)就緒表來(lái) 獲取待運(yùn)行任務(wù)的優(yōu)先級(jí),優(yōu)先級(jí),任務(wù)切換過(guò)程,獲得待運(yùn)行任務(wù)的任務(wù)控制塊,如何獲得待運(yùn)行任務(wù)的任務(wù)控制塊?,根據(jù)就緒表獲得待運(yùn)行任務(wù)的任務(wù)控制塊指針,其實(shí),調(diào)度器在進(jìn)行調(diào)度時(shí),在這個(gè)位置還要進(jìn)行一下判斷:究竟是待運(yùn)行任務(wù)是否為當(dāng)前任務(wù),如果是,則不切換;如果不是才切換,而且還要保存被中止任務(wù)的運(yùn)行環(huán)境。,1 任務(wù)切換宏 OS_TASK_SW( ),任務(wù)切換就是中止正在運(yùn)行的任務(wù)(當(dāng)前任
31、務(wù)),轉(zhuǎn)而去運(yùn)行另外一個(gè)任務(wù)的操作,當(dāng)然這個(gè)任務(wù)應(yīng)該是就緒任務(wù)中優(yōu)先級(jí)別最高的那個(gè)任務(wù),先保護(hù)被中止任務(wù)的斷點(diǎn)數(shù)據(jù),后恢復(fù)待運(yùn)行任務(wù)的斷點(diǎn)數(shù)據(jù),不要企圖用PUSH和POP指令來(lái)使程序計(jì)數(shù)器PC壓棧和出棧,因?yàn)闆](méi)有這樣的指令。 只好變通一下了。 中斷動(dòng)作和過(guò)程調(diào)用指令可以使PC壓棧; 中斷返回指令可以使PC出棧。 因此任務(wù)切換OSCtxSw( )必定是一個(gè)中斷服務(wù)程序。,需要由宏OS_TASK_SW( ) 來(lái)引發(fā)一次中斷或者一次調(diào)用來(lái)使OSCtxSw( ) 執(zhí)行任務(wù)切換工作,調(diào)度時(shí)機(jī),很容易想到的調(diào)度時(shí)機(jī)就 是定時(shí)調(diào)度。,對(duì)于實(shí)時(shí)系統(tǒng)來(lái)說(shuō),應(yīng)該盡 可能地實(shí)現(xiàn)即時(shí)調(diào)度。,用函數(shù)OSTaskCrea
32、te( ) 創(chuàng)建任務(wù),應(yīng)用程序通過(guò)調(diào)用OSTaskCreate( ) 函數(shù)來(lái)創(chuàng)建一個(gè)任務(wù),OSTaskCreate( )函數(shù)的原型如下: INT8U OSTaskCreate ( void (*task)(void *pd),/指向任務(wù)的指針 void *pdata,/傳遞給任務(wù)的參數(shù) OS_STK *ptos,/指向任務(wù)堆棧棧頂?shù)闹羔?INT8U prio/任務(wù)的優(yōu)先級(jí) ),創(chuàng)建任務(wù) 的一般方法,一般來(lái)說(shuō),任務(wù)可以在調(diào)用函數(shù)OSStart( )啟動(dòng)任務(wù)調(diào)度之前來(lái)創(chuàng)建,也可以在任務(wù)中來(lái)創(chuàng)建。但是,C/OS-II有一個(gè)規(guī)定:在調(diào)用啟動(dòng)任務(wù)函數(shù)OSStart( )之前,必須已經(jīng)創(chuàng)建了至少一個(gè)任務(wù)。
33、因此,人們習(xí)慣上在調(diào)用函數(shù)OSStart( )之前先創(chuàng)建一個(gè)任務(wù),并賦予它最高的優(yōu)先級(jí)別,從而使它成為起始任務(wù)。然后在這個(gè)起始任務(wù)中,再創(chuàng)建其他各任務(wù)。 如果要使用系統(tǒng)提供的統(tǒng)計(jì)任務(wù),則統(tǒng)計(jì)任務(wù)的初始化函數(shù)也必須在這個(gè)起始任務(wù)中來(lái)調(diào)用,void main(void) OSInit( );/對(duì)C/OS-II進(jìn)行初始化 OSTaskCreate (TaskStart,);/創(chuàng)建任務(wù)TaskStart OSStart( );/開(kāi)始多任務(wù)調(diào)度 void TaskStart(void*pdata) /在這個(gè)位置安裝并啟動(dòng)C/OS-II的時(shí)鐘 OSStatInit( );/初始化統(tǒng)計(jì)任務(wù) /在這個(gè)位置創(chuàng)建
34、其他任務(wù) for(;) 起始任務(wù)TaskStart的代碼 ,C/OS-II的 初始化,在使用C/OS-II的所有服務(wù)之前,必須要調(diào)用C/OS-II的初始化函數(shù)OSInit( )對(duì)C/OS-II自身的運(yùn)行環(huán)境進(jìn)行初始化。,函數(shù)OSInit( )將對(duì)C/OS-II的所有的全局變量和數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化,同時(shí)創(chuàng)建空閑任務(wù)OSTaskIdle,并賦之以最低的優(yōu)先級(jí)別和永遠(yuǎn)的就緒狀態(tài)。如果用戶(hù)應(yīng)用程序還要使用統(tǒng)計(jì)任務(wù)的話(huà)(常數(shù)OS_TASK_STAT_EN=1),則OSInit( )還要以?xún)?yōu)先級(jí)別為OS_LOWEST_PRIO-1來(lái)創(chuàng)建統(tǒng)計(jì)任務(wù),初始化函數(shù)OSInit( )對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化時(shí),主要要?jiǎng)?chuàng)
35、建包括空任務(wù)控制塊鏈表在內(nèi)的5個(gè)空數(shù)據(jù)緩沖區(qū)。同時(shí),為了可以快速地查詢(xún)?nèi)蝿?wù)控制塊鏈表中的各個(gè)元素,初始化函數(shù)OSInit( )還要?jiǎng)?chuàng)建一個(gè)數(shù)組OSTCBPrioTblOS_LOWEST_PRIO + 1,在這個(gè)數(shù)組中,按任務(wù)的優(yōu)先級(jí)別的順序把任務(wù)控制塊的指針存放在了對(duì)應(yīng)的元素中,C/OS-II的啟動(dòng),C/OS-II進(jìn)行任務(wù)的管理是從調(diào)用啟動(dòng)函數(shù)OSStart( )開(kāi)始的,當(dāng)然其前提條件是在調(diào)用該函數(shù)之前至少創(chuàng)建了一個(gè)用戶(hù)任務(wù),第3章 C/OS-的中斷和時(shí)鐘,本章主要內(nèi)容:,C/OS-II系統(tǒng) 響應(yīng)中斷的過(guò)程,C/OS-II系統(tǒng)響應(yīng)中斷的過(guò)程為:系統(tǒng)接收到中斷請(qǐng)求后,這時(shí)如果CPU處于中斷允許狀
36、態(tài)(即中斷是開(kāi)放的),系統(tǒng)就會(huì)中止正在運(yùn)行的當(dāng)前任務(wù),而按照中斷向量的指向轉(zhuǎn)而去運(yùn)行中斷服務(wù)子程序;當(dāng)中斷服務(wù)子程序的運(yùn)行結(jié)束后,系統(tǒng)將會(huì)根據(jù)情況返回到被中止的任務(wù)繼續(xù)運(yùn)行或者轉(zhuǎn)向運(yùn)行另一個(gè)具有更高優(yōu)先級(jí)別的就緒任務(wù)。,注意!中斷服務(wù)子程序運(yùn)行結(jié)束之后,系統(tǒng)將會(huì)根據(jù)情況進(jìn)行一次任務(wù)調(diào)度去運(yùn)行優(yōu)先級(jí)別最高的就緒任務(wù),而并不是一定要接續(xù)運(yùn)行被中斷的任務(wù)的。,中斷請(qǐng)求,關(guān)閉中斷,轉(zhuǎn)到中斷向量,保存CPU寄存器,通知內(nèi)核退出ISR,ISR給任務(wù)發(fā)信號(hào),中斷返回,恢復(fù)CPU寄存器,中斷響應(yīng),中斷恢復(fù),中斷恢復(fù),任務(wù)響應(yīng)時(shí)間,任務(wù)響應(yīng)時(shí)間,中斷的響應(yīng)過(guò)程,無(wú)新高級(jí)任務(wù)則返回原任務(wù),通知內(nèi)核進(jìn)入ISR,vo
37、id OSIntEnter (void) if (OSRunning = TRUE) if (OSIntNesting 255) OSIntNesting+; /中斷嵌套層數(shù)計(jì)數(shù)器加一 ,void OSIntExit (void) #if OS_CRITICAL_METHOD = 3 OS_CPU_SR cpu_sr; #endif if (OSRunning = TRUE) OS_ENTER_CRITICAL( ); if (OSIntNesting 0) OSIntNesting-;/中斷嵌套層數(shù)計(jì)數(shù)器減一 if (OSIntNesting = 0) ,在中斷服務(wù)程序中調(diào)用的負(fù)責(zé)任務(wù)切換工
38、作的函數(shù)OSIntCtxSw( )叫做中斷級(jí)任務(wù)切換函數(shù),OSIntCtxSw( ) OSTCBCur = OSTCBHighRdy; /任務(wù)控制塊的切換 OSPrioCur=OSPrioHighRdy; SP = OSTCBHighRdy-OSTCBStkPtr;/SP指向待運(yùn)行任務(wù)堆棧 用出棧指令把R1,R2,彈入CPU的通用寄存器; RETI;/中斷返回,使PC指向待運(yùn)行任務(wù) ,應(yīng)用程序中的臨界段,在應(yīng)用程序中經(jīng)常有一些代碼段必須不受任何干擾地連續(xù)運(yùn)行,這樣的代碼段叫做臨界段。因此,為了使臨界段在運(yùn)行時(shí)不受中斷所打斷,在臨界段代碼前必須用關(guān)中斷指令使CPU屏蔽中斷請(qǐng)求,而在臨界段代碼后必
39、須用開(kāi)中斷指令解除屏蔽使得CPU可以響應(yīng)中斷請(qǐng)求,由于各廠(chǎng)商生產(chǎn)的CPU和C編譯器的關(guān)中斷和開(kāi)中斷的方法和指令不盡相同,為增強(qiáng)C/OS-II的可移植性(即在C/OS-II的各個(gè)C函數(shù)中盡可能地不出現(xiàn)匯編語(yǔ)言代碼),C/OS-II用兩個(gè)宏來(lái)實(shí)現(xiàn)中斷的開(kāi)放和關(guān)閉,而把與系統(tǒng)的硬件相關(guān)的關(guān)中斷和開(kāi)中斷的指令分別封裝在這兩個(gè)宏中: OS_ENTER_CRITICAL( ) OS_EXIT_CRITICAL( ),第一種方法最簡(jiǎn)單,即直接使用處理器的開(kāi)中斷和關(guān)中斷指令來(lái)實(shí)現(xiàn)宏,這時(shí)需要令常數(shù)OS_CRITICAL_METHOD=1。其示意性代碼為: #define OS_ENTER_CRITICAL(
40、) asm(“DI”) 關(guān)中斷 #define OS_EXIT_CRITICAL( ) asm(“EI”) 開(kāi)中斷,第二種方法稍微復(fù)雜一些,但可以使CPU中斷允許標(biāo)志的狀態(tài),在臨界段前和臨界段后不發(fā)生改變。在宏OS_ENTER_CRITICAL( )中,把CPU的允許中斷標(biāo)志保持到堆棧中,然后再關(guān)閉中斷,這樣在臨界段結(jié)束時(shí),即在調(diào)用宏OS_EXIT_CRITICAL( )時(shí)只要把堆棧中保存的CPU允許中斷狀態(tài)恢復(fù)就可以了。這兩個(gè)宏的示意性代碼如下: #define OS_ENTER_CRITICAL( ) asm(“PUSHPSW”) /*通過(guò)保存程序狀態(tài)字來(lái)保存中 斷允許標(biāo)志*/ asm(“
41、DI”) /關(guān)中斷 #define OS_EXIT_CRITICAL( ) asm(“POPPSW”) /恢復(fù)中斷允許標(biāo)志,C/OS-II的系統(tǒng)時(shí)鐘,C/OS-II與大多數(shù)計(jì)算機(jī)系統(tǒng)一樣,用硬件定時(shí)器產(chǎn)生一個(gè)周期為ms級(jí)的周期性中斷來(lái)實(shí)現(xiàn)系統(tǒng)時(shí)鐘,最小的時(shí)鐘單位就是兩次中斷之間相間隔的時(shí)間,這個(gè)最小時(shí)鐘單位叫做時(shí)鐘節(jié)拍(Time Tick)。 硬件定時(shí)器以時(shí)鐘節(jié)拍為周期定時(shí)地產(chǎn)生中斷,該中斷的中斷服務(wù)程序叫做OSTickISR( )。中斷服務(wù)程序通過(guò)調(diào)用函數(shù)OSTimeTick( )來(lái)完成系統(tǒng)在每個(gè)時(shí)鐘節(jié)拍時(shí)需要做的工作。,void OSTickISR(void) 保存CPU寄存器; 調(diào)用OS
42、IntEnter( );/記錄中斷嵌套層數(shù) if (OSIntNesting = = 1; OSTCBCur-OSTCBStkPtr = SP; /保存堆棧指針 調(diào)用OSTimeTick( );/節(jié)拍處理 清除中斷; 開(kāi)中斷; 調(diào)用OSIntExit( );/中斷嵌套層數(shù)減一 恢復(fù)CPU寄存器; 中斷返回; ,這是系統(tǒng)時(shí)鐘中斷服務(wù)程序,void OSTimeTick (void) OSTimeTickHook( ); OSTime+;/記錄節(jié)拍數(shù) if (OSRunning = = TRUE) ptcb = OSTCBList; while (ptcb-OSTCBPrio != OS_IDLE
43、_PRIO) OS_ENTER_CRITICAL( ); if (ptcb-OSTCBDly != 0) if (-ptcb-OSTCBDly = = 0) /任務(wù)的延時(shí)時(shí)間減一 if (ptcb-OSTCBStat ,時(shí)鐘節(jié)拍服務(wù)函數(shù),函數(shù)OSTimeTick( )的任務(wù),就是在每個(gè)時(shí)鐘節(jié)拍了解每個(gè)任務(wù)的延時(shí)狀態(tài),使其中已經(jīng)到了延時(shí)時(shí)限的非掛起任務(wù)進(jìn)入就緒狀態(tài)。,任務(wù)的延時(shí),由于嵌入式系統(tǒng)的任務(wù)是一個(gè)無(wú)限循環(huán),并且C/OS-II還是一個(gè)搶占式內(nèi)核,所以為了使高優(yōu)先級(jí)別的任務(wù)不至于獨(dú)占CPU,可以給其他任務(wù)優(yōu)先級(jí)別較低的任務(wù)獲得CPU使用權(quán)的機(jī)會(huì),C/OS-II規(guī)定:除了空閑任務(wù)之外的所有任務(wù)
44、必須在任務(wù)中合適的位置調(diào)用系統(tǒng)提供的函數(shù)OSTimeDly( ),使當(dāng)前任務(wù)的運(yùn)行延時(shí)(暫停)一段時(shí)間并進(jìn)行一次任務(wù)調(diào)度,以讓出CPU的使用權(quán)。,void OSTimeDly (INT16U ticks) #if OS_CRITICAL_METHOD = = 3 OS_CPU_SR cpu_sr; #endif if (ticks 0) OS_ENTER_CRITICAL( ); if (OSRdyTblOSTCBCur-OSTCBY /調(diào)用調(diào)度函數(shù) ,這是系統(tǒng)提供的延時(shí)函數(shù),其他用來(lái)管理時(shí)間的函數(shù),INT8U OSTimeDlyResume( INT8U prio); INT32U OSTi
45、meGet( void ); void OSTimeSet( INT32U ticks );,取消任務(wù)延時(shí)函數(shù),獲得系統(tǒng)時(shí)間函數(shù),設(shè)置系統(tǒng)時(shí)間函數(shù),第4章 任務(wù)的同步與通信,系統(tǒng)中的多個(gè)任務(wù)在運(yùn)行時(shí),經(jīng)常需要互相無(wú)沖突地訪(fǎng)問(wèn)同一個(gè)共享資源,或者需要互相支持和依賴(lài),甚至有時(shí)還要互相加以必要的限制和制約,才保證任務(wù)的順利運(yùn)行。因此,操作系統(tǒng)必須具有對(duì)任務(wù)的運(yùn)行進(jìn)行協(xié)調(diào)的能力,從而使任務(wù)之間可以無(wú)沖突、流暢地同步運(yùn)行,而不致導(dǎo)致災(zāi)難性的后果。 與人們依靠通信來(lái)互相溝通,從而使人際關(guān)系和諧、工作順利的做法一樣,計(jì)算機(jī)系統(tǒng)是依靠任務(wù)之間的良好通信來(lái)保證任務(wù)與任務(wù)的同步的。,例如,兩個(gè)任務(wù):任務(wù)A和任務(wù)B
46、,它們需要通過(guò)訪(fǎng)問(wèn)同一個(gè)數(shù)據(jù)緩沖區(qū)合作完成一項(xiàng)工作,任務(wù)A負(fù)責(zé)向緩沖區(qū)寫(xiě)入數(shù)據(jù),任務(wù)B負(fù)責(zé)從緩沖區(qū)讀取該數(shù)據(jù)。顯然,當(dāng)任務(wù)A還未向緩沖區(qū)寫(xiě)入數(shù)據(jù)時(shí)(緩沖區(qū)為空時(shí)),任務(wù)B因不能從緩沖區(qū)得到有效數(shù)據(jù)而應(yīng)該處于等待狀態(tài),只有等任務(wù)A向緩沖區(qū)寫(xiě)入了數(shù)據(jù)之后,才應(yīng)該通知任務(wù)B去取數(shù)據(jù)。,例如,任務(wù)A和任務(wù)B共享一臺(tái)打印機(jī),如果系統(tǒng)已經(jīng)把打印機(jī)分配給了任務(wù)A,則任務(wù)B因不能獲得打印機(jī)的使用權(quán)而應(yīng)該處于等待狀態(tài),只有當(dāng)任務(wù)A把打印機(jī)釋放后,系統(tǒng)才能喚醒任務(wù)B使其獲得打印機(jī)的使用權(quán)。如果這兩個(gè)任務(wù)不這樣做,那么也會(huì)造成極大的混亂 。,總之,多個(gè)任務(wù)共享同一資源或有工作順序要求時(shí),在正式工作之前要互相打招呼
47、。 黃宏:別走??! 宋丹丹:我自己的腿,我愛(ài)走就走,你管不著! 黃宏:腿是你自己的,但手是咱倆的呀!,事件,任務(wù)間的同步依賴(lài)于任務(wù)間的通信。在C/OS-II中,是使用信號(hào)量、郵箱(消息郵箱)和消息隊(duì)列這些被稱(chēng)作事件的中間環(huán)節(jié)來(lái)實(shí)現(xiàn)任務(wù)之間的通信的。,一個(gè)簡(jiǎn)單的信號(hào)量,1/0,收信方,發(fā)信方,共享資源,事件控制塊,為了把描述事件的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一起來(lái),C/OS-II使用叫做事件控制塊ECB的數(shù)據(jù)結(jié)構(gòu)來(lái)描述諸如信號(hào)量、郵箱(消息郵箱)和消息隊(duì)列這些事件。事件控制塊中包含包括等待任務(wù)表在內(nèi)的所有有關(guān)事件的數(shù)據(jù),typedef struct INT8U OSEventType;/事件的類(lèi)型 INT16U
48、OSEventCnt;/信號(hào)量計(jì)數(shù)器 void *OSEventPtr;/消息或消息隊(duì)列的指針 INT8U OSEventGrp;/等待事件的任務(wù)組 INT8U OSEventTblOS_EVENT_TBL_SIZE;/任務(wù)等待表 OS_EVENT;,把一個(gè)任務(wù)置于等待狀態(tài)要調(diào)用OS_EventTaskWait( )函數(shù)。該函數(shù)的原型為: void OS_EventTaskWait ( OS_EVENT *pevent/事件控制塊的指針 ); 函數(shù)OS_EventTaskWait ( ),將在任務(wù)調(diào)用函數(shù)OSPend( ) 請(qǐng)求一個(gè)事件時(shí),被OSPend( )所調(diào)用。,如果一個(gè)正在等待的任務(wù)具
49、備了可以運(yùn)行的條件,那么就要使它進(jìn)入就緒狀態(tài)。這時(shí)要調(diào)用OS_EventTaskRdy( )函數(shù)。該函數(shù)的作用就是把調(diào)用這個(gè)函數(shù)的任務(wù)在任務(wù)等待表中的位置清0(解除等待狀態(tài))后,再把任務(wù)在任務(wù)就緒表中對(duì)應(yīng)的位置1,然后引發(fā)一次任務(wù)調(diào)度。 OS_EventTaskRdy( )函數(shù)的原型為: INT8U OS_EventTaskRdy ( OS_EVENT *pevent, /事件控制塊的指針 void *msg, /未使用 INT8U msk/清除TCB狀態(tài)標(biāo)志掩碼 ); 函數(shù)OS_EventTaskRdy ( )將在任務(wù)調(diào)用函數(shù)OSPost ( ) 發(fā)送一個(gè)事件時(shí),被函數(shù)OSPost ( )所
50、調(diào)用。,如果一個(gè)正在等待事件的任務(wù)已經(jīng)超過(guò)了等待的時(shí)間,卻仍因?yàn)闆](méi)有獲取事件等原因而未具備可以運(yùn)行的條件,卻又要使它進(jìn)入就緒狀態(tài),這時(shí)要調(diào)用OS_EventTO( )函數(shù)。 OS_EventTO( )函數(shù)的原型為: void OS_EventTO ( OS_EVENT *pevent /事件控制塊的指針 ); 函數(shù)OS_EventTO ( )將在任務(wù)調(diào)用OSPend( ) 請(qǐng)求一個(gè)事件時(shí),被函數(shù)OSPend( )所調(diào)用。,空事件控制塊鏈表,在C/OS-II初始化時(shí),系統(tǒng)會(huì)在初始化函數(shù)OSInit( )中按應(yīng)用程序使用事件的總數(shù)OS_MAX_EVENTS(在文件OS_CFG.H中定義),創(chuàng)建OS
51、_MAX_EVENTS個(gè)空事件控制塊并借用成員OSEventPtr作為鏈接指針,把這些空事件控制塊鏈接成一個(gè)單向鏈表。由于鏈表中的所有控制塊尚未與具體事件相關(guān)聯(lián),故該鏈表叫做空事件控制塊鏈表。以后,每當(dāng)應(yīng)用程序創(chuàng)建一個(gè)事件時(shí),系統(tǒng)就會(huì)從鏈表中取出一個(gè)空事件控制塊,并對(duì)它進(jìn)行初始化以描述該事件。而當(dāng)應(yīng)用程序刪除一個(gè)事件時(shí),就會(huì)將該事件的控制塊歸還給空事件控制塊鏈表,信號(hào)量及其操作,在使用信號(hào)量之前,應(yīng)用程序必須調(diào)用函數(shù)OSSemCreate( )來(lái)創(chuàng)建一個(gè)信號(hào)量,OSSemCreate( )的原型為: OS_EVENT *OSSemCreate ( INT16U cnt/信號(hào)量計(jì)數(shù)器初值 );
52、函數(shù)的返回值為已創(chuàng)建的信號(hào)量的指針。,任務(wù)通過(guò)調(diào)用函數(shù)OSSemPend( )請(qǐng)求信號(hào)量,函數(shù)OSSemPend( )的原型如下: void OSSemPend ( OS_EVENT *pevent,/信號(hào)量的指針 INT16U timeout, /等待時(shí)限 INT8U *err);/錯(cuò)誤信息 參數(shù)pevent是被請(qǐng)求信號(hào)量的指針。 為防止任務(wù)因得不到信號(hào)量而處于長(zhǎng)期的等待狀態(tài),函數(shù)OSSemPend允許用參數(shù)timeout設(shè)置一個(gè)等待時(shí)間的限制,當(dāng)任務(wù)等待的時(shí)間超過(guò)timeout時(shí)可以結(jié)束等待狀態(tài)而進(jìn)入就緒狀態(tài)。如果參數(shù)timeout被設(shè)置為0,則表明任務(wù)的等待時(shí)間為無(wú)限長(zhǎng)。,任務(wù)獲得信號(hào)量
53、,并在訪(fǎng)問(wèn)共享資源結(jié)束以后,必須要釋放信號(hào)量,釋放信號(hào)量也叫做發(fā)送信號(hào)量,發(fā)送信號(hào)量需調(diào)用函數(shù)OSSemPost ( )。OSSemPost ( )函數(shù)在對(duì)信號(hào)量的計(jì)數(shù)器操作之前,首先要檢查是否還有等待該信號(hào)量的任務(wù)。如果沒(méi)有,就把信號(hào)量計(jì)數(shù)器OSEventCnt加一;如果有,則調(diào)用調(diào)度器OS_Sched( )去運(yùn)行等待任務(wù)中優(yōu)先級(jí)別最高的任務(wù)。 函數(shù)OSSemPost ( )的原型為: INT8U OSSemPost ( OS_EVENT *pevent/信號(hào)量的指針 ); 調(diào)用函數(shù)成功后,函數(shù)返回值為OS_ON_ERR,否則會(huì)根據(jù)具體錯(cuò)誤返回OS_ERR_EVENT_TYPE、OS_SEM
54、_OVF。,應(yīng)用程序如果不需要某個(gè)信號(hào)量了,那么可以調(diào)用函數(shù)OSSemDel( )來(lái)刪除該信號(hào)量,這個(gè)函數(shù)的原型為: OS_EVENT *OSSemDel ( OS_EVENT *pevent, /信號(hào)量的指針 INT8U opt, /刪除條件選項(xiàng) INT8U *err/錯(cuò)誤信息 );,互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn),在可剝奪型內(nèi)核中,當(dāng)任務(wù)以獨(dú)占方式使用共享資源時(shí),會(huì)出現(xiàn)低優(yōu)先級(jí)任務(wù)先于高優(yōu)先級(jí)任務(wù)而被運(yùn)行的現(xiàn)象,這種現(xiàn)象叫做任務(wù)優(yōu)先級(jí)反轉(zhuǎn)。在一般情況下是不允許出現(xiàn)這種任務(wù)優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象的,下面就對(duì)優(yōu)先級(jí)的反轉(zhuǎn)現(xiàn)象做一個(gè)詳細(xì)的分析,以期找出原因及解決方法。,圖4-15描述了A、B、C三個(gè)任務(wù)的
55、運(yùn)行情況。其中,任務(wù)A的優(yōu)先級(jí)別高于任務(wù)B,任務(wù)B的優(yōu)先級(jí)別高于任務(wù)C。任務(wù)A和任務(wù)C都要使用同一個(gè)共享資源S,而用于保護(hù)該資源的信號(hào)量在同一時(shí)間只能允許一個(gè)任務(wù)以獨(dú)占的方式對(duì)該資源進(jìn)行訪(fǎng)問(wèn),即這個(gè)信號(hào)量是一個(gè)互斥型信號(hào)量。,通過(guò)例子可以發(fā)現(xiàn),使用信號(hào)量的任務(wù)是否能夠運(yùn)行是受任務(wù)的優(yōu)先級(jí)別和是否占用信號(hào)量?jī)蓚€(gè)條件約束的,而信號(hào)量的約束高于優(yōu)先級(jí)別的約束。于是當(dāng)出現(xiàn)低優(yōu)先級(jí)別的任務(wù)與高優(yōu)先級(jí)別的任務(wù)使用同一個(gè)信號(hào)量,而系統(tǒng)中還存有別的中等優(yōu)先級(jí)別的任務(wù)時(shí),如果低優(yōu)先級(jí)別的任務(wù)先獲得了信號(hào)量,就會(huì)使高級(jí)別的任務(wù)處于等待狀態(tài),而那些不使用該信號(hào)量的中等級(jí)別的任務(wù)卻可以剝奪低優(yōu)先級(jí)別的任務(wù)的CPU使用
56、權(quán)而先于高優(yōu)先級(jí)別的任務(wù)而運(yùn)行了。,解決問(wèn)題的辦法之一,是使獲得信號(hào)量任務(wù)的優(yōu)先級(jí)別在使用共享資源期間暫時(shí)提升到所有任務(wù)最高優(yōu)先級(jí)的高一個(gè)級(jí)別上,以使該任務(wù)不被其他的任務(wù)所打斷,從而能盡快地使用完共享資源并釋放信號(hào)量,然后在釋放了信號(hào)量之后再恢復(fù)該任務(wù)原來(lái)的優(yōu)先級(jí)別。,互斥型信號(hào)量,在描述互斥型信號(hào)量的事件控制塊中,除了成員OSEventType要賦以常數(shù)OS_EVENT_TYPE_MUTEX以表明這是一個(gè)互斥型信號(hào)量和仍然沒(méi)有使用成員OSEventPtr之外,成員OSEventCnt被分成了低位和高位兩部分:低位用來(lái)存放信號(hào)值(該值為0 xFF時(shí),信號(hào)為有效,否則信號(hào)為無(wú)效),高位用來(lái)存放為
57、了避免出現(xiàn)優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象而要提升的優(yōu)先級(jí)別prio。,創(chuàng)建互斥型信號(hào)量需要調(diào)用函數(shù)OSMutexCreate( )。函數(shù)OSMutexCreate( )的原型如下: OS_EVENT *OSMutexCreate ( INT8U prio,/優(yōu)先級(jí)別 INT8U *err/錯(cuò)誤信息 ); 函數(shù)OSMutexCreate( )從空事件控制塊鏈表獲取一個(gè)事件控制塊,把成員OSEventType賦以常數(shù)OS_EVENT_TYPE_MUTEX以表明這是一個(gè)互斥型信號(hào)量,然后再把成員OSEventCnt的高8位賦以prio(欲提升的優(yōu)先級(jí)別),低8位賦以常數(shù)OS_MUTEX_AVAILABLE(該常數(shù)值
58、為0 xFFFF)的低8位(0 xFF)以表明信號(hào)量尚未被任何任務(wù)所占用,處于有效狀態(tài)。,當(dāng)任務(wù)需要訪(fǎng)問(wèn)一個(gè)獨(dú)占式共享資源時(shí),就要調(diào)用函數(shù)OSMutexPend( )來(lái)請(qǐng)求管理這個(gè)資源的互斥型信號(hào)量,如果信號(hào)量有信號(hào)(OSEventCnt的低8位為0 xFF),則意味著目前尚無(wú)任務(wù)占用資源,于是任務(wù)可以繼續(xù)運(yùn)行并對(duì)該資源進(jìn)行訪(fǎng)問(wèn),否則就進(jìn)入等待狀態(tài),直至占用這個(gè)資源的其他任務(wù)釋放了該信號(hào)量。 函數(shù)OSMutexPend( )的原型為: void OSMutexPend ( OS_EVENT *pevent,/互斥型信號(hào)量指針 INT16U timeout, /等待時(shí)限 INT8U *err/錯(cuò)誤信息 );,任務(wù)可以通過(guò)調(diào)用函數(shù)OSMutexPost( )發(fā)送一個(gè)互斥型信號(hào)量,這個(gè)函數(shù)的原型為: INT8U OSMutexPost ( OS_EVENT *pevent /互斥型信號(hào)量指針 );,消息郵箱及
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026廣東陽(yáng)江市陽(yáng)西縣招聘高中教師25人(編制)考試備考題庫(kù)及答案解析
- 2026年杭州余杭區(qū)倉(cāng)前中學(xué)第一批公開(kāi)招聘事業(yè)編制教師2人考試參考題庫(kù)及答案解析
- 2026河南許昌市魏都區(qū)北大社區(qū)衛(wèi)生服務(wù)中心招聘1人考試參考題庫(kù)及答案解析
- 2026廣東惠州博羅縣第三人民醫(yī)院招聘石灣鎮(zhèn)湖山村鄉(xiāng)村衛(wèi)生從業(yè)人員1人考試備考試題及答案解析
- 2026云南師范大學(xué)實(shí)驗(yàn)中學(xué)盤(pán)龍校區(qū)面向教育部直屬師范大學(xué)開(kāi)展公費(fèi)師范畢業(yè)生招聘考試參考題庫(kù)及答案解析
- 2026年蕪湖市西灣中學(xué)招聘頂崗教師1名考試參考試題及答案解析
- 2026重慶渝高中學(xué)校招聘教師考試備考試題及答案解析
- 2026年豐城市市屬?lài)?guó)企下屬公司管理崗及專(zhuān)業(yè)技術(shù)崗招聘【24人】筆試模擬試題及答案解析
- 2026年漯河市第六人民醫(yī)院(市心血管病醫(yī)院)人才引進(jìn)備考題庫(kù)有答案詳解
- 2026年鄭州高新區(qū)科學(xué)大道第二小學(xué)教師招聘?jìng)淇碱}庫(kù)完整參考答案詳解
- 特殊作業(yè)安全管理監(jiān)護(hù)人培訓(xùn)課件
- 成本限額及配置標(biāo)準(zhǔn)
- 房屋市政工程生產(chǎn)安全重大事故隱患判定標(biāo)準(zhǔn)(2024版)宣傳畫(huà)冊(cè)
- 2020高職院校教學(xué)能力比賽大學(xué)語(yǔ)文課程實(shí)施報(bào)告(定)
- 化工廠(chǎng)叉車(chē)安全操作應(yīng)急預(yù)案
- 長(zhǎng)期合作協(xié)議書(shū)合同書(shū)
- DB11∕T 353-2021 城市道路清掃保潔質(zhì)量與作業(yè)要求
- 浙江省小型液化天然氣氣化站技術(shù)規(guī)程
- 生物化學(xué)基礎(chǔ)與應(yīng)用智慧樹(shù)知到期末考試答案章節(jié)答案2024年四川工商職業(yè)技術(shù)學(xué)院
- GB/T 2910.11-2024紡織品定量化學(xué)分析第11部分:某些纖維素纖維與某些其他纖維的混合物(硫酸法)
- GIS組合電器概述
評(píng)論
0/150
提交評(píng)論