更多可参考
Linux输入子系统分析
input 子系统架构总结
1、定义一个static struct input_dev结构体
static struct input_dev *mybutton_dev;
2、初始化时分配input_dev结构体
mybutton_dev = input_allocate_device();//分配 input_dev
/*能产生的事件类型 1. #define EV_SYN 0x00 /*表示设备支持所有的事件*/ 2. #define EV_KEY 0x01 /*键盘或者按键,表示一个键码*/ 3. #define EV_REL 0x02 /*鼠标设备,表示一个相对的光标位置结果*/ 4. #define EV_ABS 0x03 /*手写板产生的值,其是一个绝对整数值*/ 5. #define EV_MSC 0x04 /*其他类型*/ 6. #define EV_LED 0x11 /*LED 灯设备*/ 7. #define EV_SND 0x12 /*蜂鸣器,输入声音*/ 8. #define EV_REP 0x14 /*允许重复按键类型*/ 9. #define EV_PWR 0x16 /*电源管理事件*/ */
set_bit(EV_KEY, mybutton_dev->evbit);
set_bit(EV_REP, mybutton_dev->evbit);
//设置支持的按键值
set_bit(KEY_L, mybutton_dev->keybit);
set_bit(KEY_S, mybutton_dev->keybit);
set_bit(KEY_ENTER, mybutton_dev->keybit);
error = input_register_device(mybutton_dev);//注册驱动
3、//输入子系统的事件handle函数
static void inputsystemtimer_handle(unsigned long data){
struct pin_desc * pino_desc = irq_pd;
unsigned int pinval;
if (!pino_desc)
return;
pinval = s3c2410_gpio_getpin(pino_desc->pin);
if (pinval)
{
/* 松开 : 最后一个参数: 0-松开, 1-按下 */
input_report_key(mybutton_dev, pino_desc->key_val, 0);
//貌似必须这样,如果val填pinval会一直报告事件
//貌似必须这样,如果val填inb(pino_desc->pin) & 1会一直报告事件有延迟
input_sync(mybutton_dev);
}
else
{
/* 按下 */
input_report_key(mybutton_dev, pino_desc->key_val, 1);//必须填1
input_sync(mybutton_dev);
}
printk("press button is %s\n", pino_desc->name);
}
4、//注销驱动
input_unregister_device(mybutton_dev);//注销驱动
input_free_device(mybutton_dev);
完整实例:按键的输入子系统
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static struct input_dev *mybutton_dev; static struct timer_list mybutton_timer; struct pin_desc *irq_pd; struct pin_desc{ int irq; char *name; unsigned int pin; unsigned int key_val; }; struct pin_desc pins_desc[3] = { {IRQ_EINT0, "S2", S3C2410_GPF0, KEY_L}, {IRQ_EINT2, "S3", S3C2410_GPF2, KEY_S}, {IRQ_EINT11, "S4", S3C2410_GPG3, KEY_ENTER}, }; static irqreturn_t irq_handle(int irq, void *dev__id){ irq_pd = (struct pin_desc *)dev__id; mod_timer(&mybutton_timer, jiffies+HZ/100); return IRQ_HANDLED;//返回IRQ_HANDLED表示中断已经处理 } static void inputsystemtimer_handle(unsigned long data){ struct pin_desc * pino_desc = irq_pd; unsigned int pinval; if (!pino_desc) return; pinval = s3c2410_gpio_getpin(pino_desc->pin); if (pinval) { /* 松开 : 最后一个参数: 0-松开, 1-按下 */ input_report_key(mybutton_dev, pino_desc->key_val, 0); input_sync(mybutton_dev); } else { /* 按下 */ input_report_key(mybutton_dev, pino_desc->key_val, 1); input_sync(mybutton_dev); } printk("press button is %s\n", pino_desc->name); } static int inputsystem_init(void){ int i = 0; int error; init_timer(&mybutton_timer); mybutton_timer.function = inputsystemtimer_handle; add_timer(&mybutton_timer); mybutton_dev = input_allocate_device(); if(! mybutton_dev){ printk(KERN_ERR "allocate failed!\n"); error = -ENOMEM; goto err_free_irq; } mybutton_dev->name = "buttonKeyboard"; mybutton_dev->phys = "gpio-keys/input0"; mybutton_dev->id.version = 0x0100; set_bit(EV_KEY, mybutton_dev->evbit); set_bit(EV_REP, mybutton_dev->evbit); set_bit(KEY_L, mybutton_dev->keybit); set_bit(KEY_S, mybutton_dev->keybit); set_bit(KEY_ENTER, mybutton_dev->keybit); error = input_register_device(mybutton_dev); if(error){ printk(KERN_ERR"input regsiter error\n"); goto err_free_dev; } for(i = 0; i < 3; i ++) request_irq(pins_desc[i].irq, irq_handle, IRQT_BOTHEDGE, pins_desc[i].name, &pins_desc[i]); return 0; err_free_irq: for(i = 0; i < 3; i ++)free_irq(pins_desc[i].irq, &pins_desc[i]); err_free_dev: input_free_device(mybutton_dev); return error; } static void inputsystem_exit(void){ int i = 0; input_unregister_device(mybutton_dev);//注销驱动 input_free_device(mybutton_dev); del_timer(&mybutton_timer); for(i = 0; i < 3; i ++)free_irq(pins_desc[i].irq, &pins_desc[i]); } module_init(inputsystem_init); module_exit(inputsystem_exit); MODULE_LICENSE("GPL");
测试程序
#include#include #include #include #include #include #include #include #include #include #include #include int main(void) { int fd; int key_value,i=0,count; struct input_event ev_key; fd = open("/dev/event1", 666); if (fd < 0) { printf("can't open device buttons!\n"); exit(1); } for (;;) { count = read(fd,&ev_key,sizeof(struct input_event)); for(i=0; i<(int)count/sizeof(struct input_event); i++){ printf("%d\n", ev_key.type); if(EV_KEY==ev_key.type) printf("type:%d,code:%d,value:%d\n", ev_key.type,ev_key.code,ev_key.value); } if(EV_SYN==ev_key.type) printf("syn event\n\n"); } printf("app close fd\n"); close(fd); return 0; }