摘 要: 首先對Linux系統的實時機制作了分析,然后根據多媒體應用" title="多媒體應用">多媒體應用的特點,通過改進Linux系統的實時性" title="實時性">實時性,構建了面向多媒體應用的嵌入式" title="的嵌入式">的嵌入式Linux系統。實驗結果表明,該系統在實時性方面完全可以滿足多媒體應用的需求。
關鍵詞: 嵌入式系統 實時性 Linux 多媒體應用
當今信息社會,以多媒體為特征的信息技術和信息產業的發展及應用對人類社會產生的影響和作用愈來愈明顯,愈來愈重要。多媒體技術的發展在很大程度上依賴于多媒體軟件開發的水平。目前不管是支撐多媒體的系統軟件,還是應用軟件,都在能力和數量上難以滿足多媒體飛速發展的需要。特別是多媒體系統軟件的缺乏,一直是制約多媒體產業發展的瓶頸問題之一。
Linux從1991年誕生之日起至今不過十來年,卻已發展成為一個功能強大、設計完善的操作系統。在嵌入式領域,Linux同樣獲得了飛速發展。Linux具有以下特點:
(1)Linux操作系統的開放源碼易于定制剪裁,在價格上有竟爭力;
(2)Linux操作系統的內核小、功能強大、運行穩定、系統強壯、效率高;
(3)Linux操作系統不僅支持X86 CPU,還可以支持其他數十種CPU芯片;
(4)Linux支持所有標準的因特網協議,幾乎所有的協議和網絡接口都定制在其中。
因此,Linux系統是多媒體終端操作系統的首選。
1 通用Linux實時性分析及其在實時性方面的不足
雖然目前Linux內核在實時性方面有所增強,但由于Linux系統本身是一個面向桌面的系統,所以將它應用于多媒體終端時,在實時性方面仍存在一些問題。
1.1 通用Linux系統的調度策略
通用Linux系統支持實時和非實時兩種進程,實時進程相對于普通進程具有絕對的優先級。對應地,實時進程采用SCHED_FIFO或者SCHED_RR調度策略" title="調度策略">調度策略,普通的進程采用SCHED_OTHER調度策略。
SCHED_OTHER調度策略本質上是一種比例共享的調度策略,它的這種設計方法能夠保證進程調度時的公平性:一個低優先級的進程在每一個epoch中也會得到自己應得的那些CPU執行時間,另外它也提供了不同進程的優先級區分,具有高priority值的進程能夠獲得更多的執行時間。
對于實時進程來說,它們使用基于實時優先級rt_priority的優先級調度策略,但根據不同的調度策略,同一實時優先級的進程之間的調度方法有所不同。
Linux調度時,要遍歷運行隊列,對隊列中的每一個進程計算goodness值,goodness 最大的進程將被選中運行。根據調度策略的不同,進程的goodness值也要做不同的計算。普通進程的goodness值是在該進程計數值counter基礎上略有浮動,其范圍是0~999。實時進程的goodness值是將該進程實時優先級rt_priority 加上1000。所以實時進程的goodness 總是大于非實時進程,從而保證了實時進程的優先調度權。函數goodness( )如下:
static inline int goodness(struct task_struct*p,int
this_cpu,struct mm_struct*this _ mm)
{int weight;
weight=-1;
if(P->policy&SCHED_YIELD) goto out;/*非實時進程*/
if (p-> policy= =SCHED_OTHER)
{ weight=p一>counter;
if(! weight)goto out;
if(P一>mm= =this _ mm!!!p一>mm)
weight +=1;
weight +=20一P一>nice;
goto out;
}/*軟實時進程*/
weight= 1000+P一>rt_priority;
goto out;
return weight;
}一
從上面的goodness()函數可以看出普通Linux內核的進程調度算法只是軟實時的,并不是硬實時的。
1.2 通用Linux實時性方面的缺陷
(1)Linux系統中的調度單位為10ms,所以它不能夠提供精確的定時;
(2)當一個進程調用系統調用進入內核態運行時,它是不可被搶占的;
(3)Linux內核實現使用了大量的封中斷操作會造成中斷的丟失;
(4)由于使用虛擬內存技術,當發生頁出錯時,需要從硬盤中讀取交換數據,但硬盤讀寫由于存儲位置的隨機性會導致隨機的讀寫時間,這在某些情況下會影響一些實時任務的截止期限;
(5)雖然Linux進程調度也支持實時優先級,但缺乏有效的實時任務調度" title="任務調度">任務調度機制和調度算法;其網絡子系統的協議處理和其他設備的中斷處理都沒有與它對應的進程的調度關聯起來,并且其自身也沒有明確的調度機制。
2 面向多媒體應用的Linux實時性改進
提高Linux的實時性一般有兩種方法:一種是對普通的Linux內核的數據結構、調度函數、中斷方式等進行修改,使其能夠處理實時進程。另一種是在Linux內核之外,進行實時性擴展。也就是在普通Linux的基礎之上再設計一個用于專門處理實時進程的內核。為了提高Linux的實時性,并且使之能夠更好地滿足多媒體應用系統的需求,本文采用第一種方法來提高系統的實時性。
2.1 提高系統所支持的時鐘精度
為了提高Linux系統的實時特性,必須提高系統所支持的時鐘精度。但如果僅僅簡單地提高時鐘頻率,會引起調度負載的增加,從而嚴重降低系統的性能。為了解決這個矛盾, 本文將時鐘芯片設置為單次觸發狀態,即每次給時鐘芯片設置一個超時時間,然后到該超時事件發生時在時鐘中斷處理程序中再次根據需要給時鐘芯片設置一個超時時間。其基本思想是:一個精確的定時意味著時鐘中斷在一個比較精確的時間發生,但并非一定需要系統時鐘頻率達到此精度。它利用CPU的時鐘計數器來提供精度可達CPU主頻的時間精度。
2.2 可搶占式內核設計
(1)搶占式內核給task struct數據結構增加一個數據項:preempt_count。該數據項由宏preempt_disable()、preempt_enable()、以及preempt_enable_no_resched()所使用。preempt_disable對preempt_count計數進行遞增,preempt_enable對preempt_count進行遞減。preempt_enable宏查看當前進程的preempt_count和need_resched域的內容,如果 preempt_count為0并且need_resched為1,則調用preempt_schedule()函數。該函數將給當前進程的preempt_count項增加一個很大的值,然后調用進程調度函數schedule(),在schedule函數返回后從該進程preempt_count中再減去該值,從而實現內核可搶占。
(2)修改schedule函數,使它檢測進程的preempt_co-unter是否很大(這是為了屏蔽一些普通調度流程中對于搶占式調度來說是冗余的那些操作),然后執行搶占式調度。同時修改spinlock的代碼。在spin_lock()和spin_try_lock中增加了對于preempt_disable的調用,在spin_unlock()中增加了對于preempt_enable的調用。修改中斷返回的代碼,在其中增加了對于preempt_enable的調用。
由以上可看出內核的搶占式調度發生在如下情況:在釋放spinlock時,或者當中斷返回時,如果當前執行進程的need_resched被標記,則進行搶占式調度。
2.3 實時任務調度的實現
在任務切換方面限制Linux不能進入RTOS行列的主要原因是:內核無法及時進行進程調度,即任務調度器schedule()函數不能及時被執行;當中斷返回到內核態時,Linux內核禁止進行進程調度,只有中斷返回到用戶態時,Linux內核才允許進行進程調度。針對這兩點,對Linux內核的相關函數作如下修改:
(1)當系統從中斷返回到內核態時,強制調用調度函數preemp_schedule(),為此,在arch/i386/kernel/Entry.S中修改如下代碼:
……
#ifdef CONFIG PREEMPT
cli
decl preempt count(%ebx)/*恢復內核搶占標志*/
#endif
……
incl preempt count(%ebx)
sti
call SYMBOL_ NAME(preempt_schedule)
jmp ret_from_intr/*新進程返回ret_from_intr恢復搶占標志后再返回*/
……
(2)對于內核態搶占的任務不要從運行隊列刪除,為此需要對文件kernel/schedule.c作修改,關鍵代碼如下:
……
#ifdef CONFIG PREEMPT
ctx_sw_off();/*加鎖,禁止內核搶占*/
#endif
……
#ifdef CONFIG_PREEMPT
if(prev->state & TASK_PREEMPTED)
break;/*如果是內核搶占調度,則保留運行隊列*/
#endif
……
#ifdef CONFIG PREEMPT
ctx_sw_on_no_preempt();/*解鎖,允許內核搶占*/
#endif
……
這樣可以解決當中斷返回到內核態時,Linux內核禁止進行進程調度,只有中斷返回到用戶態時,Linux內核才允許進行進程調度的問題,從而增強了任務調度的實時性。
3 嵌入式Linux實時性能測試結果
測試工具:Linux Trace ToolKit-0.8
測試環境:Intel Celeron 1.2GHz CPU、256MB SDRAM,通用Linux為Red Hat9.0,RT-Linux為3.0版,Media-Linux即為本文實現的嵌入式Linux。
測試結果如表1所示。
可以看出,本文構建的Linux系統的任務響應時間處于十微秒級,完全可以滿足多媒體應用終端的實時性需求。
根據多媒體應用的特點,在盡可能地保證系統性能的前提下,本文通過提高系統所支持的時鐘精度、設計可搶占式內核、增強實時任務調度改進了通用Linux的實時性(關鍵部分給出了源代碼及數據結構)。實驗結果表明,該系統在實時性方面完全可以滿足多媒體終端應用的需求,具有較好的應用前景。
參考文獻
1 李善平,劉文峰,李程遠.Linux內核2.4版源代碼分析大全[M].北京:機械工業出版社,2001
2 鄒思鐵.嵌入式Linux設計與應用[M].北京:清華大學出版社,2002
3 Yaghmour K著,韓存兵,龔波譯.構建嵌入式Linux系統[M].北京:中國電力出版社,2004
4 Jeffay K.Scheduling Sporadic Tasks with Shared Resources in Hard-Real-Time Systems[J].in Proc.Of the 13th Real-Time Systems Symposuim.Phoenix,Arizona,1992;(12)
5 Embedded Linux nears real time.http://www.edn.com/article/CA450620.html