历史上的今天
返回首页

历史上的今天

今天是:2024年12月10日(星期二)

正在发生

2018年12月10日 | ARM中断源之定时器中断

2018-12-10 来源:eefocus

实时时钟请求中断。在控制中遇到定时检测和控制,为此常采用一个外部时钟电路(可编程)控制其时间间隔。需要定时时,CPU发出命令使时钟电路开始工作,一旦到达规定时间,时钟电路发出中断请求,由CPU转去完成检测和控制工作。


走到这里,大家肯定对Linux的中断处理有概念了,下面我们通过一个具体的实例,来了解Linux内核处理中断的全过程,那就是定时器中断。在详细分析这个过程之前,我们把Linux时间管理的概念先缕一缕。


在当前的80x86体系结构上,内核显式地与几种时钟和定时器电路打交道,其主要分为了时钟和定时器两大类:


- 时钟电路同时用于跟踪当前时间和产生精确的时间度量。


- 定时器电路由内核编程,所以它们以固定的、预先定义的频率发出中断。


1、实时时钟(RTC)


所有的PC都包含一个叫实时时钟(Renl Time Clock RTC)的时钟,它是独立于CPU和所有其他芯片的。即使当PC被切断电源,RTC还继续工作,因为它靠一个小电池或蓄电池供电。CMOS RAM和RTC被集成在一个芯片上。


RTC能在IRQ8上发出周期性的中断,频率在2~8192 Hz之间。我们可以对RTC进行编程以使当RTC到达某个特定的值时激活IRQ8线,也就是作为一个闹钟来工作。


Linux只用RTC来获取时间和日期,不过,通过对/dev/rtc设备文件进行操作,也允许透程对RTC编程。内核通过0x70和Ox71 I/O端口访问RTC。系统管理员通过执行Unix系统时钟程序(直接作用于这两个I/O端口)可以设置时钟。MC146818 RTC芯片(或其他兼容芯片,如DS12887)可以在IRQ8上产生周期性的中断,中断的频率在2HZ~8192HZ之间。与MC146818 RTC对应的设备驱动程序实现在include/linux/rtc.h和drivers/char/rtc.c文件中,对应的设备文件是/dev/rtc(major=10,minor=135,只读字符设备)。因此用户进程可以通过对她进行编程以使得当RTC到达某个特定的时间值时激活IRQ8线,从而将RTC当作一个闹钟来用。


而Linux内核对RTC的唯一用途就是把RTC用作“离线”或“后台”的时间与日期维护器。当Linux内核启动时,它从RTC中读取时间与日期的基准值。然后再运行期间内核就完全抛开RTC,从而以软件的形式维护系统的当前时间与日期,并在需要时将时间回写到RTC芯片中。所以,RTC时钟只是个为后面我们介绍的那些时钟起一个初始化的作用,仅此而已!


Linux在include/linux/mc146818rtc.h和include/asm-i386/mc146818rtc.h头文件中分别定义了mc146818 RTC芯片各寄存器的含义以及RTC芯片在i386平台上的I/O端口操作。而通用的RTC接口则声明在include/linux/rtc.h头文件中。


2、时间戳计数器(TSC)


时间戳计数器与实时时钟配合使用,用来将时钟和定时器调整得更精确。所有的80x86微处理器都包含一条CLK输入引线,它接收外部振荡器的时钟信号。从Pentium开始,80x86微处理器就都包含一个计数器,它在每次外部振荡器的时钟信号到来时加1。该计数器是利用64位的时间戳计数器(Time Stamp Counter TSC)寄存器来实现的,可以通过汇编语言指令rdtsc读这个寄存器。


为什么要出现一个时间戳计数器呢?Linux利用这个寄存器可获得更精确的时间量,以便计算进程用户态与内核态的运行时间及等待(睡眠)时间。为了做到这点,Linux在初始化系统的时候必须确定时钟信号的频率。事实上,因为编译内核时并不声明这个频率,所以同一内核映像可以运行在产生任何时钟频率的CPU上,即这个频率由CPU决定。


算出CPU实际频率的任务是在系统初始化期间完成的。calibrate_tsc()函数通过计算一个大约在5ms的时间间隔内所产生的时钟信号的个数来算出CPU实际频率。通过适当地设置可编程间隔定时器(PIT)的一个通道来产生这个时间常量。


3、可编程间隔定时器(PIT),重点!


