中断与轮询

  1. 轮询与中断
    外部设备与中央处理器交互一般有两种手段:轮询和中断。
    (1)轮询(Polling)
    很多I/O设备都有一个状态寄存器,用于描述设备当前的工作状态,每当设备状态发生改变时,设备将修改相应状态寄存器位。通过不断查询设备的状态寄存器,CPU就可以了解设备的状态,从而进行必要的I/O操作。为了节约CPU资源,查询工作往往不是连续的,而是定时进行。
    轮询方式具有简单、易实现、易控制等优势,在很多小型系统中有大量应用。对那些实时敏感性不高、具有大量CPU资源的系统来说,轮询方式有很广泛的应用。最典型的用途就是在那些任务比较单一的单片机上,嵌入式系统中也有应用。
    轮询的一种典型的实现可能是这样的:while(TRUE){// select(,,timeout); //};当然这里的select()也可以使用poll()替换。
    轮询方式主要存在以下不足:
    <1>增加系统开销。无论是任务轮询还是定时器轮询都需要消耗对应的系统资源。
    <2>无法及时感知设备状态变化。在轮询间隔内的设备状态变化只有在下次轮询时才能被发现,这将无法满足对实时性敏感的应用场合。
    <3>浪费CPU资源。无论设备是否发生状态改变,轮询总在进行。在实际情况中,大多数设备的状态改变通常不会那么频繁,轮询空转将白白浪费CPU时间片。
    (2)中断(Interrupt)
    中断,顾名思义,就是打断正在进行中的工作。中断不需要处理器轮询设备的状态,设备在自己发生状态改变时将主动发送一个信号给处理器(PIC),后者在接收到这一通知信号时,会挂起当前正在执行的任务转而去处理响应外设的中断请求。中断通知机制通过硬件信号异步唤起处理器的注意,解决了外部设备与处理器之间速度不匹配导致的资源浪费问题。
    现代设备绝大多数采用中断的方式与处理器进行沟通,因此设备驱动程序必须能够支持设备的中断特性。处理器在中断到达时会根据不同的中断号找到对应设备(IRR),并对中断请求进行响应处理。中断处理例程ISR(Interrupt Service Routine)由设备驱动程序提供,并在设备驱动模块初始化时注册到系统中断向量表中。从设备发出中断信号,到处理器最终调用ISR进行处理,期间会经过很多步骤,这个过程构成了中断处理框架。中断处理框架包括了进入ISR之前的很多进入路径(entry path),例如MIPS下要经历这样几个步骤:设置或屏蔽相关寄存器;进入异常入口点取指;现场保护;异常分类(MIPS下中断也是一种异常)处理;查找中断向量表路由ISR。不同的操作系统对中断处理框架的设计不尽相同,但是要达到的目的是一样的,那就是最终调用用户注册的设备ISR。
    (3)中断与轮询的折衷
    虽然轮询方式存在空转损耗导致名声不佳,但并非一无是处。中断模型也并非十全十美,其高优先级的VIP待遇和快速响应要求在极端条件下将造成“活锁”效应。有时候需要发挥粗暴中断和温和轮询各自的优势,根据实际应用情景,在两种模式之间切换。手机导航杆卡死情形的处理是个很好的案例。
    在过去的一些手机和PDA设备上安装有导航杆,它支持3种动作(顺时针旋转、逆时针旋转和按键),可方便菜单导航。导航杆的三种动作都会向处理器发出中断。系统中通用的目的I/O(GPIO)端口和导航杆连接。中断处理函数的工作就是查看GPIO数据寄存器解析出导航杆运动。假定导航杆由于存在运动部件(如旋轮偶尔被卡住)引起的固有的硬件问题,从而在GPIO端口产生不同于方波的波形。被卡住的旋轮会不停地产生假的中断,并可能使系统冻结。为了解决这个问题,可以捕获波形分析,在卡住的情况下动态地从中断模式切换到轮询模式。如果旋轮恢复正常,再动态地从轮询模式切换到中断模式,软件也恢复正常模式。
    在本文的最后,将介绍Linux网络设备驱动模型中的NAPI机制 ,它采用“中断+轮询”的处理方式代替纯中断处理方式,是中断和轮询的完美合体。
  2. 中断向量表
    中断向量表其实是处理器内部的概念,因为处理器除了会被外部设备中断外,其内部也可能产生异常等事件,例如在MIPS中,中断只是异常的一种。当这些事件发生时,CPU必须暂停手头上的工作,转而去处理中断或异常,因此处理器需要知道到哪里去获得这些中断或异常的处理函数的目标地址。中断向量表就是用来解决这个问题,其中每一项都是一个中断或异常处理函数的入口地址,具体来说4个字节的函数指针将指向一段汇编微码(intConnectCode)执行跳转。
    外部设备的中断常常对应向量表中的某一项,这是通用框架的外部中断处理函数入口,因此在进入通用的中断处理函数之后,系统必须知道正在处理的中断是哪一个设备产生的,而这正是由软件中断号irq定的决。中断向量表的内容是由操作系统在初始化阶段来填写,对于外部中断,操作系统负责实现一个通用的外部中断处理函数,然后把这个函数的入口地址放到中断向量表中的对应位置。用户注册设备驱动ISR,实际上就是挂接到中断向量表中,覆盖某一项的默认处理实现特化。

参考:
《深入Linux内核架构》
《精通Linux设备驱动程序开发》
《深入Linux设备驱动程序内核机制》

《中断和中断处理》
《Linux中的中断处理分析》
《PCI 中断路由机制》
《linux内核研究-3-中断》
《IA32上Linux内核中断机制分析》
《linux内核中断 - tasklet 分析》
《Linux 内核软中断(softirq)执行分析》
《基于VxWorks的多路高速串口的通信方法设计》
《NAPI模式–中断和轮询的折中以及一个负载均衡的问题》

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值