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

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基础数据类型之集合

    Python基础数据类型之集合 集合(set)是Python基本数据类型之一,它具有天生的去重能力,即集合中的元素不能重复.集合也是无序的,且集合中的元素必须是不可变类型. 一.如何创建一个集合 #1 ...

  2. Mac版有道云笔记不能自动同步

    删除本地资源文件夹 /Users/xxxx/Library/Containers/com.youdao.note.YoudaoNoteMac 直接删除整个文件夹,之后重新登录账号.

  3. apr的使用

    APR(Apache Portable Runtime),即Apache可移植运行库,正如官网所言,APR的使命是创建和维护一套软件库,以便在不同操作系统(Windows.Linux等)底层实现的基础 ...

  4. Bichrome Tree

    Bichrome Tree 时间限制: 1 Sec  内存限制: 128 MB 题目描述 We have a tree with N vertices. Vertex 1 is the root of ...

  5. 【HDOJ5949】Relative atomic mass(签到)

    题意:给定一个只由H.C.O三种分子组成物质的分子式,求相对分子质量 len<=10 思路:队友写的 #include <stdio.h> #include <vector&g ...

  6. hdu4612 无向图中任意添加一条边后使桥的数量最少 / 无向图缩点+求树的直径

    题意如上,含有重边(重边的话,俩个点就可以构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选任意起点U,进行bfs,到达最远的一个点v ...

  7. 有向图tarjan算法求连通分量的粗浅讲解、证明, // hdu1269

    打算开始重新复习一遍相关算法.对于有向图tarjan算法,通过学习过很多说法,结合自己的理解,下面给出算法自己的观点. 算法总模型是一个dfs,结合一个stack(存放当前尚未形成SCC的点集合),记 ...

  8. CentOS 7.3 源码安装 OpenVAS 9

    https://my.oschina.net/u/2613235/blog/1583198

  9. Annotation基本概念,作用以及举例说明。

    Annotation即注解,是Jav5新特征,Annotatio提供一些本来不属于程序的数据,用来将任何的信息或元数据(metadata)与程序元素(类.方法.成员变量等)进行关联.为程序的元素(类. ...

  10. go语言学习之路 二:变量

    说道变量,首先应该提一提关键字,因为不能把关键字当做变量来声明. 关键字: 下面列出GO语言的关键字或保留字: break default func interface select case def ...