Android系统--输入系统(六)模拟输入驱动程序
Android系统--输入系统(六)模拟输入驱动程序
1. 回顾输入子系统
简单字符设备驱动:应用程序通过调用驱动所实现的函数使能硬件。
输入子系统:由于有多个应用程序使用输入子系统,故肯定使用的是早已规定好驱动接口,我们所需要实现的这是实现硬件相关的操作。
2. 输入子系统特性
有多套open/read/write接口
当应用程序调用这些接口,驱动程序将提供多套实现方法
evdev.c(evdev_open/evdev_read/evdev_write),通过这些接口提供原始数据
keyboard.c、mousedev.c,得到的是一些加工之后的数据
3. Android的输入系统特性
Android系统只使用evdev.c,只处理原始数据
内核具有多个接口,应用程序则通过不同的设备节点,来使用特定节点的驱动接口
硬件相关:根据硬件的状态上报数据(原始数据),我们一般只需要实现该功能
硬件
4. 如何实现Input驱动
分配/构造:input_device结构体
注册:input_register_device
有输入事件产生时,中断程序上报:input_event(dev,type,code,value)
5. 具体输入流程框架
APP层
4、 应用程序open /dev/input/event
6、 应用程序read
驱动层(evdev.c)
3、 connect函数被调用:生成一些信息,导致创建设备节点/dev/input/event
5、 evdev_open被调用:根据设备节点与 input_device结构体建立联系
7、 evdev_read被调用:无数据,则休眠
12、evde_read被唤醒,有数据,开始读取数据
硬件相关的驱动层
1、 构造input_device结构体
2、 注册该结构体:input_register_device
9、 中断服务程序被掉用:input_event产生数据,上报数据
10、 放入evdev的buffer
11、 唤醒读进程
硬件层
- 8、用户按下按键,产生中断
6. 忽略复杂的硬件操作,模拟输入系统的驱动程序
6.1 实现原理
通过另外一个应用程序,打开设备节点,写数据,唤醒读进程。
APP open节点
写数据(使用Android系统中有sendevent函数)
6.2 驱动实现
分配input_device结构
设置该结构体
注册该结构体
6.3 具体实现程序
InputEmulator.c
/* 参考drivers\input\keyboard\gpio_keys.c */
#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/input.h>
static struct input_dev *input_emulator_dev;
static int input_emulator_init(void)
{
int i;
/* 1. 分配一个input_dev结构体 */
input_emulator_dev = input_allocate_device();;
/* 2. 设置 */
/* 2.1 能产生哪类事件 */
set_bit(EV_KEY, input_emulator_dev->evbit); //产生按键类似键
set_bit(EV_REP, input_emulator_dev->evbit); //重复上报事件
/* 2.2 能产生所有类型的按键*/
for(i=0;i<BITS_TO_LONGS(KEY_CNT);i++)
input_emulator_dev->keybit[i] = ~0UL;
/*2.3 为Android构建一些设备信息*/
input_emulator_dev->name = "InputEmulatorFromLKQ";
input_emulator_dev->id.bustype = 1;
input_emulator_dev->id.vendor = 0x1234;
input_emulator_dev->id.product=0x5678;
input_emulator_dev->id.version=1;
/* 3. 注册 */
input_register_device(input_emulator_dev);
return 0;
}
static void input_emulator_exit(void)
{
input_unregister_device(input_emulator_dev);
input_free_device(input_emulator_dev);
}
module_init(input_emulator_init);
module_exit(input_emulator_exit);
MODULE_LICENSE("GPL");
Makefile
KERN_DIR = /opt/Tiny4412/KernelSrc/linux-3.0.86
all:
make -C $(KERN_DIR) M=`pwd` modules
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += InputEmulator.o
6.4测试方法
insmod InputEmulator.ko
打开开发板任意一个文本输入框
串口输入:
sendevent /dev/input/event5 1 2 1 // 1 2 1 : EV_KEY, KEY_1, down
sendevent /dev/input/event5 1 2 0 // 1 2 0 : EV_KEY, KEY_1, up
sendevent /dev/input/event5 0 0 0 // sync
串口输入:
sendevent /dev/input/event5 1 3 1
sendevent /dev/input/event5 1 3 0
sendevent /dev/input/event5 0 0 0
6.5 实验现象
开发板文本输入框出现1和2两个字符
Android系统--输入系统(六)模拟输入驱动程序的更多相关文章
- Android系统--输入系统(十六)APP跟输入系统建立联系_InputChannel和Connection
Android系统--输入系统(十六)APP跟输入系统建立联系_InputChannel和Connection 0. 核心:socketpair机制 1. 回顾Dispatch处理过程: 1.1 放入 ...
- Android系统--输入系统(八)Reader线程_使用EventHub读取事件
Android系统--输入系统(八)Reader线程_使用EventHub读取事件 1. Reader线程工作流程 获得事件 size_t count = mEventHub->getEvent ...
- Android系统--输入系统(九)Reader线程_核心类及配置文件
Android系统--输入系统(九)Reader线程_核心类及配置文件 1. Reader线程核心类--EventHub 1.1 Reader线程核心结构体 实例化对象:mEventHub--表示多个 ...
- Android系统--输入系统(十一)Reader线程_简单处理
Android系统--输入系统(十一)Reader线程_简单处理 1. 引入 Reader线程主要负责三件事情 获得输入事件 简单处理 上传给Dispatch线程 InputReader.cpp vo ...
- Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件
Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件 1. 输入按键 我们知道Android系统的按键分为三类:(1)Global Key;(2)Syste ...
- Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理
Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理 1. 回顾 我们知道Android输入系统是Reader线程通过驱动程序得到上报的输入事件,还要经过处理 ...
- Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序
Android系统--输入系统(十五)实战_使用GlobalKey一键启动程序 1. 一键启动的过程 1.1 对于global key, 系统会根据global_keys.xml发送消息给某个组件 & ...
- Android系统--输入系统(五)输入系统框架
Android系统--输入系统(五)输入系统框架 1. Android设备使用场景: 假设一个Android平板,APP功能.系统功能(开机关机.调节音量).外接设备功能(键盘.触摸屏.USB外接键盘 ...
- Android系统--输入系统(七)Reader_Dispatcher线程启动分析
Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...
随机推荐
- TCP四个计数器
持续计时器 TCP 为每一个连接设有一个持续计时器. 只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器. 若持续计时器设置的时间到期,就发送一个零窗口探测报文段(仅携带 1 字节的数据) ...
- Omi应用md2site发布-markdown转网站利器
写在前面 Md2site是基于Omi的一款Markdown转网站工具,使用简单,生成的文件轻巧,功能强大. 当我们想把一堆markdown文档转成网站时,你可能有许多选择,倘若选择 md2site , ...
- Nginx+IIS+Redis 处理Session共享问题 1
最近遇到一个棘手的问题,微信公众平台的前端站点session老是丢失,我们是走的微信网页授权,授权后获取用户openid,丢失后没有openid后续的操作全白搭了,因为没了openid只能判断为客户不 ...
- PHP文本的读写
<?php $txtPart="test0.txt"; //export $txtPartContent=fopen($txtPart,"r"); //读 ...
- 说说MySQL中的Redo log Undo log都在干啥
在数据库系统中,既有存放数据的文件,也有存放日志的文件.日志在内存中也是有缓存Log buffer,也有磁盘文件log file,本文主要描述存放日志的文件. MySQL中的日志文件, ...
- php基础语法(20161021)
上午: 数据库总结: 1.创建数据库 create database 数据库名称 删除数据库 drop database 数据库名称 2.创建表 create table 表名 ( 列名 类型(长度) ...
- 一种抛弃GPS的中近距离高精度无线同步新方案
目前,对于需要做同步数据采集的项目,大家不约而同的选用GPS作同步源,用GPS的秒脉冲作同步基准.对于是1000米内的多采集点的应用来说,这是一种浪费. 目前福州慧聚通信技术有限公司推出一款无线同步数 ...
- Selenium2 WebDriver环境搭建
1.下载Selenium Client Servers包 在Selenium官网上可以下载到最新的开源的包http://seleniumhq.org/download/,根据编写测试脚本所使用的语言下 ...
- 兼容主流浏览器的js原生函数封装
1.获取和修改垂直滚动条的滚动距离 //获取滚动条滚动距离function getScrollTop(){ var fromTop=document.documentElement.scrollTop ...
- a里面不能嵌套a
1. <a href=""> <a href=""></a></a> 会被浏览器解析为 2. <a hre ...