# 一、input子系统基本框架

Linux内核为了两个目的:

1. 简化纯输入类外设(如:键盘、鼠标、游戏杆、轨迹球、触摸屏。。。等等)的驱动开发

2. 统一输入类外设产生的数据格式(struct input_event),更加方便应用层编程

设计了输入子系统

事件处理层:接收来自核心层上报的事件,并选择对应的handler(事件处理器 struct input_handler)去处理。内核维护着多个事件处理器对象,每个input_handler对象专门处理一类事件,所有产生同类事件的设备驱动共用同一个handler。

设备驱动层:主要实现获取硬件设备的数据信息(包括触摸屏被按下、按下位置、鼠标移动、键盘按下等等),并转换为核心层定义的规范事件后提交给核心层,该层每个设备对应一个struct input_dev对象,

核心层:负责连接设备驱动层和事件处理层,为设备驱动层提供输入设备驱动的接口(struct input_dev)以及输入设备驱动的注册函数(input_register_device),为事件处理层提供输入事件驱动的接口;通知事件处理层对事件进行处理。

# 二、驱动开发步骤

/*init或probe函数中:1. 创建struct input_dev对象input_allocate_device2. 设置事件类型以及相关参数set_bit3. 注册struct input_dev对象input_register_device*//*exit或remove函数中:1. 注销struct input_dev对象input_unregister_device2. 销毁struct input_dev对象input_free_device*//*上报事件两种事件上报方式:1. 对有中断支持的输入设备:在其中断处理函数(上半部或下半部)中上报事件2. 对无中断支持的输入设备:使用workqueue循环定时上报(struct delayed_work)主要函数:input_eventinput_report_absinput_sync*/

相关接口:

/*_init*/struct input_dev *input_allocate_device(void)//创建对象void set_bit(struct input_dev *dev,unsigned long whichbits)//设置事件类型void input_set_abs_params(struct input_dev *dev,unsigned int axis,int min,int max,int fuzz,int flat)int input_register_device(struct input_dev *dev)//注册input设备到内核/*_exit*/void input_unregister_device(struct input_dev *dev)void input_free_device(struct input_dev *dev)/*上报事件*/void input_event(struct input_dev *,unsigned int t,unsigned int c,int v)void input_report_key(struct input_dev *,unsigned int c,int v) //上报按键事件void input_report_abs(struct input_dev *,unsigned int c,int v)//上报绝对坐标事件void input_sync(struct input_dev *)//上报完成后需要调用这些函数来通知系统处理完整事件/*应用层数据类型*/struct input_event {struct timeval time;       // 时间戳__u16 type;             // 事件类型__u16 code;             // 哪个分值__s32 value;            // 具体值      };

# 三、key3-input版代码解析

驱动代码

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/cdev.h>
#include <linux/wait.h>
#include <linux/input.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <asm/uaccess.h>struct fs4412key3_dev
{struct input_dev *pdev;int gpio;int irqno;
};struct fs4412key3_dev *pgmydev = NULL;irqreturn_t key3_irq_handle(int no,void *arg)
{struct fs4412key3_dev *pmydev = (struct fs4412key3_dev *)arg;int status1 = 0;int status2 = 0;status1 = gpio_get_value(pmydev->gpio);mdelay(1);status2 = gpio_get_value(pmydev->gpio);if(status1 != status2){return IRQ_NONE;}if(status2){input_event(pmydev->pdev, EV_KEY, KEY_3, 0);input_sync(pmydev->pdev);}else{input_event(pmydev->pdev, EV_KEY, KEY_3, 1);input_sync(pmydev->pdev);}return IRQ_HANDLED;
}int __init fs4412key3_init(void)
{int ret = 0;struct device_node *pnode = NULL;pnode = of_find_node_by_path("/fs4412-key");if(NULL == pnode){printk("find node failed\n");return -1;}pgmydev = (struct fs4412key3_dev *)kmalloc(sizeof(struct fs4412key3_dev),GFP_KERNEL);if(NULL == pgmydev){printk("kmallc for struct fs4412key3_dev failed\n");return -1;}pgmydev->gpio = of_get_named_gpio(pnode,"key3-gpio",0);pgmydev->irqno = irq_of_parse_and_map(pnode,0);pgmydev->pdev = input_allocate_device();set_bit(EV_KEY, pgmydev->pdev->evbit);set_bit(KEY_3, pgmydev->pdev->keybit);ret = input_register_device(pgmydev->pdev);ret = request_irq(pgmydev->irqno,key3_irq_handle,IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,"fs4412key3",pgmydev);if(ret){printk("request_irq failed\n");input_unregister_device(pgmydev->pdev);input_free_device(pgmydev->pdev);kfree(pgmydev);pgmydev = NULL;return -1;}return 0;
}void __exit fs4412key3_exit(void)
{input_unregister_device(pgmydev->pdev);input_free_device(pgmydev->pdev);kfree(pgmydev);pgmydev = NULL;
}MODULE_LICENSE("GPL");module_init(fs4412key3_init);
module_exit(fs4412key3_exit);

