硬件中断处理是实时系统设计中的关键性问题,设计人员有必要对其作深入研究,以更好地满足开发工作需要。文中以VxWorks操作系统为软件平台,讨论了在实时系统中进行中断应用设计时要注意的一些问题。由于软硬件的相关性,选用广泛应用的X86架构的嵌入式汁算机为硬件平台,对PenriumCPU和计算机主板对硬件中断的管理机制也做了详细介绍 所得出的研究结论在具体的开发项目中均得以验证,可供相关技术人员参考。

硬件中断处理是实时系统设计中最重要、最关键的问题。文中综合软硬件,从工程应用的角度对此问题加以讨论。文中所述内容针对的软件平台是VxWorks实时操作系统,硬件平台选用广泛使用的X86架构的嵌入式计算机,全文按照CPU、主板、操作系统自下而上的顺序展开。

1 Pentium CPU的中断类型

有两类事件可引起Pentium挂起当前的指令流,即中断和异常。中断是由外部事件引发的,在程序执行的任何时刻都可能出现;异常也称异常中断,是由内部事件引发的。中断和异常各有两类触发源:

(1)中断。

可屏蔽中断:CPU的INTR引脚收到有效信号,如果Pentium标志寄存器IF位为1,则允许中断,否则信号在CPU内被屏蔽。

非屏蔽中断:CPU的NMI引脚收到有效信号而引发的中断,这类中断不能被阻止。

(2)异常。

执行异常:CPU试图执行一条指令的过程中出现错误、故障等不正常条件而引发的异常中断。

执行软件中断指令:Pentium指令系统中包括一些如INTO,INT n这类软件中断指令,执行时产生异常中断。

详细分类的话,Pentium可以识别256种中断和异常。每种中断给予一个编号,即0~255,称为中断向量号(interrupt vector number)。其中NMI、异常以及系统保留占用中断向量号0~31,而32~255为用户中断向量号,可供INTR和自定义软件中断(如汇编中的INT指令)使用。

2 Pentium CPU的中断响应过程

中断处理子程序的入口地址信息存于内存中的一个表内,实模式为中断向量表IVT,保护模式为中断描述符表IDT。中断发生时,CPU首先通过某种方式获得中断向量号,再以中断向量号检索此表,即可获取中断服务子程序入口地址,详述如下:

(1)实模式使用中断向量表。

中断向量表IVR的基地址由IDTR(中断描述符寄存器)指定,大小为1kB。中断响应时的查表过程与8086/8088一致,在此不再赘述。

(2)保护模式使用中断描述符表。

中断描述符表(IDT)的基地址也由IDTR指定,大小为2kB。中断描述符表每一表项对应一个中断向量号,但表项称为中断门描述符或陷阱门描述符。这些门描述符为8字节长,对应256个中断向量号。以中断向量号乘以8作为访问IDT的偏移,读取相应的中断门/陷阱门描述符表项。门描述符给出中断服务子程序人口地址(段:偏移),其中32位偏移量装入EIP,16位的段值被装入CS寄存器。但此段值是选择符,CPU会自动查GDT或LDT取得代码段描述符并送到相应的描述符寄存器中。

3 X86架构的计算机对外部中断的管理

在嵌入式应用中,人们感兴趣的主要是指由硬件信号触发的非屏蔽中断与可屏蔽中断。在单CPU的X86计算机中,采用两片8259级联来管理16个可屏蔽外部中断,由于主8259的IRQ2用于级联,所以实际可用的IRQ只有15个,其中又有一些被系统占用,这种逻辑如今已被集成在主板芯片组的南桥中,如图1所示。由于传统的PIC提供的中断资源较少,现代PC开始采用APIC(高级可编程中断控制器)管理外部中断,它的一个显著优点是能够扩充系统可用的IRQ资源。文中问题的讨论基于传统的PIC结构。




图1 外部中断管理逻辑

4 在VxWorks中设计中断应用

Vxworks运行在保护模式下。在Vxworks中,可以采用intConnect关联中断服务程序至某个中断向量。然而intConnect并不是直接将用户设计的ISR与中断门描述符相关联,而是对它加了一层封装,然后将封装代码的内存首地址与中断门描述符相关联,中断响应过程如图2所示。采用intConnect为ISA总线设备关联中断服务程序IRQ—ISR至IRQ10的程序片断如下:

