1. 程式人生 > >pc解讀13:定時器的使用與時間獲取

pc解讀13:定時器的使用與時間獲取

現代計算機上的作業系統基本上都是多工的作業系統,每個任務輪流佔用系統一個小時間片,系統速度如此之快,以至於每個任務都覺得自己佔有整臺計算機。同時現代計算機上執行著很多時間敏感的程式,比如定期備份系統,每日凌晨進行系統維護等等。要實現這些功能,離不開定時和計時的需求,而這些需求的高效實現離不開硬體的支援,我們來解讀下,pc機給軟體提供了怎樣的平臺。

RTC
最早的IBM-PC上有RTC實時時鐘晶片,並且有電池供電,有了它,計算機就有了手錶的功能,RTC是一個獨立的系統,即使PC關機或者斷電,仍可正常工作,這也是為什麼機器關機後再次啟動仍能保持時間的基礎。RTC整合在南橋中。

既然RTC是一個獨立的系統,那麼程式指令能否訪問到它呢,這是肯定的。在PC機中可以通過I/O埠0×70和0×71來讀寫RTC晶片中的暫存器。其中,埠0×70是RTC的暫存器地址索引埠,0×71是資料埠。接下來我們看看暫存器地址索引埠能索引到哪些東西。

最常見的RTC晶片是MC146818(Motorola),一共有64個暫存器。編號為0×00~0x3F,這些暫存器一共可以分為三組,時鐘與日曆暫存器組:共有10個(0×00~0×09),表示時間、日曆的具體資訊。在PC機中,這些暫存器中的值都是以BCD格式來儲存的(比如23dec=0x23BCD)。狀態和控制暫存器組:共有4個(0x0A~0x0D),控制RTC晶片的工作方式,並表示當前的狀態。 CMOS配置資料:通用的CMOS RAM,它們與時間無關,因此我們暫時不關心它。可見,我們隨時可以通過io訪問指令讀寫系統時間。

PIT
時間有了,我們還需要定時器的功能。於是PIT(可程式設計間隔計時器)就出現了。PIT, 一般用8254晶片實現,訊號來源是主機板的晶振,根據時鐘脈衝訊號來計數,用來計數的儲存單元是16位,所以最多接收65536個時鐘訊號就復原了。一般工作方式是程式設定一個初始值,然後每收到一個脈衝就自動減1,減到0時向系統發出中斷訊號,以達到定時功能。但由於只有16位資料,頻率高了之後能定時時間太短,頻率低了又不夠精確,所以現在基本已經被淘汰了。該晶片本身有3個通道:通道0與IRQ0繫結,用於給作業系統提高時間中斷,通道1通常用於DMA控制器對RAM的重新整理,通道2被連線到PC機的揚聲器,以產生方波訊號。

東西在這了,怎麼用是畢竟是軟體的事情。但總得告訴軟體用怎樣的指令來控制他。與RTC一樣,也是通過IO空間來訪問。三個通道計數埠地址分別為 40h,41h,42h,再加一個控制暫存器43h。為什麼要加一個控制器呢,原因是每個通道計數器是16位的,但是對應的埠地址是8位的,所以要讀整個計數需要兩次讀相應的埠,先得告訴控制器你要讀的是高8位資料還是第8位資料。同時每個通道還可以設定工作模式,每個通道可以有6種工作模式,由於PIT已經基本被淘汰了,所以也沒有必要深究了,有興趣的可以百度

TSC
從Pentium 起,cpu提供一個暫存器 TSC,用來累計每一次外部振盪器產生的時鐘訊號,也就是說cpu每收到一個時鐘脈衝,就修改tsc中的計數,相應的TSC暫存器是64位的,大大增長了計數能力。由於在整個系統中cpu頻率是最高的,相應的TSC的精度就非常高。TSC暫存器是隻讀的,通過單獨的指令rdtsc(read tsc)來讀取。

問題是TSC獲取的頻率來源可能並不是固定的,因為有後來發展的降頻技術,在cpu閒時,可把頻率降下來以降低功率,節省能源。所以後來又出來了HPET。

HPET高精度定時器
HPET(High Precision Event Timer)俗稱高精度定時器。是PIT 和 RTC 的替代者,提供了更高的時鐘頻率(至少10 MHz )以及更寬的計數器寬度。一個 HPET 包括了一個固定頻率的數值增加的計數器以及3到32個獨立的計時器,這每一個計時器有包涵了一個比較器和一個暫存器(儲存一個數值,表示觸發中斷的時機)。每一個比較器都比較計數器中的數值和暫存器中的數值,當這兩個數值相等時,將產生一箇中斷。對HPET的配置通過訪問timer配置暫存器完成。該暫存器會被MMIO到某個記憶體區域(由BIOS階段acpi權舉得到),大小為1k(64bit上大小會最多到64k)。更詳細的說明可百度