Linux设备驱动中中断处理相关的首先是申请与释放IRQ的API request_irq()和free_irq()函数
int request_irq(unsigned int irq, //irq是要申请的硬件中断号 void (*handler)(int irq, void *dev_id, struct pt_regs *regs), unsigned long irqflags, const char * devname, //设备名 中断属于哪一个设备的 void *dev_id);
handler是向系统登记的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数
spa
irqflags是中断处理的属性,若设置IRQF_DISABLED,标明中断处理程序是快速处理程序,快速处理程序被调用时屏蔽全部中断,慢速处理程序不屏蔽;若设置IRQF_SHARED,则多个设备共享中断,操作系统
dev_id在中断共享时会用到,通常设置为这个设备的device结构自己或者NULL。code
快速/慢速中断区别orm
快速中断保证中断处理的原子性(不被打断),而慢速中断则不保证。换句话说,也就是“开启中断”标志位(处理器IF)在运行快速中断处理程序时是关闭的,所以在服务该中断时,不会被其余类型的中断打断;而调用慢速中断处理时,其它类型的中断仍能够获得服务,默认状况是慢速中断。进程
共享中断ci
共享中断就是将不一样的设备挂到同一个中断信号线上。Linux对共享的支持主要是为PCI设备服务。共享中断也是经过request_irq函数来注册的,但有三个特别之处:回调函数
1)申请共享中断时,必须在flags参数中指定 IRQF_SHARED位it
2)dev_id参数必须是惟一的。 //由于共享中断 中断号相同,因此须要dev_id来区别是哪一个设备中断class
3)共享中断的处理程序中,不能使用disable_irq(unsigned int irq) ,由于这个会关闭该中断的全部设备
中断处理程序void (*handler)
中断处理程序。特别之处在于中断处理程序是在中断上下文中运行的,它的行为受到某些限制:
1) 不能向用户空间发送或接受数据 由于用户空间和进程对应,进程变了用户空间会变,中断不对应任何进程,不属于 进程
2) 不能使用可能引发阻塞的函数
3) 不能使用可能引发调度的函数 。防止用户空间发生变化
五、 中断处理函数流程
操做系统还有一个进程上下文,如驱动中的读写函数就是进程上下文
用户的应用程序,fread 经过内核 调用 驱动中的.read操做。read是进程主动调用的,属于进程上下文。中断上下文是硬件发出的,不是进程主动调用的。
中断处理函数的流程
void short_sh_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* 判断是不是本设备产生了中断 由于共享中断产生中断会调用该中断号的全部设备 因此每一个设备须要判断是否本身产生 中断,不然处理会出错*/ value = inb(short_base); if (!(value & 0x80)) return; //不是自己设备产生的中断 返回 /* 清除中断位(若是设备支持自动清除,则不须要这步) */ outb(value & 0x7F, short_base); /* 中断处理,一般是数据接收 */ 。。。。。。。。。 /* 唤醒等待数据的进程 */ ake_up_interruptible(&short_queue); //接收数据 可能会阻塞别的进程,因此须要唤醒 }
卸载中断
当设备再也不须要使用中断时(一般在驱动卸载时), 应当把它们返还给系
void free_irq(unsigned int irq, void *dev_id)