代码
  1. #define IRQNum 10 /*1*/
  2. ……
  3. /* 2,3 */
  4. if(intConneet((VOIDFUNCPTR)INUM_TO_IVEC(IRQNum+0x20),IRQ_ISR,0)==OK)
  5. {
  6. if(sysIntEnablePIC(IRQNum)==OK) /*4*/
  7. {
  8. print{("Succeeded.\n");
  9. }
  10. }
  11. void IRQ_ISR()
  12. {
  13. int intLockKey;
  14. intLockKey=intLock();/*5*/
  15. ……(critical section)
  16. intUnlock(intLocKey);
  17. }




图2 中断响应过程

程序要点详述:

① X86架构的计算机中,一些中断资源已经固定地分配给某些外部设备,如系统时钟固定使用IRQ0,所以在选择中断号时首先应参考硬件手册,避免与已用的中断资源冲突。选定中断号后,需要在BIOS中加以设置。避免BIOS在初始化时,把此中断号作为可用资源分配给PCI设备,造成中断冲突。以上是在开发ISA设备时要注意的,若开发PCI设备,一般不做上述考虑,因为BIOS可为PCI设备动态分配中断资源,且多个PCI设备可共享一个中断号,只需从PCI配置头中读取分配到的中断号使用即可。

② VxWorks中使用intConnect挂接中断服务程序,但对于PCI设备,一般采用pciIntConnect挂接中断,它与intConnect的主要不同在于intConnect使用的中断向量是独占的,而pciIntConnect则可使多个外部中断共享一个中断向量。它在内部使用一个链表管理多个ISR,发生中断时,链接在一个链表上的各个ISR被依次调用,pciIntConnect要求每个ISR被调用时,应该首先查询是否为自己的设备产生的中断,不是则应立即返回,以继续调用其它ISR。

③ 在VxWorks中要注意区分以下4个与中断相关的概念:IRQNumber,INumber,IVector,ILevel。

  • IRQNumber:外部中断信号由两片8259级联构成的PIC的那个输入管脚引入,主8259的8条中断输入线对应IRQ0~IRQ7,从8259对应IRQ8~IRQ15。
  • INumber:Pentium CPU 的中断向量号。INumber=IRQNumber+INT_NUM_IRQ0,INT_NUM_IRQ0,即IRQ0对应的中断向量号,BSP的config.h中定义其为0x20(十进制的32),即Pentium CPU 中断向量号用户定义区的起始编号。
  • IVector:中断向量,是指某中断的中断描述符在中断描述符表中的偏移量。INumber与IVector间的关系可简单描述为:IVector=INumber*8。可以用ivi86.h中定义的两个宏(INUM_TO_IVEC,IVEC_TO_INUM)实施转换。
  • ILevel:中断优先级。由于主从8259都被初始化为固定优先级,优先级逐渐递减,且两片8259存在级联关系,所以优先级关系为IRQ0 > IRQ1> IRQ2[IRQ8>IRQ9>…>IRQ15]>IRQ3>…>IRQ6>IRQ7。

表1列出了IRQ0~IRQ15对应的中断向量号(INumber)与中断向量(IVector)。

表1 中断相关概念对照表
IRQNumber INumber IVector
0 32 0x100
1 33 0x108
2 34 0x110
15 47 0x178

④ 用intConnect挂中断后,还必须用sysIntEnablePIC使能中断,sysIntEnablePIC的函数原型在i8259Pic.C中定义,实际上就是针对某个IRQ,置8259中断屏蔽寄存器中的相应位为允许。sysIntEnablePIC中的基本操作是利用端口读写函数sysInByte,sysOutByte读写8259的中断屏蔽寄存器。sysInByte,sysOutByte的函数原型在sysALib.s中定义。

⑤ 关键代码段可用关中断intLock和开中断intUnlock加以保护。语句对intLock与intUnlock在不同的CPU体系架构中实现原理不同。在X86架构中,它们是通过操作EFLAGS中的IF位实现的。反汇编后可观察它们的汇编形式代码。

intLock的反汇编代码:

_intLock: PUSHF /*将EFLAGS压栈*/

_intLock: POP EAX

+0x002: AND EAX,0x200 /*只保存感兴趣的位IF*/

+0x007: CLI /*清IF位*/

+0x008: RET /*EAX作为返回值,即lock-out key */

intUnlock的反汇编代码:

_intUnlock: MOV EAX,[ESP+4] /*将lock-out key作为参数传给EAX */

+0x004: AND EAX,0x200 /*判封锁中断前IF位的状态如何*/

+0x009: JE intUnlock0 /*若封锁中断前也是关中断状态,则不做操作*/

+0x011: STI /*若封锁中断前是开中断状态,则置IF位*/

intUnlock0: RET /*返回*/

注意不要在中断闭锁期间调用Vxworks系统函数,否则有可能意外打开中断闭锁,违反临界代码的设计意图。intLock可以在ISR或通常的任务中使用,当在任务中使用时,关中断并不会禁止任务调度,所以,若一个任务关中断后,又发生了任务调度,则新任务的上下文将被恢复,而EFLAGS是任务上下文的一部分,所以IF位可能会发生变化,中断屏蔽可能会被解除。为了在关中断的同时禁止任务调度,可采用如下形式:

if(taskLock()==OK)

{

intLockKey= intLock();

…(critical section)

intUnlock(intLockKey);

taskUnlock();

}

以上介绍了设计中断应用时在软件方面要注意的一些问题,再简单说一下硬件中断信号的提供。VxWorks中8259被初始化为上升沿触发,值得注意的是,外部中断信号 须保持为高电平直至第一个INTA信号的下降沿到来,否则会造成假中断,触发IRQ7的中断服务程序,常用的硬件中断信号形式是利用一个负脉冲的后沿(上升沿)。IRQ7是并口使用的中断号,在调试过程中,可以在VxWorks中裁减掉并口模块,在IRQ7上挂一个测试用的中断服务程序,以观察记录假中断。

5 结束语

文中结合工程实践,以VXWorks与X86架构的嵌入式计算机为软硬件平台,较深入地阐述了在实时系统中设计中断应用时需要考虑的一些问题。由于篇幅所限,一些在其他资料中被广泛提及的设计要点(如中断服务程序不能调用可能会引起调用阻塞的函数)在此不作介绍。

VxWorks中的中断应用设计要点的更多相关文章

  1. 浅谈游戏中BUFF的设计要点

    其实这类帖子并没有多少的设计理论,对于策划的提升和帮助也并不大,原因其实在于其适用性太窄,当我要设计XX象棋的时候,它就滚一边去了. 废话不多说切入正题: 游戏中的BUFF/DEBUFF我们见过很多, ...

  2. 痞子衡嵌入式:嵌入式MCU中通用的三重中断控制设计

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是嵌入式MCU中通用的三重中断控制设计. 我们知道在 MCU 裸机中程序代码之所以能完成多任务并行实时处理功能,其实主要是靠中断来调度的, ...

  3. Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  4. Netty_Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  5. 【netty】Netty系列之Netty百万级推送服务设计要点

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  6. Netty系列之Netty百万级推送服务设计要点(转)

    1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...

  7. 【转】Flume(NG)架构设计要点及配置实践

    Flume(NG)架构设计要点及配置实践   Flume NG是一个分布式.可靠.可用的系统,它能够将不同数据源的海量日志数据进行高效收集.聚合.移动,最后存储到一个中心化数据存储系统中.由原来的Fl ...

  8. 嵌入式操作系统VxWorks中网络协议存储池原理及实现

    嵌入式操作系统VxWorks中网络协议存储池原理及实现 周卫东 蔺妍 刘利强 (哈尔滨工程大学自动化学院,黑龙江 哈尔滨,150001) 摘  要  本文讨论了网络协议存储池的基本原理和在嵌入式操作系 ...

  9. atitit.html编辑器的设计要点与框架选型 attilax总结

    atitit.html编辑器的设计要点与框架选型 attilax总结 1. html编辑器的设计要求1 1.1. 障碍訪问 1 1.2. 强大Ajax上传 1 1.3. Word完美支持 2 1.4. ...

随机推荐

  1. CSS中的字体属性和文本属性

    1.CSS字体的属性 font 简写,作用是把所有的针对字体的属性设置在一个声明中 font-family 设置字体系列 font-size 设置字体尺寸 font-style 设置字体风格,ital ...

  2. python数据类型之元组、字典、集合

    python数据类型元组.字典.集合 元组 python的元组与列表类似,不同的是元组是不可变的数据类型.元组使用小括号,列表使用方括号.当元组里只有一个元素是必须要加逗号: >>> ...

  3. 【三思笔记】 全面学习Oracle分区表及分区索引

    [三思笔记]全面学习Oracle分区表及分区索引 2008-04-15 关于分区表和分区索引(About PartitionedTables and Indexes) 对于 10gR2 而言,基本上可 ...

  4. xBIM IFC 层次结构

    目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...

  5. CF798E. Mike and code of a permutation [拓扑排序 线段树]

    CF798E. Mike and code of a permutation 题意: 排列p,编码了一个序列a.对于每个i,找到第一个\(p_j > p_i\)并且未被标记的j,标记这个j并\( ...

  6. BZOJ 1415: [Noi2005]聪聪和可可 [DP 概率]

    传送门 题意:小兔子乖乖~~~ 题意·真:无向图吗,聪抓可,每个时间聪先走可后走,聪一次可以走两步,朝着里可最近且点编号最小的方向:可一次只一步,等概率走向相邻的点或不走 求聪抓住可的期望时间 和游走 ...

  7. POJ 1222 EXTENDED LIGHTS OUT [高斯消元XOR]

    题意: $5*6$网格里有一些灯告诉你一开始开关状态,按一盏灯会改变它及其上下左右的状态,问最后全熄灭需要按那些灯,保证有解 经典问题 一盏灯最多会被按一次,并且有很明显的异或性质 一个灯作为一个方程 ...

  8. Redis服务器启动之后3个警告信息的解决方案

    今天是年前最后一篇文章了,不想写太多的东西,就写一些有关Redis相关问题的解决方案.当我们启动了Redis服务器之后,会看到3个警告,如果没看到,那是很好的,但是我看到了.看到了就不能不管,所以就好 ...

  9. Selenium+PhantomJS实现简易有道翻译爬虫

    Selenium一款自动化测试工具,当然用来写爬虫也是没有问题的.它支持Chrome.Safari.Firefox等主流界面式浏览器,另外它也支持多种语言开发,比如 Java,C,Ruby,Pytho ...

  10. 使用 RxJS 实现一个简易的仿 Elm 架构应用

    使用 RxJS 实现一个简易的仿 Elm 架构应用 标签(空格分隔): 前端 什么是 Elm 架构 Elm 架构是一种使用 Elm 语言编写 Web 前端应用的简单架构,在代码模块化.代码重用以及测试 ...