日期:2014-05-16 浏览次数:20657 次
在前面的这篇文章linux内核分析--中断的分类讲解了关于中断的基本概念,从宏观的角度了解了中断的基本知识。从这篇文章中要明白几点知识
1、中断是由硬件产生的异步中断,而异常则是处理器产生的同步中断
2、中断质上是一种特殊的电信号,由硬件设备发向处理器,处理器接收到中断后,会马上向操作系统反应此信号的带来,然后就由OS负责处理这些新到来的数据,中断可以随时发生,才不用操心与处理器的时间同步问题。不同的设备对应的中断不同,他们之间的不同从操作系统级来看,差别就在于一个数字标识-----中断号。专业一点就叫中断请求(IRQ)线,通常IRQ都是一些数值量。有些体系结构上,中断好是固定的,有的是动态分配的,这不是问题所在,问题在于特定的中断总是与特定的设备相关联,并且内核要知道这些信息,这才是最关键的,
3、中断产生告诉中断控制器,继续告诉操作系统内核,内核总是要处理的,是不?这里内核会执行一个叫做中断处理程序或中断处理例程的函数。这里特别要说明,中断处理程序是和特定中断相关联的,而不是和设备相关联,如果一个设备可以产生很多中断,这时该设备的驱动程序也就需要准备多个这样的函数。一个中断处理程序是设备驱动程序的一部分,在接下来的文章中会介绍关于如何注册中断。前边说过一个问题:中断是可能随时发生的,因此必须要保证中断处理程序也能随时执行,中断处理程序也要尽可能的快速执行,只有这样才能保证尽可能快地恢复中断代码的执行。
4、为了达到第三步的条件,尽可能让中断处理程序快速执行结束。将中断处理切为两个部分或两半。中断处理程序上半部(top half)---接收到一个中断,它就立即开始开始执行,但只做严格时限的工作,这些工作都是在所有中断被禁止的情况下完成的。同时,能够被允许稍后完成的工作推迟到下半部(bottom half)去,此后,下半部会被执行,通常情况下,下半部都会在中断处理程序返回时立即执行。linux内核分析--为什么把中断分为上半部和下半步这篇文章讲解了其中的原因
下面进入今天的正题:
int request_irq(unsigned int irq,irqreturn_t (*handler)(int, void *,struct pt_regs *),unsigned long irqflags,const char * devname,void *dev_id)
void free_irq(unsigned int irq, void *dev_id)
static irqreturn_t intr_handler(int irq, void *dev_id, struct pt_regs *regs)
下面要说到的一个问题是和共享的中断处理程序相关的。共享和非共享在注册和运行方式上比较相似的。差异主要有以下几点:
1.request_irq()的参数flags必须设置为SA_SHIRQ标志。 2.对每个注册的中断处理来说,dev_id参数必须唯一。指向任一设备结构的指针就可以满足这一要求。通常会选择设备结构,因为它是唯一的,而且中 断处理程序可能会用到它,不能给共享的处理程序传递NULL值。 3.中断处理程序必须能够区分它的设备是否真的产生了中断。这既需要硬件的支持,也需要处理程序有相关的处理逻辑。如果硬件不支持这一功能,那中 断处理程序肯定会束手无策,它根本没法知道到底是否与它对应的设备发生了中断,还是共享这条中断线的其他设备发出了中断。 |