可编程间隔定时器(Programmable Interval Timer PIT)的作用类似于微波炉的闹钟,即让用户意识到烹调的时间间隔已经过了。所不同的是,这个设备不是通过振铃,而是发出一个特殊的中断,叫做时钟中断(timer interrupt)来通知内核又一个时间间隔过去了。每个IBM兼容PC都至少包含一个PIT,PIT通常是使用0x40~0x43 I/O端口的一个8254 CMOS芯片,该芯片作为I/O设备与中断控制器的IRQ0相连,向量号为32。


Linux给PC的PIT进行编程,使它以1000 Hz的频率向IRQ0发出时钟中断,即每1ms产生一次时钟中断。这个时间间隔叫做一个节拍(tick),它的长度以纳秒为单位存放在tick_nsec变量中。在PC上,tick_nsec被初始化为999848ns(产生的时钟信号频率大约为1000.15 Hz),但是如果计算机被外部时钟同步的话,它的值可能被内核自动调整。


时钟中断的频率可以通过编译内核前对一些参数的设定来满足于具体硬件体系结构的要求。较慢的机器,其节拍大约为lOms(每秒产生100次时钟中断),而较快的机器的节拍为大约1ms(每秒产生1000或1024次时钟中断)。


在Linux的代码中,有几个宏产生决定时钟中断频率的常量,对此讨论如下:


- HZ产生每秒时钟中断的近似个数,也就是时钟中断的频率。在IBM PC上,这个值设置为1000。


- CLOCK_TICK_RATE产生的值为1193182,这个值是8254芯片的内部振荡器频率。


- LATCH产生CLOCK_TICK_RATE和HZ的比值再四舍五入后的整数值。这个值用来对PIT编程。


PIT由setup_pit_timer()进行如下初始化:


    spin_lock_irqsave(&i8253_lock, flags);

    outb_p(0x34,0x43);

    udelay(10);

    outb_p(LATCH & 0xff, 0x40);

    udelay(10);

    outb(LATCH >> 8, 0x40);

    spin_unlock_irqrestore(&i8253_lock, flags);


outb()C函数等价于outb汇编语言指令:它把第一个操作数拷贝到由第二个操作数指定的I/O端口。outb_p()函数类似于outb(),不过,它会通过一个空操作而产生一个暂停,以避免硬件难以分辨。udelay()宏函数引入了一个更短的延迟。


第一条outb_p()语句让PIT以新的频率产生中断。接下来的两条outb_p()和outb()语句为设备提供新的中断频率。把16位LATCH常量作为两个连续的字节发送到设备的8位I/O端口0x40。结果,PIT将以(大约)1000Hz的频率产生时钟中断,也就是说,每1ms产生一次时钟中断。


4、其他定时器


除了PIT,80x86体系还有其他几个定时器,这里只简单提一提:


- CPU本地定时器:CPU本地定时器是一种能够产生单步中断或周期性中断的设备,向量范围是239 (0xef),比PIT更灵活地编程。


- 高精度事件定时器(HPET):可以通过映射到内存空间的寄存器来对HPET芯片编程的定时器。


- ACPI电源管理定时器:时钟信号拥有大约为3.58 MHz的固定频率,专门针对ACPI电源的定时器。


本博文,我们重点讨论第三项,即可编程间隔定时器,它是整个Linux内核的心脏,驱动着若干进程的运行。PS,这里只讨论单CPU的计时体系。


推荐阅读

史海拾趣

Davies Molding公司的发展小趣事

Davies Molding公司深知,人才是企业发展的核心动力。因此,公司高度重视团队建设与人才培养。通过建立完善的培训体系,Davies Molding公司不断提升员工的技能和素质,打造了一支高素质、专业化的团队。这支团队不仅为公司的发展提供了有力保障,还为行业的进步做出了积极贡献。

DC Components公司的发展小趣事

随着电子行业的快速发展,技术创新成为企业发展的重要动力。DC Components公司紧跟行业趋势,积极引进先进技术,加大研发投入,不断推出具有竞争力的新产品。这些新产品不仅满足了市场的多样化需求,还为公司的发展注入了新的活力。

ERNI公司的发展小趣事

1947年,瑞士工程师Ernst Rudolf Erni和他的妻子Elsa在瑞士那提空(Nänikon)共同创立了“ERNI & CO.”公司。他们的首个订单是为苏黎世克洛腾机场开发地雷探测器和机场导航灯。这个起点虽小,但为ERNI日后在电子行业的辉煌奠定了基础。随着订单的增多,公司逐渐扩大了生产规模,并开始涉足继电器、电气设备等领域。

Fong Ya Enterprise Co Ltd公司的发展小趣事

