zoukankan      html  css  js  c++  java
  • 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驱动

    1. 分配/构造:input_device结构体

    2. 注册:input_register_device

    3. 有输入事件产生时,中断程序上报: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 驱动实现

    1. 分配input_device结构

    2. 设置该结构体

    3. 注册该结构体

    6.3 具体实现程序

    InputEmulator.c
    
    /* 参考driversinputkeyboardgpio_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两个字符

  • 相关阅读:
    编程实现SQL Server备份和还原
    [推荐]asp.net string与color互换
    ASP.NET执行SQL超时的解决方案
    Starling 环形进度条实现
    [转]列举好游戏应具备的10个要素
    基于Starling的mask实现
    一直以来最头痛的问题:怎么样才能行之有效的解决游戏中后期枯燥的问题呢?求解
    [转]战棋系统的分析
    [转] java开源游戏
    设计模式(基础篇)软件设计七大设计原则(续一)
  • 原文地址:https://www.cnblogs.com/lkq1220/p/6727334.html
Copyright © 2011-2022 走看看