from http://blog.csdn.net/fovwin/article/details/11020977
一 實(shí)時(shí)操作系統(tǒng)概述
1 操作系統(tǒng)概述
在計(jì)算機(jī)技術(shù)發(fā)展的初期階段,計(jì)算機(jī)系統(tǒng)中沒(méi)有操作系統(tǒng)(Operating System)這個(gè)概念。應(yīng)用程序開(kāi)發(fā)人員都要對(duì)處理器和硬件進(jìn)行徹頭徹尾的控制。實(shí)際上,第一個(gè)操作系統(tǒng)的誕生,就是為了提供一個(gè)虛擬的硬件平臺(tái),以方便程序員開(kāi)發(fā),同時(shí)提高計(jì)算機(jī)的資源利用率。為實(shí)現(xiàn)這個(gè)目標(biāo),操作系統(tǒng)只需提供一些較為松散的函數(shù)、例程――就好象現(xiàn)在的軟件庫(kù)一樣――以便于對(duì)硬件設(shè)備進(jìn)行重置、讀取狀態(tài)、寫(xiě)入指令之類(lèi)的操作。
這是操作系統(tǒng)的雛形:計(jì)算機(jī)監(jiān)控程序(Monitor),使用戶(hù)能通過(guò)監(jiān)控程序來(lái)使用計(jì)算機(jī)。
隨著計(jì)算機(jī)技術(shù)的發(fā)展,計(jì)算機(jī)系統(tǒng)的硬件、軟件資源也愈來(lái)愈豐富,監(jiān)控程序已不能適應(yīng)計(jì)算機(jī)應(yīng)用的要求。于是在六十年代中期,監(jiān)控程序又進(jìn)一步發(fā)展,形成了操作系統(tǒng)(Operating System)。 發(fā)展到現(xiàn)在,廣泛使用的有三種操作系統(tǒng)即多道批處理操作系統(tǒng)、分時(shí)操作系統(tǒng)以及實(shí)時(shí)操作系統(tǒng)。
多道批量處理系統(tǒng)一般用于計(jì)算中心較大的計(jì)算機(jī)系統(tǒng)中。由于它的硬件設(shè)備比較全,價(jià)格較高,所以此類(lèi)系統(tǒng)十分注意CPU及其它設(shè)備的充分利用,追求高的吞吐量,不具備實(shí)時(shí)性。
分時(shí)系統(tǒng)的主要目的是讓多個(gè)計(jì)算機(jī)用戶(hù)能共享系統(tǒng)的資源,能及時(shí)地響應(yīng)和服務(wù)于聯(lián)機(jī)用戶(hù),只具有很弱的實(shí)時(shí)功能,但與真正的實(shí)時(shí)操作系統(tǒng)仍然有明顯的區(qū)別。具體的說(shuō),對(duì)于分時(shí)操作系統(tǒng),軟件的執(zhí)行在時(shí)間上的要求,并不嚴(yán)格,時(shí)間上的錯(cuò)誤,一般不會(huì)造成災(zāi)難性的后果。而對(duì)于實(shí)時(shí)操作系統(tǒng),主要任務(wù)是對(duì)事件進(jìn)行實(shí)時(shí)的處理,雖然事件可能在無(wú)法預(yù)知的時(shí)刻到達(dá),但是軟件上必須在事件發(fā)生時(shí)能夠在嚴(yán)格的時(shí)限內(nèi)作出響應(yīng)(系統(tǒng)響應(yīng)時(shí)間),即使是在尖峰負(fù)荷下,也應(yīng)如此,系統(tǒng)時(shí)間響應(yīng)的超時(shí)就意味著致命的失敗。另外,實(shí)時(shí)操作系統(tǒng)的重要特點(diǎn)是具有系統(tǒng)的可確定性,即系統(tǒng)能對(duì)運(yùn)行情況的最好和最壞等的情況能做出精確的估計(jì)。
現(xiàn)代操作系統(tǒng)則在單處理器上引入了多任務(wù)機(jī)制,每個(gè)用戶(hù)的應(yīng)用程序可以設(shè)計(jì)成多個(gè)不同的任務(wù),每個(gè)任務(wù)都是一個(gè)軟件模塊,可以是互相獨(dú)立的,這些任務(wù)可以并發(fā)執(zhí)行,提高系統(tǒng)的吞吐量,更有效地利用系統(tǒng)資源。嵌入式軟件經(jīng)常是可以劃分成小的互相獨(dú)立的模塊。這些任務(wù)的劃分提供了一個(gè)很關(guān)鍵的軟件抽象概念,這使得嵌入式操作系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)更加容易,源程序也更易于理解和維護(hù)。通過(guò)把大的程序進(jìn)行模塊化劃分,程序員可以集中精力克服系統(tǒng)開(kāi)發(fā)過(guò)程中的關(guān)鍵問(wèn)題?;谌蝿?wù)的設(shè)計(jì)的可擴(kuò)展性、可管理性大大提高了系統(tǒng)的可靠性。
2 實(shí)時(shí)多任務(wù)操作系統(tǒng)的定義
一個(gè)實(shí)時(shí)系統(tǒng),根據(jù)它所要執(zhí)行的任務(wù)的復(fù)雜程度,可以使用不同的運(yùn)行和管理方法。
對(duì)較小的實(shí)時(shí)系統(tǒng),只需使用實(shí)時(shí)監(jiān)控程序(Monitor)即可簡(jiǎn)單而有效地運(yùn)行和管理。監(jiān)控程序管理應(yīng)用程序的運(yùn)行和對(duì)I/O設(shè)備的操作,并具有按優(yōu)先級(jí)控制的中斷系統(tǒng)。被硬件激活等各項(xiàng)功能可以由中斷服務(wù)程序來(lái)完成。
對(duì)規(guī)模較大的實(shí)時(shí)系統(tǒng),需要使用實(shí)時(shí)多任務(wù)操作系統(tǒng)來(lái)加以管理。較簡(jiǎn)單的情況,可以?xún)H使用實(shí)時(shí)多任務(wù)內(nèi)核(Kernel),又稱(chēng)為實(shí)時(shí)多任務(wù)執(zhí)行程序(Executive)。對(duì)復(fù)雜的情況,則必須使用包括了文件系統(tǒng)在內(nèi)的完全的實(shí)時(shí)多任務(wù)操作系統(tǒng)。
一個(gè)操作系統(tǒng)操可以定義為:使得計(jì)算機(jī)系統(tǒng)的硬件成為可用的、由軟件或固件(firmware)所實(shí)現(xiàn)的一個(gè)程序集。操作系統(tǒng)是介于編程者與機(jī)器硬件之間的一個(gè)軟件層。如圖1 所示。
圖 1 操作系統(tǒng)是硬件與編程者之間的接口
操作系統(tǒng)是一組計(jì)算機(jī)程序的集合,用來(lái)有效地控制和管理計(jì)算機(jī)的硬件和軟件資源,即合理地對(duì)資源進(jìn)行調(diào)度,并為用戶(hù)提供方便的應(yīng)用接口。它為應(yīng)用支持軟件提供運(yùn)行環(huán)境,即對(duì)程序開(kāi)發(fā)者提供功能強(qiáng)、使用方便的開(kāi)發(fā)環(huán)境。
傳統(tǒng)的通用操作系統(tǒng)通常包括以下幾部分:命令解釋程序,內(nèi)核和I/O設(shè)備驅(qū)動(dòng)程序。它所提供的運(yùn)行及管理機(jī)制為:
多任務(wù)的管理
內(nèi)存及資源管理
任務(wù)間的信息傳遞
文件系統(tǒng)的管理
邏輯I/O設(shè)備的管理
實(shí)時(shí)操作系統(tǒng)也同樣包括以上各個(gè)部分,只是由于實(shí)時(shí)性的要求,管理方法上要作許多擴(kuò)充。
實(shí)時(shí)多任務(wù)操作系統(tǒng)(Real Time Operating System)是根據(jù)操作系統(tǒng)的工作特性而言的。實(shí)時(shí)是指物理進(jìn)程的真實(shí)時(shí)間。實(shí)時(shí)操作系統(tǒng)是指具有實(shí)時(shí)性,能支持實(shí)時(shí)控制系統(tǒng)工作的操作系統(tǒng)。首要任務(wù)是調(diào)度一切可利用的資源完成實(shí)時(shí)控制任務(wù),其次才著眼于提高計(jì)算機(jī)系統(tǒng)的使用效率,重要特點(diǎn)是要滿足對(duì)時(shí)間的限制和要求。
3 實(shí)時(shí)操作系統(tǒng)的發(fā)展歷史
許多嵌入式系統(tǒng)根本就沒(méi)有操作系統(tǒng),只不過(guò)有一個(gè)控制環(huán)而已。對(duì)很簡(jiǎn)單的嵌入式系統(tǒng)來(lái)說(shuō),這可能已經(jīng)足夠了。不過(guò),隨著嵌入式系統(tǒng)在復(fù)雜性上的增長(zhǎng),操作系統(tǒng)顯得重要起來(lái),因?yàn)榉駝t的話,將使(控制)軟件復(fù)雜度變得極不合理。
實(shí)時(shí)操作系統(tǒng)(RTOS)的研究是從六十年代開(kāi)始的。從系統(tǒng)結(jié)構(gòu)上看,RTOS到現(xiàn)在已經(jīng)歷了如下三個(gè)階段:
3.1 早期的實(shí)時(shí)操作系統(tǒng)
同硬件一起,軟件也得到了發(fā)展。最初,只有一些簡(jiǎn)單的開(kāi)發(fā)工具可供用以創(chuàng)建和調(diào)試軟件。各工程項(xiàng)目的運(yùn)行軟件通常以信手涂鴉的方式編出來(lái)。由于編譯器經(jīng)常有很多錯(cuò)誤而且也缺乏象樣的調(diào)試器,這些軟件差不多總是用匯編語(yǔ)言或宏語(yǔ)言來(lái)寫(xiě)。采用軟件構(gòu)建塊和標(biāo)準(zhǔn)庫(kù)的編程思想直到20世紀(jì)70年代中期才流行起來(lái)。
早期的實(shí)時(shí)操作系統(tǒng),還不能稱(chēng)為真正的RTOS,它只是小而簡(jiǎn)單的、帶有一定專(zhuān)用性的軟件,功能較弱,可以認(rèn)為是一種實(shí)時(shí)監(jiān)控程序。它一般為用戶(hù)提供對(duì)系統(tǒng)的初始化管理以及簡(jiǎn)單的實(shí)時(shí)時(shí)鐘管理,有的實(shí)時(shí)監(jiān)控程序也引入了任務(wù)調(diào)度及簡(jiǎn)單的任務(wù)間協(xié)調(diào)等功能,屬于這類(lèi)實(shí)時(shí)監(jiān)控程序的有RTMX等。這個(gè)時(shí)期,實(shí)時(shí)應(yīng)用較簡(jiǎn)單,實(shí)時(shí)性要求也不高。應(yīng)用程序、實(shí)時(shí)監(jiān)控程序和硬件運(yùn)行平臺(tái)往往是緊密聯(lián)系在一起的。
用于嵌入式系統(tǒng)的與"擱架"無(wú)關(guān)的操作系統(tǒng)在20世紀(jì)70年代后期開(kāi)始出現(xiàn)。它們中的許多是用匯編語(yǔ)言寫(xiě)就的,并且僅能用于為其編寫(xiě)的微處理器上。當(dāng)這些微處理器變得過(guò)時(shí)的時(shí)候,它們使用的操作系統(tǒng)也厄運(yùn)同臨。只能在新的處理器上從新寫(xiě)一遍才能運(yùn)行。今天,許多這種早期的系統(tǒng)只不過(guò)成了人們模糊的記憶。當(dāng)C語(yǔ)言出現(xiàn)后,操作系統(tǒng)可以用一種高效的、穩(wěn)定的和可移植的方式來(lái)編寫(xiě)。這種方式對(duì)使用和經(jīng)營(yíng)有直接的吸引力,因?yàn)樗休d著人們當(dāng)微處理器廢棄不用時(shí)能保護(hù)他們的軟件投資的希望。聽(tīng)起來(lái),有點(diǎn)兒像商業(yè)市場(chǎng)營(yíng)銷(xiāo)中的一段傳奇故事。用C來(lái)編寫(xiě)操作系統(tǒng)已經(jīng)成了一種標(biāo)準(zhǔn),直至今天??傊?,軟件的可復(fù)用性已經(jīng)為人接受而且正在很好地發(fā)揮作用。
3.2 專(zhuān)用實(shí)時(shí)操作系統(tǒng)
隨著應(yīng)用的發(fā)展,早期的實(shí)時(shí)操作系統(tǒng)已越來(lái)越顯示出明顯的不足了。有些實(shí)時(shí)系統(tǒng)的開(kāi)發(fā)者為了滿足實(shí)時(shí)應(yīng)用的需要,自己研制與特定硬件相匹配的實(shí)時(shí)操作系統(tǒng)。這類(lèi)專(zhuān)用實(shí)時(shí)操作系統(tǒng)在國(guó)外稱(chēng)為Real-Time Operating System Developed in House。它是在早期用戶(hù)為滿足自身開(kāi)發(fā)需要而研制的,它一般只能適用于特定的硬件環(huán)境,且缺乏嚴(yán)格的評(píng)測(cè),移植性也不太好。屬于這類(lèi)實(shí)時(shí)操作系統(tǒng)的有Intel公司的iRMX等。
在各種專(zhuān)用的實(shí)時(shí)操作系統(tǒng)中,一些多任務(wù)的機(jī)制如基于優(yōu)先級(jí)的調(diào)度、實(shí)時(shí)時(shí)鐘管理、任務(wù)間的通信、同步互斥機(jī)構(gòu)等基本上是相同的,不同的只是面向各自的硬件環(huán)境與應(yīng)用目標(biāo)。實(shí)際上,相同的多任務(wù)機(jī)制是能夠共享的,因而可以把這部分很好地組織起來(lái),形成一個(gè)通用的實(shí)時(shí)操作相同內(nèi)核。這類(lèi)實(shí)時(shí)操作系統(tǒng)大多采用軟組件結(jié)構(gòu),以一個(gè)個(gè)軟件"標(biāo)準(zhǔn)組件"構(gòu)成通用的實(shí)時(shí)操作系統(tǒng),一方面,在RTOS內(nèi)核的最底層將不同的硬件特性屏蔽掉;另一方面,對(duì)不同的應(yīng)用環(huán)境提供了標(biāo)準(zhǔn)的、可剪裁的系統(tǒng)服務(wù)軟組件。這使得用戶(hù)可根據(jù)不同的實(shí)時(shí)應(yīng)用要求及硬件環(huán)境選擇不同的軟組件,也使得實(shí)時(shí)操作系統(tǒng)開(kāi)發(fā)商在開(kāi)發(fā)過(guò)程中減少了重復(fù)性工作。
3.3 通用實(shí)時(shí)操作系統(tǒng)
許多用于嵌入式系統(tǒng)的的商業(yè)操作系統(tǒng)在20世紀(jì)80年代獲得了蓬勃發(fā)展。從1981年Ready System發(fā)布的世界上第一個(gè)商業(yè)嵌入式實(shí)時(shí)內(nèi)核(VRTX32),到今天已有20年的歷史。目前已經(jīng)有幾打的商業(yè)性實(shí)時(shí)操作系統(tǒng)可供選擇,出現(xiàn)了許多互相競(jìng)爭(zhēng)的產(chǎn)品,如VxWorks,pSOS,Neculeus和WindowsCE等。
這類(lèi)通用實(shí)時(shí)操作系統(tǒng),有Integrated System公司的Psos+、Intel公司的iRMX386、Ready System公司(1995年與Microtec Research合并)的VRTX32(后推出新一代的實(shí)時(shí)內(nèi)核VRTXsa)等。它們一般都提供了實(shí)時(shí)性較好的內(nèi)核、多種任務(wù)通信機(jī)制、基于TCP/IP的網(wǎng)絡(luò)組件、文件管理及I/O服務(wù),提供了集編輯、編譯、調(diào)試、仿真為一體的集成開(kāi)發(fā)環(huán)境,支持用戶(hù)使用C、C++進(jìn)行應(yīng)用程序的開(kāi)發(fā)。如Integrated System公司的Prism+,Windriver公司的Tornado,Ready System公司的Spectra。
作為候選的嵌入式操作系統(tǒng),Linux有一些吸引人的優(yōu)勢(shì):它可以移植到多個(gè)有不同結(jié)構(gòu)的CPU和硬件平臺(tái)上,具有很好的穩(wěn)定性,以及各種性能的升級(jí)能力,而且開(kāi)發(fā)更容易。
4 實(shí)時(shí)操作系統(tǒng)的分類(lèi)
從實(shí)時(shí)系統(tǒng)的應(yīng)用特點(diǎn)來(lái)看,實(shí)時(shí)操作系統(tǒng)可以分為兩種:一般實(shí)時(shí)操作系統(tǒng)和嵌入式實(shí)時(shí)操作系統(tǒng)。
一般實(shí)時(shí)操作系統(tǒng)與嵌入式實(shí)時(shí)操作系統(tǒng)都是具有實(shí)時(shí)性的操作系統(tǒng),它們的主要區(qū)別在于應(yīng)用場(chǎng)合和開(kāi)發(fā)過(guò)程。
一般實(shí)時(shí)操作系統(tǒng)應(yīng)用于實(shí)時(shí)處理系統(tǒng)的上位機(jī)和實(shí)時(shí)查詢(xún)系統(tǒng)等實(shí)時(shí)性較弱的實(shí)時(shí)系統(tǒng),并且提供了開(kāi)發(fā)、調(diào)試、運(yùn)用一致的環(huán)境。
嵌入式實(shí)時(shí)操作系統(tǒng)應(yīng)用于實(shí)時(shí)性要求高的實(shí)時(shí)控制系統(tǒng),而且應(yīng)用程序的開(kāi)發(fā)過(guò)程是通過(guò)交叉開(kāi)發(fā)來(lái)完成的,即開(kāi)發(fā)環(huán)境與運(yùn)行環(huán)境是不一致的。
5 實(shí)時(shí)操作系統(tǒng)的特點(diǎn)
RTOS是操作系統(tǒng)研究的一個(gè)重要分支,它與一般商用多任務(wù)操作系統(tǒng)如Unix、Windows、Multifinder等有共同的一面,也有不同的一面。對(duì)于商用多任務(wù)操作系統(tǒng),其目的是方便用戶(hù)管理計(jì)算機(jī)資源,追求系統(tǒng)資源最大利用率;而RTOS追求的是實(shí)時(shí)性、可確定性、可靠性。
評(píng)價(jià)一個(gè)實(shí)時(shí)操作系統(tǒng)一般可以從任務(wù)調(diào)度、內(nèi)存管理、任務(wù)通訊、內(nèi)存開(kāi)銷(xiāo)、任務(wù)切換時(shí)間、最大中斷禁止時(shí)間等幾個(gè)方面來(lái)衡量。因此,實(shí)時(shí)操作系統(tǒng)一般具備以下要求:
5.1 可確定性(deterministic)
操作系統(tǒng)的可確定性是指它可以按照固定的、預(yù)先確定的時(shí)間或時(shí)間間隔執(zhí)行操作。當(dāng)多個(gè)任務(wù)競(jìng)爭(zhēng)使用資源和處理器時(shí),沒(méi)有哪個(gè)系統(tǒng)是完全可確定的。在實(shí)時(shí)操作系統(tǒng)中,任務(wù)請(qǐng)求服務(wù)是用外部事件和時(shí)間安排來(lái)描述的。操作系統(tǒng)可以確定性地滿足請(qǐng)求的程度首先取決于它響應(yīng)中斷地速度,其次取決于系統(tǒng)是否具有足夠的能力在要求的時(shí)間內(nèi)處理所有的請(qǐng)求。
操作系統(tǒng)可確定性能力的一個(gè)非常有用的度量是從高優(yōu)先級(jí)中斷到達(dá)到開(kāi)始服務(wù)之間的延遲。在非實(shí)時(shí)操作系統(tǒng)中,這個(gè)延遲可以是幾十到幾百毫秒,而在實(shí)時(shí)操作系統(tǒng)中,這個(gè)延遲的上限可以從幾微秒到1毫秒。
5.2 響應(yīng)性(responsiveness)
確定性關(guān)注的是操作系統(tǒng)獲知有一個(gè)中斷之前的延遲,響應(yīng)性關(guān)注的是在知道中斷之后操作系統(tǒng)為中斷提供服務(wù)的時(shí)間。
響應(yīng)性包括以下幾個(gè)方面:
A) 最初處理中斷并開(kāi)始執(zhí)行中斷服務(wù)程序所需要的時(shí)間總量。如果ISR的執(zhí)行需要一次任務(wù)切換,需要的延遲將比在當(dāng)前任務(wù)上下文環(huán)境中執(zhí)行ISR的延遲長(zhǎng)。
B) 執(zhí)行ISR所需的時(shí)間總和,通常與硬件環(huán)境有關(guān)。
C) 中斷嵌套的影響。如果一個(gè)ISR可以被另一個(gè)中斷的到達(dá)而中斷,服務(wù)將會(huì)延遲。
確定性和響應(yīng)性共同組成了對(duì)外部事件的響應(yīng)時(shí)間。對(duì)實(shí)時(shí)系統(tǒng)來(lái)說(shuō),響應(yīng)時(shí)間的要求非常重要,因?yàn)樗仨殱M足外部事件的時(shí)間要求。
5.3 用戶(hù)控制(user control)
用戶(hù)控制在實(shí)時(shí)操作系統(tǒng)中通常比在普通操作系統(tǒng)中更廣泛。在典型的非實(shí)時(shí)操作系統(tǒng)中,用戶(hù)或者對(duì)操作系統(tǒng)的調(diào)度功能沒(méi)有任何控制,或者僅提供了概括性的指導(dǎo),例如把用戶(hù)分成多個(gè)優(yōu)先級(jí)組。但在實(shí)時(shí)操作系統(tǒng)中,允許用戶(hù)細(xì)粒度地控制任務(wù)的優(yōu)先級(jí)是必不可少的。用戶(hù)應(yīng)該能夠區(qū)分硬任務(wù)和軟任務(wù),并且確定其相對(duì)優(yōu)先級(jí)。實(shí)時(shí)系統(tǒng)還允許用戶(hù)指定一些特性,例如哪個(gè)任務(wù)必須常駐Cache。
5.4 可靠性(reliability)
在實(shí)時(shí)系統(tǒng)中比非實(shí)時(shí)系統(tǒng)中更重要。在非實(shí)時(shí)系統(tǒng)中,暫時(shí)性故障可以通過(guò)重新啟動(dòng)系統(tǒng)來(lái)解決,多處理器非實(shí)時(shí)系統(tǒng)中的處理器失敗可能導(dǎo)致服務(wù)級(jí)別降低,直到發(fā)生故障的處理器被修復(fù)或替換。但是實(shí)時(shí)系統(tǒng)是實(shí)時(shí)地響應(yīng)和控制事件,性能的損失或降低可能產(chǎn)生災(zāi)難性的后果,從資金損失到損壞主要設(shè)備甚至危及生命。
5.5.故障弱化運(yùn)行(fail-soft running)
與其它領(lǐng)域一樣,實(shí)時(shí)操作系統(tǒng)和非實(shí)時(shí)操作系統(tǒng)的區(qū)別只是一個(gè)程度問(wèn)題,即使實(shí)時(shí)系統(tǒng)也必須設(shè)計(jì)成響應(yīng)各種故障模式。故障弱化運(yùn)行是指在系統(tǒng)故障時(shí)實(shí)時(shí)系統(tǒng)將試圖改正這個(gè)問(wèn)題或者最小化它的影響并繼續(xù)運(yùn)行。
故障弱化運(yùn)行的一個(gè)重要特征是穩(wěn)定性。我們說(shuō)一個(gè)實(shí)時(shí)系統(tǒng)是穩(wěn)定的,是指如果當(dāng)它不可能滿足所有任務(wù)的最后期限時(shí),即使總是不能滿足一些不太重要的任務(wù)的最后期限,系統(tǒng)也將首先滿足最重要的、優(yōu)先級(jí)最高的任務(wù)的最后期限。
為滿足前面的要求,當(dāng)前的實(shí)時(shí)操作系統(tǒng)典型地包括以下特征:
快速的任務(wù)切換
當(dāng)由于某種原因使一個(gè)任務(wù)退出運(yùn)行時(shí),RTOS保存它的運(yùn)行現(xiàn)場(chǎng)信息、插入相應(yīng)隊(duì)列、并依據(jù)一定的調(diào)度算法重新選擇一個(gè)任務(wù)使之投入運(yùn)行,這一過(guò)程所需時(shí)間稱(chēng)為任務(wù)切換時(shí)間。任務(wù)切換時(shí)間一般在毫秒或微秒數(shù)量級(jí)上。
體積?。ㄖ痪邆渥钚∠薅鹊墓δ埽?/p>
實(shí)時(shí)操作系統(tǒng)的設(shè)計(jì)過(guò)程中,最小內(nèi)存開(kāi)銷(xiāo)是一個(gè)較重要的指標(biāo),這是因?yàn)樵诠I(yè)控制領(lǐng)域中的某些工控機(jī),由于基于降低成本的考慮,其內(nèi)存的配置一般都不大,例如康拓5000系列5185板,其基本內(nèi)存配置僅為256K SRAM+128K EPROM,而在這有限的空間內(nèi)不僅要裝載實(shí)時(shí)操作系統(tǒng),還要裝載用戶(hù)程序。因此,在RTOS的設(shè)計(jì)中,其占用內(nèi)存大小是一個(gè)很重要的指標(biāo),這是實(shí)時(shí)操作系統(tǒng)設(shè)計(jì)與其它操作系統(tǒng)設(shè)計(jì)的明顯區(qū)別之一。
一般實(shí)時(shí)內(nèi)核只有幾十K字節(jié)大小,并可固化使用。
通過(guò)諸如信號(hào)量、事件之類(lèi)的任務(wù)間通信手段,實(shí)現(xiàn)多任務(wù)處理
下面我們將詳細(xì)介紹多任務(wù)有關(guān)的一些概念。
1.使用特殊的順序文件,可以快速存儲(chǔ)數(shù)據(jù)
提供存取盤(pán)上數(shù)據(jù)的優(yōu)化方法,使得存取數(shù)據(jù)時(shí)查找時(shí)間最少。通常要求把數(shù)據(jù)存儲(chǔ)在順序文件上。
2.基于優(yōu)先級(jí)的搶占調(diào)度
實(shí)時(shí)操作系統(tǒng)的實(shí)時(shí)性和多任務(wù)能力在很大程度上取決于它的任務(wù)調(diào)度機(jī)制。為保證響應(yīng)時(shí)間,實(shí)時(shí)操作系統(tǒng)必須允許高優(yōu)先級(jí)任務(wù)一旦準(zhǔn)備好運(yùn)行,馬上搶占低優(yōu)先級(jí)任務(wù)的執(zhí)行。
3.最小化禁止中斷的時(shí)間間隔
當(dāng)RTOS運(yùn)行在核態(tài)或執(zhí)行某些系統(tǒng)調(diào)用的時(shí)候,是不會(huì)因?yàn)橥獠恐袛嗟牡絹?lái)而中斷執(zhí)行的。只有當(dāng)RTOS重新回到用戶(hù)態(tài)時(shí)才響應(yīng)外部中斷請(qǐng)求,這一過(guò)程所需的最大時(shí)間就是最大中斷禁止時(shí)間。
4.硬件抽象化
硬件抽象化的目的是透過(guò)操作系統(tǒng)本身的設(shè)計(jì)將硬件因素降到最低,軟件本身牽涉到的硬件因素越少,則其跨平臺(tái)的可能性越高,而硬件抽象化的最直接作法即是將操作系統(tǒng)本身與硬件有關(guān)的部分集中成一個(gè)模塊,利用此模塊將操作系統(tǒng)及應(yīng)用程序與硬件界面相隔絕。
5.用于使任務(wù)延遲一段固定的時(shí)間或暫停/恢復(fù)任務(wù)的原語(yǔ)
6.特別的告警和超時(shí)設(shè)定
總的來(lái)說(shuō),實(shí)時(shí)操作系統(tǒng)是事件驅(qū)動(dòng)的(event driven),能對(duì)來(lái)自外界的作用和信號(hào)在限定的時(shí)間范圍內(nèi)作出響應(yīng)。它強(qiáng)調(diào)的是實(shí)時(shí)性、可靠性和靈活性, 與實(shí)時(shí)應(yīng)用軟件相結(jié)合成為有機(jī)的整體,起著核心作用,由它來(lái)管理和協(xié)調(diào)各項(xiàng)工作,為應(yīng)用軟件提供良好的運(yùn)行軟件環(huán)境及開(kāi)發(fā)環(huán)境。
進(jìn)入20世紀(jì)90年代后,RTOS在嵌入式系統(tǒng)設(shè)計(jì)中的主導(dǎo)地位已經(jīng)確定,越來(lái)越多的工程師使用RTOS,更多的新用戶(hù)愿意選擇購(gòu)買(mǎi)而不是自己開(kāi)發(fā)。當(dāng)前,RTOS的技術(shù)發(fā)展有以下一些變化:
因?yàn)樾绿幚砥髟絹?lái)越多,RTOS自身結(jié)構(gòu)的設(shè)計(jì)更易于移植,以便在短時(shí)間內(nèi)支持更多種微處理器。
開(kāi)發(fā)源碼之風(fēng)已波及RTOS廠家。數(shù)量相當(dāng)多的RTOS廠家出售RTOS時(shí),就附加了源碼并含生產(chǎn)版權(quán)。
后PC時(shí)代更多的產(chǎn)品使用RTOS,它們對(duì)實(shí)時(shí)性要求并不高,如手持設(shè)備等。微軟的WinCE,Plam OS,Java OS等RTOS產(chǎn)品就是順應(yīng)應(yīng)用而開(kāi)發(fā)出來(lái)的。
電信設(shè)備、控制系統(tǒng)要求的高可靠性對(duì)RTOS提出了新的要求。瑞典Enea公司的OSE和WindRiver新推出的VxWorks AE對(duì)支持高可用性和熱切換等特點(diǎn)都下了一番功夫。
嵌入式Linux已經(jīng)在消費(fèi)電子設(shè)備中得到廣泛應(yīng)用。
6 實(shí)時(shí)操作系統(tǒng)的標(biāo)準(zhǔn)-POSIX
對(duì)于嵌入式系統(tǒng)最煩人的事情之一就是它們?nèi)狈σ粋€(gè)公共的應(yīng)用程序接口(API),這對(duì)于希望在基于不同操作系統(tǒng)的產(chǎn)品之間共享應(yīng)用程序代碼的公司來(lái)說(shuō),這是一個(gè)特別問(wèn)題。
其實(shí),每一個(gè)嵌入式操作系統(tǒng)的基本功能大致一樣。每一個(gè)函數(shù)或者方法代表了操作系統(tǒng)可以向應(yīng)用程序提供的一種服務(wù)。但是沒(méi)有那么多不同的可能的服務(wù)。經(jīng)常是這種情況:兩個(gè)實(shí)現(xiàn)之間真正的不同只是在于函數(shù)和方法的名稱(chēng)。
這個(gè)問(wèn)題從嵌入式操作系統(tǒng)產(chǎn)生就出現(xiàn)了,已經(jīng)持續(xù)了幾十年了。與此同時(shí)的Win32和POSIX API已經(jīng)分別占據(jù)了PC機(jī)和UNIX工作站,成為事實(shí)上的標(biāo)準(zhǔn),雖然這兩種API在實(shí)現(xiàn)上差別很大,但基本原理是相同的。
POSIX全稱(chēng)為“可移植的UNIX操作系統(tǒng)接口”,不僅僅是API接口標(biāo)準(zhǔn),而且是一個(gè)完整的操作系統(tǒng)標(biāo)準(zhǔn),它囊括了與操作系統(tǒng)有關(guān)的各個(gè)方面的內(nèi)容。其中,系統(tǒng)服務(wù)接口(IEEE 1003.1)是最基本的標(biāo)準(zhǔn)。
原始POSIX標(biāo)準(zhǔn)(IEEE 1003.1)的作者們也為實(shí)時(shí)操作系統(tǒng)創(chuàng)建了一個(gè)類(lèi)似標(biāo)準(zhǔn)(IEEE 1003.4b)。一些很像UINX的嵌入式操作系統(tǒng),例如VxWorks和LynxOS,就是符合這個(gè)標(biāo)準(zhǔn)API。
7 實(shí)時(shí)操作系統(tǒng)的發(fā)展方向
實(shí)時(shí)操作系統(tǒng)經(jīng)過(guò)多年的發(fā)展,先后從實(shí)模式進(jìn)化到保護(hù)模式,從微內(nèi)核技術(shù)進(jìn)化到到超微內(nèi)核技術(shù),在系統(tǒng)規(guī)模上也從單處理器的RTOS發(fā)展到支持多處理器的RTOS和網(wǎng)絡(luò)RTOS,在操作系統(tǒng)研究領(lǐng)域中形成了一個(gè)重要分支。
目前,嵌入式實(shí)時(shí)操作系統(tǒng)及其應(yīng)用開(kāi)發(fā)環(huán)境的發(fā)展動(dòng)向是:
7.1 嵌入式實(shí)時(shí)操作系統(tǒng)正向?qū)崟r(shí)超微內(nèi)核(Nanokernel)、開(kāi)放發(fā)展
八十年代后期,國(guó)外提出了微內(nèi)核(Microkernel)的思想,即將傳統(tǒng)操作系統(tǒng)中的許多共性的東西抽象出來(lái),構(gòu)成操作系統(tǒng)的公共基礎(chǔ),即微內(nèi)核,真正具體的操作系統(tǒng)功能則由構(gòu)造在微內(nèi)核之外的服務(wù)器實(shí)現(xiàn)。這是一種機(jī)制與策略分離的開(kāi)放式設(shè)計(jì)思路。
近幾年,國(guó)外發(fā)展了一種基于微內(nèi)核思想設(shè)計(jì)的精巧的嵌入式微內(nèi)核,即實(shí)時(shí)超微內(nèi)核(Nanokernel)。超微內(nèi)核是一種非常緊湊的基本內(nèi)核代碼層, 為嵌入式應(yīng)用提供了可搶占, 快而確定的實(shí)時(shí)服務(wù), 在它的基礎(chǔ)上可以靈活地構(gòu)造各種類(lèi)型的、與現(xiàn)成系統(tǒng)兼容的、可伸縮的嵌入式實(shí)時(shí)操作系統(tǒng)。因此能滿足應(yīng)用代碼的可重用和可伸縮性(scalability)的需求。MRI首先推出的基于實(shí)時(shí)超微內(nèi)核的嵌入式實(shí)時(shí)操作系統(tǒng)VRTXsa,它與VRTX32兼容,并具有更強(qiáng)的功能,實(shí)時(shí)性和可靠性有了很大的改進(jìn)。
7.2 開(kāi)發(fā)環(huán)境向開(kāi)放的、集成化的方向發(fā)展
由于嵌入式應(yīng)用軟件的特殊性,往往要求應(yīng)用程序設(shè)計(jì)者具有一定的實(shí)時(shí)操作系統(tǒng)的專(zhuān)門(mén)知識(shí),能合理地劃分任務(wù),合理的配置系統(tǒng)以及目標(biāo)聯(lián)機(jī)的調(diào)試。因此,要設(shè)計(jì)實(shí)現(xiàn)一個(gè)高性能的實(shí)時(shí)應(yīng)用軟件,需要強(qiáng)有力的交叉開(kāi)發(fā)工具系統(tǒng)的支持。國(guó)外十分重視發(fā)展與實(shí)時(shí)操作系統(tǒng)配合的嵌入式應(yīng)用的集成開(kāi)發(fā)環(huán)境,現(xiàn)已發(fā)展到第三代,它以客戶(hù)-服務(wù)器的系統(tǒng)結(jié)構(gòu)為基礎(chǔ),具有運(yùn)行系統(tǒng)的無(wú)關(guān)性、連接的無(wú)關(guān)性、開(kāi)放的軟件接口(與嵌入式實(shí)時(shí)操作系統(tǒng),與開(kāi)發(fā)工具,與目標(biāo)環(huán)境的接口)、環(huán)境的一致性、宿主機(jī)上的目標(biāo)仿真的特點(diǎn)。
1993年, MRI推出了世界上最先進(jìn)的第三代嵌入式集成交叉開(kāi)發(fā)系統(tǒng)Spectra。該系統(tǒng)可在UNIX及WINDOWS NT上建立起開(kāi)放的、網(wǎng)絡(luò)環(huán)境的交叉開(kāi)發(fā)平臺(tái),能將多來(lái)源的開(kāi)發(fā)工具有機(jī)地結(jié)成一體,對(duì)復(fù)雜的嵌入式應(yīng)用開(kāi)發(fā)提供全過(guò)程支持。
綜上所述,嵌入式實(shí)時(shí)操作系統(tǒng)及其應(yīng)用開(kāi)發(fā)環(huán)境正向開(kāi)放、集成發(fā)展。
今后,RTOS研究方向主要集中在如下幾個(gè)方面:
1. RTOS的標(biāo)準(zhǔn)化研究
如今國(guó)外的RTOS開(kāi)發(fā)商有數(shù)十家,提供了上百個(gè)RTOS,它們各具特色。但這也給應(yīng)用開(kāi)發(fā)者帶來(lái)難題,首先是應(yīng)用代碼的重用性難,當(dāng)選擇不同的RTOS開(kāi)發(fā)時(shí),不能保護(hù)用戶(hù)已有的軟件投資,RTOS的標(biāo)準(zhǔn)化研究越來(lái)越被重視。美國(guó)IEEE協(xié)會(huì)在UNIX的基礎(chǔ)上,制定了實(shí)時(shí)UNIX系統(tǒng)的標(biāo)準(zhǔn)POSIX 1001.4系列協(xié)議,但仍有許多工作還待完成。
2. 多處理器結(jié)構(gòu)RTOS、分布式實(shí)時(shí)操作系統(tǒng)和實(shí)時(shí)網(wǎng)絡(luò)的研究
實(shí)時(shí)應(yīng)用的飛速發(fā)展,對(duì)RTOS的性能提出了更高的要求。單處理器的計(jì)算機(jī)系統(tǒng)已不能很好地滿足某些復(fù)雜實(shí)時(shí)應(yīng)用系統(tǒng)的需要,開(kāi)發(fā)支持多處理器結(jié)構(gòu)的RTOS已成為發(fā)展方向,這方面比較成功的系統(tǒng)有Psos+m等。至于分布式RTOS,國(guó)外一些RTOS廠家雖
已推出部分產(chǎn)品,如QNX、Chorus、Plan 9等,但分布式實(shí)時(shí)操作系統(tǒng)的研究還未完全成熟,特別是在網(wǎng)絡(luò)實(shí)時(shí)性和多處理器間任務(wù)調(diào)度算法上還需進(jìn)一步研究。
3. 集成的開(kāi)放式實(shí)時(shí)系統(tǒng)開(kāi)發(fā)環(huán)境的研究
RTOS研究的另一個(gè)重要方向是集成開(kāi)發(fā)環(huán)境的研究。開(kāi)發(fā)實(shí)時(shí)應(yīng)用系統(tǒng),只有RTOS是不夠的,需要集編輯、編譯、調(diào)試、模擬仿真等功能為一體的集成開(kāi)發(fā)環(huán)境的支持。開(kāi)發(fā)環(huán)境的研究還包括網(wǎng)絡(luò)上多主機(jī)間協(xié)作開(kāi)發(fā)與調(diào)試應(yīng)用技術(shù)的研究、RTOS與環(huán)境的無(wú)縫連接技術(shù)等。
8 實(shí)時(shí)操作系統(tǒng)的結(jié)構(gòu)
一 操作系統(tǒng)的模型
任何操作系統(tǒng)在設(shè)計(jì)上若沒(méi)有一個(gè)簡(jiǎn)化的模型(藍(lán)圖)做為整個(gè)大方向的引導(dǎo),就很容易陷入一種混淆的局面――程序代碼無(wú)組織的交相混雜在一起,甚至導(dǎo)致失敗。模型就象大樓的骨架,先有健全的骨架,然后繼續(xù)填土,粉刷等修飾的工作會(huì)變得比較容易。所以提出一個(gè)操作系統(tǒng)模型(Operating System Model)勢(shì)在必行。
有人稱(chēng),早期的MS-DOS,Windows3.x等產(chǎn)品還稱(chēng)不上操作系統(tǒng),而只是文件操作和圖形界面的“程序組”,因?yàn)楹湍切┑堑蒙洗笱胖玫乃^理論上的模型比較之下,它們離“真正的”操作系統(tǒng)還差一大截,所以操作系統(tǒng)模型應(yīng)該是個(gè)滿足“學(xué)術(shù)理論模型”的操作系統(tǒng),甚至應(yīng)較理論上的更強(qiáng)些。
在操作系統(tǒng)理論上,有較常見(jiàn)的三種模型:?jiǎn)误w模型(Monolithic Model),層狀模型(Layered Model),主從模型(Client/Server Model)。在確定實(shí)時(shí)操作系統(tǒng)模型之前,我們先簡(jiǎn)單了解現(xiàn)有其它操作系統(tǒng)模型:
1 單體模型
20世紀(jì)50年代中期到后期開(kāi)發(fā)的早期操作系統(tǒng)很少考慮結(jié)構(gòu)問(wèn)題,沒(méi)有人具有構(gòu)造大型軟件系統(tǒng)的經(jīng)驗(yàn),并且對(duì)由于相互依賴(lài)和交互產(chǎn)生的問(wèn)題估計(jì)過(guò)低。
單體模型把該有的功能都整合于一個(gè)整體,其中分不出明顯的模塊,任何過(guò)程實(shí)際上都可以調(diào)用任何別的過(guò)程,操作系統(tǒng)內(nèi)部之間的關(guān)系就像炒大鍋菜一般,或者用藕斷絲連來(lái)形容它,其中的函數(shù)調(diào)用來(lái),調(diào)用去,很難分割出單獨(dú)的個(gè)體,如MS-DOS。
這種模型的最大特點(diǎn)就是牽一而發(fā)全身,所以更新,升級(jí)困難。
2 層狀模型
單體模型缺乏結(jié)構(gòu),無(wú)法解決大規(guī)模軟件開(kāi)發(fā)的問(wèn)題,需要采用模塊化的程序設(shè)計(jì)技術(shù),這就產(chǎn)生了分層操作系統(tǒng)。
層狀模型所有功能按層次組織,只是相鄰層之間發(fā)生交互。大多數(shù)層或所有層都在內(nèi)核模式下執(zhí)行。
圖 2 分層的內(nèi)核模型
層狀模型的主要特色是一種由上而下的多層階梯結(jié)構(gòu)(類(lèi)似于我們熟悉的OSI七層模型),與應(yīng)用程序越有關(guān)的東西擺在越靠近應(yīng)用程序的地方(較上層),與應(yīng)用程序越無(wú)關(guān)或不希望應(yīng)用程序直接碰觸到的東西則擺在距離應(yīng)用程序較遠(yuǎn)的地方(較下層),命令則一律由上往下層發(fā)送,執(zhí)行,不允許跨層或任意方向發(fā)送至其它層。
與單體模型比較,層狀模型主要有兩個(gè)優(yōu)點(diǎn):
1.操作系統(tǒng)按功能模塊化使得子系統(tǒng)(模塊)的更新,除錯(cuò)容易。
2.應(yīng)用程序僅接觸到操作系統(tǒng)的最上層應(yīng)用程序界面(API)部分,不易對(duì)整個(gè)系統(tǒng)造成傷害,API是由操作系統(tǒng)提供的較低層的成套函數(shù)或切入點(diǎn),程序設(shè)計(jì)者于其程序中呼叫種種API以獲得各種內(nèi)建于操作系統(tǒng)的功能,如打開(kāi)文件,讀文件,移動(dòng)光標(biāo)位置等等。
層狀模型也存在一些問(wèn)題。每層都處理相當(dāng)多的功能,一層中的主要變化可能會(huì)產(chǎn)生巨大的影響,跟蹤相鄰層(上一層或下一層)中的代碼有很多困難。其結(jié)果是,通過(guò)增加或減少一些功能,在基本操作系統(tǒng)上很難實(shí)現(xiàn)一個(gè)專(zhuān)用版本,并且由于相鄰層之間有很多交互,因而很難保證安全性。
3 主從模型
當(dāng)我們?cè)诰W(wǎng)絡(luò)方面說(shuō)到主從模型(Server/Client)時(shí),一般指的是一部負(fù)責(zé)提供數(shù)據(jù)的服務(wù)器及另一部取得數(shù)據(jù)的工作站,其中所共享的數(shù)據(jù)通常是文件和打印機(jī)等。
操作系統(tǒng)的主從模型也很類(lèi)似,但所分享的數(shù)據(jù)是系統(tǒng)所提供的種種服務(wù),當(dāng)然也負(fù)責(zé)提供服務(wù)的程序及所接受服務(wù)的程序,WindowsNT采用的操作系統(tǒng)架構(gòu)就是主從模型。這兩個(gè)主從模型在抽象上都有個(gè)服務(wù)器及客戶(hù)機(jī)主體,只是形式不一樣,換言之,透過(guò)這種機(jī)制,可將操作系統(tǒng)主體設(shè)計(jì)成分散于一群機(jī)器的分散式操作系統(tǒng),應(yīng)用系統(tǒng)扮演客戶(hù)端角色,操作系統(tǒng)本身則作為服務(wù)器,應(yīng)用程序向操作系統(tǒng)要求服務(wù),操作系統(tǒng)則提供服務(wù)?!?/p>
二 實(shí)時(shí)內(nèi)核
多任務(wù)系統(tǒng)中,內(nèi)核負(fù)責(zé)管理各個(gè)任務(wù),或者說(shuō)為每個(gè)任務(wù)分配CPU時(shí)間,并且負(fù)責(zé)任務(wù)之間的通信。內(nèi)核提供的基本服務(wù)是任務(wù)切換。
之所以使用實(shí)時(shí)內(nèi)核可以大大簡(jiǎn)化應(yīng)用程序的設(shè)計(jì),是因?yàn)閷?shí)時(shí)內(nèi)核允許將應(yīng)用分成若干個(gè)任務(wù),由實(shí)時(shí)內(nèi)核來(lái)管理它們。內(nèi)核本身也增加了應(yīng)用程序的額外負(fù)荷,代碼空間增加了ROM的用量,內(nèi)核本身的數(shù)據(jù)結(jié)構(gòu)增加了RAM的用量。但更為主要的是,每個(gè)任務(wù)要有自己的堆??臻g,這一塊占起內(nèi)存來(lái)是相當(dāng)厲害的。內(nèi)核本身對(duì)CPU的占用時(shí)間一般在2%-5%之間。
單片機(jī)一般不能運(yùn)行實(shí)時(shí)內(nèi)核,因?yàn)閱纹瑱C(jī)的RAM很有限。通過(guò)提供必不可少的系統(tǒng)服務(wù),諸如信號(hào)量管理、消息隊(duì)列、延時(shí)等,實(shí)時(shí)內(nèi)核使得CPU的利用更為有效。
需要指出的是,實(shí)時(shí)內(nèi)核并不等于實(shí)時(shí)操作系統(tǒng),實(shí)時(shí)內(nèi)核只是實(shí)時(shí)操作系統(tǒng)的一部分。
內(nèi)核是整個(gè)操作系統(tǒng)的基礎(chǔ),實(shí)時(shí)內(nèi)核同樣是實(shí)時(shí)操作系統(tǒng)的基礎(chǔ),目前很多實(shí)時(shí)內(nèi)核采用微內(nèi)核結(jié)構(gòu)。實(shí)時(shí)內(nèi)核通常是基于優(yōu)先級(jí)調(diào)度的內(nèi)核,所有時(shí)間要求苛刻的事件都得到了盡可能快捷、有效的處理。
如果應(yīng)用項(xiàng)目對(duì)額外的需求可以承受,應(yīng)該考慮使用實(shí)時(shí)內(nèi)核。這些額外的需求為:內(nèi)核的價(jià)格,額外的ROM/RAM開(kāi)銷(xiāo),2-5%的CPU額外負(fù)荷。使用實(shí)時(shí)內(nèi)核會(huì)增加價(jià)格成本,在一些應(yīng)用中,價(jià)格就是一起,以至于對(duì)使用RTOS連想都不敢想。
為滿足某些特殊需要的實(shí)時(shí)軟件開(kāi)發(fā)的要求,可能會(huì)需要自己開(kāi)發(fā)實(shí)時(shí)內(nèi)核,一般它要符合POSIX實(shí)時(shí)擴(kuò)展標(biāo)準(zhǔn)接口(支持系統(tǒng)的開(kāi)發(fā)性和可移植性要求)。
實(shí)時(shí)內(nèi)核設(shè)計(jì)時(shí)要考慮輪詢(xún)、協(xié)同、中斷驅(qū)動(dòng)以及前/后臺(tái)工作等需求,提供對(duì)任務(wù)、中斷、時(shí)間和多處理器等的全面管理,并要求用高級(jí)語(yǔ)言實(shí)現(xiàn)(可移植性考慮)。設(shè)計(jì)出的實(shí)時(shí)內(nèi)核要求緊湊、高效、專(zhuān)用、可移植性好。
實(shí)時(shí)內(nèi)核的多處理器支持應(yīng)包括處理同構(gòu)和異構(gòu)系統(tǒng)的能力,其內(nèi)核程序應(yīng)具有自動(dòng)補(bǔ)償不同處理器之間體系結(jié)構(gòu)的差別(如字節(jié)交換等)。這使得從一個(gè)處理器家族到另一個(gè)處理器家族的轉(zhuǎn)換變得異常容易,且不需要重新設(shè)計(jì)。
三 微內(nèi)核
微內(nèi)核(microkernel)是一個(gè)小型的操作系統(tǒng)核心,為模塊化擴(kuò)展提供了基礎(chǔ)。微內(nèi)核通過(guò)在Mach操作系統(tǒng)中的使用而推廣。理論上,微內(nèi)核方法提供了高度的靈活性和模塊化。當(dāng)今許多操作系統(tǒng)都聲稱(chēng)采用了微內(nèi)核結(jié)構(gòu),例如Windows 2000。
目前關(guān)于微內(nèi)核的概念還有一些含糊,關(guān)于微內(nèi)核的許多問(wèn)題,例如微內(nèi)核應(yīng)該提供什么功能以及實(shí)現(xiàn)什么結(jié)構(gòu),不同的操作系統(tǒng)設(shè)計(jì)者有不同的回答。
與微內(nèi)核相對(duì)的是宏內(nèi)核的概念。 宏內(nèi)核中把本來(lái)在微內(nèi)核之外實(shí)現(xiàn)的許多操作系統(tǒng)功能放到了內(nèi)核之中實(shí)現(xiàn)(如進(jìn)程管理,內(nèi)存管理等)。 Linux就是這樣的系統(tǒng)。
微內(nèi)核將許多操作系統(tǒng)服務(wù)放入分離的服務(wù)器,如文件系統(tǒng),設(shè)備驅(qū)動(dòng)程序,而應(yīng)用程序通過(guò)消息傳遞調(diào)用操作系統(tǒng)服務(wù)。微內(nèi)核結(jié)構(gòu)必然是多任務(wù)的,第一代微內(nèi)核,在核心提供了較多的服務(wù),因此被稱(chēng)為“胖微內(nèi)核”,它的典型代表是Mach,它既是GNU HURD也是APPLE SERVER OS 的核心,可以說(shuō),蒸蒸日上。第二代為內(nèi)核只提供最基本的操作系統(tǒng)服務(wù),典型的操作系統(tǒng)是QNX,QNX在理論界很有名,被認(rèn)為是一種先進(jìn)的操作系統(tǒng)。
微內(nèi)核通常采用分層結(jié)構(gòu),如圖 3所示。
圖 3 微內(nèi)核操作系統(tǒng)
微內(nèi)核通常只保留進(jìn)程間通訊(IPC),任務(wù)調(diào)度,低級(jí)存儲(chǔ)管理,中斷處理等幾項(xiàng)最基本的功能,它依據(jù)客戶(hù)-服務(wù)器模型概念,把所有的其它的操作系統(tǒng)功能都變成一個(gè)都變成一個(gè)個(gè)用戶(hù)態(tài)的服務(wù)器,而用戶(hù)態(tài)進(jìn)程則被當(dāng)作客戶(hù)??蛻?hù)應(yīng)用程序要用到操作系統(tǒng)時(shí),其實(shí)就是通過(guò)微內(nèi)核與服務(wù)器通訊,微內(nèi)核僅僅成了一個(gè)傳遞消息的工具。微內(nèi)核驗(yàn)證消息的有效性,在客戶(hù)機(jī)和服務(wù)器之間傳遞它們并核準(zhǔn)對(duì)硬件的存取。例如,如果應(yīng)用程序想打開(kāi)一個(gè)文件,則它給文件系統(tǒng)服務(wù)器發(fā)送消息,如圖4所示;如果要?jiǎng)?chuàng)建一個(gè)任務(wù),則它給任務(wù)服務(wù)器發(fā)送消息。每個(gè)服務(wù)器也可以給別的服務(wù)器發(fā)送消息,并可以調(diào)用微內(nèi)核提供的其它功能。
圖 4 應(yīng)用程序與服務(wù)器之間的通訊
微內(nèi)核是指內(nèi)核功能少,而不一定是內(nèi)核尺寸小,例如著名的微內(nèi)核操作系統(tǒng)Mach的內(nèi)核就有100-200K字節(jié)。
采用微內(nèi)核的優(yōu)點(diǎn):
1.一致性接口:微內(nèi)核提供了一致性接口,所有的服務(wù)都通過(guò)消息傳遞提供,用戶(hù)態(tài)程序不需要區(qū)分是內(nèi)核級(jí)服務(wù)還是用戶(hù)級(jí)服務(wù)。
2.可移植性:與CPU有關(guān)的硬件方面的細(xì)節(jié)都在微內(nèi)核中,這樣,整個(gè)操作系統(tǒng)就很容易從一個(gè)CPU體系移植到另一個(gè)CPU體系。
3.可擴(kuò)展性:如果要擴(kuò)展功能,僅是要增加或修改相應(yīng)的服務(wù)器,而不用構(gòu)造一個(gè)新內(nèi)核。
4.靈活性:與可擴(kuò)展性相對(duì)應(yīng),不僅可以增加新功能,還可以刪除現(xiàn)有的功能,以產(chǎn)生一個(gè)更小、更高效的實(shí)現(xiàn)。用戶(hù)可以根據(jù)應(yīng)用的實(shí)際需要,刪除某些可選的功能,從而自己定制了一個(gè)更符合自己需要的操作系統(tǒng)。
5.可靠性:在微內(nèi)核方式下,各個(gè)服務(wù)器都是獨(dú)立的用戶(hù)態(tài)進(jìn)程,有自己的內(nèi)存保護(hù)空間,以標(biāo)準(zhǔn)的IPC方式通訊,一個(gè)服務(wù)器出錯(cuò),不會(huì)導(dǎo)致整個(gè)系統(tǒng)崩潰。另外,軟件規(guī)模越大,越難以保證其可靠性,而微內(nèi)核較小,可以被嚴(yán)格測(cè)試,而且它只使用了少量的API接口,便于掌握,而且與其它模塊的交互較少,有利于產(chǎn)生高質(zhì)量的代碼。
6.分布式系統(tǒng)支持:服務(wù)器可以在不同的處理機(jī)上運(yùn)行,適合多處理機(jī)系統(tǒng)或分布式處理系統(tǒng)。
當(dāng)把微內(nèi)核機(jī)制用于實(shí)時(shí)操作系統(tǒng)時(shí),存在兩種擔(dān)心:一是用戶(hù)態(tài)與內(nèi)核態(tài)的切換頻率,會(huì)增加上下文切換時(shí)間;另一是進(jìn)程之間的消息傳遞開(kāi)銷(xiāo)要比傳統(tǒng)操作系統(tǒng)的系統(tǒng)調(diào)用的開(kāi)銷(xiāo)要大。通常上下文切換時(shí)間與執(zhí)行一項(xiàng)操作系統(tǒng)服務(wù)總的時(shí)間相比很小,尤其是在將上下文切換時(shí)間作了優(yōu)化之后。分立的服務(wù)器進(jìn)程可以使各項(xiàng)操作系統(tǒng)服務(wù)并行地進(jìn)行,而且各個(gè)服務(wù)器進(jìn)程還可以像用戶(hù)進(jìn)程一樣按優(yōu)先級(jí)處理,高優(yōu)先級(jí)服務(wù)進(jìn)程可以搶占低優(yōu)先級(jí)服務(wù)進(jìn)程。這些都帶來(lái)極大的優(yōu)越性。因此,總體來(lái)看,微內(nèi)核開(kāi)銷(xiāo)比傳統(tǒng)操作系統(tǒng)的開(kāi)銷(xiāo)反而要小。
大多數(shù)消息傳輸都在20字節(jié)的數(shù)量級(jí),傳輸這樣的消息的開(kāi)銷(xiāo)本來(lái)就不大,微內(nèi)核提供multi-part消息傳輸機(jī)制,在傳輸長(zhǎng)消息時(shí),可以將消息從一個(gè)進(jìn)程直接傳到另一個(gè)進(jìn)程,避免了為使消息塊相鄰而進(jìn)行多余的拷貝工作。在傳輸長(zhǎng)消息時(shí),高優(yōu)先級(jí)進(jìn)程還可以搶占,不至于被長(zhǎng)消息傳輸所延誤。另外,直接傳遞消息而不是傳遞消息的指針,就不必使用信號(hào)燈來(lái)判斷哪一個(gè)進(jìn)程擁有消息,從而避免了信號(hào)燈的開(kāi)銷(xiāo)。最后,消息傳遞方法使得用戶(hù)的地址空間和系統(tǒng)服務(wù)提供者的地址空間完全分開(kāi),使它們十分容易在不同的網(wǎng)絡(luò)節(jié)點(diǎn)上運(yùn)行。所有這些,都使得消息傳遞的開(kāi)銷(xiāo)不大。
二 實(shí)時(shí)操作系統(tǒng)的基本概念
1 任務(wù)(task)
實(shí)時(shí)操作系統(tǒng)任務(wù)的概念與我們通常所說(shuō)的通用計(jì)算機(jī)操作系統(tǒng)不同,通用操作系統(tǒng)的任務(wù)是指提交給計(jì)算機(jī)的一項(xiàng)工作,一個(gè)任務(wù)可以包括多個(gè)進(jìn)程,而一個(gè)進(jìn)程又可以包括多個(gè)線程。RTOS的任務(wù)是由計(jì)算機(jī)所執(zhí)行的一項(xiàng)活動(dòng),也就是一段程序,該程序可以認(rèn)為CPU完全只屬于該程序自己,它大致等同于分時(shí)操作系統(tǒng)中的進(jìn)程(Process)的概念。
實(shí)時(shí)應(yīng)用程序的設(shè)計(jì)過(guò)程包括如何把問(wèn)題劃分成多個(gè)任務(wù),每個(gè)任務(wù)都是整個(gè)應(yīng)用的某一部分,它包括一段程序和與這個(gè)程序有關(guān)的數(shù)據(jù)及計(jì)算機(jī)資源(有它自己的一套CPU寄存器和堆棧空間等)。如圖5所示。
圖 5 多任務(wù)
圖6給出了一個(gè)多任務(wù)系統(tǒng)的內(nèi)存分配。在內(nèi)存里,操作系統(tǒng)本身以及各個(gè)任務(wù)都被指定有各自動(dòng)堆棧區(qū)。有一個(gè)自由存儲(chǔ)池被操作系統(tǒng)用來(lái)生成消息通道或用作公共數(shù)據(jù)區(qū),供各個(gè)任務(wù)用來(lái)交換數(shù)據(jù)。另外,還有供操作系統(tǒng)和所有任務(wù)共同使用的若干變量。注意:具體的內(nèi)存分配情況與CPU緊密有關(guān),而且與操作系統(tǒng)也有一些關(guān)系。
圖 6 多任務(wù)的內(nèi)存分配圖
幾個(gè)任務(wù)可以執(zhí)行同一個(gè)程序,但它們之間并無(wú)關(guān)系,因?yàn)樗鼈兪褂酶髯詣?dòng)堆棧、各自的消息通道和其它資源。例如,一個(gè)實(shí)時(shí)系統(tǒng)有三個(gè)A/D轉(zhuǎn)換器,可以生成三個(gè)任務(wù),各使用一個(gè)ADC,三個(gè)任務(wù)運(yùn)行同一個(gè)程序,但被指定用于不同的資源(ADC),使用各自動(dòng)堆棧區(qū)和各自動(dòng)消息通道來(lái)將輸入數(shù)據(jù)傳送到其它任務(wù)去。這三個(gè)任務(wù)是獨(dú)立運(yùn)行的,哪一個(gè)任務(wù)準(zhǔn)備好,就運(yùn)行哪一個(gè)任務(wù)。
由于若干任務(wù)使用同一個(gè)程序,因此在實(shí)時(shí)多任務(wù)系統(tǒng)中,程序必須是可重入的。除了用戶(hù)程序的可重入性之外,還有內(nèi)核的可重入性。
實(shí)時(shí)操作系統(tǒng)的內(nèi)核啟動(dòng)后一般都會(huì)創(chuàng)建兩個(gè)任務(wù):根任務(wù)(root task)和空閑任務(wù)(idle task)。
根任務(wù)(root task)
根任務(wù)通常是內(nèi)核啟動(dòng)后創(chuàng)建的第一個(gè)任務(wù),再由它根據(jù)用戶(hù)的需要?jiǎng)?chuàng)建其它一些任務(wù)。
空閑任務(wù)(idle task)
如果沒(méi)有任務(wù)處于就緒隊(duì)列,空閑任務(wù)將被執(zhí)行,也就是說(shuō),空閑任務(wù)是優(yōu)先級(jí)最低的任務(wù),總處于就緒隊(duì)列的末尾,在處理器空閑時(shí)調(diào)度程序就自動(dòng)運(yùn)行它??臻e任務(wù)看起來(lái)與其它用戶(hù)任務(wù)一樣,只是它是一個(gè)不作任何事情的循環(huán),對(duì)上層軟件開(kāi)發(fā)者來(lái)說(shuō),可以完全不知道其存在,應(yīng)用程序不能刪除空閑任務(wù)。
A, 任務(wù)的特點(diǎn)
任務(wù)就是一個(gè)具有獨(dú)立功能的無(wú)限循環(huán)的程序段的一次運(yùn)行活動(dòng)。具有動(dòng)態(tài)性、并發(fā)性、異步獨(dú)立性的特點(diǎn)。
1.動(dòng)態(tài)性:
任務(wù)的狀態(tài)是不斷變化的,一般分為:休眠態(tài)(dormant), 就緒態(tài)(ready),運(yùn)行態(tài)(running),掛起態(tài)(suspended)等。
2.并發(fā)性:
系統(tǒng)中同時(shí)存在多個(gè)任務(wù),它們宏觀上是同時(shí)運(yùn)行的
3.異步獨(dú)立性:
任務(wù)是系統(tǒng)中獨(dú)立運(yùn)行的基本單元,也是內(nèi)核分配和調(diào)度的基本單元,每個(gè)任務(wù)各自按相互獨(dú)立的不可預(yù)知的速度運(yùn)行,走走停停。
每個(gè)任務(wù)都要按排一個(gè)決定其重要性的優(yōu)先級(jí),都有一個(gè)無(wú)限循環(huán)的程序段規(guī)定其功能(如一個(gè)C語(yǔ)言過(guò)程),并相應(yīng)有一個(gè)數(shù)據(jù)段、堆棧段及一個(gè)任務(wù)控制塊TCB(用于保存CPU的現(xiàn)場(chǎng),狀態(tài)等)。
B. 任務(wù)的狀態(tài)
系統(tǒng)中的一個(gè)任務(wù)可以處于各種狀態(tài),最基本的狀態(tài)有四種:運(yùn)行(Executing),就緒(Ready),等待(waiting,通常又稱(chēng)為掛起,suspend),休眠(Dormant)。圖7 顯示了在一個(gè)任務(wù)中這幾種狀態(tài)之間的關(guān)系。
圖 7 一個(gè)任務(wù)可能的狀態(tài)遷移圖
1.休眠:
一個(gè)休眠的任務(wù)是指沒(méi)有被初始化的未被創(chuàng)建的任務(wù),或任務(wù)的執(zhí)行被終止的任務(wù)(任務(wù)刪除),也可以認(rèn)為是系統(tǒng)中不存在了的任務(wù)。操作系統(tǒng)一般不為處于休眠狀態(tài)的任務(wù)分配TCB。
任務(wù)在它們被創(chuàng)建之前處于休眠狀態(tài)。當(dāng)它們被刪除后,又重新回到休眠狀態(tài)??梢哉f(shuō)休眠狀態(tài)是一個(gè)任務(wù)的起點(diǎn)和終點(diǎn)。
2.運(yùn)行:
處于運(yùn)行態(tài)的任務(wù)擁有CPU控制權(quán)并正在執(zhí)行。任何時(shí)刻都只有一個(gè)任務(wù)處于運(yùn)行態(tài)。
處于運(yùn)行態(tài)的任務(wù)可以被中斷打斷,當(dāng)中斷發(fā)生時(shí),轉(zhuǎn)向中斷處理程序(ISR),原來(lái)正在運(yùn)行的任務(wù)暫時(shí)不能運(yùn)行,就進(jìn)入了中斷狀態(tài)。
3.就緒:
就緒狀態(tài)的任務(wù)是指運(yùn)行的一切條件都準(zhǔn)備好馬上就能運(yùn)行的任務(wù)。例如,剛被創(chuàng)建的任務(wù)就處于就緒狀態(tài)。但就緒態(tài)的任務(wù)要成為運(yùn)行態(tài),就必須比所有處于就緒態(tài)的任務(wù)的優(yōu)先級(jí)高。
4.等待:
任務(wù)發(fā)生阻塞,被移到任務(wù)等待隊(duì)列,等待系統(tǒng)實(shí)時(shí)事件的發(fā)生而喚醒。從而轉(zhuǎn)為就緒或運(yùn)行。
任務(wù)有激活和非激活兩種。非激活的任務(wù)是休眠態(tài)(dormant)的任務(wù), 它不競(jìng)爭(zhēng)CPU。激活的任務(wù)具有運(yùn)行,掛起和就緒三種狀態(tài)。每個(gè)激活的任務(wù)都需安排一優(yōu)先級(jí)(0-255), 具有唯一的任務(wù)標(biāo)識(shí)號(hào)(1-最大任務(wù)數(shù)),應(yīng)用的最大激活任務(wù)數(shù)需要在配置表中配置。調(diào)度程序根據(jù)優(yōu)先級(jí)和引起重調(diào)度的系統(tǒng)調(diào)用將任務(wù)由一個(gè)狀態(tài)變?yōu)榱硪粋€(gè)狀態(tài)。
內(nèi)核為每個(gè)激活的任務(wù)分配一任務(wù)控制塊(TCB)和任務(wù)堆棧,以保存任務(wù)在非運(yùn)行狀態(tài)時(shí)的任務(wù)狀態(tài)信息即上下文。
任務(wù)可創(chuàng)建其它的任務(wù)。它們也可以刪除、掛起、喚醒任務(wù),查詢(xún)?nèi)蝿?wù)的狀態(tài),改變它們自身或其任務(wù)的優(yōu)先級(jí)。任務(wù)還可鎖住調(diào)度使其他任務(wù)搶占它,以運(yùn)行其關(guān)鍵的臨界代碼區(qū)。
C. 任務(wù)控制塊與任務(wù)的上下文切換
任務(wù)控制塊(TCB)用來(lái)描述任務(wù),每一個(gè)任務(wù)都與一個(gè)TCB相關(guān)聯(lián)。TCB包括了任務(wù)的當(dāng)前狀態(tài)、優(yōu)先級(jí)、要等待的事件或資源、任務(wù)的程序代碼的起始地址、初始堆棧指針、寄存器內(nèi)容等信息。調(diào)度程序在任務(wù)狀態(tài)切換時(shí)要用到這些信息。
在多任務(wù)系統(tǒng)中,上下文切換(context switch)指的是當(dāng)處理器的控制權(quán)由運(yùn)行任務(wù)轉(zhuǎn)移到另外一個(gè)就緒任務(wù)時(shí)所發(fā)生的事件序列。當(dāng)前運(yùn)行的任務(wù)轉(zhuǎn)為就緒,掛起,或刪除時(shí),另外一個(gè)被選定的就緒任務(wù)就成為當(dāng)前任務(wù)。上下文切換包括保存當(dāng)前任務(wù)的狀態(tài),決定哪個(gè)任務(wù)運(yùn)行,恢復(fù)將要運(yùn)行的那個(gè)任務(wù)的狀態(tài)。保存和恢復(fù)上下文是依賴(lài)于相關(guān)的處理器的。
任務(wù)切換過(guò)程增加了應(yīng)用程序的額外負(fù)荷。CPU的內(nèi)部寄存器越多,額外負(fù)荷就越重。做任務(wù)切換所需要的時(shí)間取決于CPU有多少寄存器要入棧。實(shí)時(shí)內(nèi)核的性能不應(yīng)該以每秒鐘能做多少次任務(wù)切換來(lái)評(píng)價(jià)。
D. 實(shí)時(shí)嵌入式系統(tǒng)的任務(wù)劃分原則
任務(wù)是代碼運(yùn)行的一個(gè)映象,從系統(tǒng)的角度看,任務(wù)是競(jìng)爭(zhēng)系統(tǒng)資源的最小運(yùn)行單元。任務(wù)可以使用或等待CPU、I/O設(shè)備及內(nèi)存空間等系統(tǒng)資源,并獨(dú)立于其它任務(wù),與它們一起并發(fā)運(yùn)行(宏觀上如此)。操作系統(tǒng)內(nèi)核通過(guò)一定的指示來(lái)進(jìn)行任務(wù)的切換,這些指示都是來(lái)自對(duì)內(nèi)核的系統(tǒng)調(diào)用。
在應(yīng)用程序中,任務(wù)在表面上具有與普通函數(shù)相似的格式,但任務(wù)有著自己較明顯的特點(diǎn):
1. 任務(wù)具有任務(wù)初始化的起點(diǎn)(如獲取一些系統(tǒng)對(duì)象的ID等);
2. 具有存放執(zhí)行內(nèi)容的私用數(shù)據(jù)區(qū)(如任務(wù)創(chuàng)建時(shí)明確定義的用戶(hù)堆棧和堆棧);
3. 任務(wù)的主體結(jié)構(gòu)表現(xiàn)為一個(gè)無(wú)限循環(huán)體或有明確的終止(任務(wù)不同于函數(shù),無(wú)返回)。
在設(shè)計(jì)一個(gè)較為復(fù)雜的多任務(wù)應(yīng)用時(shí),進(jìn)行的合理的任務(wù)劃分對(duì)系統(tǒng)的運(yùn)行效率、實(shí)時(shí)性和吞吐量影響極大。任務(wù)分解過(guò)細(xì)會(huì)引起任務(wù)頻繁切換的開(kāi)銷(xiāo)增加,而任務(wù)分解不夠徹底會(huì)造成原本可以并行的操作只能按順序串行完成,從而減少了系統(tǒng)的吞吐量。
為了達(dá)到系統(tǒng)效率和吞吐量之間的平衡與折衷,在應(yīng)用設(shè)計(jì)應(yīng)遵循如下的任務(wù)分解規(guī)則(假設(shè)下述任務(wù)的發(fā)生都依賴(lài)于唯一的觸發(fā)條件,如兩個(gè)任務(wù)能夠滿足下面的條件之一,它們可以合理地分開(kāi)):
1. 時(shí)間:兩個(gè)任務(wù)所依賴(lài)的周期條件具有不同的頻率和時(shí)間段;
2. 異步性:兩個(gè)任務(wù)所依賴(lài)的條件沒(méi)有相互的時(shí)間關(guān)系;
3. 優(yōu)先級(jí):兩個(gè)任務(wù)所依賴(lài)的條件需要有不同的優(yōu)先級(jí);
4. 清晰性/可維護(hù)性:兩個(gè)任務(wù)可以可在功能上或邏輯上互相分開(kāi)。
從軟件工程和面向?qū)ο蟮脑O(shè)計(jì)方法來(lái)看,各個(gè)模塊(任務(wù))間數(shù)據(jù)的通信量應(yīng)該盡量小,并且最好少出現(xiàn)控制耦合(即一個(gè)任務(wù)可控制另一個(gè)任務(wù)的執(zhí)行流程或功能),如非得出現(xiàn),這應(yīng)采取相應(yīng)的措施(任務(wù)間通信)使他們實(shí)現(xiàn)同步或互斥。避免可能引起的臨界資源沖突。
在設(shè)計(jì)一個(gè)復(fù)雜應(yīng)用時(shí),上面的任務(wù)分解原則僅能作一初步的參考,真正設(shè)計(jì)時(shí)還需要更多的實(shí)際分析和設(shè)計(jì)經(jīng)驗(yàn),才能使系統(tǒng)達(dá)到預(yù)定性能指標(biāo)和效率。
2 互斥
實(shí)現(xiàn)任務(wù)間通信最簡(jiǎn)便的方法是使用共享數(shù)據(jù)結(jié)構(gòu)。特別是當(dāng)所有的任務(wù)都在一個(gè)單一地址空間下,能使用全程變量、指針、緩沖區(qū)、鏈表、循環(huán)緩沖區(qū)等,使用共享數(shù)據(jù)結(jié)構(gòu)通信就更為容易。雖然共享數(shù)據(jù)區(qū)的方法簡(jiǎn)化了任務(wù)間的信息交互,但是必須保證每個(gè)任務(wù)在處理共享數(shù)據(jù)時(shí)的排它性,以避免競(jìng)爭(zhēng)和數(shù)據(jù)的破壞。
兩個(gè)或多個(gè)任務(wù)訪問(wèn)某些共享數(shù)據(jù),其最后的執(zhí)行結(jié)果取決于任務(wù)運(yùn)行的精確時(shí)序,這稱(chēng)為競(jìng)爭(zhēng)條件(race conditions)。調(diào)試包含有競(jìng)爭(zhēng)條件的程序是一件很頭痛的事情,大多數(shù)情況的運(yùn)行結(jié)果都很好,但在極少數(shù)情況下發(fā)生了一些無(wú)法解釋的奇怪現(xiàn)象。實(shí)際上凡是涉及到共享內(nèi)存、共享文件,以及其它任何共享資源的情況都可能引發(fā)類(lèi)似的錯(cuò)誤。要避免這類(lèi)錯(cuò)誤,需要以某種手段確保當(dāng)一個(gè)任務(wù)使用一個(gè)共享資源時(shí),其它任務(wù)不能做同樣的操作,這就是互斥(mutual exclusion)。
避免競(jìng)爭(zhēng)條件的問(wèn)題也可以用一種抽象的方式進(jìn)行描述,我們把對(duì)共享資源進(jìn)行訪問(wèn)的程序片段稱(chēng)作臨界區(qū)(critical region)或臨界段(critical section)。如果能夠適當(dāng)安排使多個(gè)任務(wù)不可能同時(shí)處于臨界區(qū),就可以避免競(jìng)爭(zhēng)條件。盡管這樣可以防止競(jìng)爭(zhēng)條件,但它還不能保證使用共享資源的并發(fā)任務(wù)能夠正確和高效地進(jìn)行操作。對(duì)于一個(gè)好的解決方案,需要滿足以下四個(gè)條件:
1.任何兩個(gè)任務(wù)不能同時(shí)處于臨界區(qū);
2.不應(yīng)對(duì)CPU的速度和數(shù)目作任何假設(shè);
3.臨界區(qū)外的任務(wù)不得阻塞其它任務(wù);
4.不得使任務(wù)在臨界區(qū)外無(wú)休止地等待。
在單處理器環(huán)境下,多任務(wù)并發(fā)執(zhí)行,實(shí)際上它們并不重疊,而是交替執(zhí)行。與共享資源打交道時(shí),使之滿足互斥條件最一般的方法有:關(guān)中斷、使用測(cè)試并置位指令、禁止做任務(wù)切換或利用信號(hào)量等。下面我們將分別進(jìn)行介紹。
A. 關(guān)中斷和開(kāi)中斷
處理共享資源時(shí)保證互斥,最簡(jiǎn)便快捷的方法是關(guān)中斷和開(kāi)中斷。
中斷被關(guān)閉后,時(shí)鐘中斷也被屏蔽了,CPU只有在發(fā)生時(shí)鐘或其它中斷時(shí)才會(huì)進(jìn)行任務(wù)切換,關(guān)中斷也就意味著CPU將不會(huì)被切換到其它任務(wù),因此在訪問(wèn)共享資源時(shí)可以不用擔(dān)心其它任務(wù)的可能介入。
可是,必須小心,關(guān)中斷的時(shí)間不能太長(zhǎng),因?yàn)樗鼤?huì)影響整個(gè)系統(tǒng)的中斷響應(yīng)時(shí)間,即中斷延遲時(shí)間。
當(dāng)改變或復(fù)制某幾個(gè)變量的值時(shí),應(yīng)想到這種方法來(lái)做。這也是在中斷服務(wù)子程序中處理共享變量或共享數(shù)據(jù)結(jié)構(gòu)的唯一方法。在任何情況下,關(guān)中斷的時(shí)間都要盡量短。
如果采用某種實(shí)時(shí)內(nèi)核,一般來(lái)說(shuō),關(guān)中斷地最長(zhǎng)時(shí)間不超過(guò)內(nèi)核本身的關(guān)中斷時(shí)間,就不會(huì)影響系統(tǒng)中斷延遲。當(dāng)然得知道內(nèi)核里中斷關(guān)了多久。凡是好的實(shí)時(shí)內(nèi)核,廠商都提供這方面的數(shù)據(jù)。
對(duì)于上層應(yīng)用程序,一般我們不主張使用關(guān)中斷的方法來(lái)實(shí)現(xiàn)互斥,至少它不應(yīng)該作為通用的互斥機(jī)制。
需要注意的是:該方法不適用于多處理器環(huán)境。
B. 測(cè)試并置位
如果不使用實(shí)時(shí)內(nèi)核,當(dāng)兩個(gè)任務(wù)共享一個(gè)資源時(shí),一定要約定好,先測(cè)試某一個(gè)全局變量,如果該變量為0,則允許該任務(wù)A與共享資源打交道。為防止另一個(gè)任務(wù)B也要使用該資源,前者只要簡(jiǎn)單地將全局變量置為1,這通常稱(chēng)為測(cè)試并置位(Test-And-Set,簡(jiǎn)稱(chēng)為T(mén)AS)。
TAS操作可能是微處理器的單獨(dú)一條不會(huì)被中斷地指令,或者是在程序關(guān)中斷做TAS操作再開(kāi)中斷。有些微處理器有硬件的TAS指令,如Motorola的68000系列。
這種機(jī)制通常存在一些較為嚴(yán)重的缺點(diǎn),例如:一般使用了忙等待策略這會(huì)消耗處理器時(shí)間,而且還可能會(huì)出現(xiàn)餓死和死鎖問(wèn)題。
在實(shí)際應(yīng)用中,這種方法使用并不多。
C. 禁止,然后允許任務(wù)切換
如果任務(wù)不與中斷服務(wù)子程序共享變量或數(shù)據(jù)結(jié)構(gòu),可以禁止、然后允許任務(wù)切換。注意,此時(shí)雖然任務(wù)切換被禁止了,但中斷還是開(kāi)著的。如果這時(shí)中斷來(lái)了,中斷服務(wù)子程序會(huì)在這一臨界區(qū)內(nèi)立即執(zhí)行。中斷服務(wù)子程序結(jié)束時(shí),盡管可能有優(yōu)先級(jí)高的任務(wù)已經(jīng)進(jìn)入就緒態(tài),內(nèi)核還是返回到原來(lái)被中斷了的任務(wù)。直到執(zhí)行完給任務(wù)切換開(kāi)鎖函數(shù),內(nèi)核再查看有沒(méi)有優(yōu)先級(jí)更高的任務(wù)被中斷服務(wù)子程序激活而進(jìn)入進(jìn)入就緒態(tài),如果有,則做任務(wù)切換。
雖然這種方法是可行的,但應(yīng)盡量避免禁止任務(wù)切換之類(lèi)的操作,因?yàn)閮?nèi)核最主要的功能就是任務(wù)的調(diào)度與協(xié)調(diào)。禁止任務(wù)切換顯然與內(nèi)核的初衷相違背。
D. 信號(hào)量(semaphore)
信號(hào)量是1965年Edgser Dijkstra提出的一種方法。信號(hào)量實(shí)際上是一種約定機(jī)制。在多任務(wù)內(nèi)核中普遍使用信號(hào)量用于:
控制共享資源的使用權(quán)(滿足互斥條件);
標(biāo)志某事件的發(fā)生;
使兩個(gè)任務(wù)的行為同步。
信號(hào)量的操作有兩種:P和V。對(duì)一個(gè)信號(hào)量進(jìn)行P操作就是檢查其值是否大于0,若是,則將其值減1并繼續(xù)執(zhí)行;否則當(dāng)前任務(wù)將被阻塞,而且此時(shí)P操作并沒(méi)有結(jié)束。檢查數(shù)值、改變數(shù)值,以及可能發(fā)生的任務(wù)阻塞操作均作為一個(gè)單一的、不可分割的原子操作(atomic action)完成。即保證一旦一個(gè)信號(hào)量操作開(kāi)始,則在操作完成或阻塞之前,別的任務(wù)均不允許訪問(wèn)該信號(hào)量。與P操作相對(duì)應(yīng),對(duì)一個(gè)信號(hào)量進(jìn)行V操作就是遞增信號(hào)量的值(它同樣是一個(gè)不可分割的原子操作),如果一個(gè)或多個(gè)任務(wù)正因?yàn)樵撔盘?hào)量而阻塞,無(wú)法完成一個(gè)先前的P操作,則由操作系統(tǒng)選擇其中的一個(gè)(例如,隨機(jī)挑選或選擇優(yōu)先級(jí)最高的任務(wù)),并允許其完成它的V操作。
二進(jìn)制信號(hào)量(binary semaphore)是一種經(jīng)常使用的特殊信號(hào)量,它是只有兩個(gè)值(0和1)的變量。二進(jìn)制信號(hào)量象是一把鑰匙,任務(wù)要運(yùn)行下去,得先拿到這把鑰匙。如果信號(hào)量已被任務(wù)占用,該任務(wù)只得掛起,直到信號(hào)量被當(dāng)前使用者釋放。
大多數(shù)實(shí)時(shí)操作系統(tǒng)都不允許在中斷處理程序中進(jìn)行P操作(如果允許P操作,一般也要求調(diào)用后立即返回,不能等待,即不允許發(fā)生阻塞),但一般允許V操作。
信號(hào)量常被用過(guò)了頭。處理簡(jiǎn)單的共享變量也使用信號(hào)量則是多余的。請(qǐng)求和釋放信號(hào)量的過(guò)程是要花相當(dāng)?shù)臅r(shí)間的。有時(shí)這種額外的負(fù)荷是不必要的。用戶(hù)可能只需要關(guān)中斷、開(kāi)中斷來(lái)處理簡(jiǎn)單的共享變量,以提高效率。然而如果關(guān)中斷時(shí)間長(zhǎng)了會(huì)影響中斷延遲時(shí)間,就有必要使用信號(hào)量了。
3 函數(shù)的可重入性
可重入型(Reentrancy)函數(shù)可以被一個(gè)以上的任務(wù)調(diào)用,而不必?fù)?dān)心數(shù)據(jù)的破壞??芍厝胄秃瘮?shù)任何時(shí)候都可以被中斷,一段時(shí)間以后又可以運(yùn)行,而相應(yīng)數(shù)據(jù)不會(huì)丟失。
可重入型函數(shù)或者只使用局部變量,即變量保存在寄存器或堆棧中。如果使用全局變量,則要對(duì)全局變量予以保護(hù)。
應(yīng)用程序中的不可重入型函數(shù)引起的錯(cuò)誤很可能在測(cè)試時(shí)發(fā)現(xiàn)不了,直到產(chǎn)品到了現(xiàn)場(chǎng)問(wèn)題出現(xiàn)。在使用不可重入型函數(shù)時(shí)一定要小心。
4 同步
如果各個(gè)任務(wù)是獨(dú)立運(yùn)行的,則它們之間就不存在同步問(wèn)題,但實(shí)時(shí)系統(tǒng)中,通常幾個(gè)任務(wù)總是協(xié)同工作,需要在確定的時(shí)間里執(zhí)行各自的功能,這就產(chǎn)生同步問(wèn)題。
對(duì)于單個(gè)的任務(wù)而言,所謂同步就是使它能在指定的時(shí)間執(zhí)行。實(shí)時(shí)操作系統(tǒng)都提供時(shí)鐘功能,一個(gè)任務(wù)可以通過(guò)系統(tǒng)調(diào)用來(lái)使自己掛起一段時(shí)間或者掛起到某一指定的時(shí)刻。
通常我們所謂的任務(wù)同步,主要是指兩個(gè)或兩個(gè)以上的任務(wù)需要協(xié)調(diào)執(zhí)行的情況。實(shí)現(xiàn)同步主要有兩種方式:信號(hào)量和事件。
A. 用信號(hào)量實(shí)現(xiàn)同步
可以利用信號(hào)量使某任務(wù)與中斷服務(wù)程序同步(或者是與另一個(gè)任務(wù)同步,這兩個(gè)任務(wù)間沒(méi)有數(shù)據(jù)交換)。與實(shí)現(xiàn)互斥功能的信號(hào)量(類(lèi)似于一把鑰匙)不同,完成同步功能的信號(hào)量類(lèi)似于通行標(biāo)志。
同步可以分為單向同步(unilateral rendezvous)和雙向同步(bilateral rendezvous)。單向同步,例如,一個(gè)任務(wù)做I/O操作,然后等待信號(hào)回應(yīng),當(dāng)I/O操作完成,中斷服務(wù)程序(或另外一個(gè)任務(wù))發(fā)出信號(hào),該任務(wù)得到信號(hào)后,繼續(xù)執(zhí)行。
如果內(nèi)核支持計(jì)數(shù)信號(hào)量,信號(hào)量的值表示尚未得到處理的事件數(shù)。請(qǐng)注意,可能會(huì)有一個(gè)以上的任務(wù)在等待同一事件的發(fā)生,則這種情況下內(nèi)核會(huì)根據(jù)以下原則之一發(fā)信號(hào)給相應(yīng)的任務(wù):
發(fā)信號(hào)給等待事件發(fā)生的任務(wù)中優(yōu)先級(jí)最高的任務(wù);
發(fā)信號(hào)給最先開(kāi)始等待事件發(fā)生的那個(gè)任務(wù);
根據(jù)不同的應(yīng)用,發(fā)信號(hào)以標(biāo)識(shí)事件發(fā)生的中斷服務(wù)或任務(wù)也可以是多個(gè)。
兩個(gè)任務(wù)可以使用兩個(gè)信號(hào)量同步它們的行為,這稱(chēng)為雙向同步。雙向同步類(lèi)似于單向同步,只是兩個(gè)任務(wù)要相互同步。
注意:在任務(wù)與中斷服務(wù)之間不能使用雙向同步,因?yàn)樵谥袛喾?wù)中不能等待一個(gè)信號(hào)量。
B. 事件(event)
當(dāng)某任務(wù)要與多個(gè)事件同步時(shí),要使用事件標(biāo)志(event flag)。若任務(wù)需要與任何事件之一發(fā)生同步,可稱(chēng)為獨(dú)立型同步(disjunctive synchronization,即邏輯或關(guān)系)。任務(wù)也可以和若干事件都發(fā)生了同步,稱(chēng)為關(guān)聯(lián)型同步(conjunctive synchronization,邏輯與關(guān)系)。獨(dú)立型同步和關(guān)聯(lián)型同步如圖8所示。
圖 8 獨(dú)立型和關(guān)聯(lián)型同步
可以用多個(gè)事件的組合發(fā)信號(hào)給多個(gè)任務(wù),典型地,8個(gè)、16個(gè)或32個(gè)事件可以組合在一起,取決于所使用的內(nèi)核。每個(gè)事件對(duì)應(yīng)其中一位。任務(wù)或中斷服務(wù)程序可以給某一位置置位或復(fù)位,當(dāng)任務(wù)所需的事件都發(fā)生了,這個(gè)任務(wù)繼續(xù)執(zhí)行。至于哪個(gè)任務(wù)該繼續(xù)執(zhí)行,是在一組新的事件發(fā)生時(shí)確定的,也就是在事件位置位時(shí)做判斷。
5 任務(wù)間的通信
有時(shí)很需要任務(wù)間的通信和中斷服務(wù)與任務(wù)間的通信,這種信息傳遞被稱(chēng)為任務(wù)間的通信。任務(wù)間通信主要有兩種途徑:通過(guò)共享數(shù)據(jù)結(jié)構(gòu)或發(fā)消息給另一個(gè)任務(wù)。任務(wù)間的通信主要涉及通信機(jī)制的選擇與實(shí)現(xiàn)、臨界區(qū)域的保護(hù)以及死鎖的預(yù)防等問(wèn)題。
A. 共享數(shù)據(jù)結(jié)構(gòu)
在多任務(wù)系統(tǒng)中,共享內(nèi)存是任務(wù)間通信最簡(jiǎn)單、最迅速的方法。特別是在實(shí)時(shí)操作系統(tǒng)環(huán)境下,高優(yōu)先級(jí)任務(wù)與低優(yōu)先級(jí)的任務(wù)共享同一塊內(nèi)存時(shí),經(jīng)常會(huì)造成共享數(shù)據(jù)的沖突。因此,在設(shè)計(jì)任務(wù)間的通信時(shí)必須避免共享數(shù)據(jù)沖突。使用共享數(shù)據(jù)結(jié)構(gòu)的缺點(diǎn)是,通常一個(gè)任務(wù)不知道共享數(shù)據(jù)結(jié)構(gòu)何時(shí)被中斷服務(wù)程序或其它任務(wù)修改了,除非采取同步措施,或者它以查詢(xún)發(fā)生周期性查詢(xún)?cè)撟兞康闹担绻苊膺@種情況,可以考慮使用郵箱(mail box)或消息隊(duì)列(message queue)。
共享數(shù)據(jù)結(jié)構(gòu)最簡(jiǎn)單的實(shí)現(xiàn)方式就是全局變量。使用全程變量時(shí),必須保證每個(gè)任務(wù)或中斷服務(wù)程序獨(dú)占該變量。前面已經(jīng)提到中斷服務(wù)中保證獨(dú)占地唯一方法就是關(guān)中斷。如果兩個(gè)任務(wù)共享某個(gè)全局變量,可以采用前面介紹的關(guān)中斷或信號(hào)量等方法。
如果要用共享內(nèi)存實(shí)現(xiàn)較大數(shù)據(jù)的傳送,可能需要考慮采用特殊的緩沖區(qū)數(shù)據(jù)結(jié)構(gòu)來(lái)避免共享數(shù)據(jù)沖突。
在傳送與時(shí)間相關(guān)的數(shù)據(jù)時(shí)(例如數(shù)據(jù)處理速度大于數(shù)據(jù)的輸入速度),一般采用“乒乓”緩沖結(jié)構(gòu)。它由兩塊緩沖區(qū)構(gòu)成,通過(guò)硬件或軟件來(lái)控制兩個(gè)緩沖區(qū)間的切換。其典型應(yīng)用有磁盤(pán)控制器、圖形接口卡等設(shè)備。
環(huán)緩沖結(jié)構(gòu)類(lèi)似于FIFO表,但它比FIFO表易于管理。在環(huán)緩沖結(jié)構(gòu)中,并發(fā)的輸入和輸出可用通過(guò)頭尾指針來(lái)控制。數(shù)據(jù)從尾指針處寫(xiě)入,從頭指針處讀出。環(huán)緩沖結(jié)構(gòu)與信號(hào)量一起使用可以控制資源的并發(fā)使用。例如在訪問(wèn)內(nèi)存、打印機(jī)等資源時(shí),可以將資源的請(qǐng)求置于尾指針指向的存儲(chǔ)區(qū),資源分配程序從頭指針中取出數(shù)據(jù)后按照請(qǐng)求分配資源。
B. 消息郵箱
郵箱是大多數(shù)多任務(wù)操作系統(tǒng)任務(wù)間通信的一種方式。它是公認(rèn)的一塊內(nèi)存區(qū)域,由一個(gè)集中調(diào)度者來(lái)控制各任務(wù)對(duì)其的讀寫(xiě),從而實(shí)現(xiàn)任務(wù)間傳遞數(shù)據(jù)的目的。任務(wù)可以通過(guò)post操作來(lái)寫(xiě)這塊內(nèi)存,或通過(guò)pend操作來(lái)讀取這塊內(nèi)存的數(shù)據(jù)。這種pend操作與簡(jiǎn)單輪詢(xún)郵箱的區(qū)別在于:前者在等待數(shù)據(jù)時(shí)處于掛起(suspend)狀態(tài),不占用任何CPU資源;后者則是占用CPU,不停地檢查郵箱。郵箱傳遞的數(shù)據(jù)一般是一個(gè)標(biāo)志(flag)、單個(gè)數(shù)據(jù),或者是指向鏈表或隊(duì)列的指針。在具體實(shí)現(xiàn)時(shí),數(shù)據(jù)一旦從郵箱讀出來(lái),郵箱就置成空狀態(tài)。這樣,盡管有多個(gè)任務(wù)能對(duì)同一個(gè)郵箱執(zhí)行pend操作,但只有一個(gè)任務(wù)能從郵箱中取出數(shù)據(jù)。
在基于任務(wù)控制塊(TCB)模型的任務(wù)管理系統(tǒng)中,郵箱是最容易實(shí)現(xiàn)的。在這種模型中,一般都有一個(gè)監(jiān)管任務(wù)和兩個(gè)列表(任務(wù)資源列表和資源狀態(tài)列表),任務(wù)資源列表和資源狀態(tài)列表保持協(xié)調(diào)一致。
當(dāng)超級(jí)任務(wù)被系統(tǒng)調(diào)用或硬件中斷激活后,它首先檢查是否有任務(wù)在郵箱中處于pend狀態(tài)。如果郵箱中數(shù)據(jù)就緒就重啟該任務(wù)。類(lèi)似地,如果某任務(wù)已執(zhí)行post操作,操作系統(tǒng)則確保數(shù)據(jù)置于郵箱中,并更新其狀態(tài)。
郵箱除了上述的post和pend操作外,還可以有accept操作。accept操作允許任務(wù)在郵箱數(shù)據(jù)就緒的情況下可立即讀出數(shù)據(jù),否則返回錯(cuò)誤代碼。此外,在郵箱的pend操作中還可以添加超時(shí)控制來(lái)防止死鎖。
C. 消息隊(duì)列
隊(duì)列可以認(rèn)為是由許多郵箱排列而成,因而可以由上述相同的資源表來(lái)實(shí)現(xiàn)。其操作相應(yīng)地有qpost操作、qpend操作和qaccept操作。發(fā)送和接收消息的任務(wù)約定,隊(duì)列所傳遞的數(shù)據(jù)也應(yīng)該是指針,而不是數(shù)組。通常,先進(jìn)入消息隊(duì)列的消息先傳遞給任務(wù),即先進(jìn)先出原則(FIFO),有些實(shí)時(shí)內(nèi)核也支持后進(jìn)先出(LIFO)的方式。
6 中斷處理
中斷是一種硬件機(jī)制,用于通知CPU有個(gè)異步事件發(fā)生了。異步事件是指無(wú)一定時(shí)序關(guān)系的隨機(jī)發(fā)生的事件。如外部設(shè)備完成數(shù)據(jù)傳輸,實(shí)時(shí)控制設(shè)備出現(xiàn)異常情況等。中斷一旦被識(shí)別,CPU就保存部分(或全部)上下文,即部分或全部寄存器值,跳轉(zhuǎn)到專(zhuān)門(mén)的子程序,稱(chēng)為中斷服務(wù)子程序(ISR)。中斷服務(wù)子程序做事件處理,處理完成后,程序回到:
在前后臺(tái)系統(tǒng)中,程序回到后臺(tái)程序;
對(duì)非搶占內(nèi)核,程序回到被中斷地任務(wù);
對(duì)搶占內(nèi)核,讓進(jìn)入就緒態(tài)的優(yōu)先級(jí)最高的任務(wù)開(kāi)始運(yùn)行。
中斷使得CPU可以在事件發(fā)生時(shí)才予以處理,而不必讓微處理器連續(xù)不斷地查詢(xún)(polling)是否有事件發(fā)生。通過(guò)兩條特殊指令:關(guān)中斷(disable interrupt)和開(kāi)中斷(enable interrupt)可以讓微處理器不響應(yīng)或響應(yīng)中斷。在實(shí)時(shí)環(huán)境下,關(guān)中斷的時(shí)間應(yīng)盡可能的短,因?yàn)殛P(guān)中斷影響中斷延遲時(shí)間,關(guān)中斷時(shí)間太長(zhǎng)可能會(huì)引起中斷丟失。微處理器一般允許中斷嵌套,也就是說(shuō),在中斷服務(wù)期間,微處理器可以識(shí)別另一個(gè)更重要的中斷,并服務(wù)于那個(gè)更重要的中斷。
圖 9 中斷嵌套
中斷延遲
可能實(shí)時(shí)內(nèi)核最重要的指標(biāo)就是中斷關(guān)了多長(zhǎng)時(shí)間,所有實(shí)時(shí)系統(tǒng)在進(jìn)入臨界區(qū)代碼段之前都要關(guān)中斷,執(zhí)行完臨界代碼之后再開(kāi)中斷。中斷延遲由以下表達(dá)式給出:
中斷延遲 = 關(guān)中斷地最長(zhǎng)時(shí)間 + 開(kāi)始執(zhí)行中斷服務(wù)子程序的第一條指令的時(shí)間
關(guān)中斷是實(shí)時(shí)內(nèi)核最重要的指標(biāo)之一,它直接影響應(yīng)用程序?qū)?shí)時(shí)事件的響應(yīng)速度。關(guān)中斷的時(shí)間很大程度取決于微處理器的架構(gòu)以及編譯器所生成的代碼質(zhì)量。
中斷響應(yīng)
中斷響應(yīng)定義為從中斷發(fā)生到開(kāi)始執(zhí)行用戶(hù)的中斷服務(wù)子程序代碼來(lái)處理這個(gè)中斷的時(shí)間。中斷響應(yīng)時(shí)間包括開(kāi)始處理這個(gè)中斷前的全部開(kāi)銷(xiāo)。典型地,執(zhí)行用戶(hù)代碼之前要保護(hù)現(xiàn)場(chǎng),將CPU的各寄存器存入堆棧。這段時(shí)間將被記作中斷響應(yīng)時(shí)間。
對(duì)于前后臺(tái)系統(tǒng),保存寄存器以后立即執(zhí)行用戶(hù)代碼,中斷響應(yīng)時(shí)間為:
中斷響應(yīng)時(shí)間 = 中斷延遲 + 保存CPU內(nèi)部寄存器的時(shí)間
對(duì)于非搶占內(nèi)核,微處理器保存內(nèi)部寄存器以后,用戶(hù)的中斷服務(wù)子程序全部立即得到執(zhí)行。非搶占內(nèi)核的重點(diǎn)響應(yīng)時(shí)間為:
中斷響應(yīng)時(shí)間 = 中斷延遲 + 保存CPU內(nèi)部寄存器的時(shí)間
對(duì)于搶占內(nèi)核,則要先調(diào)用一個(gè)特定的函數(shù),該函數(shù)通知內(nèi)核即將進(jìn)行中斷服務(wù),使得內(nèi)核可以跟蹤中斷的嵌套。搶占內(nèi)核的中斷響應(yīng)時(shí)間為:
中斷響應(yīng)時(shí)間 = 中斷延遲 + 保存CPU內(nèi)部寄存器的時(shí)間
+ 內(nèi)核進(jìn)入中斷服務(wù)函數(shù)的執(zhí)行時(shí)間
中斷響應(yīng)時(shí)間是系統(tǒng)在最壞情況下的響應(yīng)中斷的時(shí)間,例如某系統(tǒng)100次中有99次在50微秒內(nèi)響應(yīng)中斷,只有一次響應(yīng)中斷的時(shí)間是250微秒,則只能認(rèn)為中斷響應(yīng)時(shí)間是250微秒。
中斷恢復(fù)時(shí)間(interrupt recovery)
中斷恢復(fù)時(shí)間是微處理器返回到被中斷了大程序代碼所需要的時(shí)間。在前后臺(tái)系統(tǒng)中,中斷恢復(fù)時(shí)間很簡(jiǎn)單,只包括恢復(fù)CPU內(nèi)部寄存器值得時(shí)間和執(zhí)行中斷返回指令的時(shí)間。中斷恢復(fù)時(shí)間為:
中斷恢復(fù)時(shí)間 = 恢復(fù)CPU內(nèi)部寄存器值的時(shí)間 + 執(zhí)行中斷返回指令的時(shí)間
和前后臺(tái)系統(tǒng)一樣,非搶占內(nèi)核的恢復(fù)時(shí)間也很簡(jiǎn)單,只包括恢復(fù)CPU內(nèi)部寄存器值的時(shí)間和執(zhí)行中斷返回指令的時(shí)間。
對(duì)于搶占內(nèi)核,中斷恢復(fù)要復(fù)雜一些。典型地,在中斷服務(wù)子程序的末尾,要調(diào)用一個(gè)由實(shí)時(shí)內(nèi)核提供的函數(shù),用于判斷是否脫離了所有的中斷嵌套。如果脫離了嵌套(即已經(jīng)返回到被中斷了大任務(wù)級(jí)時(shí)),內(nèi)核要判斷,由于中斷服務(wù)子程序的執(zhí)行,是否使得一個(gè)優(yōu)先級(jí)更高的任務(wù)進(jìn)入了就緒態(tài)。如果是,則要讓這個(gè)優(yōu)先級(jí)更高的任務(wù)開(kāi)始運(yùn)行。在這種情況下,被中斷了大任務(wù)只有重新成為優(yōu)先級(jí)最高的任務(wù)而進(jìn)入就緒態(tài)時(shí)才能繼續(xù)運(yùn)行。對(duì)于搶占內(nèi)核,中斷恢復(fù)時(shí)間為:
中斷恢復(fù)時(shí)間 = 判斷是否有優(yōu)先級(jí)更高的任務(wù)進(jìn)入了就緒態(tài)的時(shí)間
+恢復(fù)那個(gè)優(yōu)先級(jí)更高任務(wù)的CPU內(nèi)部寄存器值的時(shí)間
+ 執(zhí)行中斷返回指令的時(shí)間
圖10至12分別給出了前后臺(tái)系統(tǒng)、非搶占內(nèi)核和搶占內(nèi)核相應(yīng)的中斷延遲、響應(yīng)和恢復(fù)過(guò)程。
圖 10 前后臺(tái)系統(tǒng)的中斷延遲、響應(yīng)和恢復(fù)過(guò)程
圖 11 非搶占內(nèi)核的中斷延遲、響應(yīng)和恢復(fù)過(guò)程
圖 12 搶占內(nèi)核的中斷延遲、響應(yīng)和恢復(fù)過(guò)程
注意:搶占內(nèi)核的中斷返回函數(shù)將決定是返回到被中斷的任務(wù),還是由于中斷服務(wù)程序使優(yōu)先級(jí)更高的任務(wù)進(jìn)入就緒狀態(tài)而讓最高優(yōu)先級(jí)的任務(wù)運(yùn)行。在后一種情況下,恢復(fù)中斷的時(shí)間要稍一些,因?yàn)閮?nèi)核要做任務(wù)切換。
中斷處理時(shí)間
雖然中斷服務(wù)的處理時(shí)間應(yīng)盡可能的短,但對(duì)處理時(shí)間并沒(méi)有絕對(duì)的限制。不能說(shuō)中斷服務(wù)必須全部小于100微秒,500微秒或1微秒。如果中斷服務(wù)是在任何給定的時(shí)間開(kāi)始,且中斷服務(wù)程序代碼是應(yīng)用程序中最重要的代碼,則中斷服務(wù)需要多長(zhǎng)時(shí)間就應(yīng)該給它多長(zhǎng)時(shí)間。然而在大多數(shù)情況下,中斷服務(wù)子程序應(yīng)識(shí)別中斷來(lái)源,從產(chǎn)生中斷地設(shè)備取得數(shù)據(jù)或狀態(tài),并通知真正做該事件處理的那個(gè)任務(wù)。當(dāng)然應(yīng)該考慮到是否通知一個(gè)任務(wù)去做事件處理所花的時(shí)間比處理這個(gè)事件所花的時(shí)間還多。在中斷服務(wù)中通知一個(gè)任務(wù)做事件處理(通過(guò)信號(hào)量或信息隊(duì)列等)是需要一定時(shí)間的,如果事件處理需花的時(shí)間短于給一個(gè)任務(wù)發(fā)通知的時(shí)間,就應(yīng)該考慮在中斷服務(wù)子程序中做事件處理并在中斷服務(wù)子程序中開(kāi)中斷,以允許優(yōu)先級(jí)更高的中斷進(jìn)入并優(yōu)先得到服務(wù)。
7 非屏蔽中斷(NMI)
有時(shí),中斷服務(wù)必須來(lái)得盡可能地塊,內(nèi)核引起的延時(shí)變得不可忍受。在這種情況下,可以使用非屏蔽中斷(non-maskable interrupt),絕大多數(shù)微處理器有非屏蔽中斷功能。通常非屏蔽中斷留做緊急處理用,如斷電時(shí)保存重要的信息。然而,如果應(yīng)用程序沒(méi)有這方面的要求,非屏蔽中斷可用于時(shí)間要求最苛刻的中斷服務(wù)。
在非屏蔽中斷的中斷服務(wù)子程序中,不能使用內(nèi)核提供的服務(wù),因?yàn)榉瞧帘沃袛嗍顷P(guān)不掉的,故不能在非屏蔽中斷中處理臨界區(qū)代碼。
8 時(shí)鐘節(jié)拍(clock tick)
在實(shí)時(shí)系統(tǒng)中, 一般不能缺少實(shí)時(shí)時(shí)鐘,它是實(shí)時(shí)軟件運(yùn)行的必不可少的硬件設(shè)施。實(shí)時(shí)時(shí)鐘單純地提供一個(gè)規(guī)則的脈沖序列,脈沖之間的間隔可以作為系統(tǒng)的時(shí)間基準(zhǔn)稱(chēng)為時(shí)基,時(shí)基的大小代表了實(shí)時(shí)時(shí)鐘的精度,這個(gè)精度取決于系統(tǒng)的要求。
為了計(jì)準(zhǔn)時(shí)間間隔,一個(gè)很重要的問(wèn)題是CPU與時(shí)鐘應(yīng)同步工作。同步的方法可以用硬件,也可以用軟件。軟件方法是使CPU能用程序啟動(dòng)、停止時(shí)鐘工作,設(shè)置時(shí)基的大小,并在啟動(dòng)后,利用實(shí)時(shí)時(shí)鐘中斷信號(hào)的方法來(lái)對(duì)準(zhǔn)系統(tǒng)的時(shí)鐘。每當(dāng)實(shí)時(shí)時(shí)鐘的時(shí)基到時(shí),它就引起中斷,中斷響應(yīng)后實(shí)時(shí)時(shí)鐘又開(kāi)始工作,時(shí)基到時(shí)又引起中斷,這樣達(dá)到與CPU的同步。顯然,軟件方法具有簡(jiǎn)單、靈活、易實(shí)現(xiàn)和低成本的優(yōu)點(diǎn),可以很方便修改實(shí)時(shí)時(shí)鐘的設(shè)置和系統(tǒng)時(shí)間的表示,且可以在不增加硬件的基礎(chǔ)上非常靈活地用軟件模擬多個(gè)“軟時(shí)鐘”,因此,在實(shí)時(shí)系統(tǒng)中廣泛采用此種方法。但由于中斷的延遲,對(duì)系統(tǒng)的時(shí)鐘可能會(huì)造成一定的誤差,因此在設(shè)計(jì)中通常將實(shí)時(shí)時(shí)鐘中斷的優(yōu)先級(jí)設(shè)置的很高,一般僅次于非屏蔽中斷。系統(tǒng)的時(shí)間精度要求的越高,時(shí)鐘中斷的頻度就越高,這樣執(zhí)行時(shí)鐘ISR的時(shí)間就會(huì)增多,系統(tǒng)的開(kāi)銷(xiāo)就會(huì)增大,就會(huì)影響系統(tǒng)的其他的工作,因此,應(yīng)使時(shí)鐘ISR程序竟盡可能的短,同時(shí)要考慮時(shí)間精度。
硬件所做的工作僅僅是按已知時(shí)間間隔產(chǎn)生時(shí)鐘中斷。其它與時(shí)間有關(guān)的工作都必須由軟件驅(qū)動(dòng)程序來(lái)完成。不同操作系統(tǒng)的時(shí)鐘驅(qū)動(dòng)程序完成的功能可能不同,但一般包括如下內(nèi)容:
1.維護(hù)日期時(shí)間;
2.防止任務(wù)的運(yùn)行時(shí)間超過(guò)其允許的時(shí)間;
3.對(duì)CPU的使用情況進(jìn)行統(tǒng)計(jì);
4.處理系統(tǒng)或用戶(hù)程序提出的定時(shí)服務(wù);
時(shí)鐘節(jié)拍是特定的周期性中斷。這個(gè)中斷可以看作是系統(tǒng)心臟的脈動(dòng)。中斷之間的時(shí)間間隔取決于不同的應(yīng)用,一般在10毫秒到200毫秒之間。時(shí)鐘的節(jié)拍式中斷使得內(nèi)核可以將任務(wù)延時(shí)若干個(gè)整數(shù)時(shí)鐘節(jié)拍,以及當(dāng)任務(wù)等待事件發(fā)生時(shí),提供等待超時(shí)的依據(jù)。時(shí)鐘節(jié)拍頻率越快,系統(tǒng)的額外開(kāi)銷(xiāo)就越大。時(shí)鐘節(jié)拍的實(shí)際頻率取決于用戶(hù)應(yīng)用程序的精度。
各種實(shí)時(shí)內(nèi)核都有將任務(wù)延時(shí)若干個(gè)時(shí)鐘節(jié)拍的功能。然而這并不意味著延時(shí)的精度是一個(gè)時(shí)鐘節(jié)拍,只是在每個(gè)時(shí)鐘節(jié)拍中斷到來(lái)時(shí)對(duì)任務(wù)延時(shí)做一次裁決而已。
上述情況在所有的實(shí)時(shí)內(nèi)核中都會(huì)出現(xiàn),這與CPU負(fù)荷有關(guān),也可能與系統(tǒng)設(shè)計(jì)不正確有關(guān)。以下是這類(lèi)問(wèn)題可能的解決方案:
1.增加微處理器的時(shí)鐘頻率;
2.增加時(shí)鐘節(jié)拍的頻率;
3.重新安排任務(wù)的優(yōu)先級(jí);
4.避免使用浮點(diǎn)運(yùn)算(如果非使用不可,盡量使用單精度數(shù));
5.使用能較好地優(yōu)化程序代碼的編譯器;
6.時(shí)間要求苛刻的代碼用匯編語(yǔ)言編寫(xiě);
7.如果可能,用同一家族的更快的微處理器做系統(tǒng)升級(jí)。如從8086向80186升級(jí),從68000向68020升級(jí)等。
不管怎么樣,抖動(dòng)總是存在的。
9 死鎖
A. 死鎖的產(chǎn)生
死鎖的定義:
若一個(gè)進(jìn)程集合中的每一個(gè)進(jìn)程都在等待只能由本集合中的另一個(gè)進(jìn)程才能引發(fā)的事件,則這種情況被視為死鎖(deadlock)。
由于所有的進(jìn)程都在等待,所以沒(méi)有一個(gè)進(jìn)程能夠觸發(fā)那個(gè)(些)能夠喚醒本集合中另一個(gè)進(jìn)程的事件,于是所有的進(jìn)程都將永遠(yuǎn)地等待下去。
多數(shù)情況下,進(jìn)程是等待本集合中另一個(gè)進(jìn)程釋放的資源。換句話說(shuō),就是每個(gè)進(jìn)程都在等待另一個(gè)進(jìn)程所占有的資源。但因?yàn)樗羞M(jìn)程都無(wú)法運(yùn)行,因而無(wú)法釋放資源,于是所有進(jìn)程都不能被喚醒。至于進(jìn)程數(shù)及申請(qǐng)的資源數(shù)并不重要。
當(dāng)多個(gè)任務(wù)競(jìng)爭(zhēng)同樣的兩個(gè)或多個(gè)臨界資源時(shí),就可能會(huì)出現(xiàn)死鎖。在實(shí)時(shí)多任務(wù)操作系統(tǒng)環(huán)境下,互斥、循環(huán)等待、占有等待、禁止搶占都有可能產(chǎn)生死鎖。死鎖在多任務(wù)操作系統(tǒng)中是個(gè)很?chē)?yán)重的問(wèn)題,往往不可能靠測(cè)試來(lái)發(fā)現(xiàn)和消除。由于死鎖出現(xiàn)的概率很小,很難發(fā)現(xiàn),解決死鎖也往往要追溯前因后果。
當(dāng)任務(wù)在所分配的時(shí)隙內(nèi)因得不到所需的資源而不能完成任務(wù)處理時(shí),就會(huì)出現(xiàn)“饑荒”。饑荒與死鎖的不同之處在于:饑荒至少有一個(gè)任務(wù)能利用其所需的資源,但是其它任務(wù)則得不到資源;而在死鎖的情況下,所有的任務(wù)都因得不到所需的資源而被迫處于阻塞狀態(tài)。
Coffman等人1971年總結(jié)出了死鎖發(fā)生的四個(gè)條件:
1.互斥(mutual exclusion)條件,每個(gè)資源或者被分配給一個(gè)進(jìn)程或者空閑,即不可共享;
2.保持和等待(hold and wait)條件,已分配到了一些資源的進(jìn)程可以申請(qǐng)新的資源;
3.非剝奪(no preemption)條件,已分配給一進(jìn)程的資源不可被剝奪,只能被占有它的進(jìn)程釋放;
4.循環(huán)等待(circular wait)條件,系統(tǒng)必然有一條由兩個(gè)或兩個(gè)以上的進(jìn)程組成的循環(huán)鏈,鏈中的每一個(gè)進(jìn)程都在等待相鄰進(jìn)程占用的資源。
以上四個(gè)條件是死鎖發(fā)生的必要條件,只要一條或多條不成立,死鎖就不會(huì)發(fā)生。
B. 死鎖的處理
處理死鎖主要有四種策略:
1.忽略該問(wèn)題;
最簡(jiǎn)單的解決死鎖的問(wèn)題是對(duì)死鎖視而不見(jiàn),首先要了解死鎖發(fā)生的頻率、系統(tǒng)因其它原因崩潰的頻率、以及死鎖有多嚴(yán)重,如果死鎖平均每50年發(fā)生一次,而系統(tǒng)每個(gè)月會(huì)因硬件故障或操作系統(tǒng)錯(cuò)誤等而崩潰一次,那么就可以不用不惜工本地去消除死鎖。另外,可能解決死鎖的代價(jià)太大,忽略它也是在方便性和正確性之間的折中考慮。
例如系統(tǒng)中進(jìn)程的數(shù)目受有多少進(jìn)程表項(xiàng)(PCB)的制約,如果一個(gè)fork調(diào)用由于當(dāng)前沒(méi)有空閑PCB而失敗,那么一種合理的辦法是等待一段隨機(jī)的時(shí)間后重試,但這有可能是個(gè)無(wú)休止的循環(huán),這實(shí)際上就是死鎖。雖然發(fā)生這類(lèi)事件的可能概率很小,但它的確是存在的。UNIX解決這類(lèi)問(wèn)題的方法就是忽略它。
這種方法在我們實(shí)際應(yīng)用中比較常見(jiàn),例如內(nèi)存控制塊(MCB)、任務(wù)控制塊(TCB),定時(shí)器控制塊(TCB)、進(jìn)程控制塊(PCB)等的管理我們都是采用這種處理方法,具體配置情況一般根據(jù)經(jīng)驗(yàn)在調(diào)試過(guò)程中不斷調(diào)整得出的,與具體的系統(tǒng)環(huán)境有關(guān)。
2.檢測(cè)死鎖并恢復(fù);
利用資源分配圖檢查是否存在環(huán)路,可以分析給定的申請(qǐng)/釋放序列是否將導(dǎo)致死鎖。系統(tǒng)監(jiān)視資源的申請(qǐng)和釋放情況,每次資源被申請(qǐng)或釋放時(shí)立即刷新資源分配圖,檢測(cè)釋放存在環(huán)路,如果存在,則撤銷(xiāo)環(huán)路中的一個(gè)進(jìn)程,如果仍不能破除死鎖,則撤銷(xiāo)再另一個(gè)進(jìn)程,直到環(huán)路被破壞。
更為簡(jiǎn)單的一種處理方法是不維護(hù)資源分配圖,而是周期性檢測(cè)進(jìn)程是否連續(xù)阻塞超過(guò)一定時(shí)間,如1小時(shí)。一旦發(fā)現(xiàn)這樣的進(jìn)程則將其撤銷(xiāo)。
撤銷(xiāo)一個(gè)進(jìn)程時(shí)必須同時(shí)消除可能導(dǎo)致的所有副作用。
實(shí)時(shí)系統(tǒng)中一般很少因?yàn)橘Y源不可用而將進(jìn)程中途終止并重新執(zhí)行,因?yàn)橛行┎僮魇遣荒苤貜?fù)進(jìn)行的,例如文件的更新。
進(jìn)程間通信,尤其是板間通信時(shí),我們經(jīng)常采用超時(shí)機(jī)制(根據(jù)情況重發(fā)或者其它處理)來(lái)消除進(jìn)程可能發(fā)生的死鎖。
3.謹(jǐn)慎地對(duì)資源進(jìn)行動(dòng)態(tài)分配,避免死鎖;
死鎖避免不是通過(guò)對(duì)進(jìn)程隨意強(qiáng)加一些規(guī)則,而是通過(guò)對(duì)每一次資源申請(qǐng)進(jìn)行認(rèn)真的分析來(lái)判斷它是否能安全地分配,條件是必須事先獲得一些特定的信息。
“銀行家算法”最早由Dijkstra于1965年發(fā)表。其原理類(lèi)似于一個(gè)小銀行的存取款過(guò)程,將進(jìn)程比作客戶(hù),資源比作貸款,操作系統(tǒng)比作銀行家。這種算法能確保分配給所有任務(wù)的資源都不可能超過(guò)系統(tǒng)可用資源。這樣就可以預(yù)留一部分可用資源來(lái)滿足其它任務(wù)的需求。遺憾的是,這種算法的實(shí)時(shí)性不是很好,并且任務(wù)所需的資源的優(yōu)先級(jí)往往是未知的。
4.通過(guò)破壞產(chǎn)生死鎖的四個(gè)必要條件來(lái)預(yù)防死鎖發(fā)生。
對(duì)于某些不可共享的資源,必須采用互斥保護(hù)措施。當(dāng)然,也可以通過(guò)其它技術(shù)手段來(lái)使得這些資源變?yōu)榭晒蚕碣Y源,這時(shí)就可以去掉互斥的保護(hù)措施,前面已有詳細(xì)介紹。
通常我們采用帶有超時(shí)控制的信號(hào)燈。這樣,信號(hào)燈在超時(shí)后不再保護(hù)臨界資源,臨界資源可以被其它任務(wù)使用,從而化解了可能的死鎖。目前,內(nèi)核大多允許用戶(hù)在申請(qǐng)信號(hào)量時(shí)定義等待超時(shí)。
當(dāng)某一任務(wù)占用資源A并申請(qǐng)資源B,另一任務(wù)占用資源B并申請(qǐng)資源A時(shí),就會(huì)出現(xiàn)循環(huán)等待。一個(gè)消除循環(huán)等待行之有效的方法就是:強(qiáng)加給資源一個(gè)次序,并且迫使所有的任務(wù)在申請(qǐng)資源時(shí)必須以遞增的次序。例如,設(shè)計(jì)如下的資源次序:磁盤(pán)(1)、打印機(jī)(2)、監(jiān)視器(3)。如果某個(gè)任務(wù)希望使用打印機(jī)和監(jiān)視器,它就必須先申請(qǐng)打印機(jī),然后申請(qǐng)監(jiān)視器??梢宰C明,采用這種方案可以消除死鎖,遺憾的是幾乎找不出一種使每個(gè)人都滿意的編號(hào)次序,由于潛在的資源以及各種不同用途的數(shù)目,以至于使編號(hào)根本無(wú)法使用。
當(dāng)任務(wù)申請(qǐng)到某一可用的資源,并且在它能夠申請(qǐng)到另一可用的資源之前,一直不釋放前一個(gè)資源時(shí),就會(huì)出現(xiàn)占有等待。一個(gè)可行的解決辦法就是,在同一時(shí)間分配給任務(wù)所有需要(包括潛在需要)的資源,這樣有可能延長(zhǎng)響應(yīng)時(shí)間,甚至有可能導(dǎo)致其它任務(wù)產(chǎn)生饑荒。另一個(gè)辦法就是決不允許任何任務(wù)在同一時(shí)刻鎖住多個(gè)資源。
最后,禁止搶占也會(huì)導(dǎo)致死鎖。也就是說(shuō),如果一個(gè)低優(yōu)先級(jí)的任務(wù)占有信號(hào)燈保護(hù)的某一資源,另一個(gè)高優(yōu)先級(jí)的任務(wù)中斷低優(yōu)先級(jí)的任務(wù)的運(yùn)行,并處于等待該信號(hào)燈狀態(tài)時(shí),由于低優(yōu)先級(jí)的任務(wù)不可能釋放其信號(hào)燈,這樣高優(yōu)先級(jí)的任務(wù)將一直等待下去。這就是所謂的“優(yōu)先級(jí)逆轉(zhuǎn)”。如果我們?cè)试S高優(yōu)先級(jí)的任務(wù)能夠搶占低優(yōu)先級(jí)任務(wù),就不會(huì)出現(xiàn)死鎖。然而,這樣也可能導(dǎo)致低優(yōu)先級(jí)任務(wù)“饑荒”以及其它干擾問(wèn)題,例如I/O操作問(wèn)題。
三 實(shí)時(shí)調(diào)度策略
任務(wù)調(diào)度就是從就緒狀態(tài)的任務(wù)中,挑選一個(gè)任務(wù)到處理器上運(yùn)行。負(fù)責(zé)任務(wù)調(diào)度功能的內(nèi)核程序稱(chēng)為任務(wù)調(diào)度程序或任務(wù)調(diào)度器。任何操作系統(tǒng)的核心和靈魂都是它的調(diào)度程序(Scheduler或Dispatcher)。在設(shè)計(jì)任務(wù)調(diào)度器時(shí),首先要決定選擇何種調(diào)度算法,然后根據(jù)此算法來(lái)編制相應(yīng)的調(diào)度程序。而調(diào)度算法實(shí)際上就是系統(tǒng)所采取的調(diào)度策略,選擇時(shí)所要考慮的因素很多。如系統(tǒng)各類(lèi)資源的均衡使用;對(duì)用戶(hù)公平并使用戶(hù)滿意等。
常見(jiàn)的調(diào)度算法有:先進(jìn)先出、短任務(wù)優(yōu)先、輪循調(diào)度,它們都是用于非嵌入式系統(tǒng)的簡(jiǎn)單調(diào)度算法。目前,大多數(shù)實(shí)時(shí)內(nèi)核都是采用優(yōu)先級(jí)(priority)的調(diào)度算法。
一 先進(jìn)先出(FIFO)調(diào)度
先進(jìn)先出(FIFO)又稱(chēng)為先來(lái)先服務(wù)(first-come-first-served,F(xiàn)CFS)是最簡(jiǎn)單的調(diào)度策略,在早期的操作系統(tǒng)中使用較多。當(dāng)一個(gè)任務(wù)就緒后,就把它放到就緒隊(duì)列的尾部,當(dāng)當(dāng)前正在運(yùn)行的任務(wù)停止執(zhí)行時(shí),調(diào)度器選擇就緒隊(duì)列中最前面的任務(wù)(也是在就緒隊(duì)列中存在時(shí)間最長(zhǎng)的任務(wù))運(yùn)行。
例如DOS,它并不是一個(gè)多任務(wù)的操作系統(tǒng)。每個(gè)任務(wù)一直運(yùn)行到它結(jié)束為止,并且直到那時(shí)下一個(gè)任務(wù)才被啟動(dòng)。當(dāng)然,在DOS中一個(gè)任務(wù)可以把自己掛起,從而讓下一個(gè)就緒任務(wù)獲得處理器的控制權(quán),這正是舊版本的Windows操作系統(tǒng)如何允許用戶(hù)從一個(gè)任務(wù)切換到其它任務(wù)的工作機(jī)理。Microsoft在Windows NT之前的任何操作系統(tǒng)都不包含真正的多任務(wù)。
典型地,任務(wù)的執(zhí)行時(shí)間越長(zhǎng),可以容忍的延遲時(shí)間就越長(zhǎng)。FIFO調(diào)度策略對(duì)短任務(wù)不利,與執(zhí)行時(shí)間相比,延遲時(shí)間相對(duì)較長(zhǎng),對(duì)于有實(shí)時(shí)要求的任務(wù)可能無(wú)法滿足其實(shí)時(shí)性要求。FIFO不強(qiáng)調(diào)系統(tǒng)的吞吐量,即系統(tǒng)的整體性能不高,它最大的優(yōu)點(diǎn)是不會(huì)發(fā)生餓死現(xiàn)象。
FIFO對(duì)于單處理器系統(tǒng)并不是一個(gè)很有吸引力的選擇,通常與優(yōu)先級(jí)策略相結(jié)合,以提供一種更有效的調(diào)度方法。調(diào)度器可以維護(hù)多個(gè)隊(duì)列,每個(gè)優(yōu)先級(jí)對(duì)應(yīng)一個(gè)隊(duì)列,每個(gè)隊(duì)列中的調(diào)度基于先來(lái)先服務(wù)的原則。
二 短任務(wù)優(yōu)先調(diào)度
它是一個(gè)近似的調(diào)度算法。與先進(jìn)先出調(diào)度算法的唯一不同之處在于,每一次運(yùn)行的任務(wù)在完成或者掛起的時(shí)候,下一個(gè)被選擇的任務(wù)是需要最少處理器完成時(shí)間的任務(wù)。
短任務(wù)優(yōu)先調(diào)度在早期的主流系統(tǒng)中是相當(dāng)普遍的,因?yàn)樗苁勾蠖鄶?shù)用戶(hù)滿意(只有那些最長(zhǎng)任務(wù)的用戶(hù)才會(huì)警告和抱怨)。
由于短任務(wù)優(yōu)先常常伴隨著最短響應(yīng)時(shí)間,唯一的問(wèn)題是如何從當(dāng)前就緒隊(duì)列中選擇最短的那一個(gè)。一種辦法就是根據(jù)任務(wù)過(guò)去的行為進(jìn)行推測(cè),并執(zhí)行估計(jì)運(yùn)行時(shí)間最短的那一個(gè)。假設(shè)某任務(wù)每次的估計(jì)運(yùn)行時(shí)間為T(mén)0,現(xiàn)在假設(shè)測(cè)量到其下一次的運(yùn)行時(shí)間為T(mén)1,我們可以將這兩個(gè)值的加權(quán)和來(lái)改進(jìn)我們的 估計(jì)時(shí)間,即aT0+(1-a)T1。通過(guò)選擇合適的a值,我們可以決定是盡快忘掉老的運(yùn)行時(shí)間,還是在一段較長(zhǎng)的時(shí)間內(nèi)記住它們。當(dāng)a=1/2時(shí),我們可以得到如下的序列:
T0,T0/2+T1/2,T0/4+T1/4+T2/2,T0/8+T1/8+T2/4+T3/2
我們看到,三輪過(guò)后,T0在新的估計(jì)值中占的比重下降到1/8。
這種通過(guò)將當(dāng)前測(cè)量值和先前估計(jì)值進(jìn)行加權(quán)平均而得到下一個(gè)估計(jì)值的技術(shù)有時(shí)稱(chēng)為老化(aging)。它適用于許多測(cè)量值必須基于先前值的情況。老化算法在a=1/2時(shí)特別容易實(shí)現(xiàn),只需將新值加到當(dāng)前估計(jì)值上然后除以2(即右移一位)。
需要特別指出的是,最短任務(wù)優(yōu)先算法只在所有任務(wù)同時(shí)可用的情況下才是最優(yōu)的。
下面給出一個(gè)反例:假設(shè)5個(gè)任務(wù),A,B,C,D,E的運(yùn)行時(shí)間分別為2,4,1,1,1;到達(dá)時(shí)間分別為0,0,3,3,3。最初只有A和B就緒。使用最短任務(wù)優(yōu)先調(diào)度算法,將按照A,B,C,D,E的順序運(yùn)行,其平均等待時(shí)間為4.6。而按照B,C,D,E,A的順序運(yùn)行,其平均等待時(shí)間為4.4。
三 輪循調(diào)度(round-robin scheduling)
輪循調(diào)度(round-robin scheduling)是最公平,且使用最廣的調(diào)度算法,實(shí)現(xiàn)較為簡(jiǎn)單。
所有的任務(wù)都有相同的優(yōu)先級(jí),就緒隊(duì)列簡(jiǎn)單地按照先進(jìn)先出(FIFO)的規(guī)則來(lái)排列,調(diào)度器分配給每個(gè)任務(wù)一個(gè)相同的(或者不同的)執(zhí)行時(shí)間片(time slice),一個(gè)任務(wù)用完自己的時(shí)間片之后,就停止執(zhí)行,放入隊(duì)列的尾部,從就緒隊(duì)列中取出下一個(gè)任務(wù)開(kāi)始執(zhí)行。
時(shí)間片的長(zhǎng)度由時(shí)鐘所決定,它以相等的時(shí)間間隔發(fā)出中斷,激活調(diào)度器,調(diào)度器被激活后,就進(jìn)行任務(wù)切換(task switch,又稱(chēng)為上下文切換),停止執(zhí)行當(dāng)前運(yùn)行的任務(wù),開(kāi)始執(zhí)行就緒隊(duì)列中的下一個(gè)任務(wù)。如圖13所示。
圖 13 輪循調(diào)度
從上我們可以看出,輪循調(diào)度與先進(jìn)先出調(diào)度、短任務(wù)優(yōu)先調(diào)度最大的不同在于它可以使運(yùn)行中的任務(wù)被搶占。
輪循調(diào)度可以和優(yōu)先級(jí)策略相結(jié)合,構(gòu)成優(yōu)先級(jí)輪循調(diào)度,也就是說(shuō),各個(gè)任務(wù)可以設(shè)立不同的優(yōu)先級(jí),對(duì)優(yōu)先級(jí)高的任務(wù),它分到的時(shí)間片長(zhǎng)度就長(zhǎng),或者說(shuō)分到的時(shí)間片次數(shù)多。
時(shí)間片大小的選擇對(duì)系統(tǒng)的有效操作是有很大影響的。如果時(shí)間片選擇太大,時(shí)間片輪循調(diào)度基本上等同于先進(jìn)先出調(diào)度,也就失去其意義;如果時(shí)間片選擇太小,任務(wù)切換過(guò)于頻繁,處理器開(kāi)銷(xiāo)大,真正用于運(yùn)行應(yīng)用程序的時(shí)間將會(huì)減小,也直接影響了系統(tǒng)性能。
輪循優(yōu)先調(diào)度的缺點(diǎn)是,具有實(shí)時(shí)響應(yīng)要求的任務(wù)無(wú)法搶先執(zhí)行。以一個(gè)中斷服務(wù)任務(wù)為例,當(dāng)調(diào)度器收到中斷信號(hào),將該任務(wù)從掛起隊(duì)列中取出,并加入到就緒隊(duì)列之后,必須要等到就緒隊(duì)列中前面所有的任務(wù)依次用完自己的時(shí)間片后,才輪到這個(gè)中斷服務(wù)任務(wù)執(zhí)行,其調(diào)度時(shí)間可能會(huì)長(zhǎng)達(dá)幾秒鐘。
使用輪循調(diào)度方法的多任務(wù)操作系統(tǒng)通常被稱(chēng)為分時(shí)系統(tǒng)(time sharing),UNIX就是著名的分時(shí)系統(tǒng),目前許多流行的實(shí)時(shí)操作系統(tǒng)就是從UNIX演變而來(lái),例如LynxOS,OS-9,VRTX,pSOSystem,VxWorks等。
由于輪循調(diào)度的缺點(diǎn),顯然它不適于管理實(shí)時(shí)任務(wù)。多數(shù)實(shí)時(shí)內(nèi)核基于優(yōu)先級(jí)調(diào)度,根據(jù)何時(shí)讓高優(yōu)先級(jí)的任務(wù)獲得CPU的控制權(quán),分為搶占調(diào)度和非搶占調(diào)度。
四 基于優(yōu)先級(jí)的非搶占(non-preemptive)調(diào)度
優(yōu)先級(jí)調(diào)度算法是按照任務(wù)的優(yōu)先級(jí)大小來(lái)調(diào)度,使高優(yōu)先級(jí)任務(wù)得到優(yōu)先處理的調(diào)度策略。任務(wù)的優(yōu)先級(jí)可以由系統(tǒng)自動(dòng)地按一定的原則賦給它,也可以由系統(tǒng)外部來(lái)安排,甚至可由用戶(hù)支付高費(fèi)用來(lái)購(gòu)買(mǎi)優(yōu)先級(jí)。在實(shí)時(shí)操作系統(tǒng)中,任務(wù)的優(yōu)先級(jí)是應(yīng)用程序設(shè)計(jì)者按照任務(wù)的重要程度來(lái)安排的,并且任務(wù)在運(yùn)行中其優(yōu)先級(jí)可以動(dòng)態(tài)改變的。一般,任務(wù)越重要,對(duì)應(yīng)的優(yōu)先級(jí)越高。
基于優(yōu)先級(jí)的非搶占(non-preemptive)調(diào)度即一旦某個(gè)高優(yōu)先級(jí)的任務(wù)占有了處理器,就一直運(yùn)行下去,直到任務(wù)由于自身的原因自愿放棄處理器時(shí)(如任務(wù)等待事件)才按優(yōu)先級(jí)進(jìn)行調(diào)度讓另一高優(yōu)先級(jí)任務(wù)運(yùn)行。非搶占調(diào)度又稱(chēng)為合作型多任務(wù)(cooperative multitasking),各個(gè)任務(wù)彼此合作共享一個(gè)CPU。
任務(wù)在運(yùn)行過(guò)程中可以被中斷,中斷處理程序在運(yùn)行過(guò)程中即使喚醒了一個(gè)更高優(yōu)先級(jí)的任務(wù),在ISR完成后還是返回到被中斷的任務(wù),只有這個(gè)任務(wù)放棄了處理器時(shí),更高優(yōu)先級(jí)的任務(wù)才能運(yùn)行。
圖14 所示為非搶占內(nèi)核程序流程:
圖 14非搶占內(nèi)核程序流程
(1)低優(yōu)先級(jí)任務(wù)(LPT)執(zhí)行;
(2)低優(yōu)先級(jí)任務(wù)被中斷;
(3)執(zhí)行中斷服務(wù)程序,使高優(yōu)先級(jí)任務(wù)(HPT)就緒;
(4)中斷服務(wù)程序返回到被中斷地低優(yōu)先級(jí)任務(wù);
(5)低優(yōu)先級(jí)任務(wù)繼續(xù)執(zhí)行;
(6)低優(yōu)先級(jí)任務(wù)放棄CPU;
(7)高優(yōu)先級(jí)任務(wù)運(yùn)行。
圖 15 基于優(yōu)先級(jí)的非搶占調(diào)度
非搶占內(nèi)核的一個(gè)優(yōu)點(diǎn)是響應(yīng)中斷快。在任務(wù)級(jí),非搶占內(nèi)核允許使用不可重入函數(shù),每個(gè)任務(wù)都可以調(diào)用不可重入函數(shù),而不必?fù)?dān)心其它任務(wù)可能正在使用該函數(shù),從而造成數(shù)據(jù)的破壞。當(dāng)然,該不可重入型函數(shù)本身不能有放棄CPU控制權(quán)的企圖。
非搶占內(nèi)核的另一個(gè)優(yōu)點(diǎn)是,幾乎不需要使用信號(hào)量保護(hù)共享數(shù)據(jù)。但這也不是絕對(duì)的,例如,共享I/O設(shè)備時(shí)仍需要使用互斥型信號(hào)量。
非搶占內(nèi)核的最大缺陷在于其響應(yīng)時(shí)間。雖然,非搶占內(nèi)核的任務(wù)級(jí)響應(yīng)時(shí)間要大大好于前后臺(tái)系統(tǒng),但與前后臺(tái)系統(tǒng)一樣,非搶占內(nèi)核的任務(wù)級(jí)響應(yīng)時(shí)間是不確定的,不知道什么時(shí)候最高優(yōu)先級(jí)的任務(wù)才能獲得CPU的控制權(quán),這完全取決于當(dāng)前正在運(yùn)行的任務(wù)什么時(shí)候釋放CPU的控制權(quán),有可能搶占時(shí)間長(zhǎng)達(dá)幾秒鐘。因此,非搶占內(nèi)核極少在實(shí)時(shí)應(yīng)用中使用,商業(yè)實(shí)時(shí)內(nèi)核幾乎沒(méi)有采用非搶占內(nèi)核。
五 基于優(yōu)先級(jí)的搶占(preemptive)調(diào)度
基于優(yōu)先級(jí)的搶占調(diào)度避免了輪循調(diào)度的缺點(diǎn),這種調(diào)度方法為每個(gè)任務(wù)指定不同的優(yōu)先級(jí),任何時(shí)刻都嚴(yán)格按照高優(yōu)先級(jí)任務(wù)在處理器上運(yùn)行的原則進(jìn)行任務(wù)的調(diào)度,或者說(shuō),在處理器上運(yùn)行的任務(wù)永遠(yuǎn)是就緒任務(wù)中優(yōu)先級(jí)最高的任務(wù)。當(dāng)優(yōu)先級(jí)高的任務(wù)能運(yùn)行時(shí),保證其CPU的時(shí)間,讓其盡快運(yùn)行完。如果優(yōu)先級(jí)高的任務(wù)因故(如等待事件)暫停運(yùn)行,則就讓CPU運(yùn)行次高優(yōu)先級(jí)的任務(wù), 一旦優(yōu)先級(jí)高的任務(wù)又就緒(因事件的到來(lái)而成為就緒),任務(wù)調(diào)度器就迫使當(dāng)前運(yùn)行的低優(yōu)先級(jí)任務(wù)馬上讓出處理器給優(yōu)先級(jí)最高的任務(wù)使用。優(yōu)秀的實(shí)時(shí)內(nèi)核的搶占延時(shí)一般是微秒級(jí)的。
“搶占”就是指如果一個(gè)高優(yōu)先級(jí)的任務(wù)就緒之后,任何任務(wù)都能被操作系統(tǒng)中斷。對(duì)實(shí)時(shí)內(nèi)核的一個(gè)重要要求就是要支持內(nèi)核搶占,主要有以下幾種實(shí)現(xiàn)方法:
一種就是在修改通用的操作系統(tǒng)內(nèi)核(主要是UNIX內(nèi)核),在其中插入一些搶占點(diǎn)(又稱(chēng)為調(diào)度點(diǎn)),每當(dāng)?shù)竭_(dá)這些搶占點(diǎn)時(shí),操作系統(tǒng)就做一次快速檢查,看看是否有更高優(yōu)先級(jí)的實(shí)時(shí)任務(wù)準(zhǔn)備就緒,如果有,則調(diào)度器就調(diào)入這個(gè)任務(wù)開(kāi)始執(zhí)行。通常這類(lèi)操作系統(tǒng)中設(shè)置的搶占點(diǎn)約在30到3000個(gè)之間,由于搶占點(diǎn)之間有時(shí)間間隔,一般會(huì)有幾毫秒的延時(shí)。因此只適用于弱實(shí)時(shí)系統(tǒng),例如事務(wù)處理系統(tǒng)。
第二種實(shí)現(xiàn)實(shí)時(shí)內(nèi)核的方法也是修改通用的操作系統(tǒng)內(nèi)核,用信號(hào)量等同步機(jī)制來(lái)保護(hù)內(nèi)核的全局?jǐn)?shù)據(jù)結(jié)構(gòu),使搶占可以發(fā)生在內(nèi)核的任意地方,這也就是所謂的完全搶占。只要使信號(hào)量作足夠精細(xì)的顆粒化,便可使搶占的延遲小到小于100微秒。但由于在內(nèi)核中處處加上了信號(hào)量,導(dǎo)致因等待信號(hào)量所引起的延遲,而且經(jīng)常進(jìn)行信號(hào)量操作也在一定程度上抵消了縮短搶先調(diào)度帶來(lái)的好處。
目前較流行的實(shí)現(xiàn)實(shí)時(shí)內(nèi)核的方法就是在保留通用操作系統(tǒng)內(nèi)核(主要是UNIX內(nèi)核)接口的同時(shí),重新開(kāi)發(fā)實(shí)時(shí)內(nèi)核。為減少前一種方法信號(hào)量的影響,它采用內(nèi)部共享的數(shù)據(jù)結(jié)構(gòu)而不使用信號(hào)量,對(duì)于與外部共享的數(shù)據(jù)結(jié)構(gòu),仍使用信號(hào)量機(jī)制來(lái)保護(hù)。例如LynxOS就是采用的這種策略。
目前實(shí)時(shí)性能最高的實(shí)時(shí)內(nèi)核采用的專(zhuān)用內(nèi)核,例如VxWorks,響應(yīng)時(shí)間通常低于10微秒。
下面介紹搶占內(nèi)核的程序流程,如圖16所示:
圖 16 搶占內(nèi)核程序流程
(1)低優(yōu)先級(jí)任務(wù)(LPT)執(zhí)行;
(2)異步事件使當(dāng)前任務(wù)被中斷;
(3)響應(yīng)異步事件,執(zhí)行中斷服務(wù)程序,使高優(yōu)先級(jí)任務(wù)(HPT)就緒;
(4)中斷服務(wù)程序返回到高優(yōu)先級(jí)任務(wù);
(5)高優(yōu)先級(jí)任務(wù)執(zhí)行,直到它被中斷轉(zhuǎn)向執(zhí)行更高優(yōu)先級(jí)的任務(wù);
(6)高優(yōu)先級(jí)任務(wù)放棄CPU,內(nèi)核切換到低優(yōu)先級(jí)任務(wù);
(7)低優(yōu)先級(jí)任務(wù)繼續(xù)運(yùn)行。
各任務(wù)的優(yōu)先級(jí)可以是靜態(tài)的,也即在系統(tǒng)初始化時(shí)各任務(wù)的優(yōu)先級(jí)就被固定下來(lái)(實(shí)際上在程序編譯時(shí)就已知了),在執(zhí)行過(guò)程中不能改變;優(yōu)先級(jí)也可以是動(dòng)態(tài)的,它們可以在系統(tǒng)運(yùn)行時(shí)被用戶(hù)使用系統(tǒng)調(diào)用來(lái)加以改變,但不能在運(yùn)行時(shí)被操作系統(tǒng)所改變。
基于優(yōu)先級(jí)的搶占調(diào)度可以保證有快的響應(yīng)時(shí)間,它使得最重要的任務(wù)只要在它需要的時(shí)候就可以獲得處理器的控制權(quán)。使用搶占內(nèi)核使得任務(wù)級(jí)響應(yīng)時(shí)間達(dá)到最優(yōu),而且是可知的。目前大多數(shù)嵌入式操作系統(tǒng)采用了基于優(yōu)先級(jí)的搶占調(diào)度算法。
這種調(diào)度方法的缺點(diǎn)是,它要求上層軟件設(shè)計(jì)人員恰當(dāng)?shù)姆峙淙蝿?wù)的優(yōu)先級(jí),任務(wù)的優(yōu)先級(jí)分配不合理會(huì)造成任務(wù)頻繁切換,從而會(huì)嚴(yán)重影響系統(tǒng)整體性能。另外,如果不作適當(dāng)安排,最高優(yōu)先級(jí)的任務(wù)便有可能獨(dú)占CPU,使得其它其它任務(wù)都無(wú)法運(yùn)行,這就是所謂的“餓死”現(xiàn)象。
使用搶占內(nèi)核時(shí),應(yīng)用程序不能直接使用不可重入型函數(shù)。調(diào)用不可重入型函數(shù)時(shí),要滿足互斥條件,這可以利用互斥型信號(hào)量來(lái)實(shí)現(xiàn)。
實(shí)用的實(shí)時(shí)多任務(wù)操作系統(tǒng)通常都兼具有輪循調(diào)度和搶占調(diào)度兩種方法,對(duì)于高優(yōu)先級(jí)的任務(wù),采用搶占調(diào)度;對(duì)于優(yōu)先級(jí)相同的任務(wù),采用時(shí)間片輪循調(diào)度,即:當(dāng)有兩個(gè)或多個(gè)就緒任務(wù)具有相同的優(yōu)先級(jí)且它們是就緒任務(wù)中優(yōu)先級(jí)最高的任務(wù)時(shí),調(diào)度程序就選擇這組任務(wù)中的第一個(gè)就緒任務(wù),讓它僅運(yùn)行一段時(shí)間,在運(yùn)行完一個(gè)時(shí)間片后,該任務(wù)即使還沒(méi)有停止運(yùn)行,它也必須釋放處理器讓下一個(gè)與它相同優(yōu)先級(jí)的任務(wù)運(yùn)行(假設(shè)這時(shí)沒(méi)有比更高優(yōu)先級(jí)的任務(wù)就緒),而釋放處理器的任務(wù)就排到同級(jí)優(yōu)先級(jí)最后任務(wù)的后面,等待再次運(yùn)行。
理論上,采用實(shí)時(shí)調(diào)度算法可以將一個(gè)通用操作系統(tǒng)轉(zhuǎn)變?yōu)橐粋€(gè)實(shí)時(shí)操作系統(tǒng),但實(shí)際上,通用操作系統(tǒng)的上下文切換開(kāi)銷(xiāo)太大,以至于只能對(duì)那些時(shí)間限制較松的應(yīng)用才能達(dá)到其實(shí)時(shí)性能要求。這就導(dǎo)致了多數(shù)實(shí)時(shí)系統(tǒng)使用的是專(zhuān)用的實(shí)時(shí)操作系統(tǒng)。
六 優(yōu)先級(jí)反轉(zhuǎn)(priority inversion)
使用實(shí)時(shí)內(nèi)核,優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題是實(shí)時(shí)系統(tǒng)中出現(xiàn)得最多的問(wèn)題。圖17解釋了優(yōu)先級(jí)反轉(zhuǎn)是如何出現(xiàn)的。
圖 17 優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題
任務(wù)1的優(yōu)先級(jí)高于任務(wù)2,任務(wù)2的優(yōu)先級(jí)高于任務(wù)3。
(1)任務(wù)1和2處于掛起狀態(tài),等待某一事件發(fā)生,任務(wù)3正在運(yùn)行;
(2)任務(wù)3要使用共享資源,在使用共享資源之前,必須首先得到該資源的信號(hào)量,任務(wù)3得到該信號(hào)量后,開(kāi)始使用該共享資源;
(3)任務(wù)1的優(yōu)先級(jí)比任務(wù)3高,當(dāng)任務(wù)1等待的事件到達(dá)后,就剝奪了任務(wù)3的CPU控制權(quán);
(4)任務(wù)1開(kāi)始執(zhí)行;
(5)運(yùn)行中的任務(wù)1也要使用正被任務(wù)3使用著的共享資源,因此只能進(jìn)入掛起狀態(tài),等待任務(wù)3釋放該信號(hào)量;
(6)任務(wù)3繼續(xù)運(yùn)行;
(7)由于任務(wù)2的優(yōu)先級(jí)高于任務(wù)3,當(dāng)任務(wù)2等待的事件發(fā)生后,任務(wù)2剝奪了任務(wù)3的CPU使用權(quán);
(8)任務(wù)2開(kāi)始運(yùn)行;
(9)當(dāng)任務(wù)2運(yùn)行完畢或掛起后,讓出CPU的控制權(quán),任務(wù)3獲得CPU的控制權(quán);
(10)任務(wù)3接著運(yùn)行;
(11)任務(wù)3運(yùn)行到釋放那個(gè)共享資源的信號(hào)量;
(12)因?yàn)槿蝿?wù)1正在等待這個(gè)信號(hào)量,且比任務(wù)3的優(yōu)先級(jí)高,內(nèi)核進(jìn)行任務(wù)切換,任務(wù)1獲得該信號(hào)量后,接著運(yùn)行。
在這種情況下,任務(wù)1的優(yōu)先級(jí)實(shí)際上降到了任務(wù)3的優(yōu)先級(jí)水平。因?yàn)槿蝿?wù)1直到任務(wù)3釋放占有的那個(gè)共享資源,由于任務(wù)2可以剝奪任務(wù)3的CPU的控制權(quán),使任務(wù)的狀況更加惡化,任務(wù)2使任務(wù)1增加了額外的延遲時(shí)間。任務(wù)1和任務(wù)2的優(yōu)先級(jí)發(fā)生了反轉(zhuǎn)。
糾正的方法可以是,在任務(wù)3使用共享資源時(shí),提升任務(wù)3的優(yōu)先級(jí)(任務(wù)3的優(yōu)先級(jí)必須升至最高,高于允許使用該共享資源的任何任務(wù)),在使用完畢共享資源后,恢復(fù)其優(yōu)先級(jí)。
多任務(wù)內(nèi)核應(yīng)允許動(dòng)態(tài)改變?nèi)蝿?wù)的優(yōu)先級(jí)以避免發(fā)生優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象,然而改變?nèi)蝿?wù)的優(yōu)先級(jí)是很花時(shí)間的。如果任務(wù)3并沒(méi)有被任務(wù)1剝奪CPU的控制權(quán),卻要在使用共享資源之前花時(shí)間提升任務(wù)3的優(yōu)先級(jí),并在使用完畢后恢復(fù)任務(wù)3的優(yōu)先級(jí),這無(wú)形中浪費(fèi)了很多CPU時(shí)間。
真正需要的是,為防止優(yōu)先級(jí)反轉(zhuǎn),內(nèi)核能自動(dòng)變換任務(wù)的優(yōu)先級(jí),這叫優(yōu)先級(jí)繼承(priority inheritance),一些商業(yè)實(shí)時(shí)內(nèi)核支持優(yōu)先級(jí)繼承功能,如VRTXsa。
如果內(nèi)核支持優(yōu)先級(jí)繼承,圖18解釋了上述例子應(yīng)如何處理。
圖 18 支持優(yōu)先級(jí)繼承的內(nèi)核
(1)-(4)同上;
(5)任務(wù)1要使用共享資源,此時(shí)內(nèi)核知道該信號(hào)量被任務(wù)3占用,而任務(wù)3的優(yōu)先級(jí)比任務(wù)1低,于是內(nèi)核將任務(wù)3的優(yōu)先級(jí)提升至與任務(wù)1一樣,然后將CPU的控制權(quán)交給任務(wù)3;
(6)任務(wù)3繼續(xù)運(yùn)行,使用該共享資源;
(7)任務(wù)3使用完該共享資源后,釋放信號(hào)量,內(nèi)核恢復(fù)任務(wù)3的優(yōu)先級(jí),將信號(hào)量交給任務(wù)1;
(8)任務(wù)1繼續(xù)運(yùn)行;
(9)任務(wù)1讓出CPU的控制權(quán)后,內(nèi)核調(diào)度程序?qū)PU的控制權(quán)交給任務(wù)2;
(10)任務(wù)2開(kāi)始運(yùn)行。
在某種程度上,任務(wù)2和任務(wù)3之間還是有不可避免的優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題。
七 任務(wù)優(yōu)先級(jí)分配
給任務(wù)給定優(yōu)先級(jí)可不是件小事,因?yàn)閷?shí)時(shí)系統(tǒng)相當(dāng)復(fù)雜。許多系統(tǒng)中,并非所有的任務(wù)都至關(guān)重要,不重要任務(wù)的優(yōu)先級(jí)自然可以低一些。實(shí)時(shí)系統(tǒng)大多綜合了軟實(shí)時(shí)和硬實(shí)時(shí)這兩種需求。
一項(xiàng)有意思的技術(shù)可稱(chēng)為速率單調(diào)調(diào)度算法RMS(Rate Monotonic Scheduling),用于分配任務(wù)的優(yōu)先級(jí)。這種方法基于哪個(gè)任務(wù)執(zhí)行的次數(shù)最頻繁,執(zhí)行最頻繁多任務(wù)的優(yōu)先級(jí)最高。如果把任務(wù)的優(yōu)先級(jí)描述成關(guān)于它們速率的函數(shù),其結(jié)果是一個(gè)單調(diào)遞增函數(shù),如圖19所示,因此稱(chēng)為速率單調(diào)調(diào)度。
圖 19速率單調(diào)調(diào)度算法
RMS做了一系列假設(shè):
1.所有任務(wù)都是周期性的;
2.任務(wù)間不需要同步,沒(méi)有共享資源,沒(méi)有任務(wù)間數(shù)據(jù)交換等問(wèn)題;
3.CPU必須總是執(zhí)行那個(gè)優(yōu)先級(jí)最高且處于就緒態(tài)度任務(wù)。換句話說(shuō),要使用搶占優(yōu)先調(diào)度算法。
給出一系列n值表示系統(tǒng)中的不同任務(wù)數(shù),要使所有的任務(wù)滿足硬實(shí)時(shí)條件,必須使下面的不等式成立,這就是RMS定理:
這里,Ei是任務(wù)I的最長(zhǎng)執(zhí)行時(shí)間,Ti是任務(wù)I的執(zhí)行周期(該任務(wù)的執(zhí)行頻率為T(mén)i的倒數(shù)),n是系統(tǒng)中的任務(wù)數(shù)。Ei/Ti是任務(wù)I所需的CPU時(shí)間。對(duì)于無(wú)窮多個(gè)任務(wù),n(21/n-1)的極限值是ln2或0.693。這意味著,要任務(wù)滿足硬實(shí)時(shí)條件,所有有時(shí)間條件要求的任務(wù)I總的CPU利用時(shí)間應(yīng)小于70%!請(qǐng)注意,這是指有時(shí)間條件要求的任務(wù),系統(tǒng)中當(dāng)然還可以有對(duì)時(shí)間沒(méi)有要求的任務(wù)(軟實(shí)時(shí)任務(wù)),可以給它們分配較低的優(yōu)先級(jí),占用硬實(shí)時(shí)任務(wù)在RMS調(diào)度中沒(méi)有使用的處理器的時(shí)間,使得CPU的利用率達(dá)到100%。當(dāng)然,使CPU的利用率達(dá)到100%并不好,因?yàn)槟菢拥脑?,程序就沒(méi)有了修改的余地,也沒(méi)法增加新功能了。作為系統(tǒng)設(shè)計(jì)的一條原則,CPU利用率應(yīng)小于60%-70%。
RMS認(rèn)為最高執(zhí)行率的任務(wù)具有最高的優(yōu)先級(jí),但某些情況下,最高執(zhí)行率的任務(wù)并非最重要的任務(wù)。如果實(shí)際應(yīng)用都真的象RMS說(shuō)的那樣,也就沒(méi)有什么優(yōu)先級(jí)分配可以討論了。然而討論優(yōu)先級(jí)分配問(wèn)題,RMS無(wú)疑是一個(gè)有意思的起點(diǎn)。
八 最早最后期限調(diào)度
當(dāng)代大多數(shù)實(shí)時(shí)操作系統(tǒng)的設(shè)計(jì)目標(biāo)是盡可能快速地啟動(dòng)實(shí)時(shí)任務(wù),因此強(qiáng)調(diào)快速中斷處理和任務(wù)調(diào)度。事實(shí)上,在評(píng)估實(shí)時(shí)操作系統(tǒng)時(shí),并沒(méi)有一個(gè)特別有用的度量。盡管存在動(dòng)態(tài)資源請(qǐng)求和沖突、處理過(guò)負(fù)荷和軟硬件故障,實(shí)時(shí)應(yīng)用程序通常并不關(guān)注絕對(duì)速度,它關(guān)注的是在最有價(jià)值的時(shí)間內(nèi)完成(或啟動(dòng))任務(wù),既不要太早,也不要太晚。
近年來(lái),不斷提出了許多關(guān)于實(shí)時(shí)任務(wù)調(diào)度的更有力、更適合的方法,所有這些方法都基于每個(gè)任務(wù)的額外信息,最常見(jiàn)到信息有:
1.就緒時(shí)間:任務(wù)開(kāi)始準(zhǔn)備執(zhí)行時(shí)的時(shí)間。對(duì)于周期性任務(wù),這實(shí)際上是一個(gè)事先知道的時(shí)間序列。而對(duì)于非周期性任務(wù),或者也事先知道這個(gè)時(shí)間,或者操作系統(tǒng)僅僅知道什么時(shí)候任務(wù)真正就緒。
2.啟動(dòng)最后期限:任務(wù)必須開(kāi)始的時(shí)間。
3.完成最后期限:任務(wù)必須完成的時(shí)間。典型的實(shí)時(shí)應(yīng)用程序或者有啟動(dòng)最后期限,或者有完成最后期限,但不會(huì)兩者都存在。
4.處理時(shí)間:從執(zhí)行任務(wù)直到完成任務(wù)所需要的時(shí)間。在某些情況下,可以提供這個(gè)時(shí)間,而在另外一些情況下,操作系統(tǒng)度量指數(shù)平均值。其它調(diào)度算法沒(méi)有使用這個(gè)信息。
5.資源需求:任務(wù)在執(zhí)行過(guò)程中所需要的資源集合(指處理器之外的資源)。
6.子任務(wù)結(jié)構(gòu):一個(gè)任務(wù)可以分解成一個(gè)必須執(zhí)行的子任務(wù)和一個(gè)可選的子任務(wù)。只有必須執(zhí)行的子任務(wù)擁有硬最后期限。
當(dāng)考慮到最后期限時(shí),實(shí)時(shí)調(diào)度功能可以分成許多維:下一次調(diào)度哪個(gè)任務(wù)以及允許哪種類(lèi)型的搶占??梢钥吹?,對(duì)一個(gè)給定的搶占策略,其具有啟動(dòng)最后期限或者完成最后期限,用最早最后期限優(yōu)先的策略調(diào)度任務(wù)可以使超過(guò)最后期限的任務(wù)數(shù)最少。這個(gè)結(jié)論既適用于單處理器配置,也適用于多處理器配置。
另一個(gè)重要的設(shè)計(jì)問(wèn)題是搶占。當(dāng)確定了啟動(dòng)最后期限后,可以使用非搶占的調(diào)度程序。在這種情況下,如果實(shí)時(shí)任務(wù)完成了必須執(zhí)行的部分或者關(guān)鍵部分,它自己負(fù)責(zé)阻塞自己,使得別的實(shí)時(shí)啟動(dòng)最后期限能夠得到滿足。對(duì)于具有完成最后期限的系統(tǒng),搶占策略更適合一些,可以立即搶占,也可以在調(diào)度點(diǎn)搶占。
如果要詳細(xì)了解可以查閱有關(guān)的技術(shù)資料,目前常見(jiàn)的商用實(shí)時(shí)內(nèi)核還沒(méi)有見(jiàn)到采用最后期限調(diào)度算法的。
四 對(duì)存儲(chǔ)器的需求
如果設(shè)計(jì)是前后臺(tái)系統(tǒng),對(duì)存儲(chǔ)器容量的需求僅僅取決于應(yīng)用程序代碼。而使用多任務(wù)內(nèi)核時(shí)情況則很不一樣。內(nèi)核本身需要額外的代碼空間(ROM)。內(nèi)核的大小取決于多種因素,取決于內(nèi)核的特性,從1K到100K字節(jié)都是可能的。8位CPU用的最小內(nèi)核只提供任務(wù)調(diào)度、任務(wù)切換、信號(hào)量處理、延時(shí)及超時(shí)服務(wù)約需要1K到3K代碼空間。代碼總需要量為:
總代碼量 = 應(yīng)用程序代碼 + 內(nèi)核代碼
因?yàn)槊總€(gè)任務(wù)都是獨(dú)立運(yùn)行的,必須給每個(gè)任務(wù)提供單獨(dú)的堆棧空間。應(yīng)用程序設(shè)計(jì)人員決定分配給每個(gè)任務(wù)多少堆??臻g時(shí),應(yīng)該盡可能地使之接近實(shí)際需求量(有時(shí),這是相當(dāng)困難的一件事)。堆棧空間的大小不僅僅要計(jì)算任務(wù)本身的需求(局部變量、函數(shù)調(diào)用等),還需要計(jì)算最多中斷嵌套層數(shù)(保存寄存器、中斷服務(wù)程序中的局部變量等)。根據(jù)不同的目標(biāo)微處理器和內(nèi)核電類(lèi)型,任務(wù)堆棧和系統(tǒng)堆棧可以是分開(kāi)的。系統(tǒng)堆棧專(zhuān)門(mén)用于處理中斷級(jí)代碼。這樣做有很多好處,每個(gè)任務(wù)需要的堆??臻g可以大大減少。內(nèi)核的另一個(gè)應(yīng)該具有的性能是,每個(gè)任務(wù)所需的堆??臻g可以分別定義。相反,有些內(nèi)核要求每個(gè)任務(wù)要求每個(gè)任務(wù)所需的堆棧空間都相同,所有內(nèi)核都需要額外的堆??臻g以保證內(nèi)部變量、數(shù)據(jù)結(jié)構(gòu)、隊(duì)列等。如果內(nèi)核不支持單獨(dú)的中斷堆棧,總的RAM需求為:
RAM總需求 = 應(yīng)用程序的RAM需求
+ (任務(wù)堆棧需求+最大中斷嵌套堆棧需求)×任務(wù)數(shù)
如果內(nèi)核支持中斷堆棧分離,總的RAM需求為:
RAM總需求 = 應(yīng)用程序的RAM需求 + 內(nèi)核數(shù)據(jù)區(qū)的RAM需求
+ 各任務(wù)堆棧需求之總和 + 最多中斷嵌套堆棧之需求
除非有特別大的RAM空間可用,對(duì)堆棧空間的分配與使用要非常小心。為減少應(yīng)用程序需要的RAM空間,對(duì)每個(gè)任務(wù)堆??臻g的使用都要非常小心,特別要注意以下幾點(diǎn):
1.定義函數(shù)和中斷服務(wù)子程序中的局部變量,特別是定義大型數(shù)組合數(shù)據(jù)結(jié)構(gòu);
2.函數(shù)(即子程序)嵌套;
3.中斷嵌套;
4.庫(kù)函數(shù)需要的堆??臻g;
5.多變?cè)暮瘮?shù)調(diào)用。
綜上所述,多任務(wù)系統(tǒng)比前后臺(tái)系統(tǒng)需要更多的代碼空間(ROM)和數(shù)據(jù)空間(RAM)。額外的代碼空間取決于內(nèi)核的大小,而RAM的用量取決于系統(tǒng)中的任務(wù)數(shù)。
聯(lián)系客服