linux 中断处理

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)

相关文章
相关标签/搜索