这是一个简单的输入设备驱动实例。这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理。该实例的代码如下:
 
 
   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...\n", 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\n",
  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\n",
  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\n");
  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\n");
  96:          goto end4;
  97:      }
  98:   
  99:      printk("initialized\n");
 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 input子系统实例分析(一)的更多相关文章

  1. Linux input子系统实例分析(二)

    紧接着上一节的实例我们来分析调用的input子系统的接口: 1. input_dev,用来标识输入设备 1: struct input_dev { 2: const char *name; //设备名 ...

  2. Linux input子系统分析

    输入输出是用户和产品交互的手段,因此输入驱动开发在Linux驱动开发中很常见.同时,input子系统的分层架构思想在Linux驱动设计中极具代表性和先进性,因此对Linux input子系统进行深入分 ...

  3. Linux Input子系统

    先贴代码: //input.c int input_register_handler(struct input_handler *handler) { //此处省略很多代码 list_for_each ...

  4. Linux Input子系统浅析(二)-- 模拟tp上报键值【转】

    转自:https://blog.csdn.net/xiaopangzi313/article/details/52383226 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...

  5. Linux input子系统 io控制字段【转】

    转自:http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html http://blog.csdn.net/guoshaobei/arc ...

  6. Linux input子系统编程、分析与模板

    输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系 ...

  7. linux input子系统详解

    首先,什么是linux的子系统: 输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如鼠标移动通过Driver->Input core->Event handler- ...

  8. Android驱动之 Linux Input子系统之TP——A/B(Slot)协议

    将A/B协议这部分单独拿出来说一方面是因为这部分内容是比较容易忽视的,周围大多数用到input子系统的开发人员也不甚理解:另一方面是由于这部分知识一旦扩展到TP(触摸屏Touch Panel)的多点触 ...

  9. Linux输入子系统框架分析(1)

    在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...

随机推荐

  1. python-通过openpy操作excel

    1.安装 openpyxl pip install openpyxl == 2.3.5  安装指定版本 遇到问题: 查询结果:这是因为电脑上有其他软件也有pip命令,我的电脑上是因为装了loadrun ...

  2. ubuntu上传项目到github

    https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70544159

  3. zoj 2104 Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2 Seconds      Memory Limit: 65536 KB Contest time again! How excit ...

  4. 牛腩新闻发布系统(三):CSS盒子模型及其基本内容

    导读: 这些天一直在做牛腩的网页,比如什么首页.出错页.新闻内容页等.在学习的不断推进中,一些刚开始理解的不是很好的东西,也逐渐的深刻了起来.下面,就对这一段时间的学习,做一个总结.主要总结内容有:盒 ...

  5. 【bzoj2229】[Zjoi2011]最小割 分治+网络流最小割

    题目描述 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分 ...

  6. 【Luogu】P1972HH的项链(链表+树状数组)

    题目链接 难题,所以会讲得细一些. 首先我们想如何统计区间[l,r]内不同贝壳的个数. 第一个思路就是线段树/树状数组,query(1,r)-query(1,l-1)对不对? 然而这样是不对的. 然后 ...

  7. [luoguP2051] [AHOI2009]中国象棋(DP)

    传送门 注释写明了一切 #include <cstdio> #define N 111 #define p 9999973 #define LL long long int n, m; L ...

  8. 解决PHP无法接收post超过1000个字段的问题

    今天在做与后台交互的的过程中,发现php对于接收的POST有一个限制,超出1000个字段之后便无法接收,项目要求在不改变PHP配置的情况下通过前端方式解决,通过分析并且网上差一些大牛的资料终于找到了解 ...

  9. C/C++怎样传递二维数组,转载自CSDN

    用二维数组作为参数传递(用二维数组处理矩阵),但是希望接受传递二维数组参数的函数可以处理任意维度的数组(希望矩阵的行数和列数都是不固定的). [以下转帖] ---------------------- ...

  10. Linux 系统的常用命令之 rm ,rm -rf , rm -f 以及rm 命令的其他参数命令

    1.rm -rf * 删除当前目录下的所有文件,这个命令很危险,应避免使用. 所删除的文件,一般都不能恢复! 2.rm -f 其中的,f参数 (f --force ) 忽略不存在的文件,不显示任何信息 ...