Android和kernel间,通过设备节点建立关联
待机API由kernel建立提供,待机请求由android通过节点向kernel发送。
# ls sys/android_power/ state request_state acquire_full_wake_lock acquire_partial_wake_lock release_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函数。