Linux设备驱动四 (1)中断上半部分

        1、注册中断处理函数


        int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id)
        使用:将中断号irq与中断处理函数handler对应
        参数:

        irq:指定要分配的中断号(参考芯片手册)。

            注意,不管是单独占有中断请求线的中断,还是共享中断请求线的每个中断,都有一个对应的中断号。所以,调用该函数不需要考虑是哪种中断(是否共享寄存器),你想哪种中断响应,你就填对应的中断号。

        handler:   中断处理函数指针

        irqflags:   中断处理标记,待会介绍:

        devname:该字符串将显示在/proc/irq和/pro/interrupt中。

        dev_id:    ID 号

        返回值:成功返回0,失败返回非0

        2) 中断处理标志irqflags
        /*linux-2.6.29/include/linux/interrupt.h*/
        #define IRQF_TRIGGER_NONE 0x00000000
        #define IRQF_TRIGGER_RISING 0x00000001        //上升沿触发中断
        #define IRQF_TRIGGER_FALLING 0x00000002      //下降沿触发中断
        #define IRQF_TRIGGER_HIGH 0x00000004           //高电平触发中断
        #define IRQF_TRIGGER_LOW 0x00000008           //低电平触发中断
        #define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
        #define IRQF_TRIGGER_PROBE 0x00000010

        SA_INTERRUPT:这个标志表明该中断处理程序是一个快速中断处理程序。过去,linux系统会区分快速我慢速中断,但现在这个标志只有这样的效果:当响应这个中断时,禁止所有的中断,是该中断处理函数不会被其他中断打断,迅速执行。
        SA_SAMPLE_RANDOM:这个标志表明产生的中断会对内核的entropy pool有贡献。Entropy pool负责产生随机数。
        SA_SHIRQ:这个标志表明多个中断处理程序可以共享一个中断号, 在ARM下SA_SHIRQ相当于标志IRQF_SHARED;设置此位可以实现多个驱动共享一个中断

        共享中断:

        有时候会有这样的情况,如果开发板上按键的中断已经被另外的驱动程序注册中断了,而我现在又想再注册一次这个中断,这就出现了一个中断号不止对应一个中断函数的情况。注意,这里与硬件上的共享中断不一样,这里是指,当一个中断信号来了,基于操作系统,一个中断的到来可以调用多个中断处理程序,与硬件无关。


        代码:

        /*******************************************存放按键信息结构体*******************************************/
        /* 定义结构体类型,由它把按钮中断的信息综合起来 */
        struct button_irq_desc 
        {
            int irq;                      /* 按键对应的中断号            */
            int pin;              /* 按键所对应的 GPIO 端口  */
            int number;      /* 键值,传递给应用层           */
            char *name;      /* 按键名称                         */
        };
        /* 结构体实体定义 */
        static struct button_irq_desc button_irqs[] =
        {
            {HI3520D_IRQ_GPIO0, HI35XX_GPIO_PORT0*10+HI35XX_GPIO_PIN6, 1, "test-key1"},
            {HI3520D_IRQ_GPIO0, HI35XX_GPIO_PORT0*10+HI35XX_GPIO_PIN7, 2, "test-key2"},
        };

        /* 存放按键的值 copy_to_user(buff, &key, min(sizeof(key),count)中调用 */
        static char key[2] = {0, 0};
        /*******************************************存放按键信息结构体*******************************************/

        request_irq(button_irqs[0].irq, button_dev_irq_interrupt, IRQF_SHARED, button_irqs[0].name, (void *)&button_irqs);


        2、释放中断处理函数
        void free_irq(unsigned int irq, void *dev_id)

        代码:

        free_irq(button_irqs[0].irq, (void *)&button_irqs);


        3、中断处理函数声明如下
        static irqreturn_t button_dev_irq_interrupt(int irq, void *dev_id)

        第一个参数irq,这是调用中断处理函数时传给它的中断号,对于新版本的内核,这个参数已经用处不大,一般只用于打印。

        第二个参数dev_id, 这个参数与request_irq()的参数dev_id一致

        返回值,中断处理函数的返回值有三个:
        /*linux-2.6.29/include/linux/interrupt..h*/
        #define  IRQ_NONE (0)                   //如果产生的中断并不会执行该中断处理函数时返回该值
        #define  IRQ_HANDLED (1)             //中断处理函数正确调用会返回
        #define  IRQ_RETVAL(x) ((x) != 0)   //指定返回的数值,如果非0,返回IRQ_HADLER,否则
        #difndef IRQ_NONE                       //返回IRQ_NONE。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值