linux input 按键驱动几点说明

来源:互联网 发布:linux开发工程师招聘 编辑:程序博客网 时间:2024/05/01 13:15
如果我们要写一个gpio 的按键驱动,可以有两种写法

1. 写个字符设备,利用中断 ,阻塞读写就能实现。
2. 注册成input 设备,利用中断向上报告按键。

如果只是测试,第一种写法是可行的,也更加简洁,它的优点就在于高效,不依靠输入子系统。
但是,这种按键实现复杂一点的按键功能就要写很多底层代码了,而且它有个最大的缺点:上层的界面系统很难友好的使用这种驱动,除非把上层界面系统的按键接口做相应的修改。

所以,input 设备,依靠了输入子系统,上层界面系统对它的使用很方便了。

input 按键驱动的工作机制大概如下:

按键产生中断,在中断中向上报告键值:
这里要注意两点:

1. input_event(input, type, button->code, !!state);  这个函数 如果第一次报告了 input_event(input, type, button->code,1);  第二次又报告了 input_event(input, type, button->code,1);  那么第二次是报告不上的,也就是说 只有键值变化了报告才有效。这也是按键驱动为什么都是双边延触发,就是为了产生按键按下 和 按键抬起 ,如果每次只报告一次按键按下,那么 驱动只会报告一次按键。

2. 如果 设置了 __set_bit(EV_REP, input->evbit);  也就是重复报告,它的工作机制是这样的:

   如果按键报告了input_event(input, type, button->code,1);  之后,  在250ms (可以改)后,依然没有报告 input_event(input, type, button->code,0); 则 input 会每隔 33ms 继续报告一次 input_event(input, type, button->code,2);  直到 报告了  input_event(input, type, button->code,0); 才停止 ,这就是我们按住一个按键不松开时,会一直打印键值的原因;

这段代码在 drivers/input/input.c 中
/*
     * If delay and period are pre-set by the driver, then autorepeating
     * is handled by the driver itself and we don't do it in input.c.

     */

    init_timer(&dev->timer);
    if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
        dev->timer.data = (long) dev;
        dev->timer.function = input_repeat_key;
        //dev->rep[REP_DELAY] = 250;
        dev->rep[REP_DELAY] = 2500;
        dev->rep[REP_PERIOD] = 33;
    }
这里要注意红色的说明文字,也就说如果我们自己的驱动里自己定义了 dev->rep[REP_DELAY] = 2500;  那么就不会使用input 的timer ,而要使用自己编写的timer 。
原创粉丝点击