Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android底層開發之Linux輸入子系統要不要判斷系統休眠狀態上報鍵值

Android底層開發之Linux輸入子系統要不要判斷系統休眠狀態上報鍵值

編輯:關於Android編程

Android底層開發之Linux輸入子系統要不要判斷系統休眠狀態上報鍵值

 

題外話:一個問題研究到最後,那邊記錄文檔的前半部分基本上都是無用的,甚至是錯誤的。重點在最後,前邊僅僅是一些假想推測。

 

在調試一下紅外遙控器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手機的實現方式

 

 

還有一點:按鍵中的狀0,並不是input_sync(ddata->input);發出的,它只會發出當前的值。它僅僅是一個「同步」,意思是數據都准備好了,可以發送了。還是沒有對驅動了解的很清楚加上自己的一些瞎想像誤導了自己。內核input驅動中是不區分POWER鍵,WAKEUP鍵;真是有差異了,問題一定是出在了自己的驅動代碼中。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved