第五節(jié):同步與通信 一:同步 任務之間有各種各樣的關系來完成一個工作,有時候,一個任務的完成的齊納提需要另外一個任務給出的結(jié)果,任務之間的這種制約性的合作運行機制叫做任務間的同步。 總例: A任務實現(xiàn)計算功能,B任務輸出A任務計算的結(jié)果,然后循環(huán)運行。A任務和B任務就必須同步,否則B任務輸出的可能不是A任務剛完成的結(jié)果,或則B任務訪問結(jié)果時,A任務正在修改,因而輸出錯誤的結(jié)果。A和B就是必須進行同步的任務。 二:互斥: 例中,A,B任務都要訪問計算結(jié)果這個共享資源,當時在A寫這個資源的同事,B必須等待,而不能再A寫到一半時候結(jié)束A而讓B來讀。這樣的共享資源成為臨界資源,這種訪問共享資源的排他性就是互斥。 臨界資源可以是全局變量,也可以是指針,緩沖區(qū)或鏈表等其他數(shù)據(jù)結(jié)構(gòu),也可以是打印機,硬盤等硬件。 互斥訪問臨界資源,操作系統(tǒng)有很多方法, ucos采用的方法有 關中斷,給調(diào)度器上鎖 和使用信號量等(但是,操作共享資源的時候都要進去臨界區(qū)) 三:臨界區(qū) 每個任務中訪問共享資源的那段程序成為臨界區(qū),因為共享資源的訪問是要互斥的。 因為如果在訪問共享資源的時候進行任務切換,就可能導致災難性后果,在臨界區(qū)不允許任務切換,這是最根本的原則。----臨界區(qū)代碼要盡量短,能夠盡量在限定時間之內(nèi)完成。 所以在進入臨界臨界區(qū)訪問共享資源之前,采用 關中斷,、給調(diào)度器上鎖或使用信號量的方法,達到互斥的目的。 例: int functionl(int p1) { OS_ENTER_CRITICAL(); //進入臨界區(qū),不允許任務切換 訪問臨界區(qū)代碼段 //臨界區(qū) 臨界區(qū)代碼,訪問臨界資源 OS_EXIT_CRITICAL(); //離開臨界區(qū),允許任務切換 其他代碼 //其他代碼,可以在這些代碼執(zhí)行期間進行任務切換。 } 四:任務事件: 事件就是在操作系統(tǒng)運行過程中發(fā)生的事情。 事件處理就是操作系統(tǒng)處理信號量,互斥信號量,時間表蜘蛛,郵箱,消息隊列信息的手段。 例:A任務寫緩沖區(qū),B任務讀緩沖區(qū)。什么時候B任務應該運行呢?就是在A任務寫完緩沖區(qū)這個事件之后,需要調(diào)用OSSemPost()這樣的函數(shù),釋放緩沖區(qū)資源。 在該函數(shù)中,發(fā)現(xiàn)有任務B在排隊等候緩沖區(qū)資源,于是調(diào)用任務切換函數(shù)將cpu給B,達到了任務間的無縫同步。 事件處理的對象主要有:信號量,互斥信號量,時間表蜘蛛,郵箱,消息隊列。 信號量,郵箱,消息隊列是消息的來源。 來消息了是一個事件,等待消息也是在等待時間的發(fā)生。 例如:OSSemPost()函數(shù)的功能就是執(zhí)行的發(fā)信號量操作。 五:信號量: 信號量標識了共享資源的有效被訪問數(shù)量,于是要獲得共享資源的訪問權,就首先要得到信號量。 使用信號量管理共享資源,請求訪問資源就演變成為請求信號量了。 (因為資源是具體的東西,把他數(shù)字化之后,操作系統(tǒng)就便于管理這些資源) 在ucos中,信號量的取值范圍是16位的二進制整數(shù),范圍是十進制的0--65535.或者是其他長度,如8位,32位。 簡單使用信號量的3種操作: 1:建立creat 建立并且初始化信號量,在一個事件中標識該信號,記錄該信號的量值。 2:請求pend 請求信號,如果還有信號量,就去請求一個,(信號量--)執(zhí)行下去,如果沒有,就要把自己阻塞掉(不能執(zhí)行下去就不需要占用cpu) 3:釋放post 訪問資源的操作完成之后(信號量++). 例:A,B兩個任務通過信號量同步: 過程如下: 首先創(chuàng)建信號量S,因為該緩沖區(qū)本質(zhì)上是全局的一個數(shù)組,屬于臨界資源,因此設置信號量的初值為1。另外,該信號量使用一個事件控制塊。 A任務請求信號量S,做pend操作(請求)。 因為信號量S=1,所以請求得到滿足,pend操作中將S減1變?yōu)?. 任務A繼續(xù)執(zhí)行,訪問緩沖區(qū)。 繼 任務A在執(zhí)行過程中因為其他的時間而阻塞,任務B得到運行,要訪問緩沖區(qū),因此請求信號量S,做pend操作。 因為信號量S=0,請求不能得到滿足,任務B只能被阻塞。S的值保持為0. 注:但是在信號量S所使用的時間控制模塊中,標記了事件B在等待信號量S的信息。 任務A在滿足時繼續(xù)執(zhí)行,訪問緩沖區(qū)完成后,做post操作釋放緩沖區(qū)。 Post操作中將S加1,S的值變?yōu)?. 在post操作中,由于事件控制塊中,標記了事件B在等待信號量S的信息,且我們設置任務B有更高的優(yōu)先級,操作系統(tǒng)調(diào)用任務切換函數(shù),切換到任務B運行,使任務B獲得信號量,訪問A寫好的緩沖區(qū)。 任務B訪問完成,再釋放該信號量,任務A又可以訪問該緩沖區(qū)了。 六:互斥信號量: 是一種特殊的信號量(不僅在于該信號量只有用于互斥資源的訪問,還在于使用互斥信號量管理需要解決優(yōu)先級反轉(zhuǎn)問題。) 優(yōu)先級反轉(zhuǎn):
例: 系統(tǒng)中有三個任務,分別是高優(yōu)先級A、中優(yōu)先級B、低優(yōu)先級C:
當?shù)蛢?yōu)先級的任務在運行時候訪問互斥資源,而中優(yōu)先級的任務運行時將使低優(yōu)先級的任務得不到運死抱著資源不放。
這時,高優(yōu)先級的任務開始運行的時候,必須等待中優(yōu)先級的任務運行完成,然后等待低優(yōu)先級任務的任務訪問資源完成才行。
如果在低優(yōu)先級的任務訪問資源過程中又有中優(yōu)先級任務運行,那么高優(yōu)先級的任務只有繼續(xù)等待。這種情況叫優(yōu)先級反轉(zhuǎn)。
在ucosii對互斥信號量的管理中,針對這個問題采用了優(yōu)先級繼承機制
優(yōu)先級繼承機制:是一種對占用資源的任務的優(yōu)先級進行升級的機制,用以優(yōu)化系統(tǒng)的調(diào)度。
例:
當前的任務的優(yōu)先級是比較低的。
高優(yōu)先級的任務請求互斥信號量的時候因為信號量已被占有,所以只有阻塞。這時有中優(yōu)先級的任務就緒。
如果不采用優(yōu)先級繼承,那么高優(yōu)先級的任務是競爭不過中優(yōu)先級的任務。
采用優(yōu)先級繼承機制,將占有資源的低優(yōu)先級的任務臨時設置為一個很高的優(yōu)先級,允許其在占有資源的時候臨時獲得特權,先于中優(yōu)先級任務完成,在訪問互斥資源結(jié)束又回到原來的優(yōu)先級,這樣高優(yōu)先級的任務就會先于中優(yōu)先級的任務運行,解決了這個問題。
七:事件標志組:
1:多個事件都發(fā)生
2:多個事件中有一個事件發(fā)生
3:多個事件都沒有發(fā)生
4:多個事件中有任何一個事件沒有發(fā)生。 如果任務要等待多個事件的發(fā)生,或多個事件中的某一個事件的發(fā)生就可以繼續(xù)運行,那么應該采用事件標志組管理。
事件標志組管理的條件組合可以是多個事件都發(fā)生,也可以是多個事件中有任何一個事件發(fā)生。尤其特別的是,還可以是多個事件都沒有發(fā)生或多個事件中有任何一個事件沒有發(fā)生。
八:消息郵箱和消息隊列
操作系統(tǒng)通過郵箱來管理人物間的通信與同步,郵箱中的內(nèi)容不是信件本身,而是指向消息內(nèi)容的地址。
注:消息的內(nèi)容不是消息本身而是地址(指針),指針所指向的內(nèi)容才是任務想得到的東西。
這個指針是void類型的,可以指向任何數(shù)據(jù)結(jié)構(gòu)。 這樣說發(fā)送的信息范圍也更寬,郵箱中可以容納下任何長度的數(shù)據(jù)。
例如:
我們打開自己的郵箱,發(fā)現(xiàn)一封信,信的內(nèi)容是“中國浙江省杭州市河坊街123號”。那么在河坊街的123號,我們可以找到自己想要的東西。
如果郵箱里面沒有內(nèi)容,那么我們看到的就是個空地址。
在取得事件控制塊之后,要設置他的類型:是信號量型還是郵箱型。(郵箱和信號量都保存在事件控制塊中。)
(因為一個事件控制塊可以作為信號量的容器,也可以作為郵箱的容器,但是不能同時作為兩者的容器)
A,B兩個任務通過發(fā)消息來同步訪問緩沖區(qū): 過程如下:
任務A創(chuàng)建緩沖區(qū),寫緩沖區(qū),發(fā)消息。
任務B請求消息,如果郵箱里面沒有消息,就把自己阻塞,如果有,就讀取消息。
任務B最終讀取消息后,根據(jù)郵箱里的地址讀取緩沖區(qū)。

什么情況下采用消息而不是信號量來完成同步和通信:
假如A寫緩沖區(qū),B讀緩沖區(qū),但是緩沖區(qū)是A創(chuàng)建的,B并不知道它在哪里,但是B知道緩沖區(qū)的類型是10個字節(jié)長的數(shù)組。
消息隊列: 也用于給任務發(fā)消息,但是它是由多個消息郵箱組合形成的,是消息郵箱的集合。,實質(zhì)上是消息郵箱的隊列。
一個消息郵箱只能容納一條消息,
采用消息隊列,一是可以容納多條消息,二是消息是有序的。
消息隊列 消息 信息量的 異同:
相同:消息隊列同樣采用事件控制塊來指示 消息的位置和標記等待消息的任務。
不同:
消息隊列自身有消息控制塊這樣的數(shù)據(jù)結(jié)構(gòu),事件控制塊中指示的不再是消息的地址,而是消息控制塊的地址,使用消息控制塊可以先進先出的方式管理多條消息。
第四節(jié):基于優(yōu)先級的可剝奪內(nèi)核
內(nèi)核是操作系統(tǒng)最核心的部分,
內(nèi)核的主要功能是進行任務調(diào)度。
內(nèi)核中最核心的本服務就是調(diào)度的核心--------任務切換。
調(diào)度:決定多任務的運行狀態(tài)(哪個任務應該處于哪種狀態(tài))
時間:內(nèi)核也是程序,運行要占用cpu的時間,即內(nèi)核要和用戶程序之間爭奪cpu,因此,實時內(nèi)核要設計得運行效率盡可能的快,調(diào)度算法應該盡可能的好。(比較好的內(nèi)核系統(tǒng),內(nèi)核占用cpu的2%-5%負荷。ucos可以。)
空間:內(nèi)核還要占用大量的空間。因為要進行任務調(diào)度,就會有大量的數(shù)據(jù)結(jié)構(gòu)(任務控制塊,就緒表,信號量,郵箱,消息隊列等),并且為了進行任務切換,每個任務都有自己的堆?臻g,占用大量的RAM空間。
(所以沒有擴充內(nèi)存的單片機系統(tǒng)因為沒有足夠的內(nèi)存空間就不能運行ucos)
ucos使用的是一種基于優(yōu)先級的可剝奪型內(nèi)核
一:基于優(yōu)先級的調(diào)度算法:
在ucos中,可以同時又64個就緒任務,每個任務都有各自的優(yōu)先級(優(yōu)先級用0—63的無符號整數(shù)來表示,數(shù)字越大則優(yōu)先級越低)
ucos總是調(diào)度就緒了的、優(yōu)先級最高的任務獲得cpu的控制權 。
二:不可剝奪型內(nèi)核 和 可剝奪型內(nèi)核
(一):不可剝奪型內(nèi)核含義: 當任務一旦獲得了cpu的使用權得到運行,如果不將自己阻塞,將一直運行。
(不管是否有更緊迫的任務(優(yōu)先級更高的任務)在等待。注:高優(yōu)先級的任務已經(jīng)進入就緒態(tài)。)。就算發(fā)生了中斷,也只讓中斷服務程序運行(不論中斷服務程序是否創(chuàng)建了更高優(yōu)先級的任務,也都要返回原任務運行)。

