zoukankan      html  css  js  c++  java
  • 内核中断过程

    为什么需要中断?

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

    2)CPU不能一直等外部事件

    所以设备必须有一种方法来通知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);
    

      

  • 相关阅读:
    ubuntu 解决“无法获得锁 /var/lib/dpkg/lock -open (11:资源暂时不可用)”的方法
    解决VMware安装ubuntu16.04后无法全屏的问题
    力推:无限制下载神器aria2
    使用Pangolon在同一副图中,画出两个轨迹,比较误差
    Pangolin中opengl的混合(gl_blend)
    Ubuntu 16.04: How to install OpenCV
    ubuntu16.04下安装Eigen
    ubuntu16.04下安装Sophus
    svn删除账户信息
    javaweb乱码(tomcat服务器)
  • 原文地址:https://www.cnblogs.com/still-smile/p/12574633.html
Copyright © 2011-2022 走看看