Linux内核时钟驱动的基本概念

介绍

这篇文章主要讲解了“Linux内核时钟驱动的基本概念”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux内核时钟驱动的基本概念”吧!


<强> 1基本概念
首先,有必要明确一些Linux内核时钟驱动中的基本概念。
(1)时钟周期(时钟周期)的频率:8253/8254坑的本质就是对由晶体振荡器产生的时钟周期进行计数,晶体振荡器在1秒时间内产生的时钟脉冲个数就是时钟周期的频率。
Linux用宏CLOCK_TICK_RATE来表示8254年坑的输入时钟脉冲的频率(在PC机中这个值通常是1193180 HZ),该宏定义在包括/asm-i386 timex.h头文件中:

 # define  CLOCK_TICK_RATE  1193180,/*, Underlying  HZ  */


(2)时钟滴答(时钟周期):我们知道,当坑通道0的计数器减到0值时,它就在IRQ0上产生一次时钟中断,也即一次时钟滴答.PIT通道0的计数器的初始值决定了要过多少时钟周期才产生一次时钟中断,因此也就决定了一次时钟滴答的时间间隔长度。
(3)时钟滴答的频率(HZ):也即1秒时间内坑所产生的时钟滴答次数。类似地,这个值也是由坑通道0的计数器初值决定的(反过来说,确定了时钟滴答的频率值后也就可以确定8254年坑通道0的计数器初值).Linux内核用宏赫兹来表示时钟滴答的频率,而且在不同的平台上赫兹有不同的定义值。对于α和IA62平台赫兹的值是1024,对于SPARC, MIPS,手臂和i386等平台赫兹的值都是100。该宏在i386平台上的定义如下(包括/asm - i386/param.h):

 # ifndef  HZ ,, # define  HZ  100年,,,# endif 

根据赫兹的值,我们也可以知道一次时钟滴答的具体时间间隔应该是(1000 ms/HZ)=10 ms。
(4)时钟滴答的时间间隔:Linux用全局变量蜱虫来表示时钟滴答的时间间隔长度,该变量定义在内核/计时器。c文件中,如下:
长蜱虫=(1000000 + HZ/2)/赫兹;/* 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向上圆整成一个整数。
2 表示系统当前时间的内核数据结构
作为一种UNIX类操作系统,Linux内核显然采用本节一开始所述的第三种方法来表示系统的当前时间。Linux内核在表示系统当前时间时用到了三个重要的数据结构:
①全局变量jiffies:这是一个32位的无符号整数,用来表示自内核上一次启动以来的时钟滴答次数。每发生一次时钟滴答,内核的时钟中断处 理函数timer_interrupt()都要将该全局变量jiffies加1。该变量定义在kernel/timer.c源文件中,如下所示:

unsigned long volatile jiffies;

C语言限定符volatile表示jiffies是一个易该变的变量,因此编译器将使对该变量的访问从不通过CPU内部cache来进行。
②全局变量xtime:它是一个timeval结构类型的变量,用来表示当前时间距UNIX时间基准1970-01-01 00:00:00的相对秒数值。结构timeval是Linux内核表示时间的一种格式(Linux内核对时间的表示有多种格式,每种格式都有不同的时间 精度),其时间精度是微秒。该结构是内核表示时间时最常用的一种格式,它定义在头文件include/linux/time.h中,如下所示:

struct timeval {   time_t tv_sec; /* seconds */   suseconds_t tv_usec; /* microseconds */   };

Linux内核时钟驱动的基本概念