例:
不可剝奪型內(nèi)核的調(diào)度:
1:在任務A運行時發(fā)生中斷,進入中斷服務程序(使更高優(yōu)先級任務B就緒)。
2:從中斷返回,繼續(xù)運行任務A
3:任務A結(jié)束,任務B獲得運行。
分析:
1:任務A由于優(yōu)先級較低,在運行中發(fā)生了中斷時,cpu將控制權交給中斷服務函數(shù),任務A被掛起。
2:中斷服務程序?qū)⒏邇?yōu)先級的任務B從睡眠態(tài)或者阻塞態(tài)恢復到就緒態(tài)。
中斷服務程序返回,由于采用不可剝奪型內(nèi)核,將cpu仍交給任務A運行。
3:知道任務A運行完成或者被阻塞,才將cpu交給任務B,任務B才得到運行。
綜上所述:采用不可剝奪型內(nèi)核缺點在于其響應時間。
高優(yōu)先級的任務就算進入了就緒轉(zhuǎn)臺,還必須等待低優(yōu)先級的任務運行完成或者阻塞后猜得到運行,相應時間不能確定。
因此:不可剝奪型內(nèi)核不適合實時操作系統(tǒng)。
(二):可剝奪型內(nèi)核: 是這樣調(diào)度的:最高優(yōu)先級的任務一旦就緒,就能獲得CPU的控制權而得到運行,而不管當前運行的任務運行到什么狀態(tài)。
例:

