Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值
来源:互联网 发布:学编程在家里能赚钱吗 编辑:程序博客网 时间:2024/05/18 02:05
Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值
题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是无用的,甚至是错误的。重点在最后,前边仅仅是一些假想推测。
http://blog.csdn.net/kangear/article/details/40072707
在调试一下红外遥控器input驱动时,直接采用的是一个半成品的驱动在上边实现的自己的设备的匹配,但同时遇到了一些关于input输入子系统的疑惑。
按键一般有「按下和抬起」两个状态一般使用0和1来分别表示。一般如下方式上报按键键值就可以完成「按下和抬起」两个状态的收集。
input_event(ddata->input, EV_KEY, KEY_POWER, 1);
input_sync(ddata->input);
但是最近遇到一个奇怪的问题是内核中的KEY_WAKEUP唤醒键值使用上述方法上报时,用户空间只能检测到状态0,第二次按键时才会有状态1。这样导致Android系统不能正常唤醒,需要按两次才能唤醒系统。
目前的解决方法是将之前上报KEY_WAKEUP的地上改为KEY_POWER键值。但是好奇心引着我弄清楚它们是怎么回事。
经验出这里边上报如下一样连续上报1/0状态才可以在用户空间正常的检测到1/0状态。
input_event(ddata->input, EV_KEY, KEY_WAKEUP, 1);
input_sync(ddata->input);
input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);
input_sync(ddata->input);
直觉告诉我可以是由于我对这个两个api的不了解造成的,比较是凡事必有因的。
除了KEY_WAKEUP换个其它键值试试。结果和KEY_WAKEUPG一样不能同步,可以推断出是非POWER按键就不行。这可以能所在代码位置有关系:
}else if ((get_suspend_state())&&(ddata->keycode==KEY_POWER)){
input_event(ddata->input, EV_KEY, KEY_POWER, 1);
input_sync(ddata->input);
}
再进一步测试在非PM_SUSPEND_ON电源模式下,所有的按键都是如何的。测试结果是所有的非POWER按键都出现了按键不能同步的问题。但是不能以点概面,使用GPIO连接的物理按键并不会有此问题,那么就排除了input子系统中做了手脚。问题出就出在了Remote control驱动中对的处理。
找出了问题所在了,确实是出在了Remote control驱动中,上报键值对PM状态进行了判断,如果
static void remotectl_timer(unsigned long _data)
if(ddata->press != ddata->pre_press) {
ddata->pre_press = ddata->press = 0;
if (get_suspend_state()==0){
//input_event(ddata->input, EV_KEY, ddata->keycode, 1);
//input_sync(ddata->input);
input_event(ddata->input, EV_KEY, ddata->keycode, 0);
input_sync(ddata->input);
}else if ((get_suspend_state())&&(ddata->keycode==KEY_POWER)){
//input_event(ddata->input, EV_KEY, KEY_WAKEUP, 1);
//input_sync(ddata->input);
input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);
input_sync(ddata->input);
}
}
将过滤条件去除后,可以和GPIO连接的物理按键一样的效果了,即无论系统处理什么样的状态,休眠或者唤醒状态都上传了键值。同时这也给我带来了一个疑惑,按键驱动中要不要进行suspend状态判断,根据Android中的经验所有的状态都要上传的,响应不响应是看上层系统的决定;但是如果对于普通的嵌入式Linux系统就不一定了,如果input子系统在系统休眠的时候上传了键值,那么对应的应用层可以就会直接去响应键值。要使用哪种方法实现,这是一个悖论!结合Android的宏这样实现了:
diff --git a/drivers/input/remotectl/rkxx_remotectl.c b/drivers/input/remotectl/rkxx_remotectl.c
index db91516..201c5dd 100644
--- a/drivers/input/remotectl/rkxx_remotectl.c
+++ b/drivers/input/remotectl/rkxx_remotectl.c
@@ -306,6 +306,10 @@ static void remotectl_do_something(unsigned long data)
if ((ddata->scanData&0x0ff) == ((~ddata->scanData >> 8)&0x0ff)){
if (remotectl_keycode_lookup(ddata)){
ddata->press = 1;
+#ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state
+ input_event(ddata->input, EV_KEY, ddata->keycode, 1);
+ input_sync(ddata->input);
+#else
if (ddata->keycode==KEY_POWER || get_suspend_state()==PM_SUSPEND_ON){
input_event(ddata->input, EV_KEY, ddata->keycode, 1);
input_sync(ddata->input);
@@ -314,6 +318,7 @@ static void remotectl_do_something(unsigned long data)
}
//input_event(ddata->input, EV_KEY, ddata->keycode, ddata->press);
//input_sync(ddata->input);
+#endif // CONFIG_ANDROID
ddata->state = RMC_SEQUENCE;
}else{
ddata->state = RMC_PRELOAD;
@@ -437,6 +442,10 @@ static void remotectl_timer(unsigned long _data)
if(ddata->press != ddata->pre_press) {
ddata->pre_press = ddata->press = 0;
+#ifdef CONFIG_ANDROID // Android OS needs input event whatever suspend state
+ input_event(ddata->input, EV_KEY, ddata->keycode, 0);
+ input_sync(ddata->input);
+#else
if (get_suspend_state()==0){
//input_event(ddata->input, EV_KEY, ddata->keycode, 1);
//input_sync(ddata->input);
@@ -448,6 +457,7 @@ static void remotectl_timer(unsigned long _data)
input_event(ddata->input, EV_KEY, KEY_WAKEUP, 0);
input_sync(ddata->input);
}
+#endif // CONFIG_ANDROID
}
#ifdef CONFIG_PM
remotectl_wakeup(_data);
如果是Android系统,那么无论kernel处理什么样的休眠状态都实时地上报键值。这样保证在休眠播放音乐的时候可以控制音频大小。这也正是目前Android手机的实现方式。
http://blog.csdn.net/kangear/article/details/40072707
还有一点:按键中的状0,并不是input_sync(ddata->input);发出的,它只会发出当前的值。它仅仅是一个「同步」,意思是数据都准备好了,可以发送了。还是没有对驱动了解的很清楚加上自己的一些瞎想像误导了自己。内核input驱动中是不区分POWER键,WAKEUP键;真是有差异了,问题一定是出在了自己的驱动代码中。
- Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值
- android底层驱动学习之linux输入子系统的理解
- Linux Input子系统浅析(二)-- 模拟tp上报键值
- 【Android休眠】引申之uinput: 用户空间的输入子系统
- 【Linux设备驱动】Linux输入子系统之底层驱动
- Android键值上报流程
- Android系统中耳机按键键值上报不正确 解决过程
- linux嵌入式系统开发之触摸屏---驱动篇(中/Linux输入子系统)
- android 键值添加和上报
- Android input上报*、#键值笔记
- linux驱动子系统之输入子系统(1)
- linux驱动子系统之输入子系统(2)
- linux驱动子系统之输入子系统(3)
- linux驱动子系统之输入子系统(4)
- linux驱动子系统之输入子系统(5)
- linux驱动子系统之输入子系统(5)
- Linux驱动子系统之输入子系统
- Linux驱动子系统之输入子系统
- ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied
- 最受欢迎的视频网站前15名(2014年10月)
- 堆和栈的区别
- 如何减小Lazarusv IDE v1.2.4 编译出的文件的大小
- MFC隐藏主窗口运行的几种方法
- Android底层开发之Linux输入子系统要不要判断系统休眠状态上报键值
- java多线程面试题TOP50
- javascript this 指针的使用及常见问题
- Activity与Fragment
- 【递归】例题分析
- 关于shell脚本中双括号的问题
- thinkphp3.1提示Class 'RelationModel' not found
- 立体视觉和深度学习的2014国家自然科学基金申请截图
- linux 命令大全