首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

内核驱动:中断机制(2)

内核驱动:中断机制(2)

中断处理函数的编写与注册
驱动人员在设计中断处理函数时,要遵循的要求是:
(1)可嵌套不可重入
(2)不能睡眠
(3)如果硬件有中断的状态寄存器,软件要负责清除中断的标志位。一般来说,如果不清除标志位,设备无法再次产生中断
(4)中断处理函数的注册和注销
0.前提
  需要包含的头文件
  #include <linux/interrupt.h>
  #include <mach/irqs.h> //片内外设
  #include <linux/gpio.h> //片外外设
  #include <mach/gpio.h>
1.确定中断号
  正如刚才如上所述:如果是外部IO中断,那么我们可以通过GPIO号获取中断号:
  eg:#define KEY_IRQ     gpio_to_irq(gpio号);
2.中断处理函数编写
  中断处理函数的格式:
  eg:
  //参数1:int irq :中断号
  //参数2:void * dev_id :为传递给中断处理函数的参数

  //返回值:IRQ_NONE:中断不是由本设备引起的
                   IRQ_HANDLED:中断是由本设备引起的
  static irqreturn_t  key_service(int irq, void *dev_id)
  {
      //根据硬件要求完成相应工作
      ...
      return IRQ_HANDLED 或 IRQ_NONE;
  }
3.注册中断处理函数(必须检查返回值)
  u32 flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;//定义中断的标志:下降沿/上升沿/低电平/高电平触发中断
      int ret;
      ret = request_irq(  KEY_IRQ, /* 中断号 */
                     key_service, /* 中断处理函数 */
                     flags, /* 中断的标志 */
                      "xxx", /* 中断处理函数的名字 */
                      dev_id);/* dev_id为传给中断处理函数的参数,一般会设置为私有结构体的指针,非共享>中断可以为NULL */


      if (ret) {
            printk("Cannot register interrupt handler\n");
            return -1;
       }
4.注销中断处理函数 
  free_irq(irq, dev_id); //参数为中断号和dev_id。 dev_id一定要和request_irq中的最后一个参数一致

5.屏蔽中断
  1.可以人为关闭(mask)/打开某个中断:
    disable_irq(int irq);
    enable_irq(int irq);
    这两个函数是可以嵌套的,也就是说,如果对一个中断disable了3次,需要调用enable函数3次才能打开对该中断的屏蔽;
  2.还可以屏蔽本cpu的中断:
    local_irq_disable();
    local_irq_enable();
继承事业,薪火相传
返回列表