版权声明:本文为博主原创文章,任何组织或者个人可以在任何媒介上发表或转载我的文章、图片等.且转载后必须注明出处和邮箱,博客地址(https://blog.csdn.net/u011011827),本人邮箱([email protected]) https://blog.csdn.net/u011011827/article/details/87889717
- 关于怎么用input api 写驱动,参见创建输入设备驱动程序,实例参考 下面的demo
- 关于怎么在用户空间监听 input 事件,参见下面的demo
本篇提供了input内核驱动demo和用户空间监听程序demo
demo
- 内核驱动程序
驱动makefile 请参考驱动makefile
// insmod input_demo_driver.ko
// 注意:此时会生成/dev/input/eventX // X 为 0 1 2 3
// 如果没有生成,请研究 busybox中 mdev 或者 udev
// input_demo_driver.c
#include <linux/module.h>
#include <linux/input.h>
#include <linux/hrtimer.h>
/**
参考:
输入子系统的写法demo https://www.kernel.org/doc/html/latest/input/input-programming.html
输入子系统的函数api:https://www.kernel.org/doc/html/latest/driver-api/input.html
测试:cat /proc/bus/input/devices会发现注册的设备
**/
static struct input_dev *button_dev;
static struct hrtimer vibe_timer;
#define value 2000 // 2000ms
enum hrtimer_restart timer_func(struct hrtimer * timer){
input_report_key(button_dev, KEY_POWER,1);
input_report_key(button_dev, KEY_POWER,0);
input_sync(button_dev);
hrtimer_start(&vibe_timer,ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
//return HRTIMER_RESTART; // 重新开始
return HRTIMER_NORESTART; // 结束
}
static int __init test_init(void)
{
int error;
button_dev = input_allocate_device();//分配输入设备内存,失败返回NULL
if (!button_dev) {
printk(KERN_ERR "button.c: Not enough memory\n");//如果分配失败,没有足够内存
error = -ENOMEM;
return error;
}
//输入设备名字
button_dev->name="I am simplest input subsystem";
//设置设备的坐标直接和屏幕坐标向对应
set_bit(INPUT_PROP_DIRECT,button_dev->propbit);
//输入设备时间类型为键盘事件
set_bit(EV_KEY, button_dev->evbit);
//输入设备的键盘掩码为:拥有POWER键
set_bit(KEY_POWER,button_dev->keybit);
//设置产品id
button_dev->id.bustype=BUS_I8042;
button_dev->id.vendor=0x1111;
button_dev->id.product=0x2222;
button_dev->id.version=0x5555;
//将设备注册进输入子系统
error = input_register_device(button_dev);
if (error) {
printk(KERN_ERR "button.c: Failed to register device\n");//注册失败
input_free_device(button_dev);//释放内存
return error;
}
hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
vibe_timer.function = timer_func;
hrtimer_start(&vibe_timer,ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
printk(KERN_DEBUG "OK,input subsystem inited!\n");
printk("OK,input subsystem inited!\n");
return 0;
}
static void __exit test_exit(void)
{
input_unregister_device(button_dev);
hrtimer_cancel(&vibe_timer);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
- 用户空间的用户监听程序
// input_app.c
// 使用方法 : ./input_app /dev/input/eventX // X 为 0 1 2 3
// 注意: 在监听前上报的数据并不会被监听到
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, const char *argv[])
{
int fd;
struct input_event env;
int c = 0;
int i;
fd =open(argv[1],0666);
if(fd<=0)
{
puts("open error");
return -1;
}
while(1)
{
c=read(fd,&env,sizeof(struct input_event));
if(c<0)
{
perror("read error");
return -1;
}
printf("---------------------------event begin\n");
printf("type:%d code:%d value:%d\n",
env.type,
env.code,
env.value);
printf("---------------------------event end\n");
}
return 0;
}