本系列将逐步介绍linux电源管理相关的知识,涉及到常见电源管理机制、linux电源管理机制、linux驱动中有关电源管理的相关接口、内核文档中关于Linux电源管理架构文档的分析。以下将以此来介绍相关内容,尽量做到通俗易懂,条理清晰。
电是现在社会的基础设施,它点亮了整个世界。随着移动互联网的盛行,各种智能设备层出不穷,各种CPU和大屏幕,都在不断折磨手机的电池,各种刺激的手游,也在压榨智能手机的电量。电池技术发展了这么多年,在没有新型储能材料发现之前,考虑到整体的重量和发热的可接受度,手机电池电量是不会有太大突破的。大家都知道Android是基于Linux开发的,要提高未来智能设备的续航时间,一方面需要提高电池容量,另一方面,就要站在系统的视角上,像进程调度一样,调度”电力”,在满足一定负载要求下,尽量降低功耗,延迟设备使用时间。本篇文章将从下往上,依次介绍电源管理理念在Android智能手机上的设计与实现。
电源管理的对象是各种硬件设备驱动、系统框架中的各种应用调度等(这只是我的初步理解,有什么不对的地方,请各位指教)。如果以日常生活为例子来类比,一个成年人,一日三餐,就可以全速工作一整天,吃饭就像充电一样,先吃饭,再做事,体内葡萄糖等储能物质就像电池一样,在一定的能量供应下,干越多的活,Boss越欢喜。只在需要马儿跑时,才让它吃草,这是电源管理的核心思想,它主要有两点
1. 灵活的关闭暂时不使用的部分
2. 当需要重新使用那些已经关闭的部分,不能有长时间的等待,且切换状态不能消耗太多能量。
电源管理使用的前提,是待控制的硬件支持节点功能,能够通过指令暂时关闭,操作系统需要支持电源管理,
常见电源管理机制
在x86机器中,存在两种电源管理方法,APM(Advanced Power Management,高级电源管理)和ACPI(Advanced Configuration and Power Interface ,高级配置和电源接口),这两个标准不能同时允许在Linux上面,默认情况下,Linux运行ACPI.需要注意,apm和acpi是互相冲突的两个模块,用户在同一时间内只能加载其中之一
APM可以让设备处于Suspend(挂起状态)或者Standby(待机状态)和检测电池容量,使用前提,需要BIOS和Linux核心支持,并且有apmd(APM的后台服务程序)和apm等应用程序。它是基于BIOS的电源管理标准,提供了CPU和设备电源管理的功能,缺陷是对BIOS的过度依赖、新旧BIOS的兼容性、以及无法判断电源管理命令是由用户发起还是由BIOS发起,不适合新硬件的发展趋势,为了弥补APM的缺陷,人们提出了ACPI规范。
ACPI主要是将电源管理的主要执行者由BIOS转换成操作系统,这样可以提供更大的灵活性以及可扩展性。ACPI除了APM的功能之外,还可以单独控制外设,有更加细粒化的节点控制。对于的应用程序有acpid和pmtools,下载链接在此
ACPI主要支持三种节点方式:
1. standby(S1模式),待机方式:显示屏断电,只是主机断电,此时,敲任何键都可以恢复原来状态
2. suspend to ram(STR,S3模式),挂起到内存,系统把当前信息储存在内存中,只有CPU和内存等几个关键部件,按电源键可以恢复原来状态
3. suspend to disk(STD,S4模式),挂起到硬盘,系统在关机前将当前数据先保存在内存中,再把内存写入硬盘上的交换分区上,用户下次按开机键开启时,计算机直接从硬盘读取数据,恢复原来状态。
ACPI有六种工作状态:
S0-->所有设备全开
S1-->只关闭CPU(中断使能)
S2-->关闭CPU和总线时钟
S5-->关机
在/sys/power目录下
进入对于的模式,只往state输入对于的状态标志位就可以了。
由于目前没有从事有关低功耗方面的项目,所以只能是参考一下标准Linux休眠和唤醒机制分析(一~四)来理解,等以后有相关的机会,要抓紧深入去体会。
struct platform_suspend_ops {
int (*valid)(suspend_state_t state);
int (*begin)(suspend_state_t state);
int (*prepare)(void);
int (*prepare_late)(void);
int (*enter)(suspend_state_t state);
void (*wake)(void);
void (*finish)(void);
void (*end)(void);
void (*recover)(void);
};
休眠唤醒的执行过程,依次是begin—>prepare—>prepare_late—>enter—>wake—>finish—>end.
休眠停留在enter函数中,唤醒和休眠是逆过程。
在Linux驱动层面,Linux电源管理子系统已经封装好了统一的接口,各种类型的设备驱动只需要实现相关的接口函数,操作系统在它认为合适的时候就会通知驱动完成这些操作。在一般设备驱动基础之上,使用pm_register和pm_unregister进行注册和注销,使用pm_access进行休眠可行性检测,使用pm_callback函数执行状态通知后的回调响应,使用pm_dev_idle,用于检测设备idle状态机制。
对Android还不熟悉,只是知道它在标准的linux休眠唤醒的机制上,增加了early suspend和late resume两种模式,具体分析待后续相关文章。
参考资料 :Linux acpi电源管理的高级应用
5 http://www.acpi.info:ACPI的官方网站,在上面可以免费获得最新的ACPI规范。
6 http://acpi.sourceforge.net:Linux下支持ACPI项目网站。官方Linux内核中ACPI的版本实际上已经远远落后于最新的版本,因为linux稳定版中对任何新特性的加入都是非常小心谨慎的。你可以从这里下载最新的ACPI补丁。
7 Linux核心源代码目录:Documentation/power/,里面有开发人员写的一些关于电源管理在Linux上实现的文档。