LINUX系统中断系统学习心得

一、linux的中断处理体系结构

         Linux内核将所有的中断统一编号,使用一个irq_desc结构数组来描述这些中断:每个数组项对应一个中断(也可能是一组中断,他们共用相同的中断号),里面记录了中断的名称、中断状态、中断标记(比如中断类型、是否共享中断等),并提供了中断的底层硬件访问函数(清除、屏蔽、使能中断),提供了这个中断的处理函数入口,通过它可以调用用户注册的中断处理函数。

         通过irq_desc结果结构数组就可以了解中断处理体系结构,irq_desc结构的数据类型在include/linux/irq.h中定义,如下所示:

         Struct irq_desc{

         Irq_flow_handler_t handle_irq;/*当前中断的处理函数入口*/

         Struct irq_chip *chip;/*低层的硬件访问*/

。。。。。。。。。。。。。。。。。。。

         Struct irqaction *action;/*用户提供的中断处理函数链表*/

         Unsigned int status;/*IRQ状态*/

         Const char *name;/*中断名称*/

         }

         其中handle_irq是中断处理函数的入口,chip提供了中断低层寄存器等的操作。

Linux的中断处理体系结构如下图所示:

        

中断函数的处理流程如下所示:

1)在发生中断时,CPU执行异常向量vector_irq的代码

2)在vector_irq里面,最终会调用中断处理的总入口函数asm_do_IRQ;

3)asm_do_IRQ里面,最终会调用irq_desc数组项中的handler_irq。

4)handle_irq会使用chip成员中的函数来设置硬件,比如清除中断、禁止中断、使能中断等

5)handle_irq逐个调用用户在action链表中注册的处理函数

二、中断的实现

对于开发者来说最关心的应该是如何在驱动中实现中断,在linux驱动程序中,为设备实现一个中断一般来说包括两个步骤:

1)向内核注册中断

需要使用函数request_irq向内核中注册中断,其函数原型如下所示:

intrequest_irq(unsigned int irq,void (*handler)(int ,void*,struct pt_regs*),unsigned long flags,const char *devname,void *dev_id)

该函数执行成功则返回0,否则返回一个错误码。

其中的dev_id参数必须唯一,这是为共享中断时使用的。

2)实现中断

实现中断函数需要注意一下情况:中断处理函数运行于中断上下文中,他不能向用户空间发送或者接受数据,不能使用可能引起阻塞或是引起调度的函数,因为引起调度的函数只是相对于进程来说的,而中断函数一旦引起调度,调度函数就再也找不到它了,因为中断程序不是一个进程。

3)释放中断

当设备不再需要使用中断时(通常在驱动卸载时),应当把它们返回给系统,使用:

void free_irq(unsigned intirq,void *dev_id)

由中断的释放函数,可以看出dev_id的作用,如果dev_id不唯一,则不知道释放哪个中断处理函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值