这是一个简单的输入设备驱动实例。这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理。该实例的代码如下:
 
 
   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. Chrome 开发者工具(DevTools)中所有快捷方式列表(已整理)

    Chrome 开发者工具(DevTools)中所有快捷方式列表(已整理) 前言 Chrome DevTools提供了一些内置的快捷键,开发者利用这些快捷键可以节省常工作中很多日的开发时间.下面列出了每 ...

  2. 【转】SQL索引一步到位

    原文:http://www.cnblogs.com/AK2012/archive/2013/01/04/2844283.html SQL索引一步到位(此文章为“数据库性能优化二:数据库表优化”附属文章 ...

  3. 【UML】概述以及面向对象技术总结

    导读:结束了软工文档后,就开始了UML的学习,不管学习什么,都要先从整体上去把握,然后再从细节上去分析理解.在视频的开头,就对UML进行了概述.然后接着讲了面向对象技术,用例图,类图和包图等.看着软工 ...

  4. ps 批量杀死进程

    ps aux | grep xxx |awk '{print $2}'|xargs kill -9

  5. Kubernetes对象

    Kubernetes对象 在之前的文章已经讲到了很多Kubernets对象,包括pod,service,deployment等等.Kubernets对象是一种持久化,表示集群状态的实体.它是一种声明式 ...

  6. 用docker弹性部署自己的服务

    很久不看docker的东西了,之前了解的一些基本命令都忘得差不多了,适逢工作需要,再来复习巩固下.今天想完成的是:借助docker不部署下自己的服务. 环境准备 都说“巧妇难为无米之炊”,所以还是需要 ...

  7. 刷题总结——郁闷的出纳员(bzoj1503)

    题目: 题目背景 NOI2004 DAY1 T1 题目描述 OIER 公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是 ...

  8. 【二叉树】hdu 1622 Trees on the level

    [题意] 给定一棵树每个结点的权重和路径(路径用LR串表示),输出这棵树的层次遍历 [思路] 注意输入输出,sscanf用来格式化地截取需要的数据,strchr来在字符串中查找字符的位置 [Accep ...

  9. 等价表达式(codevs 1107 答案错误)

    题目描述 Description 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...

  10. HTML 文档之 Head 最佳实践--摘抄

    HTML 文档之 Head 最佳实践 story 01-10 阅读 353 收藏 0 收藏 这篇文章整理了作者认可的一些最佳实践,写在这里与各位分享 阅读原文折叠收起 HTML 文档之 Head 最佳 ...