出自:http://blog.csdn.net/zhourui1982/article/details/5282361linux
作嵌入式系統開發有一段時間了,作過用於手機平臺的嵌入式Linux,也接觸過用於交換機、媒體網關平臺的VxWorks,實際應用後回過頭來看理論,才發現本身理解的膚淺,也發現CSDN上好多同窗們都對實時、嵌入式這些概念似懂非懂,畢竟若是不作相似的產品,平時接觸的機會不多,即便作嵌入式產品開發,基本也是隻管調用Platform team封裝好的API。因此在此總結一下這些概念,加深本身的理解,同時也給新手入門,歡迎你們拍磚,爭取寫個連載,本文先總結一下實時的概念,什麼是真正的實時操做系統?算法
1. 首先說一下實時的定義及要求:編程
參見 Donal Gillies 在 Realtime Computing FAQ 中提出定義:實時系統指系統的計算正確性不只取決於計算的邏輯正確性,還取決於產生結果的時間。若是未知足系統的時間約束,則認爲系統失效。
http://www.faqs.org/faqs/realtime-computing/faq/服務器
一個實時操做系統面對變化的負載(從最小到最壞的狀況)時必須肯定性地保證知足時間要求。請注意,必需要知足肯定性,而不是要求速度足夠快!例如,若是使用足夠強大的CPU,Windows在CPU空閒時能夠提供很是短的典型中斷響應,可是,當某些後臺任務正在運行時,有時候響應會變得很是漫長,以致於某一個簡單的讀取文件的任務會長時間無響應,甚至直接掛死。這是一個基本的問題:並非Windows不夠快或效率不夠高,而是由於它不能提供肯定性,因此,Windows不是一個實時操做系統。網絡
根據實際應用,能夠選擇採用硬實時操做系統或軟實時操做系統,硬實時固然比軟實時好,可是,若是你的公司正在準備開發一款商用軟件,那請你注意了,業界公認比較好的VxWorks(WindRiver開發),會花光你原本就不多的銀子,而軟實時的操做系統,如某些實時Linux,通常是開源免費的,咱們公司原本的產品就是基於VxWorks的,如今業界都在Cost Reduction,爲了響應號召,正在調研如何把平臺換成免費的嵌入式實時Linux。同窗們,如何選擇,本身考慮吧:-)數據結構
硬實時 - 表明產品 VxWorks 架構
舉一個常用的實例,中高檔汽車中使用的氣囊。當報告車輛碰撞的傳感器中斷CPU後,操做系統應快速地分配展開氣囊的任務,而且不容許任何其餘非實時處理進行干擾,晚一秒鐘展開氣囊比沒有氣囊的狀況更糟糕,這就是一個典型的必須使用硬實時的系統。 併發
硬實時系統指系統要有確保的最壞狀況下的服務時間,即對於事件的響應時間的截止期限是不管如何都必須獲得知足。 函數
軟實時 - 表明產品 軟實時Linux 性能
再舉一個實例,IPTV數字電視機頂盒,須要實時的處理(解碼)視頻流,若是丟失了一個或幾個視頻幀,顯然會形成視頻的品質更差,可是隻要作過簡單的抖動處理的系統,丟失幾個視頻幀就不會對整個系統形成不可挽救的影響。
軟實時系統就是那些從統計的角度來講,一個任務可以獲得有確保的處理時間,到達系統的事件也可以在截止期限到來以前獲得處理,但違反截止期限並不會帶來致命的錯誤。
---------------------------------------------
請注意:講到這裏,想花點墨水區分一下實時和嵌入式的概念,由於筆者也長時間把這二者混爲一談。實時操做系統的概念上文已經講的很清楚了,主要就是要能肯定性的知足時間要求。嵌入式系統很難下一個定義,有興趣的能夠百科一下「嵌入式系統」,通常能夠認爲是板子或芯片上軟硬件的總和,嵌入式系統必定要對實時任務有很強的支持能力,因此通常嵌入式系統都會採用實時操做系統,根據不一樣應用,選擇採用硬實時或軟實時。
---------------------------------------------
2. 如何衡量一個實時操做系統的實時性能?
主要有如下兩個重要指標:
指標一、中斷響應時間(可屏蔽中斷)
計算機接收到中斷信號到操做系統做出響應,並完成切換轉入中斷服務程序的時間。對於搶先式內核,要先調用一個特定的函數,該函數通知內核即將進行中斷服務,使得內核能夠跟蹤中斷的嵌套。搶先式內核的中斷響應時間由下式給出:
中斷響應時間=關中斷的最長時間+保護CPU 內部寄存器的時間+進入中斷服務函數的執行時間+開始執行中斷服務例程(ISR)的第一條指令時間
請注意:中斷響應時間是系統在最壞狀況下響應中斷的時間,某系統100次中有99次在50ms以內響應中斷,只有一次響應中斷的時間是250ms,只能認爲中斷響應時間是250ms。
指標二、任務切換時間
除爲中斷處理提供肯定性外,實時處理也須要支持週期性間隔的任務調度。大量控制系統要求週期性採樣與處理。某個特定任務必須按照固定的週期(p)執行,從而確保系統的穩定性。考慮一下汽車的防抱死系統(ABS)。控制系統對車輛的每一個車輪的轉速進行採樣(每秒最多 20 次)並控制每一個制動器的壓力(防止它鎖死)。爲了保持控制系統的正常工做,傳感器的採樣與控制必須按照必定的週期間隔。這意味着必須搶佔其餘處理,以便 ABS 任務能按照指望的週期執行。
當多任務內核決定運行另外的任務時,它把正在運行任務的當前狀態(即CPU 寄存器中的所有內容)保存到任務本身的棧區之中。而後把下一個將要運行的任務的當前狀態從該任務的棧中從新裝入CPU 的寄存器,並開始下一個任務的運行。這個過程就稱爲任務切換。作任務切換所須要的時間取決於CPU 有多少寄存器要入棧。CPU 的寄存器越多,額外負荷就越重。
系統實時性能重要指標的典型值
-----------------------------------------------------
VxWorks uC/OS-II RT-Linux2.0 QNX6
硬件平臺 MC68000 33MHz-486 60MHz-486 33MHz-486
任務切換 3.8us < 9us 不詳 12.57us
中斷響應 < 3us < 7.5us 25us 7.54us
-----------------------------------------------------
參考文獻:《4種實時操做系統實時性的分析對比》 - 百度一下能夠搜到
3. 實時操做系統的核心 - 任務調度(VxWorks)
既然實時性對於實時操做系統如此重要,同窗們,咱們下面就來學習一下實現實時性的核心模塊 - 任務調度。筆者所在的公司花了大把銀子購買風河的VxWorks,可是爲了實現本身的可控性,除了任務調度模塊之外所有重寫,包括內存管理、文件管理等其餘核心模塊,但惟獨任務調度模塊除外,這但是人家的壓箱底法寶:-)
構成應用軟件系統的程序集合中,獨立的、相互做用的程序單元,在其執行時稱之爲任務,從系統的角度來看,任務是競爭系統資源的最小運行單元。單個CPU 中,多任務機制製造了一個多個任務同時執行的假象。其實系統只是根據一個多任務調度算法,將內核插入到這些任務中執行。實時系統VxWorks的一個任務可有多種狀態,但最基本的狀態有如下四種:
1) 就緒態(Ready):任務只等待系統分配CUP資源。
2) 掛起態(Pend):任務需等待某些不可利用的資源而被阻塞。
3) 休眠態(Sleep):若是系統不須要某一個任務工做,則這個任務處於休眠狀態。
4) 延遲態(Delay):任務被延遲時所處的狀態。
你們能夠在網上搜一下VxWorks任務調度的相關文章,通常都會配狀態機圖。
----------------------------
請注意:任務(task)、進程(process)、線程(thread)等概念相互聯繫又相互區別,由於不是本文的重點,這裏很少解釋,若是想詳細瞭解推薦看一看「Windows Kernel Programming」。在VxWorks中,由於每一個任務沒有本身獨立的虛擬內存空間,能夠把任務理解爲線程。
----------------------------
任務由系統內核調度運行一段固定長度的時間,稱爲時間片。調度是指爲任務分配資源和時間,使系統知足特定的性能要求。調度算法的目的是在正常狀況下,儘量知足全部任務的時限:在峯值負載條件下,保證強實時任務知足時限。由於時限是區分實時系統和非實時系統的關鍵因素,所以調度算法是實時系統的基本問題。實時操做系統所具備的運行性能,如吞吐量的大小、週轉時間的長短、相應的及時性和可預測性等在很大程度上都取決於實時調度。
進程調度可採用下述兩種方式:
1. 非搶佔方式。採用這種調度方式,一旦把處理機分配給某進程後,便讓該進程一直執行,直到該進程完成或發生某事件而被阻塞,纔再把處理機分配給其餘進程,決不容許某進程搶佔已經分配出去的處理機。顯然它難於知足緊急任務的要求,實時系統中不宜採用這種調度方式。
2. 搶佔方式。容許調度程序根據某種原則,去中止某個正在執行的進程,將已分配給該進程的處理機,從新分配給另外一進程。搶佔的原則有:
- 時間片原則。各進程按時間片運行,當一個時間片用完後,便中止該進程的執行而從新進行調度。
- 優先權原則。當一個進程到來時,若是其優先級比正在執行的進程的優先級高,便中止正在執行的進程,將處理機分配給優先級高的進程,使之執行。實時系統中通常採用基於優先級的搶佔式調度和輪轉調度的進程調度和中程調度相結合的調度策略。所以既可具備較大的靈活性,又能得到極小的調度延遲。
VxWorks的wind內核缺省調度機制爲基於優先級的搶佔式調度。採用這種機制時,系統把處理機分配給優先級最高的進程,使之執行。一旦出現了另外一個優先級更高的進程時,進程調度程序剝奪當前任務的執行,將處理機分配給高優先級任務。而在相同優先級的多個任務之間,採用時間片輪轉調度機制。採用這種機制時,當一個任務到達時,它被排在輪轉隊列的後面,等待分配給本身的時間片的到來,若是在時間片內沒有結束,則再等待屬於本身的時間片的到來,直到任務完成。
- 優先級搶佔式
採用基於優先級的搶佔式調度,系統中每一個任務都有一個介於最高0到最低255之間的優先級。任一時刻,系統內核一旦發現一個優先級更高的任務轉變爲就緒態,內核就保存當前任務的上下文並把當前任務狀態轉換爲阻塞態,同時切換到這個高優先級任務的上下文執行。
- 輪轉調度算法
採用輪轉調度算法,系統讓處於就緒態的優先級相同的一組任務依次輪流執行預先肯定長度的時間片。這是一種處理機平均分配的方法。若是不使用輪轉調度算法,優先級相同的一組任務中第一個得到處理機的任務將不會被阻塞而獨佔處理機,若是沒有阻塞或其餘狀況發生,它不會放棄處理機的使用權。
- 搶佔調度與輪轉調度混合方式
有時,基於優先級的搶佔式調度可與輪轉調度相結合。當優先級相同的一組任務依次輪流平均分配處理機時,如有高優先級的任務轉變爲就緒態則可搶佔該組任務。直到再一次符合執行條件時,該組任務纔可再次共享處理機。
爲了任務控制的靈活性,VxWorks內核還提供了動態優先級機制,任務的優先級在運行期間可動態地變化。同時,爲了防止優先級反轉,還具備優先級繼承機制,經過使用互斥信號量能夠防止高優先級的任務被迫等待一段不肯定時間,直到一個低優先級任務完成。
參考文獻:《實時操做系統VxWorks的內核任務調度研究》 - 百度一下能夠搜到
4. Linux的任務調度
通用Linux系統支持實時和非實時兩種進程,實時進程相對於普通進程具備絕對的優先級。對應地,實時進程採用SCHED_FIFO或者SCHED_RR調度策略,普通的進程採用SCHED_OTHER調度策略。
在調度算法的實現上,Linux中的每一個任務有四個與調度相關的參數,它們是rt_priority、policy、priority(nice)、counter。調度程序根據這四個參數進行進程調度。
在 SCHED_OTHER調度策略中,調度器老是選擇那個priority+counter值最大的進程來調度執行。從邏輯上分析SCHED_OTHER 調度策略存在着調度週期(epoch),在每個調度週期中,一個進程的priority和counter值的大小影響了當前時刻應該調度哪個進程來執行,其中priority是一個固定不變的值,在進程建立時就已經肯定,它表明了該進程的優先級,也表明這該進程在每個調度週期中可以獲得的時間片的多少;counter是一個動態變化的值,它反映了一個進程在當前的調度週期中還剩下的時間片。在每個調度週期的開始,priority的值被賦給 counter,而後每次該進程被調度執行時,counter值都減小。當counter值爲零時,該進程用完本身在本調度週期中的時間片,再也不參與本調度週期的進程調度。當全部進程的時間片都用完時,一個調度週期結束,而後周而復始。另外能夠看出Linux系統中的調度週期不是靜態的,它是一個動態變化的量,好比處於可運行狀態的進程的多少和它們priority值均可以影響一個epoch的長短。值得注意的一點是,在2.4以上的內核中,priority被nice所取代,但兩者做用相似。
可見SCHED_OTHER調度策略本質上是一種比例共享的調度策略,它的這種設計方法可以保證進程調度時的公平性--一個低優先級的進程在每個epoch中也會獲得本身應得的那些CPU執行時間,另外它也提供了不一樣進程的優先級區分,具備高priority值的進程可以得到更多的執行時間。對於實時進程來講,它們使用的是基於實時優先級rt_priority的優先級調度策略,但根據不一樣的調度策略,同一實時優先級的進程之間的調度方法有所不一樣:
- SCHED_FIFO:不一樣的進程根據靜態優先級進行排隊,而後在同一優先級的隊列中,誰先準備好運行就先調度誰,而且正在運行的進程不會被終止直到如下狀況發生:1.被有更高優先級的進程所強佔CPU;2.本身由於資源請求而阻塞;3.本身主動放棄CPU(調用sched_yield);
- SCHED_RR:這種調度策略跟上面的SCHED_FIFO如出一轍,除了它給每一個進程分配一個時間片,時間片到了正在執行的進程就放棄執行;時間片的長度能夠經過sched_rr_get_interval調用獲得;
因爲Linux系統自己是一個面向桌面的系統,因此將它應用於實時應用中時存在以下的一些問題:
- Linux系統中的調度單位爲10ms,因此它不可以提供精確的定時;
- 當一個進程調用系統調用進入內核態運行時,它是不可被搶佔的;
- Linux內核實現中使用了大量的封中斷操做會形成中斷的丟失;
- 因爲使用虛擬內存技術,當發生頁出錯時,須要從硬盤中讀取交換數據,但硬盤讀寫因爲存儲位置的隨機性會致使隨機的讀寫時間,這在某些狀況下會影響一些實時任務的截止期限;
- 雖然Linux進程調度也支持實時優先級,但缺少有效的實時任務的調度機制和調度算法;它的網絡子系統的協議處理和其它設備的中斷處理都沒有與它對應的進程的調度關聯起來,而且它們自身也沒有明確的調度機制;
參考文獻:《基於Linux的實時系統》 - 百度一下能夠搜到
5. 實時Linux研究
呼哧呼哧寫了半天,終於到了重頭戲,實時Linux研究。前文說過,風河的VxWorks雖然性能大大的好,可是要花不少銀子,對於通常的軟實時應用系統來講,仍是用開源免費的實時Linux比較好。筆者所在的公司也正在研究將平臺轉爲Linux。有許多種方法能夠賦予普通Linux實時的能力:
5.1 瘦內核(微內核)- Thin-Kernel
瘦內核(或微內核)方法使用了第二個內核做爲硬件與 Linux 內核間的抽象接口。非實時 Linux 內核在後臺運行,做爲瘦內核的一項低優先級任務託管所有非實時任務。實時任務直接在瘦內核上運行。瘦內核主要用於(除了託管實時任務外)中斷管理。瘦內核截取中斷以確保非實時內核沒法搶佔瘦內核的運行。這容許瘦內核提供硬實時支持。
雖然瘦內核方法有本身的優點(硬實時支持與標準 Linux 內核共存),但這種方法也有缺點。實時任務和非實時任務是獨立的,這形成了調試困難。並且,非實時任務並未獲得 Linux 平臺的徹底支持(瘦內核執行稱爲瘦 的一個緣由)。
使用這種方法的例子有 RTLinux (如今由 Wind River Systems 專有),實時應用程序接口(RTAI)和 Xenomai。
5.2 超微內核
這裏瘦內核方法依賴於包含任務管理的最小內核,而超微內核法對內核進行更進一步的縮減。經過這種方式,它不像是一個內核而更像是一個硬件抽象層(HAL)。超微內核爲運行於更高級別的多個操做系統提供了硬件資源共享。由於超微內核對硬件進行了抽象,所以它可爲更高級別的操做系統提供優先權,從而支持實時性。
注意,這種方法和運行多個操做系統的虛擬化方法有一些類似之處。使用這種方法的狀況下,超微內核在實時和非實時內核中對硬件進行抽象。這與 hypervisor 從客戶(guest)操做系統對裸機進行抽象的方式很類似。
關於超微內核的示例是操做系統的 Adaptive Domain Environment for Operating Systems (ADEOS)。ADEOS 支持多個併發操做系統同步運行。當發生硬件事件後,ADEOS 對鏈中的每一個操做系統進行查詢以肯定使用哪個系統處理事件。
5.3 資源內核(Resource-kernel)
另外一個實時架構是資源內核法。這種方法爲內核增長一個模塊,爲各類資源提供預留(reservation)。這種機制保證了對時分複用(time- multiplexed)系統資源的訪問(CPU、網絡或磁盤帶寬)。這些資源擁有多個預留參數,如循環週期、須要的處理時間(也就是完成處理所需的時間),以及截止時間。
資源內核提供了一組應用程序編程接口(API),容許任務請求這些預留資源。而後資源內核能夠合併這些請求,使用任務定義的約束定義一個調度,從而提供肯定的訪問(若是沒法提供肯定性則返回錯誤)。經過調度算法,如 Earliest-Deadline-First (EDF),內核能夠處理動態的調度負載。
資源內核法實現的一個示例是 CMU 公司的 Linux/RK,它把可移植的資源內核集成到 Linux 中做爲一個可加載模塊。這種實現演化成商用的 TimeSys Linux/RT 產品。
5.4 標準的Linux內核最新版本2.6中加入了實時功能
目前探討的這些方法在架構上都頗有趣,可是它們都在內核的外圍運行。然而,若是對標準 Linux 內核進行必要的修改使其支持實時性,結果會怎麼樣呢?
今天,在 2.6 內核中,經過對內核進行簡單配置使其徹底可搶佔,您就能夠獲得軟實時功能。在標準 2.6 Linux 內核中,當用戶空間的進程執行內核調用時(經過系統調用),它便不能被搶佔。這意味着若是低優先級進程進行了系統調用後,高優先級進程必須等到調用結束後才能訪問 CPU。
新的配置選項 CONFIG_PREEMPT 改變了這一內核行爲,在高優先級任務可用的狀況下(即便此進程正在進行系統調用),它容許進程被搶佔。
但這種配置選項也是一種折衷。雖然此選項實現了軟實時性能而且即便在負載條件下也可以使操做系統順利地運行,但這樣作也付出了代價。代價就是略微減低了吞吐量以及內核性能,緣由是 CONFIG_PREEMPT 選項增長了開銷。這種選項對桌面和嵌入式系統而言是有用的,但並非在任何場景下都有用(例如,服務器)。
在 2.6 內核中另外一項有用的配置選項是高精度定時器。這個新選項容許定時器以 1μs 的精度運行(若是底層硬件支持的話),並經過紅黑樹實現對定時器的高效管理。經過紅黑樹,可使用大量的定時器而不會對定時器子系統(O(log n))的性能形成影響。
只須要一點額外的工做,就能夠經過 PREEMPT_RT 補丁實現硬實時。PREEMPT_RT 補丁提供了多項修改,可實現硬實時支持。其中一些修改包括從新實現一些內核鎖定原語,從而實現徹底可搶佔,實現內核互斥的優先級繼承,並把中斷處理程序轉換爲內核線程以實現線程可搶佔。
參考文獻:實時Linux架構剖析 - M. Tim Jones, 顧問工程師, Emulex Corp.
http://www.ibm.com/developerworks/cn/linux/l-real-time-linux/#resources
-------------------------------------------------------------------------
本文就到此告一段落,結合本身的實際項目經驗,總結了實時操做系統的概念,性能指標,任務調度方法,VxWorks和Linux的實時性對比,以及相應的介紹。供筆者本身學習,也供CSDN各位同窗參考,大部份內容來自網絡,不是一篇嚴謹的論文,若有紕漏還請指出,共同進步。