linux input 按键驱动几点说明

如果我们要写一个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 。

原文链接:https://blog.csdn.net/sxw0624/article/details/7569449

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值