Linux电源管理之系统睡眠模型
前文
万物运行遵循能量守恒定律,因此,世界上并不存在永动机,一切运动都需要能量。人走路、思考需要能量,汽车在路上跑需要能量,电子产品运行需要能量。
对于电子产品的功耗管理是一个系统工程,需要在各使用场景下,用尽可能少的资源、功耗,完成想要的功能,并且还要长续航、不发烫。
为了解决不必要功耗的消耗,linux提供了多种电源管理方式。为了解决系统不工作时的功耗消耗,linux提供了休眠(suspend to ram or disk)、关机(power off)、复位(reboot)。
本文介绍了电源管理的一种方式:系统睡眠模型。
系统睡眠模型类别
1、系统睡眠模型
- ON ----------------------------(Working)
- Standby----------------------(CPU and RAM are powered but not executed)
- Suspend to RAM----------(RAM is powered and the running content is saved to RAM)
- Suspend to Disk-----------(All content is saved to Disk and power down)
软件架构
内核中该部分的软件架构大概可以分为三个层次
- API Layer
描述用户空间API的一个抽象层。
- PM Core
电源管理的核心逻辑层,位于kernel/power/目录下,包括主功能(main)、STD、STR&Standby以及辅助功能(assistant)等多个子模块。
主功能,主要负责实现global APIs相关的逻辑,为用户空间提供相应的API;
- PM Driver
电源管理驱动层,涉及体系结构无关驱动、体系结构有关驱动、设备模型以及各个设备驱动等多个软件模块。
用户空间接口
-
/sys/power/state
用于将系统置于指定的Power State(供电模式,如 disk 、standby、 freeze 、mem 等)。
-
/sys/power/pm_trace
PM Trace用于提供电源管理过程中的Trace记录
-
/sys/power/pm_test
PM test用于对电源管理功能的测试
-
/sys/power/wakeup_count
wakeup_count是内核用来保存当前wakeup event发生的计数。 是为了解决Sleep和Wakeup之间的同步问题。
-
/sys/power/disk
用于设置或获取STD的类型。 ( platform 、 shutdown 、 reboot 、 suspend )
-
/sys/power/image_size
设置或者获取当前内存中需要分配多少空间,用于缓冲需要写入到disk的数据
-
/sys/power/reserverd_size
reserverd_size用于指示预留多少内存空间
-
/sys/power/resume
reserverd_size用于指示预留多少内存空间
-
/sys/power/suspend_status
向用户空间提供suspend过程的统计信息
Linux电源管理Suspend功能
Linux内核提供了三种Suspend: Freeze、Standby和STR(Suspend to RAM),在用户空间向”/sys/power/state”文件分别写入”freeze”、”standby”和”mem”,即可触发它们。
Linux suspend&resume过程
驱动程序里相关的电源管理函数的调用过程:
- 休眠: prepare—>suspend—>suspend_late—>suspend_noirq
- 唤醒: resume_noirq—>resume_early—>resume–>complete
修改驱动程序支持电源管理
1、添加通知notifier(不推荐)
在冻结APP之前,使用pm_notifier_call_chain(PM_SUSPEND_PREPARE)来通知驱动程序
在重启APP之后,使用pm_notifier_call_chain(PM_POST_SUSPEND)来通知驱动程序
如果驱动程序有事情在上述时机要处理,可以使用register_pm_notifier注册一个notifier
2、添加suspend, resume函数
添加一个同名platform_device, platform_driver
老方法:在platform_driver里实现suspend,resume成员
新方法:在platform_driver里的driver里的pm结构体, 实现suspend,resume成员(推荐)