什么是suspend?做什么?
简单来说就是让设备暂停,进入休眠的过程。在不需要设备工作时,让其进入休眠可以节省功耗。
如何进入让设备进入suspend?
(1)用户空间向内核写入相应的电源状态进入suspend。
(2)当用户按下power key的时候,通过进入PhoneWindowManager策略类的相关方法(interceptPowerKeyUp、interceptPowerKeyDown等)实现suspend。
(3)自动息屏,简单的理解就是用户长时间内没有跟设备进行交互,达到用户设置的息屏时间时,就设置mUserActivitySummary 为USER_ACTIVITY_SCREEN_DIM,再设置成USER_ACTIVITY_SCREEN_DREAM,最后设置成0。mUserActivitySummary为0时就会触发updatePowerStateLocked里的休眠流程了。
四种电源状态:
系统休眠也有深有浅,其中睡的越深功耗越低,相应的唤醒延迟越大,睡的越浅功耗越高,而其唤醒延迟也越小。根据睡眠状态由浅到深,Linux当前一共支持freeze、standby、mem和disk四种休眠方式,其特点如下:
(1)freeze(suspend to idle):这种方式会冻结系统中的进程,挂起所有需要挂起的设备(如I/O设备),然后将cpu切换为idle进程,使其进入idle状态。它不会将cpu从内核中移除,因此一旦被唤醒只需从idle状态退出,恢复挂起的设备和被冻结的进程即可。
(2)standby(suspend to standby):这种方式除了执行所有freeze相关的流程外,还会将辅助cpu从内核中移除,然后主cpu进入standby睡眠模式。standby模式睡眠较浅,不会对cpu断电,因此在睡眠时不需要保存cpu上下文。当其一旦被唤醒,cpu就能马上投入工作,并依次恢复系统运行。
(3)mem(suspend to mem):相对于standby方式,这种方式下主cpu需要先将cpu上下文保存到内存中,然后将自身断电。因此它不能直接被唤醒,而是需要先通过其它模块为其上电,然后再执行恢复cpu上下文以及其它模块的工作。由于这种方式,内核整个都已经睡眠,因此也不会有访问ddr的需求。
(4)disk(suspend to disk或hibernate):这是最深的一种睡眠模式,与suspend to mem将系统相关上下文保存到ddr中不同,它将系统上下文保存到磁盘中。由于所有上下文都已经保存到磁盘中,因此不仅外设、cpu可以下电,而且此时ddr也可以被断电。