《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 業(yè)界動(dòng)態(tài) > linux世界里的時(shí)間

linux世界里的時(shí)間

2017-06-21
關(guān)鍵詞: Linux 計(jì)數(shù)器

      通常,操作系統(tǒng)可以使用三種方法來表示系統(tǒng)的當(dāng)前時(shí)間與日期:

  ①最簡單的一種方法就是直接用一個(gè)64位的計(jì)數(shù)器來對時(shí)鐘滴答進(jìn)行計(jì)數(shù)。

  ②第二種方法就是用一個(gè)32位計(jì)數(shù)器來對秒進(jìn)行計(jì)數(shù),同時(shí)還用一個(gè)32位的輔助計(jì)數(shù)器對時(shí)鐘滴答計(jì)數(shù),之子累積到一秒為止。因?yàn)?32超過136年,因此這種方法直至22世紀(jì)都可以讓系統(tǒng)工作得很好。

  ③第三種方法也是按時(shí)鐘滴答進(jìn)行計(jì)數(shù),但是是相對于系統(tǒng)啟動(dòng)以來的滴答次數(shù),而不是相對于相對于某個(gè)確定的外部時(shí)刻;當(dāng)讀外部后備時(shí)鐘(如RTC)或用戶輸入實(shí)際時(shí)間時(shí),根據(jù)當(dāng)前的滴答次數(shù)計(jì)算系統(tǒng)當(dāng)前時(shí)間。

  UNIX類操作系統(tǒng)通常都采用第三種方法來維護(hù)系統(tǒng)的時(shí)間與日期。

  1 基本概念

  首先,有必要明確一些Linux內(nèi)核時(shí)鐘驅(qū)動(dòng)中的基本概念。

  (1)時(shí)鐘周期(clock cycle)的頻率:8253/8254 PIT的本質(zhì)就是對由晶體振蕩器產(chǎn)生的時(shí)鐘周期進(jìn)行計(jì)數(shù),晶體振蕩器在1秒時(shí)間內(nèi)產(chǎn)生的時(shí)鐘脈沖個(gè)數(shù)就是時(shí)鐘周期的頻率。

  Linux用宏CLOCK_TICK_RATE來表示8254 PIT的輸入時(shí)鐘脈沖的頻率(在PC機(jī)中這個(gè)值通常是1193180HZ),該宏定義在include/asm-i386/timex.h頭文件中:

  #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */

  (2)時(shí)鐘滴答(clock tick):我們知道,當(dāng)PIT通道0的計(jì)數(shù)器減到0值時(shí),它就在IRQ0上產(chǎn)生一次時(shí)鐘中斷,也即一次時(shí)鐘滴答。PIT通道0的計(jì)數(shù)器的初始值決定了要過多少時(shí)鐘周期才產(chǎn)生一次時(shí)鐘中斷,因此也就決定了一次時(shí)鐘滴答的時(shí)間間隔長度。

  (3)時(shí)鐘滴答的頻率(HZ):也即1秒時(shí)間內(nèi)PIT所產(chǎn)生的時(shí)鐘滴答次數(shù)。類似地,這個(gè)值也是由PIT通道0的計(jì)數(shù)器初值決定的(反過來說, 確定了時(shí)鐘滴答的頻率值后也就可以確定8254 PIT通道0的計(jì)數(shù)器初值)。Linux內(nèi)核用宏HZ來表示時(shí)鐘滴答的頻率,而且在不同的平臺上HZ有不同的定義值。對于ALPHA和IA62平臺HZ的 值是1024,對于SPARC、MIPS、ARM和i386等平臺HZ的值都是100。該宏在i386平臺上的定義如下(include/asm- i386/param.h):

  #ifndef HZ

  #define HZ 100

  #endif

  根據(jù)HZ的值,我們也可以知道一次時(shí)鐘滴答的具體時(shí)間間隔應(yīng)該是(1000ms/HZ)=10ms。

  (4)時(shí)鐘滴答的時(shí)間間隔:Linux用全局變量tick來表示時(shí)鐘滴答的時(shí)間間隔長度,該變量定義在kernel/timer.c文件中,如下:

  long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */

  tick變量的單位是微妙(μs),由于在不同平臺上宏HZ的值會(huì)有所不同,因此方程式tick=1000000÷HZ的結(jié)果可能會(huì)是個(gè)小數(shù), 因此將其進(jìn)行四舍五入成一個(gè)整數(shù),所以Linux將tick定義成(1000000+HZ/2)/HZ,其中被除數(shù)表達(dá)式中的HZ/2的作用就是用來將 tick值向上圓整成一個(gè)整型數(shù)。

  另外,Linux還用宏TICK_SIZE來作為tick變量的引用別名(alias),其定義如下(arch/i386/kernel/time.c):

  #define TICK_SIZE tick

  (5)宏LATCH:Linux用宏LATCH來定義要寫到PIT通道0的計(jì)數(shù)器中的值,它表示PIT將沒隔多少個(gè)時(shí)鐘周期產(chǎn)生一次時(shí)鐘中斷。顯然LATCH應(yīng)該由下列公式計(jì)算:

  LATCH=(1秒之內(nèi)的時(shí)鐘周期個(gè)數(shù))÷(1秒之內(nèi)的時(shí)鐘中斷次數(shù))=(CLOCK_TICK_RATE)÷(HZ)

  類似地,上述公式的結(jié)果可能會(huì)是個(gè)小數(shù),應(yīng)該對其進(jìn)行四舍五入。所以,Linux將LATCH定義為(include/linux/timex.h):

  /* LATCH is used in the interval timer and ftape setup. */

  #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */

  類似地,被除數(shù)表達(dá)式中的HZ/2也是用來將LATCH向上圓整成一個(gè)整數(shù)。

  2 表示系統(tǒng)當(dāng)前時(shí)間的內(nèi)核數(shù)據(jù)結(jié)構(gòu)

  作為一種UNIX類操作系統(tǒng),Linux內(nèi)核顯然采用本節(jié)一開始所述的第三種方法來表示系統(tǒng)的當(dāng)前時(shí)間。Linux內(nèi)核在表示系統(tǒng)當(dāng)前時(shí)間時(shí)用到了三個(gè)重要的數(shù)據(jù)結(jié)構(gòu):

  ①全局變量jiffies:這是一個(gè)32位的無符號整數(shù),用來表示自內(nèi)核上一次啟動(dòng)以來的時(shí)鐘滴答次數(shù)。每發(fā)生一次時(shí)鐘滴答,內(nèi)核的時(shí)鐘中斷處 理函數(shù)timer_interrupt()都要將該全局變量jiffies加1。該變量定義在kernel/timer.c源文件中,如下所示:

  unsigned long volatile jiffies;

  C語言限定符volatile表示jiffies是一個(gè)易該變的變量,因此編譯器將使對該變量的訪問從不通過CPU內(nèi)部cache來進(jìn)行。

  ②全局變量xtime:它是一個(gè)timeval結(jié)構(gòu)類型的變量,用來表示當(dāng)前時(shí)間距UNIX時(shí)間基準(zhǔn)1970-01-01 00:00:00的相對秒數(shù)值。結(jié)構(gòu)timeval是Linux內(nèi)核表示時(shí)間的一種格式(Linux內(nèi)核對時(shí)間的表示有多種格式,每種格式都有不同的時(shí)間 精度),其時(shí)間精度是微秒。該結(jié)構(gòu)是內(nèi)核表示時(shí)間時(shí)最常用的一種格式,它定義在頭文件include/linux/time.h中,如下所示:

  struct timeval {

  time_t tv_sec; /* seconds */

  suseconds_t tv_usec; /* microseconds */

  };

  其中,成員tv_sec表示當(dāng)前時(shí)間距UNIX時(shí)間基準(zhǔn)的秒數(shù)值,而成員tv_usec則表示一秒之內(nèi)的微秒值,且1000000>tv_usec>=0。

  Linux內(nèi)核通過timeval結(jié)構(gòu)類型的全局變量xtime來維持當(dāng)前時(shí)間,該變量定義在kernel/timer.c文件中,如下所示:

  /* The current time */

  volatile struct timeval xtime __attribute__ ((aligned (16)));

  但是,全局變量xtime所維持的當(dāng)前時(shí)間通常是供用戶來檢索和設(shè)置的,而其他內(nèi)核模塊通常很少使用它(其他內(nèi)核模塊用得最多的是 jiffies),因此對xtime的更新并不是一項(xiàng)緊迫的任務(wù),所以這一工作通常被延遲到時(shí)鐘中斷的底半部分(bottom half)中來進(jìn)行。由于bottom half的執(zhí)行時(shí)間帶有不確定性,因此為了記住內(nèi)核上一次更新xtime是什么時(shí)候,Linux內(nèi)核定義了一個(gè)類似于jiffies的全局變量 wall_jiffies,來保存內(nèi)核上一次更新xtime時(shí)的jiffies值。時(shí)鐘中斷的底半部分每一次更新xtime的時(shí)侯都會(huì)將 wall_jiffies更新為當(dāng)時(shí)的jiffies值。全局變量wall_jiffies定義在kernel/timer.c文件中:

  /* jiffies at the most recent update of wall time */

  unsigned long wall_jiffies;

  ③全局變量sys_tz:它是一個(gè)timezone結(jié)構(gòu)類型的全局變量,表示系統(tǒng)當(dāng)前的時(shí)區(qū)信息。結(jié)構(gòu)類型timezone定義在include/linux/time.h頭文件中,如下所示:

  struct timezone {

  int tz_minuteswest; /* minutes west of Greenwich */

  int tz_dsttime; /* type of dst correction */

  };

  基于上述結(jié)構(gòu),Linux在kernel/time.c文件中定義了全局變量sys_tz表示系統(tǒng)當(dāng)前所處的時(shí)區(qū)信息,如下所示:

  struct timezone sys_tz;

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:[email protected]
主站蜘蛛池模板: 正在播放国产大学生情侣 | 中文国产成人精品久久一 | 欧美黄色a | 在线欧洲成人免费视频 | 免费人成激情视频在线观看冫 | 欧美在线播放成人免费 | 午夜手机视频 | 国产精品密蕾丝视频 | 欧美性色生活免费观看 | 男女性高爱潮免费的国产 | 国内成人精品亚洲日本语音 | 5x社区直接进入一区二区三区 | 国产精品亚洲精品爽爽 | 免费一区二区三区 | 日韩一品在线播放视频一品免费 | 久9视频这里只有精品 | 被老外玩爽的中国美女视频 | aaaaaa级特色特黄的毛片 | 日本成人一级片 | 久久在线观看免费视频 | 国产精品黄在线观看观看 | 波多野结衣在线观看一区 | 国内精品久久久久久久亚洲 | 日韩欧美一区二区三区不卡在线 | 欧美久久久久久久久 | 加勒比综合 | 成人国产精品免费视频不卡 | 欧美成人影院 在线播放 | 日韩一级片免费 | 老头老太做爰xxx视频 | 波野多结衣在线观看 | 美女视频网站永久免费观看软件 | 免费观看欧美精品成人毛片能看的 | 中文字幕一区二区小泽玛利亚 | a毛片视频| 欧美精品a毛片免费观看 | 九九精品免视看国产成人 | 欧美人成人亚洲专区中文字幕 | 在线观看视频一区二区三区 | 日本午夜vr影院新入口 | 国产精品国产亚洲精品看不卡 |