楊 皓,江 南,杜承烈
(1.西北工業(yè)大學計算機學院,西安710129;2.中國船舶重工集團公司750試驗場,昆明650051)
基于APIC的高精度定時器設計
楊 皓1,江 南2,杜承烈1
(1.西北工業(yè)大學計算機學院,西安710129;2.中國船舶重工集團公司750試驗場,昆明650051)
在操作系統(tǒng)開發(fā)過程中需要一定精度的計時器支持。在Windows實時擴展改造過程中,針對原有定時精度低和波動較大的問題,提出一種基于高級可編程中斷控制器(APIC)的高精度定時器設計方案。利用CPU片上結構APIC的計數(shù)寄存器編程,構建高精度時鐘。運用內(nèi)核驅動建立內(nèi)核調度管理,通過內(nèi)存映射提高用戶態(tài)到內(nèi)核態(tài)的數(shù)據(jù)傳輸速度,保證實時性能。利用DLL提供一組和內(nèi)核交互的定時器接口供用戶使用。實驗結果表明,該方案有效解決了定時精度和穩(wěn)定性問題,構造的定時器性能穩(wěn)定,具有良好的實用性。
高級可編程中斷控制器;定時器;高精度;穩(wěn)定性;內(nèi)存映射;實時性
在80x86體系機構上,操作系統(tǒng)內(nèi)核和時鐘常用到定時器電路。常見的時鐘有實時時鐘(RTC)、時間戳計數(shù)器(TSC)、可編程定時器(PIT)、高精度事件定時器(HPET)、高級可編程中斷控制器(Advanced Programmable Interrupt Controller,APIC)定時器以及電源管理定時器等[1]。而在當前的操作系統(tǒng)環(huán)境下,雖然硬件性能達標,但系統(tǒng)提供的時鐘精度往往不高,有些甚至達不到毫秒級別。在一些系統(tǒng)底層工程中,如操作系統(tǒng)的實時化改造,有時需要更高級別精度的定時器,來實現(xiàn)更為精密的操控。而多核系統(tǒng)中Local APIC定時器一般處于閑置狀態(tài)[2]。同時高級可編程中斷控制器處理之后硬件支持精度至少可以滿足微秒精度[3]。本文基于APIC提出了Windows系統(tǒng)下自定義高精度實時器的實現(xiàn)方法。
在x86體系中,每個邏輯處理器都有自己的local APIC,這屬于片上結構。從Pentium4和Intel Xeon處理器開始,APIC結構進一步擴展,形成了xAPIC體系,之后又在xAPIC基礎上再進一步擴展形成了x2APIC體系[4]。結構的升級帶來的更多的功能,但是基本功能還是保持不變的,其基本結構如圖1所示。
圖1 Local APIC結構
每個local APIC都包含了一組寄存器,用來控制本地和外部中斷的產(chǎn)生、發(fā)送和接收,這些寄存器組均以內(nèi)存映射的形式映射到物理地址空間,因此可以直接訪問內(nèi)存進行控制。APIC模式的寄存器則映射到MSR寄存器組,從而代替了內(nèi)存映射。在進行操作時一般使用RDMSR和WRMSR指令完成[4]。
2.1 APIC計數(shù)相關寄存器
本文以local APIC寄存器映射到物理地址中為例。其寄存器的地址以APIC_BASE作為基地址,每個APIC寄存器都有自己對應的偏移量,如 local APIC ID寄存器偏移量為20H,那么它的地址就為APIC_BASE+20H。在系統(tǒng)中APIC_BASE的值一般為FEE00000H。
Local APIC定時器實質是由LVT timer寄存器編程產(chǎn)生APIC timer中斷來實現(xiàn)的。這些寄存器主要有以下4種:
(1)LVT timer寄存器。
此寄存器偏移量是320H。它是LVT寄存器之一,使用定時器前,首先需要設置此寄存器。主要設置定時器的觸發(fā)模式。Vector為中斷描述符,寄存器描述如圖2所示。
圖2 LVT timer寄存器
(2)Divide configuration寄存器
此寄存器也叫分頻寄存器,偏移量為3E0H。local APIC計數(shù)器使用固定的時鐘頻率,但通過此寄存器可以進行分頻操作,從而確定計時精度。此基準時鐘一般都是系統(tǒng)總線頻率。以Intel處理器來說,也就是 CPU外頻。該寄存器定義如圖3所示。
圖3 Divide Configuration寄存器
(3)Initial-count寄存器和Current-count寄存器
初始計數(shù)寄存器地址偏移量為380H,當前計數(shù)寄存器偏移量為390H。這2個寄存器成對使用。它們均是32位寄存器,計時開始前要設定初始計數(shù)寄存器的值。一旦此值設定,APIC timer將會復制此值到只讀的當前計數(shù)寄存器(對用戶而言)。計時開始, Current-count值會遞減,直到為0產(chǎn)生時鐘中斷。
2.2 APIC timer計數(shù)模式
APIC timer模式設定由上文可知,主要是對于LVT timer寄存器的設定。它有3種計數(shù)模式,分別是One shot(一次性計數(shù))、Period(定期計數(shù))、TscDeadline(達到tsc值計數(shù))。
當為One shot模式時,計數(shù)器在Current-count值為0產(chǎn)生一次時鐘中斷后,即會停止工作。除非重新寫入一個Initial-count值,才會再次激活定時。若使用Period模式,當Current-count值為0時,產(chǎn)生時鐘中斷。而APIC會自動再次裝載Initial-count的值到Current-count中,重新開始計數(shù)。這就會周期性的產(chǎn)生timer中斷,除非Initial-count設定為0才會停止。TSC-deadline模式需要CPU另行支持,只用IA32_TSC_DEADLINE寄存器進行計數(shù)。此寄存器為64位,當TSC值大于或等于此寄存器的值時,將產(chǎn)生時鐘中斷[5]。
本文在Windows系統(tǒng)中基于Local APIC的計數(shù)器功能,設計實現(xiàn)了一種高精度定時器。此定時器在用戶態(tài)提供了Sleep以及觸發(fā)模式定時器的用戶接口。定時器精度可以達到微妙級別,且具有良好的穩(wěn)定性。
整個定時器系統(tǒng)設計為4個層次,最底層為APIC硬件支持層,其上是內(nèi)核驅動層,內(nèi)核驅動層中包含了APIC的關鍵操作,同時定時器的觸發(fā)和管理主要在此層內(nèi)完成。內(nèi)核驅動之上是DLL交互層,提供一些用戶接口與內(nèi)核交互功能。如設定精度,注冊定時器等,最上層為用戶應用層。定時器系統(tǒng)框架如圖4所示。
圖4 定時器系統(tǒng)框架
3.1 內(nèi)核驅動層設計實現(xiàn)
內(nèi)核驅動是一個NT框架的驅動程序,主要是提供了一種內(nèi)核訪問操作的權限,使得可以映射APIC寄存器進行操作。根據(jù)APIC工作方式,設計了內(nèi)核工作流程如圖5所示。
圖5 內(nèi)核驅動層工作設計流程
初始化時主要是進行定時器相關數(shù)據(jù)結構初始化。由于定時器只是一種周期性任務,因此將定時器設定為一個線程內(nèi)核對象,此對象應主要記錄任務線程id、句柄以及喚醒時間等。系統(tǒng)管理數(shù)據(jù)主要包括了一組預先申請的線程內(nèi)核對象以及等待和就緒鏈表的鏈表頭。等待鏈表中的內(nèi)核對象按照等待時間升序排列,每創(chuàng)建一個定時器,即生成一個內(nèi)核對象插入此鏈表中。若定時器已經(jīng)觸發(fā),任務開始運行的對象則插入就緒鏈表。
在驅動啟動時,首先初始化上述管理數(shù)據(jù)。然后是添加APIC中斷處理例程。目前的操作系統(tǒng)默認APIC都是開啟的,Initial count默認為0,此時計數(shù)器并不工作產(chǎn)生中斷。添加中斷處理需要獲取中斷描述符表(IDT),在其中添加APIC timer中斷處理程序描述符使其優(yōu)先級最高,這樣可以讓其中斷優(yōu)先得到相應[6]。中斷響應延遲影響著系統(tǒng)其它方面的實時性能[7]。在中斷處理中基本不做有效工作,而是將定時器管理觸發(fā)的大部分工作放入DPC例程中進行。這樣可以有效地保證時鐘計時的準確性。避免了在中斷狀態(tài)的時間過長問題。然后等待用戶設定定時器精度。一旦用戶設定精度通過Ioctl傳入內(nèi)核,則根據(jù)傳入精度值設定寄存器。
中斷處理添加完成之后,就需要設定定時器相關寄存器,使得APIC計數(shù)器開始工作。設定timer相關寄存器。主要是對LVT timer寄存器、分頻寄存器和Initial count寄存器進行設置。設定timer為周期循環(huán)(Period)模式,分頻為1。將Initial-count寄存器設定為傳入數(shù)據(jù)后,計數(shù)開始。寄存器設定代碼示例如下:
計數(shù)開始后,中斷處理DPC例程中完成定時器的管理工作。每次中斷處理中首先判斷下次調度時間(當前超時最短任務時間)是否到達,若到達則插入DPC例程,在此例程中遍歷等待鏈表,恢復喚醒時間已到的線程對象。由于此鏈表中的線程對象是按照喚醒時間升序排列的,因此遍歷直到第一個喚醒時間未到的對象為止。根據(jù)等待鏈表第一個對象的喚醒時間更新下次調度時間,若空則說明沒有任務,將其設為最大值[8]。
3.2 DLL交互層的設計與實現(xiàn)
在完成內(nèi)核驅動之后,需要提供一個和內(nèi)核交互的DLL交互層,以方便用戶使用定時器。在此DLL種主要是實現(xiàn)了定時器基準頻率獲取、精度設定等功能,同時向用戶提供了定時器創(chuàng)建、設置、退出等常用操作。基準頻率獲取是在用戶加載DLL時自動完成的,而精度由用戶設定。精度設定接口的實現(xiàn)可以采用Ioctl進行信息交換,利用Windows這種消息傳遞機制觸發(fā)時鐘計數(shù)[9]。此過程中由用戶態(tài)將Initial count寄存器的值傳入,進而設定。定時器相關接口則主要是將創(chuàng)建的任務信息注冊到定時器內(nèi)核中,同時進行一些設定或狀態(tài)更改,可根據(jù)具體的數(shù)據(jù)結構進行設計實現(xiàn)。
在設定精度之前,首先要做的是獲取定時器的基準頻率。APIC定時器的基準頻率是system bus頻率,也就是外頻,通過wmic指令可以直接獲取外頻數(shù)值。但是在實際應用中,由于可能會出現(xiàn)超頻等現(xiàn)象,而此指令獲取的值只是額定的出廠設置,因此還需要進一步完善。依據(jù)外頻與主頻有固定的倍數(shù)關系:主頻=外頻×倍頻。獲取CPU出廠的額定主頻后,同上述獲得的原始外頻一起先計算出倍頻。確定倍頻之后,再次查詢注冊表或利用rdtsc匯編指令計算得出當前真實主頻,從而反算得出真實的外頻,此時得到的才是系統(tǒng)有效的總線頻率。利用總線頻率就可以設定Initial-count寄存器的值,也就是本文定時器精度。具體流程如圖6所示。
圖6 定時器精度設定流程
在設置定時器精度完成之后,需要完成定時器周期任務的創(chuàng)建與注冊。所有的周期任務均可設定為一個標準的線程入口函數(shù),在此函數(shù)中主要是一個while(1)的循環(huán)語句。在初始化定時器時,將用戶定義的定時器任務入口地址及參數(shù)作為此標準線程的參數(shù)傳入,在while語句中執(zhí)行此函數(shù),這樣就可以達到重復執(zhí)行的目的。每執(zhí)行一次,更新此內(nèi)核線程對象的喚醒時間,然后掛起線程。這樣在時鐘中斷到來時,若下一次喚醒時間已到,在有DPC例程喚醒。定時器任務偽代碼lpParaml如下:
其中,lpParam1為標準線程傳入?yún)?shù)。此DLL交互層主要提供接口包括睡眠(Sleep)、創(chuàng)建定時器(CreateTimer)、設定定時器屬性(SetTimerRelative)、退出定時器(CancelTimer)、刪除定時器(DeleteTimer)。睡眠不需要創(chuàng)建定時器,系統(tǒng)會自動記錄當前線程的id等信息,并維護一個喚醒時間和周期,同時將其加入定時器管理鏈表中。創(chuàng)建定時器,實際上就是利用上述任務邏輯,創(chuàng)建一個循環(huán)的標準線程,同時記錄下相關信息。設定接口則主要是維護定時器結構中的喚醒時間和周期記錄數(shù)據(jù)[10]。
4.1 精度測試
定時器精度由當前系統(tǒng)總線頻率確定,在分頻為1系統(tǒng)總線頻率為200 MHz的情況下,理論上精度最高分辨率為5 ns[11]。實際上達不到這樣的精度。因為定時器的處理以及系統(tǒng)上下文切換等會花費一些時間。在實際應用中建議精度設定到微妙或毫秒級別。由于直接采用時間戳計數(shù)器,并不穩(wěn)定,因此測定采用HPET高精度計時器進行測定[12]。
一般Windows下精度只能到達毫秒精度,且穩(wěn)定性比較差。對Windows和本文的定時器進行精度測定,在Sleep函數(shù)執(zhí)行時睡眠時間逐次從1 ms開始增加到500 ms停止。記錄此過程中每次睡眠的真實時間。圖7是測試結果折線。為了更清楚的看清折線,此處選取了前200次記錄作圖。
圖7 定時器精度測試結果
從圖7可以看出,Windows定時功能準確度較差。15 ms以下精度均不能達到,而且精度增加過程呈階梯狀。相比APIC定時器精度可以有效達到1 ms,精度增加則基本呈線性增長。在使用過程中可以自由的設定時長,解決了系統(tǒng)定時精度差的不足。
4.2 穩(wěn)定性測試
在對精度進行測試之后,筆者選取了10 ms, 50 ms,100 ms周期,分別在Windows系統(tǒng)和APIC定時器上進行了1 000次連續(xù)測試。此測試主要是為了探查2種定時器在運行過程中定時穩(wěn)定性以及準確性的。
筆者對1 000次測試結果進行了統(tǒng)計,計算了測定周期的平均值和方差。統(tǒng)計結果如表1所示??梢钥闯?在準確度的表現(xiàn)上本文的定時器遠遠優(yōu)于Windows本身定時器。同時方差相對于平均值波動,APIC定時器更為穩(wěn)定。
表1 定時器穩(wěn)定性測試統(tǒng)計結果
除統(tǒng)計結果外,筆者還選取了前500次測定結果作折線圖如圖8所示。從圖8可以看出,本文設計的定時器準確性高于Windows系統(tǒng)本身。本文設計的定時器在運行時,測定時間與設定時間基本一致,而且波動不大。而Windows定時則不能準確地到達設定周期,準確率不夠。
圖8 定時器穩(wěn)定性測定結果
本文在 APIC timer的基礎上,設計了一種Windows系統(tǒng)下的自定義的高精度APIC定時器。以當前的系統(tǒng)總線頻率200 MHz計算,該定時器精度最高可達到5 ns。在實際中因為時鐘中斷處理等本身需要占有一定時間,所以會低于此理論精度,在應用時精度設定到100 μs或ms以上。由于APIC硬件的支撐,該定時器準確率較高,穩(wěn)定性好。因此,自定義精度可以很好地滿足不同時鐘精度需求,在對系統(tǒng)進行深度開發(fā)、實時改造等工作時可以提供有效的借鑒。
[1] Bovet D P,Cesati M.深入理解 LINUX內(nèi)核[M].陳莉君,張瓊聲,張宏偉,譯.北京:中國電力出版社,2009.
[2] 杜旭東,蔣澤軍,王麗芳,等.基于資源重分配的Windows實時性改造[J].微電子學與計算機,2012, 29(5):193-195.
[3] 蔣善峰,王麗芳,蔣澤軍.Windows時鐘機制的實時擴展研究[J].微電子學與計算機,2012,29(8): 116-119.
[4] 鄧 志.X86/x64體系探索及編程[M].北京:電子工業(yè)出版社,2012.
[5] Intel Corporation.Inte@64 and IA-32 Architectures Software Developer's Manual Volume 3B:System Programming Guide,Part 2[Z].2006.
[6] 潘 漢,莫蘇蘇.基于Local APIC的Windows 2000實時化改造[J].電子元器件應用,2009,11(10):80-83.
[7] 吳 訊,馬 媛,董勤鵬.實時操作系統(tǒng)實時性能測試技術研究[J].系統(tǒng)仿真學報,2013,25(2):313-316.
[8] Gao Zhigang,Zhang Peifeng,Dai Guojun,et al.A New Implementation Method of Timer for Periodic Tasks[J]. Journal of Embedded Computing,2010,4(1):55-57.
[9] 林聚偉.Windows內(nèi)核安全編程從入門到實踐[M].北京:電子工業(yè)出版社,2012.
[10] 張志明,孫廣清,王 磊.Windows下高精度軟件定時器的研究與實現(xiàn)[J].微型機與應用,2003,22(1): 55-57.
[11] 候 峰,童曉陽.基于APIC時鐘的嵌入式Linux內(nèi)核實時化研究[J].現(xiàn)代電子技術,2010,(14):193-195.
[12] 廖小勇.基于PC/Windows環(huán)境的實時系統(tǒng)研究與實現(xiàn)技術[D].上海:同濟大學,2002.
編輯 索書志
Design of High Precision Timer Based on Advanced Programmable Interrupt Controller
YANG Hao1,JIANG Nan2,DU Cheng-lie1
(1.School of Computer Science,Northwestern Polytechnical University,Xi'an 710129,China;
2.750 Testing Ground,China Shipbuilding Industry Corporation,Kunming 650051,China)
Timer with a certain precision is often required in the process of developing the system.In the Windows real time extending process,aiming at the problem of insufficient original timing accuracy and the fluctuation problem,this paper presents a high precision timer based on local Advanced Programmable Interrupt Controller(APIC).Making use of the counting register programs CPU sheet structure of APIC,it constructs high precision clock effectively,and uses the kernel driver construction scheduling management,memory mapping to improve data transmission speed of user state to guarantee real-time kernel to provide real-time.DLL provides a set of interface for users.Experimental results show that the scheme can effectively solve the problem of timing precision,and it has good usability.
Advanced Programmable Interrupt Controller(APIC);timer;high precision;stability;memory mapping; real-time
1000-3428(2014)09-0317-05
A
TP391
10.3969/j.issn.1000-3428.2014.09.063
國家部委基金資助項目。
楊 皓(1988-),男,碩士,主研方向:實時操作系統(tǒng);江 南,研究員;杜承烈,教授、博士生導師。
2013-08-05
2013-10-10E-mail:Email:yanghao525@163.com