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

/* 參考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兩個字符


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM