本文的主要目的是在安卓系统中添加一个input event设备,并通过它向用户层发送按键事件。方法是采用动态模块的方式将该设备加入到input子系统中,所以是一个虚拟的设备。然后通过getevent和sendevent验证设备被正确注册。
1.编写驱动模块
在安卓主目录下输入命令:
mkdir -p /kernel/drivers/hello
cd /kernel/drivers/hello
touch hello_evdev.c
注册一个字符事件设备的步骤主要是如下三点:
a.首先为evdev分配空间调用下列函数创建一个input_dev对象
struct input_dev *input_allocate_device(void)
b.设置input_dev输入事件的类型,事件码和取值范围,
c.调用下面的函数将input_dev注册到input core中,最重要的是将evdev与handler相匹配。
int input_register_device(struct input_dev *dev)
按照上述步骤,代码如下:
/*hello_evdev*/
#include<linux/device.h>
#include<linux/input.h>
#include<linux/module.h>
struct input_dev *my_dev;
static int __init hello_evdev_init(void){
int err = -1;
//使用input的专有函数分配空间,创建设备
my_dev = input_allocate_device();
if(NULL == my_dev){
printk(KERN_ALERT"Failed to allocate hello_evdev %d.\n");
goto err_input_dev_alloc_failed;
}
//设定dev的name
my_dev->name = "hello_evdev";
//申明设备类型
set_bit(EV_SYN, my_dev->evbit);//同步
set_bit(EV_KEY, my_dev->evbit);//接受按键类型的事件
set_bit(0x74, my_dev->keybit);//设定接收的按键,这里只有0x74作为测试,表示电源键,如果没有此行,则该设备不接受事件。
printk("begin to register hello_evdev !..");
//注册input设备
err = input_register_device(my_dev);
if(err){
printk(KERN_ALERT"Failed to register hello_evdev %d.\n");
goto err_input_dev_register_failed;
}
printk("%s ok!..", __func__);
//不要忘记正确执行后return
return 0;
//出错处理
err_input_dev_alloc_failed:
err_input_dev_register_failed:
input_free_device(my_dev);
return err;
}
static int __exit hello_evdev_exit(){
input_unregister_device(my_dev);
return 0;
}
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("First Android Driver");
module_init(hello_evdev_init);
module_exit(hello_evdev_exit);
2.编写makefile: vi makefile;
obj-m += hello_evdev.o
obj后面的m表示动态模块,随时添加,y表示编译时就加入内核
然后在上一层的drivers目录下,改动Makefile,在末尾添加:
obj-y += hello/
此处的y为会导致编译hello文件夹下的模块,最后还是会读取hello下的makefile,识别到该模块是动态模块
然后编译该模块,使用adb shell发送到安卓手机内。
3.验证
在adb shell进入安卓手机,敲下命令,得到如下信息:
可见设备已经正确被注册到input系统下;
然后输入
sendevent /dev/input/event0 01 116 1
sendevent /dev/input/event0 0 0 0
sendevent /dev/input/event0 01 116 0
sendevent /dev/input/event0 0 0 0
手机亮起,event设备运行正确。