請問時間的嘀嗒數是根據什么來設定的
有必要明確一些Linux內核時鍾驅動中的基本概念。
(1)時鍾周期(clock cycle)的頻率:8253/8254 PIT的本質就是對由晶體振盪器產生的時鍾周期進行計數,晶體振盪器在1秒時間內產生的時鍾脈沖個數就是時鍾周期的頻率。Linux用宏 CLOCK_TICK_RATE來表示8254 PIT的輸入時鍾脈沖的頻率(在PC機中這個值通常是1193180HZ),該宏定義在include/asm-i386/timex.h頭文件中:
#define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
(2)時鍾滴答(clock tick):我們知道,當PIT通道0的計數器減到0值時,它就在IRQ0上產生一次時鍾中斷,也即一次時鍾滴答。PIT通道0的計數器的初始值決定了要過多少時鍾周期才產生一次時鍾中斷,因此也就決定了一次時鍾滴答的時間間隔長度。
(3)時鍾滴答的頻率(HZ):也即1秒時間內PIT所產生的時鍾滴答次數。類似地,這個值也是由PIT通道0的計數器初值決定的(反過來說,確定了時鍾滴答的頻率值后也就可以確定8254 PIT通道0的計數器初值)。Linux內核用宏HZ來表示時鍾滴答的頻率,而且在不同的平台上HZ有不同的定義值。對於ALPHA和IA62平台HZ的值是1024,對於SPARC、MIPS、ARM和i386等平台HZ的值都是100。該宏在i386平台上的定義如下(include/asm- i386/param.h):
#ifndef HZ
#define HZ 100
#endif
根據HZ的值,我們也可以知道一次時鍾滴答的具體時間間隔應該是(1000ms/HZ)=10ms。
(4)時鍾滴答的時間間隔:Linux用全局變量tick來表示時鍾滴答的時間間隔長度,該變量定義在kernel/timer.c文件中,如下:
long tick = (1000000 + HZ/2) / HZ; /* timer interrupt period */
tick變量的單位是微妙(μs),由於在不同平台上宏HZ的值會有所不同,因此方程式tick=1000000÷HZ的結果可能會是個小數,因此將其進行四舍五入成一個整數,所以Linux將tick定義成(1000000+HZ/2)/HZ,其中被除數表達式中的HZ/2的作用就是用來將 tick值向上圓整成一個整型數。
另外,Linux還用宏TICK_SIZE來作為tick變量的引用別名(alias),其定義如下(arch/i386/kernel/time.c):
#define TICK_SIZE tick
(5)宏LATCH:Linux用宏LATCH來定義要寫到PIT通道0的計數器中的值,它表示PIT將沒隔多少個時鍾周期產生一次時鍾中斷。顯然LATCH應該由下列公式計算:
LATCH=(1秒之內的時鍾周期個數)÷(1秒之內的時鍾中斷次數)=(CLOCK_TICK_RATE)÷(HZ)
類似地,上述公式的結果可能會是個小數,應該對其進行四舍五入。所以,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 */
類似地,被除數表達式中的HZ/2也是用來將LATCH向上圓整成一個整數。