可剝奪型內(nèi)核調(diào)度:
1:任務A運行發(fā)生中斷,進入中斷服務程序
2:從中斷返回,任務B優(yōu)先級較高獲得運行
3:任務B結(jié)束,任務A恢復運行。
分析:在可剝奪型內(nèi)核的調(diào)度下,在中斷服務程序中就緒了更高優(yōu)先級的任務B,
2:在中斷返回后因為優(yōu)先級最高, 所以獲得了cpu控制權得到運行。
3:任務B運行結(jié)束后,任務A猜得到運行。
因此:可剝奪型內(nèi)核采用了搶占式的調(diào)度策略,總是讓優(yōu)先級最高的任務運行,直到其阻塞或者完成,任務響應的時間因此是最優(yōu)化的。
因為操作系統(tǒng)總是以時鐘中斷服務程序作為調(diào)度的手段,而時鐘中斷時間是可知的,高優(yōu)先級任務的運行時間也是可知的
因此適合于實時操作系統(tǒng)。
第六節(jié):中斷和時鐘
一:中斷
嵌入式實時操作系統(tǒng)的中斷是指在任務的執(zhí)行過程中,當出現(xiàn)異常情況或者特殊請求時,停止任務的執(zhí)行,轉(zhuǎn)而對這些異常情況或者特殊請求進行處理,處理結(jié)束后再返回當前任務的間斷處,或由于中斷服務函數(shù)使更高優(yōu)先級的程序就緒,轉(zhuǎn)而執(zhí)行優(yōu)先級更高的任務。
中斷是實時地處理內(nèi)部或外部事件的一種內(nèi)部機制。
這里,異常情況或特許請求時中斷源,稱為異步事件。
處理異步事件所用的程序是中斷服務程序。
例:
工作時,手機響了,于是先接電話,接完電話后繼續(xù)工作。
手機是中斷源,接電話是中斷服務程序。
如果不接電話繼續(xù)工作,這是對中斷的不理會,或稱中斷被屏蔽了。
工作前關掉手機,直接禁止中斷。
在ucos中,中斷處理過程如圖:

當任務A在運行的時候,由于中斷的到來,
1:操作系統(tǒng)先保存任務A當前的運行環(huán)境,
2:接著進入中斷服務程序
3:在中斷服務程序后,由于采用可剝奪型內(nèi)核,如果A仍是最高優(yōu)先級任務,就恢復A運行的環(huán)境,繼續(xù)運行A,否則將運行一個更高優(yōu)先級的任務
二:時鐘
時鐘是一種特定的周期性中斷------時鐘節(jié)拍。(在ucos中起到心臟的作用)
操作系統(tǒng)能夠同步,最根本的硬件條件是系統(tǒng)在統(tǒng)一的時鐘下工作。
在ucos中,通過對硬件的設置,使在10~200ms的時間間隔內(nèi)產(chǎn)生一次時鐘中斷,
在該時鐘中斷服務程序中,對延時的任務進行延時計數(shù) ,檢查系統(tǒng)中是否有高優(yōu)先級的任務就緒而沒有得到運行,相應進行任務調(diào)度。
因此。如果沒有時鐘中斷服務,就沒有多任務操作系統(tǒng)的任務調(diào)度,也談不上實時。
我們把這種周期性中斷稱為時鐘節(jié)拍,對應的中斷服務程序稱為時鐘中斷服務程序。
第七節(jié):內(nèi)存管理
內(nèi)存很寶貴,在ucosii中,采用分區(qū)的方式管理內(nèi)存-----將連續(xù)的大塊內(nèi)存按分區(qū)來管理,每個系統(tǒng)中有數(shù)個這樣的分區(qū),每個分區(qū)又包含數(shù)個內(nèi)存塊,每個內(nèi)存塊大小相同。這樣,在分配內(nèi)存的時候,根據(jù)需要從不同的分區(qū)中得到數(shù)個內(nèi)存塊,而在釋放時,這些內(nèi)存塊重新釋放回他們原來所在的分區(qū)。
為了方便內(nèi)存管理,ucos采用內(nèi)存控制塊來管理內(nèi)存。
內(nèi)存控制塊記錄了內(nèi)存分區(qū)的地址、分區(qū)中內(nèi)存塊的大小和數(shù)量,以及空閑塊的數(shù)量等信息。
內(nèi)存管理包含了內(nèi)存分區(qū)的創(chuàng)建、分配、釋放、使用、等待系統(tǒng)調(diào)用。
|