这是一个简单的输入设备驱动实例。这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理。该实例的代码如下:
 
 
   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. 【LeetCode】String to Integer (atoi)(字符串转换整数 (atoi))

    这道题是LeetCode里的第8道题. 题目要求: 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们 ...

  2. POJ-2318 TOYS,暴力+叉积判断!

                                                                 TOYS 2页的提交记录终于搞明白了. 题意:一个盒子由n块挡板分成n+1块区 ...

  3. linux删除N天前的文件

    列出一天之前的文件的属性用下面的命令:find . ! -mtime -1 -print |xargs ls -lfind . -mtime +1 要删除文件的话用下面的命令:find . ! -mt ...

  4. [UOJ#219][BZOJ4650][Noi2016]优秀的拆分

    [UOJ#219][BZOJ4650][Noi2016]优秀的拆分 试题描述 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 A 和 B 是任意非空字符串,则我们称该字符串的这种拆分是优秀 ...

  5. [BZOJ1594] [Usaco2008 Jan]猜数游戏(二分 + 并查集)

    传送门 题中重要信息,每堆草的数量都不一样. 可以思考一下,什么情况下才会出现矛盾. 1.如果两个区间的最小值一样,但是这两个区间没有交集,那么就出现矛盾. 2.如果两个区间的最小值一样,并且这两个区 ...

  6. NOIP 前夕 模板整理

    归并排序: #include<iostream> #include<cstdio> #include<cstring> using namespace std; ] ...

  7. 标准C程序设计七---04

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  8. Python入门--4--分之和循环

    1.用ELIF比较省CPU: 第一种方法,使用if score = int(input('请输入你的分数:')) if (score <= 100) and (score >= 90): ...

  9. Jsp中路径问题

    ${pageContext.request.contextPath}”的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的. <!--使用绝对路径的方式引入CSS文件-->& ...

  10. 代码布局relativeLayout

    后台布局   在ANDROID 开发中有时候我们需要在后台添加布局文件这里我们来说一下后台添加RelativeLayout文件的方式: RelativeLayout,顾名思义,就是以“相对”位置/对齐 ...