Intel 8253/8254是一个可编程定时/计数器(PIT-Programmable Interval Timer)芯片,用于处理计算机中的精确时间延迟。该芯片提供了 3个独立的16位计数器通道。每个通道可工作在不同的工作方式下, 并且这些工作方式均可以使用软件来设置。
对于PC/AT及其兼容微机系统采用的是8254芯片。Linux 0.11操作系统只对通道0进行了重新设置,使得该计数器工作在方式3下,并且每间隔10毫秒发出一个信号以产生中断请求信号(IRQ0)。这个间隔定时产生的中断请求就是Linux 0.11内核工作的脉搏,它用于定时切换当前执行的任务和统计每个任务使用的系统资源量(时间)。
1、Intel 8253 (8254)芯片功能
Intel 8253 (或 8254)是一个可编程定时/计数器(PIT-Programmable Interval Timer)芯片,用于解决计算机中通常碰到的时间控制问题,即在软件的控制下产生精确的时间延迟。该芯片提供了3个独立的16位计数器通道。每个通道可工作在不同的工作方式下,并且这些工作方式均可以使用软件来设置。
8254是8253的更新产品,主要功能基本一样,只是8254芯片増加了回读命令。在下面描述中我们用8253来代称8253和8254两种芯片,仅在它们功能有区别处再特别加以指出。
2、端口说明
对于PC/AT及其兼容微机系统,采用的是8254芯片。3个计数器的输入时钟频率都是 1.193180MHz。PC/AT微机中8254芯片连接示意图如下。
其中A1、A0管脚被连接到系统地址线A1、A0上。并且当系统地址线A9–A2信号是0b00100 00时会选择8254芯片,因此PC/AT系统中8254芯片的IO端口地址范围是0x40—0x43。其中0x40~0x42分别对应计数器通道0~2,0x43对应控制字寄存器写端口。
3、编程方法
当系统刚上电时,8253的状态是未知的。通过向8253写入一个控制字和一个初始计数值,我们就可以对想要使用的一个计数器进行编程。对于不使用的计数器我们可以不必对其编程。
在CPU执行写操作时,若A1,A0线为11 (此时在PC微机上对应端口 0x43),那么控制字会被写入控制字寄存器中。而控制字的内容会指定正在编程的计数器通道。
通道0、1、2分别对应PC机端口 0x40、0x41和0x42,当控制字写完后,就可以向某个通道写入初始计数值。
注意:在写入操作时,必须首先写入控制字,然后再写入初始计数值。初始计数值必须根据控制字中设定的格式写入(二进制或BCD码格式)。在计数器开始工作时,我们仍然能随时向指定计数器重新写入新的初始值,这并不会影响已设置的计数器的工作方式。
1、控制字的格式
控制字的格式如下图所示。
movb $0x36, %almovl $0x43, %edxoutb %al, %dx
以上代码用于向端口0x43写入控制字0x36,对照上图,得知选中通道0,先读写低字节再读写高字节,工作方式3,采用二进制计数。
2、工作方式三——方波发生器方式
工作方式一共有6种,这里仅说明方式3,因为Linux-0.11用的就是这种方式。
方式3:方波发生器方式(Square Wave Mode)
该方式输出的是方波。如果初始计数值是N, 那么方波的频率是输入时钟的N分之一。该方式的特点是方波占空比约为1比1 (当N为奇数时略有差异),并且在计数器递减过程中若重新设置新的初始值,这个初始值要到前一个计数完成后才起作用。
在工作方式3下,方波的频率是输入时钟频率的N分之一,又因为计数器的输入时钟频率是 1.193180MHz=1193180Hz,所以
1193180/N = 方波的频率(Hz)
如果想让计数器每10ms(=100Hz)发出一个方波上升沿用以产生中断请求信号的话,那么N=1193180/100.
Linux 0.11操作系统只对8254的计数器通道0进行了重新设置,使得该计数器工作在方式3下,计数初始值采用二进制,并且初始计数值被设置为LATCH (1193180/100)。即让计数器0每间隔10毫秒发出一个方波上升沿以产生中断请求信号(IRQ0)。
movl $11931, %eax # timer frequency 100 HZ movl $0x40, %edxoutb %al, %dx # 先写低字节movb %ah, %aloutb %al, %dx # 再写高字节
继续上文的代码,在写入控制字后,要写入初始计数值。因为控制字选择了0通道,所以写初始计数值的端口是0x40. 如果要产生100Hz的方波,那么写入的初始值是1193180/100 ,约等于 11931。