Linux 输入子系统 input
一、输入子系统
针对输入设备设计:触摸屏、键盘、按键、传感器、鼠标......
二、每种设备都属于字符设备驱动,程序的写法步骤也相同
1、实现入口函数 xxx_init() 和卸载函数 xxx_exit()
2、申请设备号 register_chrdev() --- 与内核相关
3、创建设备文件(节点) class_create() 和 device_create() --- 与内核相关
4、硬件初始化
GPIO操作 --- 与硬件相关
注册中断 --- 与硬件相关
初始化等待队列 --- 与内核相关
初始化定时器 --- 与内核相关
5、构建 file_operations 结构,实现操作硬件方法 xxx_open/xxx_read... --- 与硬件相关
三、引入输入子系统:
1、不需要每个步骤都编写,只需要编写部分代码即可
2、不同类的输入设备,编写驱动的方式是一样的
3、应用程序读取输入设备的数据结构是统一的
输入设备按照产生的数据的类型进行分类:
1、产生按键数据 --- 每个按键都是一个整数
按键、键盘
2、产生绝对数据 --- 每个数据都有最大值和最小值
触摸屏、传感器
3、产生相对数据 --- 某个收据是相对另一个数据的
鼠标
四、输入子系统的框架
-------------------------------------------------------------------------------
应用层:
-------------------------------------------------------------------------------
input handler 层:
知道如何将数据交给用户,不知道如何从硬件获取数据
driver/input/evdev.c
-------------------------------------------------------------------------------
input core 层:
维护两个链表,和上下两层交互
/driver/input/input.c
-------------------------------------------------------------------------------
input device 层:
知道如何从硬件获取数据,不知道如何将数据交给用户
-------------------------------------------------------------------------------
硬件:
触摸屏、键盘、鼠标、按键......
-------------------------------------------------------------------------------
五、输入子系统的驱动编程方法:
1、构建 input device 对象
2、初始化 input device 对象
3、注册 input device 对象
4、硬件初始化
六、描述一个具体的输入设备对象常用的参数:
struct input_dev {
const char *name; // 设备名称
const char *phys; // 物理路径
const char *uniq; // 设备唯一的识别码
struct input_id id; // 设备id,如果有多个输入设备,可以通过此id找到需要的设备
__u16 bustype; // 总线类型
__u16 vendor; // VID
__u16 product; // PID
__u16 version; // 版本号
unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; // 设备支持的事件类型
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; // 此设备具有哪些按键
unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; // 此设备具有相对坐标
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; // 此设备具有相对坐标
... ...
struct device dev; //父类
struct list_head h_list;
struct list_head node; //节点
};
evbit 是只有 1 个元素的 long 型数组,总共占 32 位,每种类型占一位,存在的就将对应位置 1
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
keybit 是含 24 个元素的 long 型数组,总共 768 位,最大支持 768 种按键,每一种按键占一位,存在的就将对应位置 1
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];