1947年,瑞士工程师Ernst Rudolf Erni和他的妻子Elsa在瑞士那提空(Nänikon)共同创立了“ERNI & CO.”公司。他们的首个订单是为苏黎世克洛腾机场开发地雷探测器和机场导航灯。这个起点虽小,但为ERNI日后在电子行业的辉煌奠定了基础。随着订单的增多,公司逐渐扩大了生产规模,并开始涉足继电器、电气设备等领域。

科达嘉CODACA公司的发展小趣事

在追求技术创新的同时,科达嘉电子也积极承担社会责任。公司关注环境保护,推行绿色生产,努力减少生产过程中的环境污染。此外,科达嘉还积极参与社会公益活动,为社区的发展贡献力量。通过不断创新和履行社会责任,科达嘉电子在电子行业中树立了良好的企业形象。

APC (APC by Schneider Electric)公司的发展小趣事

随着计算机技术的飞速发展,单一的UPS产品已无法满足市场的多样化需求。为此,APC在1989年推出了突破性的电源管理软件(PowerChute®)。这款软件能够智能地管理UPS设备,提供更为精细的电力保护。紧接着,APC又推出了Smart-UPS®系列UPS产品,该产品以其卓越的性能和稳定性,迅速成为评估所有其它网络UPS产品的标准。

问答坊 | AI 解惑

彩电企业抱团应对出口壁垒

本帖最后由 jameswangsynnex 于 2015-3-3 19:59 编辑 备受关注的中国彩电企业应对出口专利壁垒有了新的突破。经过与众多国外专利权利人近两年的接触谈判,彩电出口交纳专利费用问题有了较大程度缓和,彻底扭转了DVD时代在专利问题上的被动局面,困扰 ...…

查看全部问答>

这个程序用在2051要怎么改

芯片:89c51 工作晶振:12Hz 功能: 1、按遥控器上的\"1\"键,对应1号灯就点亮,2和3键对应另外两只灯,\"关\"将关闭所有灯。 由于这批灯泡的功率较大,考虑到器件的发热,设计中同一时间内只能亮一只灯。 2、调光功能。如要对灯进行调光,可 ...…

查看全部问答>

LED与荧光粉知识

 近年来,在照明领域最引人关注的事件是半导体照明的兴起。20世纪90年代中期,日本日亚化学公司的Nakamura等人经过不懈努力,突破了制造蓝光发光二极管(LED)的关键技术,并由此开发出以荧光材料覆盖蓝光LED产生白光光源的技术。半导体照明具有绿色 ...…

查看全部问答>

寻找串口通信高手

   问题如下,我用了cncomm1.51类,我读取数据的时候,数据老是不稳定。有的电子设备读取数据很稳定的,请问下,同过com口读取数据和硬件设备有关吗?是什么关系呢?谢谢。…

查看全部问答>

wince5.0 debug编译出错,release编译正常

如题。。。。。。debug错误提示是 BUILD: [01:0000000169:ERRORE] NMAKE :  U1073: don\'t know how to make \'F:\\wince5project\\test1\\WINCE500\\new2440_ARMV4I\\cesysgen\\sdk\\lib\\ARMV4I\\retail\\Ndis.lib\' BUILD: [01:000 ...…

查看全部问答>

地震了患难见真情,我校都捐款了,钱财身外之物。

一直关注各界捐款的情况,像网易,一般会捐,对这种会捐款的公司比较有好感。请问有没有搞嵌入式的公司捐款。最好在北京,天津。明年我一定争取机会到这种公司面试。…

查看全部问答>

【分享】单c,自己用汇编写出来了,呵呵,进步。

这是c: #include                         //包括一个标准的51头函数 #define uchar unsigned char                    &nb ...…

查看全部问答>

有谁用LTC3555?请帮忙看看芯片上的文字。我都割掉使能线了,表现仍与手册相反

的LTC3555的EN1脚表现与手册相反,手册是高电平有效,我的却是低电平有效。 已经把EN1割断了,飞线试了一下,还是一样的。 我的片子上的文字是: 6C 3555 J9729 我现在怀疑是假货,或者是Linear公司专为某些公司修改的。 有谁用?帮 ...…

查看全部问答>

WINCE下自带的数据库,创建数据库函数问题

请问在使用WINCE下自带的数据库编程的时候,在使用CeCreateDatabaseEx函数的时候,这个函数的两个参数是如何定义的? 我是这样写的 CEDBASEINFO ceDbInfo;                         ...…

查看全部问答>