摘要:介紹了Linux在實時方面存在的三個主要問題:內(nèi)核搶占、實時調(diào)度算法和時鐘細(xì)粒度定時器。針對這三個問題提出了解決的措施,并對Linux嵌入式實時化技術(shù)進行了探討。
關(guān)鍵詞:Linux;內(nèi)核搶占;硐度策略;優(yōu)先級反轉(zhuǎn)
O 引言
從Linux系統(tǒng)的發(fā)展來看,Linux向著嵌入式系統(tǒng)和高端計算領(lǐng)域兩個方向發(fā)展。它的O(1)調(diào)度算法的實現(xiàn)以及可搶占內(nèi)核的調(diào)度方式,給嵌入式系統(tǒng)帶來無限生機。但嚴(yán)格地說,Linux屬于通用的分時系統(tǒng),在嵌入式和實時性方面還存在著一些問題,為此,本文對嵌入式Linux的實時化進行了分析和探討。
1 Linux在實時方面的缺陷
1.1 內(nèi)核可搶占
內(nèi)核可搶占是指進程運行在核心態(tài)時,當(dāng)有更高優(yōu)先級的進程或更緊急的進程到來時,總會立即獲得處理機的控制權(quán),即當(dāng)前運行的進程的控制權(quán)被搶占了。Linux 2.6采用了內(nèi)核可搶占式調(diào)度方式,但它的實現(xiàn)僅僅是在內(nèi)核中增加了搶占點,并沒有實現(xiàn)真正的內(nèi)核可搶占式調(diào)度方式。在Linux 2.6中,搶占點沒在中斷處理程序即將結(jié)束時或系統(tǒng)調(diào)用即將結(jié)束時。對于強實時系統(tǒng)來說,一旦高優(yōu)先級的任務(wù)進入就緒隊列,應(yīng)立即獲得處理機來運行,而調(diào)度程序schedule()通常是在中斷處理程序結(jié)束或系統(tǒng)調(diào)用結(jié)束時,才有機會運行,這時候如果中斷處理時問過長或系統(tǒng)調(diào)用占用時間過長,都會延誤實時任務(wù)的執(zhí)行。所以,只有保證中斷處理程序和系統(tǒng)調(diào)用執(zhí)行時間在一個可控的范圍內(nèi),才能保證實時任務(wù)的正確執(zhí)行。
另外,Linux對中斷的處理,也抑制內(nèi)核可搶占調(diào)度。Linux將整個中斷處理流程分為上半部(Top half)和下半部(Bottom half)。上半部處理的是一些重要的數(shù)據(jù)結(jié)構(gòu)、以及與硬件密切相關(guān)的操作,它在執(zhí)行期間一定要關(guān)閉中斷;下半部的執(zhí)行允許中斷,它是設(shè)備中斷處理的延伸,它對設(shè)備的中斷做進一步的處理。顯然,中斷處理程序的上半部占用時間過長,同樣會影響內(nèi)核搶占。
1.2 調(diào)度策略
在Linux 2.6中仍然保留著Linux 2.4中對實時任務(wù)的調(diào)度策略。Linux進程的調(diào)度策略有三種:SCHED_FIFO、SCHED_RR和SCHED NORMAL,前兩種用于實時進程的調(diào)度。其中SCHED_FIFO指先進先出調(diào)度算法,適合于時間性要求比較強,但每次運行所需時間比較短的進程,采用該策略的進程獲得CPU后,除非有更高優(yōu)先級進程申請運行外,否則該進程將保持運行至退出或自愿放棄CPU;SCHED RR指優(yōu)先級輪轉(zhuǎn)調(diào)度算法,按實時進程的優(yōu)先級大小進行調(diào)度;SCHED_NORMAL適合于普通分時進程的凋度,調(diào)度原則山優(yōu)先級的大小決定。實時進程的優(yōu)先級范圍是0至99,普通進程的優(yōu)先級范圍是100至139,優(yōu)先級數(shù)值越大其優(yōu)先級越低。
Linux 2.6根據(jù)優(yōu)先級大小進行調(diào)度。普通進程的優(yōu)先級隨進程的運行時間、等待時間、是否為交互式進程而動態(tài)地改變;而實時進程的優(yōu)先級在運行過程中不會動態(tài)地改變,即Linux采用靜態(tài)優(yōu)先級對實時進程進行調(diào)度。以靜態(tài)優(yōu)先級來衡量任務(wù)的緊迫性和重要性,存在著偏差,因為任務(wù)的緊迫性和重要性會隨著時間的變化而動態(tài)地改變,要正確地反映實時任務(wù)的緊迫性和重要性最好采用動態(tài)優(yōu)先級。
1.3 時鐘定時器
精確的計時是實時調(diào)度器正確操作所必須的。在標(biāo)準(zhǔn)Linux中定時粒度太粗,很難滿足特定嵌入式應(yīng)用對于響應(yīng)時間精度的要求。造成時間精度低的一個原因是操作系統(tǒng)使用周期性的時鐘中斷。為了達(dá)到微秒級的粒度,如果簡單地對時鐘芯片編程,使之運行在較高頻率下,則系統(tǒng)開銷太高。比如,每秒時鐘中斷次數(shù)增加到10萬次,雖然得到10微秒的粒度,但系統(tǒng)在1秒的時間內(nèi)執(zhí)行了10萬次時鐘中斷處理程序,造成較高的系統(tǒng)開銷。當(dāng)然,這種開銷會隨著硬件速度的提高逐步降低。這種周期模式的定時器適用于某些周期性強的場合,而且,對定時器的設(shè)置僅需要在初始化時進行一次,不需要在下一個實時任務(wù)到來之前重新設(shè)置,這也保證了處理效率。但如何確定時鐘中斷頻率是系統(tǒng)設(shè)計者要考慮的主要問題,要考慮既不能使系統(tǒng)開銷過高,又不能使計時精度太低。
2 Ljnux實時性改造
2.1 可搶占式內(nèi)核的設(shè)計
在硬實時應(yīng)用領(lǐng)域,操作系統(tǒng)必須保證特定的任務(wù)在指定的時間內(nèi)完成,計算結(jié)果輸出的時間絕對不能超過所要求的截止期(Deadline)。但Linux 2.6的弱搶占內(nèi)核的調(diào)度方式,在某些關(guān)鍵的地方,并不適合硬實時的要求,所以必須對內(nèi)核進行改造。
目前,一般采用雙內(nèi)核支持Linux的硬實時性,比如,美國新墨西哥州大學(xué)計算機系研制開發(fā)的RT-Linux,就是基于這種策略而開發(fā)的。RT-Linux主要應(yīng)用于儀器設(shè)備和嵌入式系統(tǒng)。它的目標(biāo)是將Linux提供的標(biāo)準(zhǔn)POSIX服務(wù)與硬實時服務(wù)有機地結(jié)合起來,提供透明的、模塊化的、可擴展的實時操作系統(tǒng)。RT-Linux通過修改Linux/arch/i386/下與體系結(jié)構(gòu)有關(guān)的部分,在Linux與硬件之間創(chuàng)建一個硬實時內(nèi)核,Linux作為此內(nèi)核的一個優(yōu)先級最低的任務(wù)運行,硬實時任務(wù)都在硬實時內(nèi)核上運行,而所有非實時任務(wù)都在Linux上運行。RT-Linux接管了全部硬件中斷,并將Linux系統(tǒng)調(diào)用及驅(qū)動程序的開、關(guān)中斷都用RT-Linux的軟中斷代替。當(dāng)發(fā)生中斷時,實時內(nèi)核首先檢查是否有實時處理程序要處理這個中斷,如果有則調(diào)用此實時處理程序,沒有則設(shè)置相應(yīng)的中斷標(biāo)志位,交給Linux處理。
另一種是對內(nèi)核進行實時化改造,但將內(nèi)核改造成硬實時,需要大量的工作。目前,常采用的方法是在內(nèi)核代碼中增加搶占點,從而減少內(nèi)核搶占延遲。這一點在Linux 2.6中已經(jīng)做到。然而,這些局部修改屬于軟實時范疇,在控制領(lǐng)域中,只有硬實時才符合RTOS(Real Time Operating System)的發(fā)展方向。
2.2 實時調(diào)度算法的設(shè)計
在實時系統(tǒng)中,往往要求系統(tǒng)對外部事件的響應(yīng)和處理要在一個給定的時間內(nèi)完成,系統(tǒng)輸出的正確性不僅依賴于計算的邏輯結(jié)果,而且依賴于結(jié)果產(chǎn)生的時間。隨著時間的變化,實時任務(wù)的緊急程度也在變化,這就要求在基于優(yōu)先級的調(diào)度算法中,實時進程的優(yōu)先級要隨著時問的變化而動態(tài)地改變,從優(yōu)先級的大小就能判斷出任務(wù)的緊急程度,這樣調(diào)度才能正確地反映出真實的世界。Linux對實時進程的調(diào)度是基于靜態(tài)優(yōu)先級的策略,沒有反映出實時進程的緊迫性隨時間的變化。
實時調(diào)度算法大致可分為三種:優(yōu)先級驅(qū)動、時間驅(qū)動和共享驅(qū)動調(diào)度算法。其中以優(yōu)先級驅(qū)動的調(diào)度算法應(yīng)用最廣,文獻[2,4]都是基于優(yōu)先級驅(qū)動對調(diào)度算法進行討論的。在以優(yōu)先級驅(qū)動的調(diào)度算法中,動態(tài)優(yōu)先級大小通常用進程的截止期(deadline)和價值(value)來決定。
可搶占內(nèi)核調(diào)度程序的設(shè)計雖然可以加快任務(wù)的響應(yīng)時間,但同時也有副作用,那就是優(yōu)先級反轉(zhuǎn)問題:低優(yōu)先級任務(wù)L獲得臨界資源R,在執(zhí)行中來了一個高優(yōu)先級任務(wù)H,這時H搶占處理機,任務(wù)L被迫停止運行,而任務(wù)H運行時想獲得I臨界資源R而又無法得到,只好等待,而此刻又來了若干中等優(yōu)先級的任務(wù),致使任務(wù)L無法獲得處理機運行,這樣高優(yōu)先級任務(wù)H就得延遲執(zhí)行,且無法預(yù)測何時才能運行,使系統(tǒng)處于不穩(wěn)定狀態(tài)。
文獻[2]對解決優(yōu)先級反轉(zhuǎn)問題的兩種方法在中進行了詳細(xì)討論,一種方法采用優(yōu)先級繼承協(xié)議(Priority InheritanceProtoc01),另一種方法采用優(yōu)先級封頂協(xié)議(Priority CeilingProtoc01)。優(yōu)先級繼承協(xié)議是指當(dāng)?shù)蛢?yōu)先級進程占用高優(yōu)先級進程的資源而制約高優(yōu)先級進程時,將占用資源的低優(yōu)先級的進程的優(yōu)先級提升,讓其運行,盡決釋放高優(yōu)先級所需資源;當(dāng)其釋放資源后,其優(yōu)先級恢復(fù)到原來的級別。優(yōu)先級封頂協(xié)議是指當(dāng)進程申請某資源并獲得該資源時,把該進程的優(yōu)先級提升到可訪問這個資源的所有進程中的最高優(yōu)先級,這個優(yōu)先級稱為該資源的優(yōu)先級封頂。資源的優(yōu)先級封頂在資源被創(chuàng)建時就確定了。采用這兩種調(diào)度協(xié)議可解決優(yōu)先級反轉(zhuǎn)問題。
總之,實時調(diào)度程序的算法在設(shè)計實時操作系統(tǒng)時至關(guān)重要,算法的優(yōu)劣直接影響調(diào)度的性能以及系統(tǒng)對外部事件的響應(yīng)時間。
2.3 時鐘細(xì)粒度定時器
許多實時應(yīng)用真正需要的不是在每一個微秒都發(fā)生時鐘中斷,而是在任何一個微秒都允許發(fā)生時鐘中斷,這樣不再將時鐘芯片設(shè)置為固定的頻率,而是設(shè)置為下一個事件要發(fā)生的時間。這種設(shè)置時鐘芯片的方式稱之為一次性模式。但是,這樣做的代價是在每個中斷后重設(shè)時鐘。RTLinux既提供了周期性模式,也提供了一次性模式。Kansas大學(xué)開發(fā)的Kurt-Linux采用了一次性模式。
對于周期性時鐘中斷方式,時鐘中斷頻率越高,系統(tǒng)的開銷就越大;一次性模式可有效地支持硬實時系統(tǒng),減少時鐘中斷的次數(shù),但對時鐘定時器的編程將變得復(fù)雜。在細(xì)粒度定時器的實現(xiàn)中,要多方位思考,采取適合實際應(yīng)用環(huán)境的解決方案。
3 結(jié)束語
本文從內(nèi)核搶占機制、實時調(diào)度策略、時鐘細(xì)粒度定時器三方面,對嵌入式Linux實時化技術(shù)進行了探討。Linux在實時性支持方面存在著不足,在開發(fā)基于Linux嵌入式實時操作系統(tǒng)中,有許多關(guān)鍵技術(shù)需要解決。隨著Linux實時性能的逐步完善,以及嵌入式Linux實時系統(tǒng)在控制領(lǐng)域中的深入應(yīng)用,必然進一步促進其發(fā)展,相信Linux將在嵌入式實時應(yīng)用場合中發(fā)揮巨大的作用。