如果我们要写一个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); 也就是重复报告,它的工作机制是这样的
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); 也就是重复报告,它的工作机制是这样的