前言
为了节省功耗,需要让系统在不需要工作的时候尽可能的休眠(甚至断电)。同时,为了不影响到系统功能的正常运作,又必须保证休眠不能打断正在进行的重要事务,且能在适时还原回来。因此,一个高效运行的Low Power框架必不可少。 本文以Linux 4.4内核为基础,介绍Linux的Low Power框架。
架构
Linux的电源管理架构如下图。首先内核态导出了一些sysfs节点,用来给用户空间态作电源管理控制:
- /sys/power/autosleep : 主要用于控制是否开启内核自动休眠,之后会有章节介绍
- /sys/power/state:直接控制进入休眠(有多种state,后边会看到)
- /sys/power/wake_lock&wake_unlock:拿Wake lock和释放Wake lock,用于避免正在处理重要事务时系统进入休眠
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36+-----------+
|应 用 程 序|
+------------------+ +-----+-----+
|电 源 管 理 程 序 +---------+ |
+-----+------------+ | |
| | |
| | |
用 户 空 间 态 v v v
/sys/power/autosleep /sys/power/state /sys/power/wake_lock&wake_unlock
+------------------+----------------------+-----------------+---------------------------
| | |
内 核 态 | | |
v v v
+-----+----------------------+-----------------+---+
| sysfs |
+--------------------------------------------------+
kernel/power/main.c |
+ |
+--------------------------------------------------------|-------------------------+
| | v 电 源 管 理 框 架 |
| | +--------------------------------+ |
| v | | |
| +----------+ | Wakeup Source | |
| |autosleep | <---------------+ | |
| +----------+ +----------------------------^---+ |
|kernel/power/autosleep.c | |
| | +-----+-----------+ |
| | | | |
| |-------------------------------------------->| 驱 动 程 序 | |
| v | | |
| +-----+--------+ +-----------------+ |
| | 平 台 相 关 | |
| | 睡 眠 代 码 | |
| +--------------+ |
| |
+----------------------------------------------------------------------------------+
内核态是实现电源管理的核心代码,主要分为如下几大功能模块:
- 提供用户空间态操作的SYSFS节点操作
- 记录系统中拿睡眠锁的Wake Source
- 内核自动休眠例程Autosleep
- 平台相关睡眠(及唤醒)代码
- 各个硬件驱动程序:
- 注册硬件相关的睡眠及唤醒代码,保证经过一次断电恢复后的硬件仍能正常工作。
- 根据应用需要,拿Wake Lock和释放Wake Lock,保证硬件驱动可以正常工作。
数据和变量
在对电源管理的系统流程进行介绍之前,先对电源管理的一些必要的数据结构和关键变量进行分析。
wakeup_source/wakeup_sources
wakeup_source名字具有一定迷惑性,乍一看像是触发系统从睡眠中唤醒的唤醒源,实则不然。这个结构体是用来描述所有“阻挡”系统进入休眠的对象,即向电源管理模块拿wakelock用的。而wakeup_sources则是记录系统中所有wakeup_source的链表。
1 | struct wakeup_source { |
suspend_state_t
描述系统休眠几种不同状态,按照睡眠从浅入深分别是:
- On:未休眠
- Freeze:轻量级的休眠状态。
- Standby:中等休眠状态,CPU没有挂起(Memory和CPU带电)
- Mem:深度休眠,系统及设备状态挂起到Memory(Memory仍然带电),CPU不再工作(少数外围设备工作)。
1
2
3
4
5
6
7
8
9
10
11
12
13typedefint __bitwise suspend_state_t;
combined_event_count
用于记录系统中已注册的wakeup事件数量和正在生效的wakeup事件数量。这两个变量需要一起更新的,所以用combined_event_count一个变量来记录。高16 bit存放正在生效的wakeup事件数量,低16bit存放wakeup事件总数量。
后续章节预告
Autosleep及power状态设置流程 Autosleep代码分析 Wakelock拿锁与释放锁流程分析