很久没有写关于MiniKernel的文章了,这周末看着有点时间,就写一点关于定时器的东西吧。
简单介绍
可编程间隔定时器(PIT)芯片(也就是我们常说的8253/8254芯片),他包含了1个振荡器,1个预分频器和3个独立的分频器。每个分频器有一个输出,它是可以让定时器控制外部电路(例如,IRQ0)
其中PIT的振荡器的频率是1.193182 MHz。具体为什么是这么个奇怪的数字,是有一点历史的,但这些不是这篇文章的重点,有兴趣的可以Google一下。
分频器也比较容易理解,就是把高频分割为低频,一般来说就是使用一个计数器,当每次脉冲的时候,计数器的数值减少,当计数器数值为0的时候,在输出上产生一个脉冲,并且计数器复位,重新开始计数。
PIT定时器的准确度依赖于所使用的振荡器,一般来说,一天的浮动为+/- 1.73秒。不过这种浮动,对我们影响并不大,所以也不必过于在意。
PIT的输出通道一共有三个:通道0,直接连接到IRQ0,并且触发时钟中断(这个通道是我们写MiniKernel最重要的一个。)。通道1,貌似以前是定时刷新内存的,但是现在没什么用了。通道2是连接到PC扬声器的,目前我也没有研究过它的作用。
这里再重点介绍一下通道0:PIT通道0的输出是连接到PIC芯片上的(8259A,以后有空也可以写一篇简单的介绍),因此,它能生成一个IRQ0的中断。通常情况下,在开机时,BIOS会将通道0的计数器的值设置为65535或0(其中如果是0,硬件会自动转化为65536),这样,它的输出频率就是18.2065Hz。另外,之所以说通道0最重要,主要原因就是它是三个通道中,唯一一个能连接到IRQ的,对于编写系统时钟至关重要。
编程相关
PIT是使用以下IO端口进行控制:
I/O 端口 用途 |
控制字寄存器的具体内容如下:
Bits |
这里,我们要写系统时钟,那么就应该这样选择:
- 选择通道,必须是通道0,那么bit 6 7 就分别为 0 0。
- 由于我们的计数器是16位的,那么访问模式bit 4 5就应该选择1 1。
- 数据模式,毫无疑问选择二进制模式。
- 最后就是工作模式了,应该选择什么呢?这里我也不想把这些模式都讲的很清楚,因为那样就涉及到引脚和电平等等硬件知识。现在我们只需要知道0,1,4,5这些模式都可以触发中断,但是却不会自动复位。只有模式2和3会自动复位。所以模式2 3都是我们可以用来作为系统时钟的模式。那么1-3 bits可以为0 1 0或者0 1 1。
例子:
现在假设,系统的时钟中断例程已经设置好了,并且设置好了PIC的IRQ0到这个例程。下面要做的事情就是,设置时钟中断的频率了。
mov dx, 1193180 / 100 ; 没10ms触发一次中断 |
总的来说8253 和 8254 是很有用的芯片。他们可以用在很多不同的设备,并用于很多不同的目的。不过就目前的PC来说,系统对他们的依赖已经不像以前那样严重了。随着科技的进步,APIC Timer已经可以取代他们。另外2005年,Intel和MS已经联合开发了新的高精度的定时器芯片High Precision Event Timer(HPET)。
虽然成熟的系统可能已经不用8253 和 8254了,但是对于我们自己的迷你内核来说,使用它们就完全足够了