这是一个简单的输入设备驱动实例。这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理。该实例的代码如下:
 
 
   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. Sort a linked list in O(n log n) time using constant space complexity.

    因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想. 归并排序的一般步骤为: 1)将待排序数组(链表)取中点并一分为二: 2)递归地对左半部分进行归并排序: 3)递归地对右半部分进行归并排 ...

  2. Leetcode 407.接雨水

    接雨水 给定一个 m x n 的矩阵,其中的值均为正整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水. 说明: m 和 n 都是小于110的整数.每一个单位的高度都大于0 且小 ...

  3. Django之model admin自定义后台管理

    Admin管理界面是django的杀手级应用.它读取你模式中的元数据,然后提供给你一个强大而且可以使用的界面,网站管理者可以用它立即向网站中添加内容. 比如,数据表如下: from django.db ...

  4. 九度oj 题目1256:找出两个只出现了一次的数字

    题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 输入: 输入的第一行包括一个整数N(1<=N<=1000). 接下来的一行包括N个 ...

  5. Method for Estimating the Number of Concurrent Users

    1. Formula for Estimating the Average Number of Concurrent users We begin by defining what the numbe ...

  6. BZOJ 2190仪仗队【欧拉函数】

    问题的唯一难点就是如何表示队长能看到的人数?如果建系,队长所在的点为(0,0)分析几组数据就一目了然了,如果队长能看到的点为(m,n),那么gcd(m,n)=1即m n 互质或者是(0,1),(1,0 ...

  7. C 语言中的 fgets()

    转自:http://blog.csdn.net/daiyutage/article/details/8540932 原型: char *  fgets(char * s, int n,FILE *st ...

  8. angular实时显示checkbox被选中的元素

    /** * Created by zh on 20/05/15. */ // Code goes here var iApp = angular.module("App", []) ...

  9. 开始学习Objective-C

        加油!     顺便试试这MarsEdit好用不~

  10. Lucene 6.5.0 入门Demo

    Lucene 6.5.0 要求jdk 1.8 1.目录结构: 2.数据库环境: private int id; private String name; private float price; pr ...