七、常用函数
// 上报按键数据
void input_report_key(struct input_dev *dev, unsigned int code, int value)
// 上报相对坐标
void input_report_rel(struct input_dev *dev, unsigned int code, int value)
// 上报绝对坐标
void input_report_abs(struct input_dev *dev, unsigned int code, int value)
// 同步 (唤醒等待队列 /driver/input/evdev.c -> evdev_event -> wake_up_interruptible(&evdev->wait);)
input_sync(input_key);
input_key_drv.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/irq.h> static struct input_dev *input_key;
static int irqno; irqreturn_t input_key_handler(int irqno, void *dev_id)
{
int value; printk("---%s---\n", __FUNCTION__); value = gpio_get_value(EXYNOS4_GPX1());
// value = gpio_direction_input(EXYNOS4_GPX1(1));
printk("---<DRV>--- %d\n", value);
input_report_key(input_key, KEY_HOME, !value);
input_sync(input_key); return IRQ_HANDLED;
} static int __init input_key_drv_init(void)
{
int ret; input_key = input_allocate_device();
if (input_key == NULL)
{
printk("input_allocate_device fail!\n");
return -ENOMEM;
} input_key->name = "input_key";
input_key->phys = "abcd";
input_key->uniq = "efgh";
input_key->id.bustype = BUS_HOST;
input_key->id.product = 0x1234;
input_key->id.vendor = 0x5678;
input_key->id.version = 0x9ABC; input_key->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
input_key->keybit[BIT_WORD(KEY_HOME)] |= BIT_MASK(KEY_HOME); ret = input_register_device(input_key);
if (ret != )
{
printk("input_register_device fail!\n");
ret = -ENOMEM;
goto input_free;
} irqno = gpio_to_irq(EXYNOS4_GPX1());
ret = request_irq(irqno, input_key_handler, IRQ_TYPE_EDGE_BOTH, "input_eint9", NULL);
if (ret < )
{
printk("request_irq fail!\n");
ret = -EBUSY;
goto input_unregister;
} return ; input_unregister:
input_unregister_device(input_key); input_free:
input_free_device(input_key); return ret;
} static void __exit input_key_drv_exit(void)
{
free_irq(irqno, NULL);
input_unregister_device(input_key);
input_free_device(input_key);
} module_init(input_key_drv_init);
module_exit(input_key_drv_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Aaron Lee");
key_app.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h> #include <linux/input.h> struct input_event key_info; int main(void)
{
int fd;
int ret; fd = open("/dev/input/event1", O_RDWR);
if (fd < )
{
perror("open");
exit();
} while ()
{
read(fd, &key_info, sizeof(struct input_event));
if (key_info.type == EV_KEY)
if (key_info.code == KEY_HOME)
printf("---<APP>--- KEY_HOME %s\n", key_info.value ? "down" : "up");
} close(fd); return ;
}
Linux 输入子系统 input的更多相关文章
- Linux输入子系统(Input Subsystem)
Linux输入子系统(Input Subsystem) http://blog.csdn.net/lbmygf/article/details/7360084 input子系统分析 http://b ...
- 10. linux输入子系统/input 设备【转】
转自:https://www.cnblogs.com/crmn/articles/6696819.html 按键事件信息之上报绝对事件信息之上报相对事件信息之上报功能键驱动编写多点触控事件的上报 只产 ...
- Linux输入子系统(转)
Linux输入子系统(Input Subsystem) 1.1.input子系统概述 输入设备(如按键,键盘,触摸屏,鼠标等)是典型的字符设备,其一般的工作机制是低层在按键,触摸等动作发生时产生一个中 ...
- linux输入子系统(input subsystem)之evdev.c事件处理过程
1.代码 input_subsys.drv.c 在linux输入子系统(input subsystem)之按键输入和LED控制的基础上有小改动,input_subsys_test.c不变. input ...
- Linux 输入子系统
Technorati 标签: Kernel 输入子系统 Input 在Linux中,输入设备(如按键.键盘.触摸屏.鼠标等)是典型的字符设备,其一般的工作机理,是底层在按键.触摸时,触发一个 ...
- Linux输入子系统框架分析(1)
在Linux下的输入设备键盘.触摸屏.鼠标等都能够用输入子系统来实现驱动.输入子系统分为三层,核心层和设备驱动层.事件层.核心层和事件层由Linux输入子系统本身实现,设备驱动层由我们实现.我们在设备 ...
- Linux输入子系统详解
input输入子系统框架 linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(Input ...
- linux输入子系统
linux输入子系统(linux input subsystem)从上到下由三层实现,分别为:输入子系统事件处理层(EventHandler).输入子系统核心层(InputCore)和输入子系统设备驱 ...
- linux输入子系统概念介绍
在此文章之前,我们讲解的都是简单的字符驱动,涉及的内容有字符驱动的框架.自动创建设备节点.linux中断.poll机制.异步通知.同步互斥.非阻塞.定时器去抖动. 上一节文章链接:http://blo ...
随机推荐
- The remote end hung up unexpectedly while git cloning
https://stackoverflow.com/questions/6842687/the-remote-end-hung-up-unexpectedly-while-git-cloning Qu ...
- 关于Block汇总
//使用总结: //1.当block里面会有b类相关的参数要回调回去的时候,属性用copy修饰,将其拷贝到堆里面,这样即便栈释放掉了,b类的指针也在堆中存在,能够成功的回调回去. //Block默认存 ...
- pyspider脚本编写指南
注意,虽然在本文中会涉及调度策略等内容,但实际执行效果取决于具体策略实现. project 脚本分为不同的 project,不同的 project 之间的任务互相独立,建议为不同的站点建立不同的 pr ...
- python处理数据的风骚操作[pandas 之 groupby&agg]
https://segmentfault.com/a/1190000012394176 介绍 每隔一段时间我都会去学习.回顾一下python中的新函数.新操作.这对于你后面的工作是有一定好处的.本文重 ...
- Java class、Object、Class 的区别
Java的对象模型中: 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例. 所有的类都最终继承自Object类,Class是类,那么Class也继承自Obj ...
- 遍历jsonArray和jsonObject
遍历jsonArray String str = "[{name:'a',value:'aa'},{name:'b',value:'bb'},{name:'c',value:'cc'}]&q ...
- openstack-mitaka版本DRV基础
一.基础知识 1.1 路由 1.1.1 策略路由 1.1.2 路由表 (使用 ip route 命令操作静态路由表) 1.1.3 路由分类之静态路由 1.1.4 路由分类之动态路由 1.1.5 ip ...
- laravel支持的日志写入模式和日志严重程度级别:
四种日志写入模式: single:单一的 daily:日常的 syslog:系统记录 errorlog:错误日志 Monolog 识别以下严重程度的级别, 从低到高为: debug. info.not ...
- Java基础摘要(一)
三大特性 封装 所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性.简单的说,一 ...
- monkey 原理,环境搭建、命令详解
一.monkey测试的相关的原理 monkey测试的原理就是利用socket通讯的方式来模拟用户的按键输入,触摸屏输入,手势输入等,看设备多长时间会出异常.当Monkey程序在模拟器或设备运行的时候, ...