Linux内核中的可编程间隔定时器PIT

原创 2007年09月15日 19:32:00

Linux内核中的可编程间隔定时器PIT(Programmable Interval Timer)

    每个PC机中都有一个PIT,通过IRQ产生周期性的时钟中断信号来充当系统定时器。i386中使用的通常是Intel 8254 PIT芯片,它的I/O端口地址范围是40h~43h。

    8254 PIT有3个计时通道,每个通道都有其不同的用途:

        通道0用来负责更新系统时钟。它在每一个时钟滴答会通过IRQ0向系统发出一次时钟中断信号。
        通道1通常用于控制DMAC对RAM的刷新。
        通道2被连接到PC机的扬声器,以产生方波信号。

    下面我们重点关心通道0。

    每个通道都有一个递减的计数器,8254 PIT的输入时钟信号的频率是1.193181MHZ,也即一秒钟输入1193181个时钟周期。该数字在Linux内核中被定义为:

include/asm-i386/timex.h

#define CLOCK_TICK_RATE 1193180

     每输入一个时钟周期其时间通道的计数器就自减1,一直减到0。因此对于通道0而言,当他的计数器减到0时,PIT就向系统产生一次时钟中断,表示一个时钟滴答已经过去了。该计数器为16bit,因此所能表示的最大值是65536,可以算出该定时器最慢一秒内能发生的滴答数是:1193181 / 65536 = 18.206482。

    PIT的I/O端口:
        40h    通道0计数器    可读写
        41h    通道1计数器    可读写
        42h    通道2计数器    可读写
        43h    控制字         只写

    注意,因为PIT I/O端口是8位的,而PIT相应计数器是16位的,因此必须对PIT计数器进行两次读写才能得到完整的计数值。

    8254 PIT的控制寄存器43h的格式如下:

        bit[7:6]为通道选择位:
            00    通道0
            01    通道1
            10    通道2
            11    read-back command(仅8254)。

        bit[5:4]为Read/Write/Latch锁定位:
            00    锁定当前计数器以便读取计数值
            01    只读高字节
            10    只读低字节
            11    先高后低

        bit[3:1]为设定各通道的工作模式:
            000   mode0    当通道处于count out时产生中断信号,可用于系统定时
            001   mode1    Hardware retriggerable one-shot
            010   mode2    Rate Generator。产生实时时钟中断,通道0通常工作在这个模式下
            011   mode3    方波信号发生器
            100   mode4    Software triggered strobe
            101   mode5    Hardware triggered strobe

        bit[0]总为0

    我们来看看Linux2.4中是如何对PIT做初始化的:

arch/i386/kernel/i8259.c

void __init init_IRQ(void)
...{
      ...
     
outb_p(0x340x43);          /**//* binary, mode 2, LSB/MSB, ch 0 */
     
outb_p(LATCH & 0xff0x40);  /**//* LSB */
     
outb(LATCH >> 80x40);      /**//* MSB */
      ...
}
    其中的LATCH定义为:

 include/asm-i386/param.h

#define HZ     100
include/asm-i386/timex.h
#define LATCH  ((CLOCK_TICK_RATE + HZ / 2) / HZ

     也即是等于常数(1193180 + 50) / 100 = 11932,加50是为了尽可能的减小误差(结果四舍五入)。这个结果即是Linux的系统嘀嗒长度(约为0.01秒)经过所需要的PIT时钟周期数。

    上面的那段C基本等价于汇编(省去了延时操作):

mov    ax, LATCH
out    43h, 34h
out    40h, al
out    40h, ah

    首先写控制字43h,通道选择位为00(通道0),RWL锁定位为11(先高后低),通道工作模式010(Rate Generator),最后位0保留,合起来就是34h。
    然后把LATCH的值分成高低两个字节依次写入通道0计数器40h,完成PIT编程。
    当Linux下次打开中断的时候,系统时钟就将会按照设定的频率(约为100HZ)发出时钟中断了。

【手把手教你做智能车】第五节-PIT定时器(上)

飞思卡尔智能车系列教学视频教程 手把手教你做智能车:第五节-PIT定时器(上) 视频教程观看地址:http://v.youku.com/v_show/id_XNzkwN...
  • DEMOK2010
  • DEMOK2010
  • 2014年10月25日 16:21
  • 1290

PIT工作原理

转自:http://m.blog.csdn.net/blog/lvtingting2007/43372041 PIT工作原理 即使你不用固件库来编程,PIT也绝对是不会让你望而却步的一个东...
  • qq_33114231
  • qq_33114231
  • 2015年12月08日 15:35
  • 2236

Linux内核中的可编程间隔定时器PIT

Linux内核中的可编程间隔定时器PIT(Programmable Interval Timer)    每个PC机中都有一个PIT,通过IRQ产生周期性的时钟中断信号来充当系统定时器。i386中使用...
  • axx1611
  • axx1611
  • 2007年09月15日 19:32
  • 3341

《自己动手写操作系统》 第六章 系统调用的实现

在学习系统调用之前,我们有必要理清几个问题:什么是系统调用?为什么要使用系统调用?如何来实现一个系统调用。 1.理论知识     所谓系统调用,就是内核提供的、功能十分强大的一系列的函数。...
  • trochiluses
  • trochiluses
  • 2014年03月24日 21:20
  • 1236

Linux系统进程间隔定时器Itimer

所谓“间隔定时器(Interval Timer,简称itimer)就是指定时器采用“间隔”值(interval)来作为计时方式,当定时器启动后,间隔值interval将不断减小。当interval值减...
  • u010258235
  • u010258235
  • 2015年07月22日 22:53
  • 495

可编程定时/计数器 8253/8254

在微机应用系统中,定时控制具有重要的作用。经常会有这样的应用要求:一种是要求有一些外部实时时钟,以实现延时控制或定时;另一种是要求能对外部事件计数的计数器。在微机系统中,常采用以下三种方法实现:软件定...
  • u013007900
  • u013007900
  • 2015年12月26日 16:02
  • 6431

关于 Intel 8253/8254

Intel 8253/8254是一个可编程定时/计数器(PIT-Programmable Interval Timer)芯片,用于处理计算机中的精确时间延迟。该芯片提供了 3个独立的16位计数器通道。...
  • u013490896
  • u013490896
  • 2017年12月24日 16:13
  • 259

android qemu-kvm i8254 pit虚拟设备

ubuntu12.04下使用android emulator,启用kvm加速,模拟i8254定时器的代码比较旧,对应于qemu0.14或者之前的版本,这时还没有QOM(qemu object mode...
  • ayu_ag
  • ayu_ag
  • 2016年10月19日 11:41
  • 687

K60的计时器/定时器的简单介绍

一. 可编辑延迟模块(PDB) PDB的基本知识: 1)用途:可以为编辑间隔ADC模块的硬件触发时间,也可以编辑DAC模块间隔触发的可控时延,提供转换精准时间。 2)资源:15中输入触发源;分别...
  • pofenglangguayunfan
  • pofenglangguayunfan
  • 2014年01月04日 15:40
  • 3554

linux内核编程之内核定时器

【版权声明:转载请保留出处:blog.csdn.net/gentleliu。邮箱:shallnew*163.com】 如果我们需要在将来某个时间点调度执行某个动作,同时在该时间点到达之前不会阻塞当前...
  • gentleliu
  • gentleliu
  • 2014年01月01日 15:17
  • 1637
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux内核中的可编程间隔定时器PIT
举报原因:
原因补充:

(最多只允许输入30个字)