Android和kernel間,通過裝置節點建立關聯
待機API由kernel建立提供,待機請求由android通過節點向kernel發送。
# ls sys/android_power/staterequest_stateacquire_full_wake_lockacquire_partial_wake_lockrelease_wake_lock#
這些節點中,state是linux待機介面
# echo standby > /sys/android_power/state
2.6.25 kernel目前沒在使用此節點待機。
request_state是用於android請求待機時候寫入的節點,後面三個是android和kerenl間關於幾種鎖的儲存互動用的節點。
# echo idle > /sys/android_power/request_state
就可以進入idle模式待機,standby類似。
在android中./hardware/libhardware_legacy/power/power.c
引用kernel建立的節點:
const char * const PATHS[] = { "/sys/android_power/acquire_partial_wake_lock", "/sys/android_power/release_wake_lock", "/sys/android_power/request_state"};
static int set_state(const char* state){ LOGI("*** set_state :%s ", state); initialize_fds(); if (g_error) return g_error; char buf[32]; int len; len = sprintf(buf, state); len = write(g_fds[REQUEST_STATE], buf, len); if(len < 0) { LOGE("Failed setting last user activity: g_error=%d, len=%d\n", g_error, len); } return 0;}Int wake()//往request_state節點寫入wake{ return set_state(wake_state);}Int idle()//往request_state節點寫入idle{ return set_state(idle_state);}Int standby()//往request_state節點寫入standby{ return set_state(standby_state);}
問題:待機喚醒後,系統立即又進入待機
這是因為/sys/android_power/request_state 節點裡面的命令在待機喚醒後,沒有被寫入wake,還是idle或者standby; 在kernel 2.6.25中
while(g_user_suspend_state == USER_SLEEP) {ret = pm_suspend(PM_SUSPEND_MEM);}
而在寫入wake到/sys/android_power/request_state時
g_user_suspend_state = USER_AWAKE;
在android系統,往/sys/android_power/request_state寫入命令是由android操作,寫入idle、standby或者是wake;而android決定是否去寫命令、寫什麼命令,卻是根據kernel上報事件來裁決的。一般喚醒時候,如果案例喚醒就會有上報按鍵動作,RTC、timer、異常喚醒需要開發人員主動上報一個事件,android收到按鍵上報訊息,在和kernel溝通情況下,過濾掉某個索引值,然後去寫命令。
如果是QT這種非android系統,容易碰到喚醒後立即待機的問題。
解決方案是:在待機喚醒後,立即改寫/sys/android_power/request_state 節點的命令為wake。
系統如何調用request_state_store?
[22][<c02f95ac>](request_state_store+0x0/0x160)from[<c01e515c>](kobj_attr_store+0x20/0x24)[22][<c01e513c>](kobj_attr_store+0x0/0x24) from [<c014111c>] (sysfs_write_file+0x104/0x188)[22] [<c0141018>] (sysfs_write_file+0x0/0x188) from [<c0101e08>] (vfs_write+0x190/0x1b4)[22] [<c0101c78>] (vfs_write+0x0/0x1b4) from [<c0101efc>] (sys_write+0x44/0x74)[22] [<c0101eb8>] (sys_write+0x0/0x74) from [<c009da40>] (ret_fast_syscall+0x0/0x2c)
從調用關係可以看到,sys_write操作會發起_store的調用。也就是說每一次對節點的寫操作,就會調用一次_store函數。