zoukankan      html  css  js  c++  java
  • Linux input子系统实例分析(一)

    这是一个简单的输入设备驱动实例。这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理。该实例的代码如下:
     
     
       1:  #include <linux/module.h>
       2:  #include <linux/init.h>
       3:  #include <linux/fs.h>
       4:  #include <linux/interrupt.h>
       5:  #include <linux/irq.h>
       6:  #include <linux/sched.h>
       7:  #include <linux/spinlock.h>
       8:  #include <linux/pm.h>
       9:  #include <linux/slab.h>
      10:  #include <linux/sysctl.h>
      11:  #include <linux/proc_fs.h>
      12:  #include <linux/delay.h>
      13:  #include <linux/platform_device.h>
      14:  #include <linux/input.h>
      15:  #include <linux/workqueue.h>
      16:  #include <linux/gpio.h>
      17:   
      18:   
      19:  #define gpio_key        32*4+30 //PD(30) 即将使用的gpio
      20:  #define DEV_NAME         "gpio_key"
      21:   
      22:  int g_irq = -1;                    //中断号
      23:  static struct input_dev *button_dev;  //输入子系统设备结构
      24:   
      25:   
      26:  //中断处理函数
      27:  static irqreturn_t button_interrupt(int irq, void *p)
      28:  {
      29:      /*get pin value <down 0, up 1> */
      30:   
      31:      int val = gpio_get_value(gpio_key);
      32:   
      33:      input_report_key(button_dev, KEY_1, val);
      34:   
      35:      input_sync(button_dev);
      36:   
      37:      return IRQ_RETVAL(IRQ_HANDLED);
      38:  }
      39:   
      40:   
      41:   
      42:  static int __init button_init(void)
      43:  {
      44:      int irq = -1, err = -1;
      45:      unsigned long irqflags;
      46:      //申请gpio
      47:      err = gpio_request(gpio_key, "test_key");
      48:      if(err < 0){
      49:          printk("request gpio[%d] failed...
    ", gpio_key);
      50:          goto end1;
      51:      }
      52:      
      53:      //gpio输入
      54:      err = gpio_direction_input(gpio_key);
      55:      if (err < 0) {
      56:          //dev_err(dev, "failed to configure"
      57:          //    " direction for GPIO %d, error %d
    ",
      58:          //    gpio_key, error);
      59:          goto end2;
      60:      }
      61:      //申请gpio中断号
      62:      g_irq = (irq = gpio_to_irq(gpio_key));
      63:      if (irq < 0) {
      64:          err = irq;
      65:          //dev_err(dev, "Unable to get irq number for GPIO %d, error %d
    ",
      66:          //    gpio_key, irq);
      67:          goto end2;
      68:      }
      69:      //中断类型
      70:      irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
      71:      /* 申请中断 */
      72:      if (request_irq(irq, button_interrupt, irqflags, DEV_NAME, NULL)) {
      73:   
      74:          printk(KERN_ERR"cannotallocate irq");
      75:          err= -EBUSY;
      76:          goto end2;
      77:      }
      78:   
      79:      /*分配input_dev */
      80:      button_dev = input_allocate_device();
      81:      if (button_dev == NULL) {
      82:          printk(KERN_ERR "notenough memory
    ");
      83:          err= - ENOMEM;
      84:          goto end3;
      85:   
      86:      }
      87:      /*设置输入设备支持的事件类型和事件代码 */
      88:      button_dev->name = "key_gpio";
      89:      set_bit(EV_KEY, button_dev->evbit);
      90:      set_bit(KEY_1, button_dev->keybit);
      91:      
      92:      /*把输入设备注册进核心层 */
      93:      err = input_register_device(button_dev);
      94:      if(err) {
      95:          printk(KERN_ERR "failedto register device
    ");
      96:          goto end4;
      97:      }
      98:   
      99:      printk("initialized
    ");
     100:      return 0;
     101:   
     102:  end4:
     103:      input_free_device(button_dev);
     104:  end3:
     105:      free_irq(irq, NULL);
     106:  end2:
     107:      gpio_free(gpio_key);
     108:  end1:
     109:      return err;
     110:   
     111:  }
     112:   
     113:   
     114:   
     115:  static void __exit button_exit(void)
     116:  {
     117:      input_unregister_device(button_dev);
     118:       input_free_device(button_dev);
     119:   
     120:      gpio_free(gpio_key);
     121:      free_irq(g_irq, NULL);
     122:  }
     123:   
     124:   
     125:   
     126:  module_init(button_init);
     127:  module_exit(button_exit);
     128:   
     129:  MODULE_LICENSE("GPL");
     130:  MODULE_AUTHOR("xuyonghong@duotin.com>");
     131:   
     132:   
     133:   
     134:   
     135:   
     136:   
     
    当编译进内核烧写板子后可以看到相应的设备文件:

    root@CarRadio:/sys/devices# ls virtual/input/input2/
    capabilities  id            name          power         subsystem     uniq
    event2        modalias      phys          properties    uevent
    root@CarRadio:/sys/devices# cat virtual/input/input2/name
    key_gpio
    root@CarRadio:/sys/devices#

    这样就可以监控event2来捕捉按键

    root@CarRadio:/# ls dev/input/event2
    dev/input/event2
    root@CarRadio:/#

     

    驱动分析:

    1.申请gpio

    gpio_request(gpio_key, "test_key");

    2.设置为gpio输入模式

    gpio_direction_input(gpio_key);

    3.申请gpio中断号,注册中断

    //申请gpio中断号 g_irq = (irq = gpio_to_irq(gpio_key));

    /* 申请中断 */
    request_irq(irq, button_interrupt, irqflags, DEV_NAME, NULL);

    4.分配input_dev设备

    /*分配input_dev */
    button_dev = input_allocate_device();

    5.把输入设备注册进核心层

    input_register_device(button_dev);

     

     

  • 相关阅读:
    linux openssh 升级
    局域网从另一台电脑copy文件(Linux系统下)
    单例模式
    6、android传递数据之剪切板传递数据
    5、android使用意图传递数据之全局变量传递
    4、android生命周期的介绍
    3、android搭建开发环境介绍
    2、android系统框架的介绍
    1、安卓学习线路图
    7、开发有状态bean
  • 原文地址:https://www.cnblogs.com/xuyh/p/4989077.html
Copyright © 2011-2022 走看看