应用测试代码

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <unistd.h>#include <stdio.h>int main(int argc,char *argv[])
{int fd = -1;struct input_event keyevt;if(argc < 2){printf("The argument is too few\n");return 1;}fd = open(argv[1],O_RDONLY);if(fd < 0){printf("open %s failed\n",argv[1]);return 3;}while(1){read(fd, &keyevt, sizeof(keyevt));if(keyevt.type == EV_KEY && keyevt.code == KEY_3){if(keyevt.value){printf("KEY3 DOWN\n");}else{printf("KEY3 UP\n");}}}close(fd);fd = -1;return 0;
}

嵌入式系统驱动高级【5】——input子系统相关推荐

  1. LV.12 嵌入式系统驱动高级

    D1 设备模型 硬编驱动:没有设备树时,硬件资源资源信息和源代码混合在一起 Linux 2.6内核之前是借助devfs 1硬编 Linux 2.6内核之后是总线2驱动式开发 Linux 3.0内核开始 ...

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

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

  3. linux驱动系列学习之input子系统(二)

    一.input子系统简介 linux系统支持的输入设备众多,例如键盘.鼠标.按键.触摸屏等,linux系统通过抽象出一个input子系统去支持众多的输入设备.input子系统分为三层:上层:输入事件处 ...

  4. linux编译input驱动,Linux驱动开发之input子系统

    本文对mousedev.Amimouse和input子系统进行分析,旨在提纲挈领,给出它们之间的调用关系(或者说关联).阅读本文,需要与阅读Linux 2.6内核源码交叉进行,除非你是超人. 背景: ...

  5. LV.11 嵌入式系统驱动初级

    D1 背景.学习方法和环境搭建 计算机系统结构 程序分类 程序按其运行环境分为: 裸机程序:直接运行在对应硬件上的程序 应用程序:只能运行在对应操作系统上的程序 计算机系统的层次结构 无操作系统的简单 ...

  6. linux 驱动 (2)---Linux input子系统最清晰、详尽的分析

    Linux input子系统最清晰.详尽的分析 Linux input分析之二:解构input_handler.input_core.input_device 输入输出是用户和产品交互的手段,因此输入 ...

  7. linux input子系统 pdf,Linux下的Input子系统.pdf

    计 算 机 系 统 应 用 ||ww.c·S-a.org.cn 2013年 第 22卷 第 l2期 Linux下的Input子系统① 朱银瑞,吴庆洪,吴华玲 (辽宁科技大学 电子与信息工程学院,鞍山) ...

  8. Linux input子系统分析

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

  9. input子系统分析(转)

    转自:http://www.linuxidc.com/Linux/2011-09/43187.htm 作者:作者:YAOZHENGUO2006 Input子系统处理输入事务,任何输入设备的驱动程序都可 ...

最新文章

  1. Linux批量查找与替换
  2. JavaScript强化教程-JS面向对象编程
  3. Spring 框架的设计理念与设计模式分析
  4. vim的常用配置及使用方法
  5. 矩阵相乘取共轭_正交矩阵学习小结
  6. 连接数据库时提示归档器失败 ORA-00257: archiver error
  7. php+ioncube',IonCube加密PHP程序
  8. php原生读取excel文件夹,原生php实现excel文件读写的方法分析php技巧
  9. 服务器物理机怎么开,物理机怎么弄云服务器
  10. oracle 多路径 SAN,前言 - Oracle Solaris 管理:SAN 配置和多路径
  11. 免费可商用中文字体打包下载
  12. 关于matlab快速下载
  13. 计算机自动获取ip地址的协议,自动获取ip地址_计算机是如何自动获取的IP地址的...
  14. 普加甘特图数据结构解析
  15. QQ2010登录协议分析-目前可取得sessionkey
  16. IOS - Swift高德地图自定义标注、气泡
  17. Visual Studio如何在一个解决方案下创建多个独立项目并单独运行
  18. SAP 获取本机信息(IP及电脑名称)
  19. NVDLA runtime vp 搭建
  20. Python CSV Reader/Writer

热门文章

  1. html5相对路径写法,相对路径写法
  2. Android自定义Drawable第十五式之啡常OK
  3. pymssql数据库操作
  4. css display:grid布局
  5. MacBook上如何运行那些尚未在Mac App Store 上架的 iOS/iPadOS 应用程序分享
  6. mac 特殊符号如何打
  7. 美通企业日报 | 万豪将在全球取消一次性小瓶洗漱用品;保乐力加在中国建首家麦芽威士忌酒厂...
  8. STM32的独立互补PWM初始化控制 kw:PB15 TIM1_CH3N
  9. 云linux界面设计,开源企业级的UI设计语言Ant Design 3.10.2发布下载
  10. Uncaught TypeError: Cannot read properties of undefined (reading ‘push’) ---- vue-router报错