采用混合時(shí)鐘模式提高Linux時(shí)鐘精度的方法
數(shù)控技術(shù)(CNC)已經(jīng)成為現(xiàn)代制造業(yè)的核心技術(shù)之一,開放式數(shù)控系統(tǒng)相對(duì)于傳統(tǒng)數(shù)控系統(tǒng)在功能、靈活性、成本等方面的優(yōu)勢(shì),使得開放式數(shù)控成為數(shù)控系統(tǒng)未來發(fā)展的主要趨勢(shì)。目前,開放式數(shù)控系統(tǒng)主要有三種結(jié)構(gòu),即專用CNC+PC、通用PC+運(yùn)動(dòng)控制器和軟數(shù)控系統(tǒng)。其中軟數(shù)控系統(tǒng)采用多任務(wù)實(shí)時(shí)操作系統(tǒng),將運(yùn)動(dòng)控制部分與管理部分集成到一個(gè)硬件平臺(tái)上,滿足數(shù)控系統(tǒng)在功能方面和非功能方面(主要表現(xiàn)在實(shí)時(shí)性)的要求[1]。開放式數(shù)控系統(tǒng)的理想軟件平臺(tái)是實(shí)時(shí)多任務(wù)操作系統(tǒng),目前,商業(yè)實(shí)時(shí)多任務(wù)操作系統(tǒng)有很多,比較著名的有VxWORKS、iRMX、QNX等,但這些操作系統(tǒng)產(chǎn)品大多成本高、開放性差。Linux是一種發(fā)展十分迅速的類UNIX系統(tǒng),已被廣泛地運(yùn)用到服務(wù)器、桌面系統(tǒng)以及嵌入式應(yīng)用領(lǐng)域。Linux由于其開放源代碼的特點(diǎn),可以在此基礎(chǔ)上開發(fā)具有自主知識(shí)產(chǎn)權(quán)的數(shù)控系統(tǒng)。但是Linux最初的設(shè)計(jì)目標(biāo)是一個(gè)分時(shí)操作系統(tǒng),追求系統(tǒng)效率和公平性,在對(duì)實(shí)時(shí)性要求高的領(lǐng)域應(yīng)用受到限制。雖然2.6內(nèi)核的Linux時(shí)鐘粒度提高到了1 ms,但仍遠(yuǎn)不能滿足數(shù)控系統(tǒng)對(duì)定時(shí)精度的要求。
近年來的研究以細(xì)化時(shí)鐘粒度來提高Linux的實(shí)時(shí)應(yīng)用能力提出了一些方案和設(shè)想,主要有KURT-Linux系統(tǒng)、RT-Linux系統(tǒng)。本文對(duì)KURT_Linux、RT-Linux提高時(shí)鐘精度的方法進(jìn)行分析,考慮在強(qiáng)周期性應(yīng)用或者在某個(gè)時(shí)段內(nèi)有大量高精度定時(shí)器將超時(shí)的情況下,采用一種動(dòng)態(tài)的多模式時(shí)鐘機(jī)制來提高Linux的時(shí)鐘精度,并通過分析測(cè)試證明該方案確實(shí)可行。
1 Linux時(shí)鐘機(jī)制與改進(jìn)
1.1 Linux時(shí)鐘機(jī)制
時(shí)鐘和定時(shí)器對(duì)Linux系統(tǒng)來說是至關(guān)重要的。首先,內(nèi)核要管理系統(tǒng)的運(yùn)行時(shí)間以及墻上時(shí)間;其次,內(nèi)核中大量的任務(wù)是基于時(shí)間驅(qū)動(dòng),其中有些任務(wù)是周期執(zhí)行,如對(duì)調(diào)度程序中運(yùn)行隊(duì)列進(jìn)行平衡調(diào)整或?qū)ζ聊贿M(jìn)行刷新,而有些任務(wù)需要推后執(zhí)行的I/O操作則需要等待一個(gè)相對(duì)時(shí)間后才運(yùn)行。
系統(tǒng)時(shí)鐘是定時(shí)器硬件和系統(tǒng)軟件的結(jié)合,在X86體系結(jié)構(gòu)中,使用最普遍的定時(shí)器硬件是Intel8254可編程定時(shí)器芯片(PIT),它產(chǎn)生的中斷就是時(shí)鐘中斷(tick)。時(shí)鐘中斷是特定的周期性中斷,對(duì)應(yīng)中斷服務(wù)程序,完成更新系統(tǒng)時(shí)間以及任務(wù)的管理、調(diào)度等工作;系統(tǒng)在每次時(shí)鐘中斷處理中更新jiffies,維護(hù)系統(tǒng)定時(shí)器鏈表timer_list,對(duì)超時(shí)的定時(shí)器進(jìn)行處理。
與系統(tǒng)定時(shí)器相對(duì)的是動(dòng)態(tài)定時(shí)器,是用來調(diào)度事件在將來某個(gè)時(shí)刻發(fā)生的機(jī)制。它依賴于系統(tǒng)時(shí)鐘中斷,在時(shí)鐘中斷服務(wù)程序的下半部,系統(tǒng)檢查是否有超時(shí)的動(dòng)態(tài)定時(shí)器并進(jìn)行處理。linux2.6內(nèi)核的系統(tǒng)時(shí)鐘頻率為1 000 Hz,即時(shí)鐘中斷的觸發(fā)周期為1 ms,中斷服務(wù)程序最快每1 ms執(zhí)行一次。動(dòng)態(tài)定時(shí)器隨時(shí)都可能超時(shí),但只有在中斷服務(wù)處理程序執(zhí)行時(shí)才會(huì)檢查、執(zhí)行超時(shí)的動(dòng)態(tài)定時(shí)器,所以動(dòng)態(tài)定時(shí)器的平均誤差大約為半個(gè)系統(tǒng)時(shí)鐘周期。
CNC數(shù)控系統(tǒng)的工作過程通常是首先內(nèi)建一個(gè)定時(shí)器(由操作系統(tǒng)完成),然后周期性地執(zhí)行控制程序,周期通常為幾十微秒到十幾毫秒。在每個(gè)周期內(nèi)要完成狀態(tài)監(jiān)測(cè)、譯碼、刀具補(bǔ)償計(jì)算、插補(bǔ)計(jì)算、PLC管理、位置控制等工作。可見,在加工工件過程中,CNC要求的實(shí)時(shí)性非常高,必須在很短、很精確的周期內(nèi)完成一系列的計(jì)算和輸入輸出,否則加工精度無法得到保障。標(biāo)準(zhǔn)2.6內(nèi)核Linux定時(shí)器精度遠(yuǎn)遠(yuǎn)達(dá)不到數(shù)控系統(tǒng)周期實(shí)時(shí)任務(wù)要求的微秒級(jí)定時(shí)精度。
1.2 提高時(shí)鐘精度的辦法
近年來人們對(duì)Linux進(jìn)行實(shí)時(shí)化改造提出了一些方案和設(shè)想,主要有KURT-Linux、RT-Linux等[2]。下面分別進(jìn)行介紹。
KURT_Linux[3]由kansas大學(xué)開發(fā),通過對(duì)Linux內(nèi)核內(nèi)部進(jìn)行改造來滿足實(shí)時(shí)應(yīng)用需求。在時(shí)鐘精度方面,KURT-Linux將Linux的時(shí)鐘中斷固定模式改為單次觸發(fā)模式(one-shot mode),即每次給時(shí)鐘芯片設(shè)置一個(gè)超時(shí)時(shí)間,然后等到該超時(shí)事件發(fā)生,在時(shí)鐘中斷處理過程中再次根據(jù)需要設(shè)置一個(gè)超時(shí)時(shí)間。通過這種變長時(shí)鐘模式,將Linux時(shí)鐘精度提高到μs級(jí)。既保證了特定實(shí)時(shí)任務(wù)的精度要求,又避免了不必要的調(diào)度負(fù)擔(dān)。
RT-Linux是新墨西哥工學(xué)院研制的一個(gè)基于Linux的硬實(shí)時(shí)系統(tǒng)。它采用雙內(nèi)核方法,在原有Linux基礎(chǔ)上設(shè)計(jì)一個(gè)專門處理實(shí)時(shí)進(jìn)程的內(nèi)核,然后把整個(gè)Linux作為實(shí)時(shí)內(nèi)核上運(yùn)行的一個(gè)低優(yōu)先級(jí)進(jìn)程。在時(shí)鐘精度方面類似KURT_Linux,將系統(tǒng)實(shí)時(shí)時(shí)鐘設(shè)置為單次觸發(fā)狀態(tài),然后利用TSC提供高達(dá)CPU時(shí)鐘頻率的定時(shí)精度。
Monta Vista Linux是由James Ready領(lǐng)導(dǎo)開發(fā)的嵌入式Linux,通過對(duì)Linux內(nèi)核進(jìn)行內(nèi)部改造,直接修改原有Linux內(nèi)核的數(shù)據(jù)結(jié)構(gòu)等來滿足實(shí)時(shí)需要。在高精度時(shí)鐘方面,拋開傳統(tǒng)的周期中斷CPU的方法,使定時(shí)器在需要的任何一個(gè)μs產(chǎn)生中斷,但不在每個(gè)μs產(chǎn)生中斷,將系統(tǒng)的定時(shí)精度提高到μs級(jí)。
Linux-SRT是劍橋大學(xué)David Ingram的博士論文項(xiàng)目,它簡(jiǎn)單地修改了Linux中Hz的定義,將Linux時(shí)鐘頻率由100 Hz提高到1 024 Hz。這種方式實(shí)現(xiàn)起來很簡(jiǎn)單,但是由此帶來頻繁的定時(shí)中斷使得系統(tǒng)開銷很大。借鑒KURT-Linux的one-shot思想來提高時(shí)鐘精度,并利用高級(jí)可編程中斷控制器(APIC)[4]或通過附加的硬件資源實(shí)現(xiàn)一個(gè)與系統(tǒng)時(shí)鐘并行的高精度實(shí)時(shí)時(shí)鐘,在系統(tǒng)中維護(hù)一個(gè)高精度實(shí)時(shí)時(shí)鐘和一個(gè)低精度系統(tǒng)時(shí)鐘[5-7],是一種普遍采用的提高時(shí)鐘精度的方法。但是在缺乏附加硬件支持或APIC使用受限的應(yīng)用環(huán)境下,只能利用PIT芯片作為高精度時(shí)鐘源,在每次中斷處理時(shí)要重新計(jì)算下一次中斷時(shí)間和對(duì)PIT進(jìn)行編程。由于PC的兼容性,PIT芯片位于低速的ISA總線上,頻繁設(shè)置定時(shí)器硬件也需要耗費(fèi)大量的時(shí)鐘周期。因此one-shot模式時(shí)鐘中斷處理時(shí)間可能達(dá)到標(biāo)準(zhǔn)Linux時(shí)鐘中斷處理時(shí)間的7~15倍[8-9]。在強(qiáng)周期應(yīng)用或有大量定時(shí)器集中在某個(gè)時(shí)段內(nèi)時(shí)超時(shí),需要采取一種不同于one-shot的時(shí)鐘模式。
如果系統(tǒng)中沒有任何實(shí)時(shí)定時(shí)器,則系統(tǒng)每隔1 ms會(huì)有一次周期性jiffies時(shí)鐘中斷,采用one-shot模式使得系統(tǒng)性能下降大約1.5%。如果系統(tǒng)中沒有任何實(shí)時(shí)定時(shí)器,則需要重新將時(shí)鐘設(shè)置為RTL CLOCK MODE PERIODIC工作模式,并且時(shí)鐘周期和標(biāo)準(zhǔn)Linux下時(shí)鐘周期一致,使Linux能在系統(tǒng)中不存在實(shí)時(shí)任務(wù)的情況下高效地工作。
2 動(dòng)態(tài)高精度時(shí)鐘設(shè)計(jì)和實(shí)現(xiàn)
動(dòng)態(tài)高精度時(shí)鐘設(shè)計(jì)方案借鑒了KURT-Linux思想,但與其不同的是提供一個(gè)與標(biāo)準(zhǔn)Linux核心時(shí)鐘并行的具有精密刻度的實(shí)時(shí)時(shí)鐘,并與原核心時(shí)鐘區(qū)別開。采用X86體系CPU提供的TSC作為高精度的時(shí)間標(biāo)度,權(quán)衡一定時(shí)間段(如一個(gè)jiffies)內(nèi)高精度定時(shí)器的數(shù)量,設(shè)置Linux時(shí)鐘中斷模式為標(biāo)準(zhǔn)模式、one-shot模式或高頻周期時(shí)鐘模式。實(shí)現(xiàn)了μs級(jí)定時(shí)精度的同時(shí),降低了頻繁計(jì)算和設(shè)置時(shí)鐘芯片的時(shí)間代價(jià)。
下面給出關(guān)鍵的全局變量:
(1)time_mode:表示當(dāng)前時(shí)鐘工作模式。其中-1代表高頻周期時(shí)鐘模式,該模式下,根據(jù)需要達(dá)到的定時(shí)精度,設(shè)置時(shí)鐘芯片以較高的頻率產(chǎn)生周期性中斷;0代表標(biāo)準(zhǔn)模式,時(shí)鐘芯片以標(biāo)準(zhǔn)Linux默認(rèn)的頻率產(chǎn)生周期中斷;1代表one-shot模式,時(shí)鐘芯片被設(shè)置為單次觸發(fā)狀態(tài),即每次給時(shí)鐘芯片設(shè)置一個(gè)超時(shí)時(shí)間,超時(shí)事件發(fā)生時(shí),在時(shí)鐘中斷處理程序中根據(jù)需要再次給時(shí)鐘芯片設(shè)置一個(gè)超時(shí)時(shí)間。系統(tǒng)啟動(dòng)時(shí)設(shè)置為默認(rèn)值0。
(2)SCALE:時(shí)鐘精度提高比。設(shè)置高頻周期模式需要的參數(shù),用來表示所需要達(dá)到的時(shí)鐘精度相對(duì)普通Linux時(shí)鐘精度的提高倍數(shù)。
(3)Threshold:閾值。如果即將在某一時(shí)間段內(nèi)超時(shí)的實(shí)時(shí)定時(shí)器數(shù)量大于預(yù)設(shè)值,系統(tǒng)設(shè)置硬件定時(shí)器工作在高頻周期時(shí)鐘模式。
2.1 時(shí)鐘中斷處理
為了加強(qiáng)Linux的實(shí)時(shí)功能,同時(shí)又要保持Linux的完整性,本方案的動(dòng)態(tài)多模式時(shí)鐘機(jī)制以模塊化的方式實(shí)現(xiàn)有關(guān)實(shí)時(shí)部分的功能,并利用接口函數(shù)實(shí)現(xiàn)實(shí)時(shí)模塊與Linux核心的聯(lián)系。
(1)標(biāo)準(zhǔn)模式。標(biāo)準(zhǔn)模式下的中斷處理首先查詢實(shí)時(shí)定時(shí)器隊(duì)列中是否有實(shí)時(shí)定時(shí)器在下一個(gè)系統(tǒng)時(shí)鐘中斷(jiffies+1)之前超時(shí),即在(jiffies,jiffies+1)內(nèi)是否有實(shí)時(shí)定時(shí)器要處理,根據(jù)實(shí)時(shí)定時(shí)器數(shù)量設(shè)置時(shí)鐘芯片的工作模式,執(zhí)行do_timer_interrupt()等函數(shù)維護(hù)系統(tǒng)相關(guān)時(shí)間,標(biāo)記下半部。
(2)one_shot模式。one-shot模式下的中斷處理先判斷jiffies時(shí)鐘是否到期,如果到期:
①查詢實(shí)時(shí)定時(shí)器隊(duì)列中是否有實(shí)時(shí)定時(shí)器在下一個(gè)系統(tǒng)時(shí)鐘中斷(tick+1)之前超時(shí),即在(jiffies,jiffies+1)內(nèi)有實(shí)時(shí)定時(shí)器要處理(其超時(shí)時(shí)間用sub_jiffies表示),然后根據(jù)實(shí)時(shí)定時(shí)器數(shù)量設(shè)置時(shí)鐘芯片工作模式。
②執(zhí)行do_timer_interrupt()函數(shù)等維護(hù)與系統(tǒng)有關(guān)的時(shí)間,并標(biāo)記下半部。
如果jiffies時(shí)鐘未到期,則查詢實(shí)時(shí)定時(shí)器鏈表,根據(jù)其最早超時(shí)實(shí)時(shí)定時(shí)器的超時(shí)時(shí)間與當(dāng)前時(shí)間的差值設(shè)置時(shí)鐘芯片產(chǎn)生下一次中斷的時(shí)間。
(3)高頻周期時(shí)鐘模式。高頻周期模式下中斷處理先判斷jiffies時(shí)鐘是否到期,如果系統(tǒng)時(shí)鐘節(jié)拍到期,執(zhí)行上述①、②模式。否則,如果有實(shí)時(shí)定時(shí)器超時(shí),標(biāo)記中斷下半部;如果沒有實(shí)時(shí)定時(shí)器超時(shí)則直接返回。
對(duì)超時(shí)定時(shí)器的處理都留到時(shí)鐘中斷下半部(softirq)處理,超時(shí)的實(shí)時(shí)定時(shí)器優(yōu)先得到處理,以盡可能保證實(shí)時(shí)定時(shí)器的及時(shí)處理,隨后處理普通Linux的定時(shí)器,時(shí)鐘中斷處理過程如圖1所示。
2.2 定時(shí)器組織
普通Linux系統(tǒng)原有的粗粒度定時(shí)器對(duì)于內(nèi)核的穩(wěn)定和不要求高精度定時(shí)的非實(shí)時(shí)應(yīng)用仍是合適的,只是針對(duì)有高精度定時(shí)要求的實(shí)時(shí)應(yīng)用組織一個(gè)高精度定時(shí)器隊(duì)列HRT_list,隊(duì)列中的定時(shí)器按超時(shí)時(shí)間非降序排列,隊(duì)列中第一個(gè)定時(shí)器的超時(shí)時(shí)間就是隊(duì)列的最早超時(shí)時(shí)間。
原Linux內(nèi)核中的定時(shí)器是通過稱為CTW(Cascading Timer Wheel)的結(jié)構(gòu)管理和維護(hù),并因此使得對(duì)定時(shí)器的插入、刪除等操作的時(shí)間為0(1)。本文把HRT_list隊(duì)列和CTW結(jié)合起來以降低定時(shí)器處理時(shí)間、提高效率。把需要較長時(shí)間才超時(shí)的實(shí)時(shí)定時(shí)器仍舊插入到原定時(shí)器隊(duì)列中,借助該隊(duì)列維護(hù)。在每次系統(tǒng)時(shí)鐘中斷處理的下半部處理完超時(shí)的實(shí)時(shí)定時(shí)器后,把在下一次系統(tǒng)時(shí)鐘中斷前超時(shí)的高精度定時(shí)器從原隊(duì)列移除,并插入到HRT_list隊(duì)列中。因此,HRT_list隊(duì)列中所需要維護(hù)的高精度實(shí)時(shí)定時(shí)器也是有限的,避免了維護(hù)一個(gè)大規(guī)模定時(shí)器隊(duì)列的開銷,近似實(shí)現(xiàn)了0(1)的系統(tǒng)開銷。
3 性能分析與測(cè)試
3.1 性能分析
當(dāng)系統(tǒng)中沒有高精度定時(shí)器時(shí),PIT仍以Linux系統(tǒng)默認(rèn)的頻率觸發(fā)時(shí)鐘中斷,在每一次系統(tǒng)時(shí)鐘中斷處理過程中,只需要判斷工作模式以及下一次jiffies中斷前有否實(shí)時(shí)定時(shí)器超時(shí),經(jīng)測(cè)試由此而帶來的處理時(shí)間不超過1us,增加系統(tǒng)負(fù)擔(dān)0.1%,不會(huì)影響系統(tǒng)的性能。當(dāng)在某個(gè)時(shí)間段內(nèi)系統(tǒng)中實(shí)時(shí)定時(shí)器不多于閾值時(shí),系統(tǒng)時(shí)鐘工作在類似KURT-Linux的one-shot模式,同時(shí)維持普通Linux系統(tǒng)時(shí)鐘的穩(wěn)定。而由此而帶來的系統(tǒng)負(fù)擔(dān)是可以接受的[3]。
當(dāng)系統(tǒng)中存在大量實(shí)時(shí)定時(shí)器或在某個(gè)時(shí)間段內(nèi)即將超時(shí)的實(shí)時(shí)定時(shí)器數(shù)量超過一定值(閾值)時(shí),相對(duì)于one-shot模式需要頻繁地計(jì)算下次中斷時(shí)間,并重新編程在低速的ISA總線上的PIT的時(shí)間代價(jià)是可取的,證明如下:
用Thw表示中斷的硬件處理時(shí)間,Tisr表示中斷程序上半部執(zhí)行時(shí)間,n代表某個(gè)時(shí)段內(nèi)(一個(gè)jiffies內(nèi))超時(shí)的定時(shí)器數(shù)量。得到兩種模式下總的時(shí)鐘中斷處理時(shí)間關(guān)系式:
顯然,當(dāng)某個(gè)時(shí)段內(nèi)超時(shí)的定時(shí)器數(shù)量大于Threshold時(shí),采用高頻周期模式的時(shí)間開銷就會(huì)小于one-shot模式。
3.2 模擬測(cè)試
測(cè)試環(huán)境為Pentium4 3.0 GHz CPU,1GDDR內(nèi)存的硬件平臺(tái)和2.6.15.6版本內(nèi)核的Fedora core linux操作系統(tǒng)平臺(tái)。
根據(jù)數(shù)控實(shí)時(shí)任務(wù)的要求設(shè)定了周期為0.1 ms、1 ms和100 ms的進(jìn)程模擬數(shù)控實(shí)時(shí)周期任務(wù)[10],統(tǒng)計(jì)運(yùn)行1 000次的數(shù)據(jù),比較改進(jìn)后的高精度定時(shí)器和原linux定時(shí)器的平均定時(shí)偏差,并令閾值為30,設(shè)置周期任務(wù)數(shù)量為4、20、40,使時(shí)鐘工作在不同模式下。測(cè)試結(jié)果如表1所示。
由測(cè)試數(shù)據(jù)對(duì)比,原linux系統(tǒng)的定時(shí)平均偏差為968 μs,改進(jìn)后系統(tǒng)的定時(shí)平均偏差為34 ?滋s。顯而易見,改進(jìn)后的定時(shí)器定時(shí)精度大大提高,達(dá)到10 μs級(jí),能滿足數(shù)控系統(tǒng)應(yīng)用的要求。
在原Linux內(nèi)核和改進(jìn)后的高精度定時(shí)器內(nèi)核上睡眠50 μs各1 000次,測(cè)試實(shí)際睡眠時(shí)間所得結(jié)果與表1類似,50 μs的實(shí)際睡眠時(shí)間從(2.001~2.116) ms級(jí)降到(57~91) μs級(jí)。
全軟件數(shù)控系統(tǒng)以應(yīng)用軟件的形式實(shí)現(xiàn)運(yùn)動(dòng)控制,是開放式數(shù)控系統(tǒng)的發(fā)展方向。開源的Linux是開發(fā)具有自主知識(shí)產(chǎn)權(quán)數(shù)控系統(tǒng)的理想平臺(tái),但是其粗糙的時(shí)鐘粒度是普通Linux直接應(yīng)用于數(shù)控系統(tǒng)的最大障礙,因此需要細(xì)化Linux的時(shí)鐘粒度提高其實(shí)時(shí)性。
簡(jiǎn)單地提高系統(tǒng)時(shí)鐘頻率將引起頻繁的中斷處理,導(dǎo)致系統(tǒng)性能的下降。KURT-Linux采用的one-shot方式將周期性的時(shí)鐘中斷改進(jìn)為單次觸發(fā)狀態(tài),實(shí)現(xiàn)了μs級(jí)的定時(shí)精度。本文分析了普通Linux時(shí)鐘機(jī)制和幾種實(shí)時(shí)Linux操作系統(tǒng)細(xì)化時(shí)鐘精度的方式,提出了一種混合多種時(shí)鐘模式的動(dòng)態(tài)時(shí)鐘機(jī)制,達(dá)到了CNC要求的時(shí)鐘精度。最后的性能分析和模擬測(cè)試證實(shí)了新時(shí)鐘機(jī)制的技術(shù)性能。
評(píng)論