[其它] Android 5.1 电源管理-休眠简单分析

[复制链接]
436|0
 楼主 | 2018-4-24 17:57 | 显示全部楼层 |阅读模式
Linux 电源管理机制为设备低功耗的实现提供了方法。
在不同内核版本LinuxAndroid,休眠机制、流程有所差异。这里DLT-RK3288 Android 5.1 源码为例。
标准Linux 的电源状态:
- Onon                                             S0-  Working  
                                                                   - 正常的工作状态
- Standby standby                             S1 -  CPU andRAM are powered but not executed   
                                                                    - CPUDDR都供着电,但没执行任何命令。
- Suspend to RAMmem)                       S3 -  RAM is powered andthe running content is saved to RAM
                                                                    -  挂起到内存,简称待机。CPUEMMCLCD等都断了电,只有DDR供着电,以保存休眠前的工作状态。
- Suspend to DiskHibernationdisk    S4 -  All content is saved to Disk and power down
                                                                    -  挂起到硬盘,简称休眠。机器运行状态保存到硬盘中,并关机。

DLT-RK3288kernel/include/linux/suspend.h 可以看到常用的几种状态
1.  #definePM_SUSPEND_ON                ((__forcesuspend_state_t) 0)
2.  #definePM_SUSPEND_FREEZE        ((__force suspend_state_t) 1)
3.  #definePM_SUSPEND_STANDBY        ((__force suspend_state_t) 2)
4.  #definePM_SUSPEND_MEM                ((__forcesuspend_state_t) 3)
休眠相关内核源码:
kernel/kernel/power/main.c
kernel/kernel/power/suspend.c
kernel/kernel/power/wakelock.c
kernel/kernel/power/autosleep.c
main.c 主要是向用户空间提供文件接口。文件接口有以下:
suspend.c 是进入休眠前所执行的代码。主要函数调用流程: pm_suspend -- enter_state -- suspend_prepare --suspend_devices_and_enter
autosleep.c 主要负责自动进入休眠流程。
低版本的linux内核 还有earlysuspend.cearlysuspend是假休眠(只关闭部分外设的电源)的一种机制,linux 3.10中已被抛弃。

如何进入休眠?
1、当autosleep开启,当所有wakelock都释放时,自动进入休眠。
     autosleep.c 中,try_to_suspend 函数调用 pm_get_wakeup_count ,执行:
1.    for(;;) {
2.                        prepare_to_wait(&wakeup_count_wait_queue, &wait,
3.                                        TASK_INTERRUPTIBLE);
复制代码
    可以看出,一直等到wakelock 被释放,pm_get_wakeup_count 才返回。进入调用 pm_suspendhibernate休眠。
2echo mem > /sys/power/state ,强制进入休眠。
      
执行该命令,系统会直接进入休眠,不再判断是否有没释放的wakelock。(低版本内核中,执行该命令,仍需要等待wakelock释放)。


wakelock 是为休眠唤醒而存在的。可以查询相关资料进一步了解。
cat /sys/power/wake_lock可以看到当前哪个Android锁处于激活状态。(/sys/power/wake_lock 并不统计内核的锁)

如何禁止自动进入休眠?
1、在驱动源码中,初始化一个wakelock,并上锁,不释放。
1.  #include<linux/wakelock.h>
2.  structwake_lock no_suspend_lock;
复制代码
内核中的锁类型很简单,只有WAKE_LOCK_SUSPEND。(低版本内核中多了WAKE_LOCK_IDLE)。
   缺点: 只能保证不进入休眠,屏幕却被灭了。


2、在Android中加锁
Android 定义了以下几种WakeLock类型:
       *  FULL_WAKE_LOCK    保持屏幕全亮、键盘背光灯点亮和CPU运行。
       *  SCREEN_BRIGHT_WAKE_LOCK   保持屏幕全亮和CPU运行。
       *  SCREEN_DIM_WAKE_LOCK   保持屏幕开启(但是让它变暗)和CPU运行。

        *  PARTIAL_WAKE_LOCK  保持CPU运行。
可以根据需要,申请不同的锁类型。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

关闭

热门推荐上一条 /5 下一条

快速回复 返回顶部 返回列表