Chinaunix首页 | 论坛 | 博客
  • 博客访问: 375976
  • 博文数量: 96
  • 博客积分: 647
  • 博客等级: 上士
  • 技术积分: 490
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-29 22:15
文章分类
文章存档

2015年(1)

2014年(10)

2013年(26)

2012年(59)

我的朋友

分类: LINUX

2013-03-13 15:12:06

原文地址:linux内核中断机制 作者:HYYLINUX

原文地址:http://blog.csdn.net/jianchi88/article/details/6857773

为什么需要中断?

1)外设的处理速度一般慢于CPU

2CPU不能一直等外部事件

所以设备必须有一种方法来通知CPU它的工作进度,这就是中断。

Linux驱动程序中,为设备实现一个中断

步骤:

1)向内核注册中断

2)实现中断处理函数


CPU如何识别中断:

   在Intel X86中可以支持256中向量中断,为了使处理器能使别每种中断源,给它们进行了编号----->叫做中断向量 


这些中断向量在Linux中的分配:

1)编号0~31的向量对应于异常和非屏蔽中断

2)编号32~47的向量(即由IO设备引起的中断)分配给屏蔽中断。

3)编号48~255的向量用来标示软中断。

Linux用其中的128或0x80来实现系统调用, 非屏蔽中断的向量和异常的向量是固定的。


异常和中断的区别:

1)异常:是指CPU内部出现的中断,即在CPU执行特定指令时出现的非法情况。同时异常也称为同步中断,因此只有在一条指令执行后才会发出中断 ,不可能在指令执行期间发生异常。

     a.产生的原因:

              程序的错误产生的(eg:除数为0)

              内核必须处理的异常条件产生的(eg:缺页)

     b.异常又分为故障和陷阱,它们都不使用中断控制器,也不能被屏蔽

     c. X86处理处理器中大约有20中异常。Linux内核必须为每种异常提供一个专门的异常处理程序。

2)中断:也称为异步中断。因此它是由其他硬件设备依照 CPU 时钟信号随机产生,即意味着中断能在指令之间发生。

     a.中断又分为外部可屏蔽中断(INTR)和外部非屏蔽中断(NMI)

         所用I0设备产生的中断请求均引起可屏蔽中断

         硬件故障引起的故障则产生非屏蔽中断。

说明:

在CPU执行一个异常处理程序时,就不再响应其他异常和中断请求服务.那么如果此时发生了一个异常,CPU不能去响应它,又不能把它的信息丢失该怎么办呢?

这是就用到了堆栈,把所有的信息压入栈。等当前异常处理后,才从堆栈中取出信息再响应刚才的异常。(当产生多个非屏蔽中断时,CPU的处理方法同上)


中断注册

int request_irq ( unsigned int irq, void (*handler)(int, void*, struct pt_regs *)

                  , unsigned long flags , const char *devname , void *dev_id )

返回0表示成功,或者返回一个错误码

参数:

irq:中断号

handler:中断处理函数 指针

flags:与中断管理有关的各种选项

devname:设备名

dev_id:共享中断时使用

flags参数中,可以选择一些与中断管理有关的选项

   如:

      IRQF_DISABLED(SA_INTERRUPT)

    如果设置该位,表示是一个“快速”中断处理程序

    如果没有,表示是一个“慢速”中断处理程序

   IRQF_SHARED(SA_SHIRQ)

    该位表示中断可以在设备间共享

    快速中断不允许中断嵌套(不被打断)

    慢速中断可以中断嵌套,其它类型的中断可以得到服务(默认)

dev_id共享中断

  共享中断就是将不同的设备挂到同一个中断信号线上。

Linux对共享的支持主要是为PCI设备服务

共享中断也是通过request_irq函数来注册的,但有三个特别之处:

1)申请共享中断时,必须在flags参数中指定IRQF_SHARED

2)dev_id参数必须是唯一的

   为什么要唯一?

   在释放中断时要void free_irq()不然内核不知道你要释放哪个设备(共享中断时有不只一个设备在用这个中断)

3)不能使用disable_irq(unsigned int irq)(这个函数是禁止中断的)

   为什么?

   如果使用了,共享中断信号线的设备同样无法使用中断,也就是无法正常工作了。

中断处理程序

   中断处理程序是中断上下文件中运行的,所以它的行为受到某些限制:

     1)不能向用户空间发送或者接受数据

     2)不能使用可能引起阻塞的函数

     3)不能使用可能引起调度的函数

中断函数实现流程:

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);
 /*中断处理,通常是数据接收*/
  .........
 /*唤醒等待数据的进程*/
  wake_up_interruptible(&short_queue);
}

释放中断

void free_irq(unsigned int irq, void *dev_id);


阅读(1794) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~