【问题标题】:Custom interrupt handler for user button on beagleboardbeagleboard 上用户按钮的自定义中断处理程序
【发布时间】:2013-11-18 23:17:47
【问题描述】:

我是内核模块开发的新手。我正在编写一个内核模块来处理用户按钮按下。按下用户按钮后,我需要在 LED 上发光。我如何为用户按钮编写自定义处理程序,因为它最初是由内核模块获取的。我是否需要在内核配置中禁用 GPIO 按钮并编写一个完整的模块,或者我可以注册我的自定义处理程序?

【问题讨论】:

    标签: user-controls beagleboard interrupt-handling led gpio


    【解决方案1】:

    您首先需要从内核中删除模块 gpio_keys。 为此使用 rmmod 命令 - $> rmmod gpio_keys

    我不确定中断按钮上的 LED 是否发光,但我可以使用以下代码处理中断按钮:

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/gpio.h>
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    #include <asm/io.h>
    #include <linux/types.h>
    #include <asm/uaccess.h>
    #include <asm/gpio.h>
    #include <linux/platform_device.h>
    #include <linux/fs.h>
    #include <linux/errno.h>
    #include <linux/proc_fs.h>
    #include<linux/sched.h>
    
    #define GPIO 4
    
    int var;
    
    static irqreturn_t irq_handler(int irq, void *dev_id,struct pt_regs *regs)
    {
        var++;
        printk("In the Interrupt handler, Count: %d\n", var);
    
        return IRQ_HANDLED;
    }
    
    int read_proc(char *buf,char **start,off_t offset,int count,int *eof,void *data )
    {
       int len=0;
       if(offset>0)
       {len=0;}
       else{len  += sprintf(buf, "No of times button pressed: %d\n",++var);}
       return len;
    }
    
    void create_new_proc_entry()
    {
      create_proc_read_entry("hello",0,NULL,read_proc,NULL);
    }
    
    static int __init hello_init(void)
    {
           int errno = 0;
           printk("Hello: registered module successfully!\n");
    
           create_new_proc_entry();
    
          if((errno = gpio_direction_input(GPIO)) !=0)
          {
             printk(KERN_INFO "Can't set GPIO direction, error %i\n", errno);
             gpio_free(GPIO);
             return -EINVAL;
          }
           int irq_line = gpio_to_irq(GPIO);
           printk ("IRQ Line is %d \n",irq_line);
    
           errno = request_irq( irq_line, irq_handler, IRQF_TRIGGER_FALLING, "Interrupt", NULL );
          if(errno<0)
           {
             printk(KERN_INFO "Problem requesting IRQ, error %i\n", errno);
           }
           return 0;
    }
    
    
    static void __exit hello_exit(void)
    {
      printk ("Unloading my module.\n");
      remove_proc_entry("hello",NULL);
      int irq_line = gpio_to_irq(GPIO);
      free_irq(irq_line,NULL);
      printk("Hello Example Exit\n");
      return;
    }
    
    
    
    module_init(hello_init);
    module_exit(hello_exit);
    
    // do some kernel module documentation
    MODULE_AUTHOR("Deadman");
    MODULE_DESCRIPTION("Interrupt Module");
    MODULE_LICENSE("GPL");
    

    您可以忽略上面与 proc 文件系统相关的调用。只需检查中断处理函数。这段代码对我来说很好用。

    此外,如果您想在中断处理期间使用信号量或任何额外工作 - 请点击此链接创建小任务 -

    http://www.ibm.com/developerworks/library/l-tasklets/
    

    基本上你可能想在你的中断处理程序代码中调用 tasklet_schedule。

    希望这会有所帮助。

    【讨论】:

    • 如果我们可以移除 gpio_keys 模块,这意味着它是一个动态模块。在那种情况下,用这个模块获取的 LED 也被释放了?如果我错了,请纠正我。
    • 好吧,我不确定。我出于其他目的编写了上面的代码,我不得不删除 gpio_keys 来处理中断按钮。虽然我不知道 LED。我很确定您可以使用此代码处理中断。
    猜你喜欢
    • 2013-03-30
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多