嵌入式實(shí)時(shí)Linux的技術(shù)研究
中斷管理的第二個(gè)關(guān)鍵部分即是系統(tǒng)是否允許中斷嵌套的能力,也就是說(shuō),當(dāng)響應(yīng)一個(gè)中斷時(shí),是否允許其它更高優(yōu)先級(jí)的中斷打斷,等更高優(yōu)先級(jí)的中斷處理完畢,是否還能恢復(fù)原來(lái)中斷處理的現(xiàn)場(chǎng)。通過(guò)這項(xiàng)功能,系統(tǒng)設(shè)計(jì)者可以指示外部中斷的優(yōu)先級(jí),從而確保高優(yōu)先級(jí)的任務(wù)能及時(shí)處理。Linux允許中斷嵌套,它是利用外部中斷管理器來(lái)設(shè)置中斷的優(yōu)先級(jí)的。在Linux的中斷處理程序的啟動(dòng)過(guò)程中,它一般調(diào)用語(yǔ)句mask_and_ack_8259A(irq);來(lái)設(shè)置8259中的int_mask寄存器.使優(yōu)先級(jí)比此中斷低的中斷不能發(fā)生。在中斷處理程序離開時(shí),調(diào)用enable_8259A_irq(irq)來(lái)改回8259中int_mask寄存器原來(lái)的值。因此,intr類中斷的優(yōu)先級(jí)由硬件8259來(lái)決定.
由此可見,Linux的中斷管理部分具有高效的特點(diǎn),已經(jīng)可以滿足許多軟實(shí)時(shí)任務(wù)的要求。
(2)進(jìn)程搶先調(diào)度
在許多控制系統(tǒng)中,實(shí)時(shí)控制軟件是非常簡(jiǎn)單的,可以直接寫入中斷處理程序中與一個(gè)特定的中斷聯(lián)系起來(lái)。還有一些就不那么簡(jiǎn)單了,必須開啟專門的用戶進(jìn)程為它服務(wù)。
這時(shí)當(dāng)這個(gè)高優(yōu)先級(jí)的進(jìn)程提交時(shí),如有其它進(jìn)程正在運(yùn)行,它就必須打斷正在運(yùn)行的進(jìn)程。若正在運(yùn)行的進(jìn)程運(yùn)行在用戶態(tài),系統(tǒng)一般允許它被打斷且執(zhí)行其它優(yōu)先權(quán)高的進(jìn)程,若正在運(yùn)行的進(jìn)程運(yùn)行在系統(tǒng)態(tài),則此時(shí)是否允許被打斷決定了系統(tǒng)是搶先式的還是非搶先式的。
Linux就是一個(gè)非搶先式的操作系統(tǒng),在用戶執(zhí)行系統(tǒng)調(diào)用時(shí),不允許其它進(jìn)程的調(diào)度,這樣就影響了系統(tǒng)的響應(yīng)度。一個(gè)真正的搶先式的操作系統(tǒng)允許正在系統(tǒng)狀態(tài)下的當(dāng)前進(jìn)程被打斷,然后進(jìn)程切換回來(lái)時(shí)還能繼續(xù)從剛才的執(zhí)行點(diǎn)繼續(xù)下去。但某些關(guān)鍵部分的代碼段。系統(tǒng)必須保證其原子性,并防止重入。通常有如下幾種方法:
在關(guān)鍵代碼斷前關(guān)閉中斷,等其執(zhí)行完畢之后再將中斷打開; 設(shè)計(jì)一個(gè)信號(hào)量.在關(guān)鍵代碼段之前加鎖,在其后解鎖;
在系統(tǒng)代碼中保證安全的地方加入切換進(jìn)程的代碼switch(),防止該進(jìn)程長(zhǎng)久占用CPU,允許調(diào)度其它進(jìn)程; 在關(guān)鍵代碼段加入一個(gè)switchaccept標(biāo)志,開始該代碼段時(shí)。將此標(biāo)志置為否.離開時(shí)再置回原來(lái)的值.這樣在執(zhí)行該段代碼時(shí),即使進(jìn)程調(diào)度器被激活,它也會(huì)先檢查此標(biāo)志。若為否,則返回,并不進(jìn)行進(jìn)程切換。
(3)進(jìn)程調(diào)度策略
第三個(gè)影響系統(tǒng)響應(yīng)速度的關(guān)鍵部分就是進(jìn)程調(diào)度的策略。對(duì)于一個(gè)實(shí)時(shí)性能強(qiáng)的操作系統(tǒng)來(lái)說(shuō),系統(tǒng)必須規(guī)定不同進(jìn)程的優(yōu)先級(jí),并把優(yōu)先級(jí)作為唯一的進(jìn)程選擇的標(biāo)準(zhǔn)。Linux的后期版本參照Posixl.b標(biāo)準(zhǔn),在某些方面已經(jīng)具備了一些實(shí)時(shí)操作系統(tǒng)的特性。Linux有兩種類型的進(jìn)程:一般進(jìn)程和實(shí)時(shí)進(jìn)程,它可以通過(guò)sched_setscheduler系統(tǒng)調(diào)用設(shè)置實(shí)時(shí)進(jìn)程。實(shí)時(shí)進(jìn)程比所有一般進(jìn)程的優(yōu)先級(jí)高,Linux設(shè)置實(shí)對(duì)進(jìn)程的權(quán)重為它的counter值加1000;設(shè)置一般進(jìn)程的權(quán)重為counter。因此,實(shí)時(shí)進(jìn)程總會(huì)被認(rèn)為是最值得運(yùn)行的進(jìn)程。
然而,Linux核心的設(shè)計(jì)主要集中在應(yīng)用程序的吞吐量上。追求吞吐量的必然結(jié)果,就是Linux調(diào)度器運(yùn)用一種公平共享的策略保證所有的進(jìn)程得到平均的CPU資源。而且,Linux的進(jìn)程調(diào)度器只是簡(jiǎn)單地將標(biāo)有實(shí)時(shí)標(biāo)志的進(jìn)程的權(quán)重加1000,至于實(shí)時(shí)進(jìn)程間的輕重緩急還沒有周密的完整的設(shè)計(jì)。因此,Linux的進(jìn)程調(diào)度器還遠(yuǎn)不能稱作是一個(gè)真正的實(shí)時(shí)進(jìn)程凋度器。
4 擬采用的策略
根據(jù)以上分析的特點(diǎn),我們決定主要從以下4個(gè)方面來(lái)修改Linux的核心代碼。
(1)在內(nèi)核中插入搶先點(diǎn) 由于Linux是一個(gè)非搶先式的操作系統(tǒng)。因此當(dāng)一個(gè)實(shí)時(shí)進(jìn)程提交時(shí),很可能因?yàn)楫?dāng)前的進(jìn)程正處于核心態(tài)不能被打斷而不能得到及時(shí)的處理。因此有必要在Linux內(nèi)核中插入搶先點(diǎn),使實(shí)時(shí)進(jìn)程得到處理。根據(jù)上一節(jié)分析的特點(diǎn),太體有4種方法可供選擇。權(quán)衡這4種方法的利弊,我們決定采用第4種方法,即在關(guān)鍵代碼段加入一個(gè)switchaccept標(biāo)志,開始該代碼段時(shí),將此標(biāo)志置為否.離開時(shí)再置回原來(lái)的值。這種方法比采甩semaphore的好處是,如果采用許多種semaphore的話.要考慮是否會(huì)產(chǎn)生死鎖的問題。比采用鎖中斷的好處是.將中斷鎖住將丟失中斷,而這樣不會(huì)。而以固定的周期加switch語(yǔ)句顯然有失靈活性。這樣.采用這種方法,需要我們分析Linux所有系統(tǒng)調(diào)用的代碼,畫出其結(jié)構(gòu)流程圖。分析出哪些部分是關(guān)鍵部分,也即不允許置入的部分。在關(guān)鍵代碼前后更改switchaccept標(biāo)志。這項(xiàng)工作比較艱巨。同時(shí)修改進(jìn)程調(diào)度器,使其判斷switchaccept標(biāo)志來(lái)決定是否執(zhí)行進(jìn)程切換。
(2)修改進(jìn)程調(diào)度器Linux的進(jìn)程調(diào)度器雖然已經(jīng)具有一定的實(shí)時(shí)性能,但還遠(yuǎn)遠(yuǎn)達(dá)不到真正實(shí)時(shí)調(diào)度器的標(biāo)準(zhǔn),因此需要修改其進(jìn)程調(diào)度器,必要的話可讓Linux運(yùn)行在兩種模式下,實(shí)時(shí)模式和分時(shí)模式。可設(shè)計(jì)一些相關(guān)的系統(tǒng)調(diào)用,并在實(shí)時(shí)進(jìn)程提交時(shí),將系統(tǒng)轉(zhuǎn)化為實(shí)時(shí)模式,當(dāng)實(shí)時(shí)進(jìn)程結(jié)束時(shí),再轉(zhuǎn)化為分時(shí)模式。
(3)Linux的中斷管理根據(jù)前面分析過(guò)的,Linux的中斷管理及時(shí)地將緊要的任務(wù)完成后,將其余不重要的緩慢的任務(wù)放置在任務(wù)隊(duì)列中,等到系統(tǒng)空閑(cpu idle())或系統(tǒng)調(diào)用等返回時(shí)再完成這些任務(wù),這樣就提高了系統(tǒng)的響應(yīng)速度,同時(shí),Linux還支持中斷嵌套。因此,不再對(duì)其作太大改動(dòng)。
(4)鎖定內(nèi)存 在本項(xiàng)目的規(guī)劃中本打算實(shí)現(xiàn)Linux鎖內(nèi)存的功能,使優(yōu)先權(quán)高的進(jìn)程在內(nèi)存中的數(shù)據(jù)不被換出,從而提高實(shí)時(shí)進(jìn)程的運(yùn)行速度。然而,在分析了Linux代碼后,發(fā)現(xiàn)后來(lái)版本的Linux已通過(guò)系統(tǒng)調(diào)用sys mlock實(shí)現(xiàn)了此項(xiàng)功能。
5 結(jié)束語(yǔ)
采用上述方法修改了內(nèi)核代碼后,由于每個(gè)修改方案都是有一定的代價(jià)的,它在增加了系統(tǒng)響應(yīng)速度的同時(shí)也在某種程度上降低了系統(tǒng)的整體效率,比如說(shuō)將內(nèi)核設(shè)置成可搶先的,在進(jìn)程頻繁的切換過(guò)程中也要消耗一定的cpu處理時(shí)間。因此,還需要對(duì)各種解決方案進(jìn)行測(cè)試、比較。另外,為了減少嵌入式Linux自身的長(zhǎng)度,在存儲(chǔ)管理部分對(duì)虛擬內(nèi)存也應(yīng)作進(jìn)一步的處理。
評(píng)論