<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 牛人業(yè)話(huà) > linux世界里的時(shí)間

linux世界里的時(shí)間

作者: 時(shí)間:2016-12-08 來(lái)源:網(wǎng)絡(luò ) 收藏

  通常,操作系統可以使用三種方法來(lái)表示系統的當前時(shí)間與日期:

本文引用地址:http://dyxdggzs.com/article/201612/341309.htm

 ?、僮詈?jiǎn)單的一種方法就是直接用一個(gè)64位的計數器來(lái)對滴答進(jìn)行計數。

 ?、诘诙N方法就是用一個(gè)32位計數器來(lái)對秒進(jìn)行計數,同時(shí)還用一個(gè)32位的輔助計數器對滴答計數,之子累積到一秒為止。因為232超過(guò)136年,因此這種方法直至22世紀都可以讓系統工作得很好。

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

  UNIX類(lèi)操作系統通常都采用第三種方法來(lái)維護系統的時(shí)間與日期。

  1 基本概念

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

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

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

  #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */

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

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

  #ifndef HZ

  #define HZ 100

  #endif

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

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

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

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

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

  #define TICK_SIZE tick

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

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

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

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

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

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

  2 表示系統當前時(shí)間的內核數據結構

  作為一種UNIX類(lèi)操作系統,Linux內核顯然采用本節一開(kāi)始所述的第三種方法來(lái)表示系統的當前時(shí)間。Linux內核在表示系統當前時(shí)間時(shí)用到了三個(gè)重要的數據結構:

 ?、偃肿兞縥iffies:這是一個(gè)32位的無(wú)符號整數,用來(lái)表示自?xún)群松弦淮螁?dòng)以來(lái)的時(shí)鐘滴答次數。每發(fā)生一次時(shí)鐘滴答,內核的時(shí)鐘中斷處 理函數timer_interrupt()都要將該全局變量jiffies加1。該變量定義在kernel/timer.c源文件中,如下所示:

  unsigned long volatile jiffies;

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

 ?、谌肿兞縳time:它是一個(gè)timeval結構類(lèi)型的變量,用來(lái)表示當前時(shí)間距UNIX時(shí)間基準1970-01-01 00:00:00的相對秒數值。結構timeval是Linux內核表示時(shí)間的一種格式(Linux內核對時(shí)間的表示有多種格式,每種格式都有不同的時(shí)間 精度),其時(shí)間精度是微秒。該結構是內核表示時(shí)間時(shí)最常用的一種格式,它定義在頭文件include//time.h中,如下所示:

  struct timeval {

  time_t tv_sec; /* seconds */

  suseconds_t tv_usec; /* microseconds */

  };

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

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

  /* The current time */

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

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

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

  unsigned long wall_jiffies;

 ?、廴肿兞縮ys_tz:它是一個(gè)timezone結構類(lèi)型的全局變量,表示系統當前的時(shí)區信息。結構類(lèi)型timezone定義在include//time.h頭文件中,如下所示:

  struct timezone {

  int tz_minuteswest; /* minutes west of Greenwich */

  int tz_dsttime; /* type of dst correction */

  };

  基于上述結構,Linux在kernel/time.c文件中定義了全局變量sys_tz表示系統當前所處的時(shí)區信息,如下所示:

  struct timezone sys_tz;



關(guān)鍵詞: linux 時(shí)鐘

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>