- 电源管理子系统
1.电源管理子系统概述
电源管理子系统是 OpenHarmony 的基本能力子系统,有电池服务组件、显示控制组件和电源管理服务组件,主要提供如下功能:
- 重启服务:系统重启和下电。
- 系统电源管理服务:系统电源状态管理和休眠运行锁管理。
- 显示相关的能耗调节:包括根据环境光调节背光亮度,和根据接近光亮灭屏。
- 省电模式 :在不损害主要功能和性能的前提下,提供一种低功耗操作模式 。
- 电池服务:支持充放电、电池和充电状态的监测,包括状态的更新和上报,还包括关机充电。
- 温控 :在设备温度到一定程度之后对应用、SoC、外设进行管控,限制温升 。
- 耗电统计: 主要包括软件耗电和硬件耗电统计,以及单个应用的耗电统计 。
- 轻设备电池服务。
- 轻设备电源管理服务。
1.1.电源管理子系统架构
电源管理子系统架构图:
目录结构如下:
/base/powermgr
├── battery_lite # 轻设备电池服务
├── battery_manager # 电池服务
├── battery_statistics # 耗电统计服务
├── display_manager # 显示能效管理服务
├── power_manager # 系统电源管理服务
├── powermgr_lite # 轻设备电源管理服务
└── thermal_manager # 温控和热管理服务
电源管理提供了七个子部件,其中部分部件提供了对外接口或者公共事件通知,开发者可以根据场景使用:
- Power Manager 提供的接口,可以进行申请和释放休眠运行锁 RunningLock、设置电源模式、重启设备、关机等操作,同时也可以通过公共事件来监听省电模式和关机状态的变化。
- Battery Manager 提供了电池信息查询的接口,同时开发者也可以通过公共事件监听电池状态和充放电状态的变化。
- Thermal Manager 提供的设备温升状态的查询接口,同时开发者也可以通过注册回调和公共事件来监听设备温升状态。
- Battery Statistics 提供了软硬件耗电统计的功能,可以查询硬件耗电或者应用耗电情况。
- Display Power Manager 提供了亮度设置接口。
1.2.电源管理模式
OH节能模式有两种状态:熄屏状态和休眠状态。电源管理子系统包括内核态以及用户态的相互协同工作。
-
内核对休眠的支持与相关流程如下:
- freeze: 冻结I/O设备,将它们置于低功耗状态,使处理器进入空闲状态,唤醒最快,耗电比其它standby, mem, disk方式高
- standby:除了冻结I/O设备外,还会暂停系统,唤醒较快,耗电比其它 mem, disk方式高
- mem: 将运行状态数据存到内存,并关闭外设,进入等待模式,唤醒较慢,耗电比disk方式高
- disk: 将运行状态数据存到硬盘,然后关机,唤醒最慢
-
用户态电源管理子系统电源模式:正常模式,省电模式,性能模式,超级省电。可通过配置文件对详细策略进行修改:
- base/powermgr/power_manager/services/native/profile/power_mode_config.xml
如下图,电源管理服务与电源管理服务相互协同管理屏幕亮息屏及通过UHDF对设备电源的状态切换。
2.电源服务组件
电源管理服务组件是 OpenHarmony 的电源管理子系统中的重要组件之一,主要提供如下功能:
- 重启系统。
- 管理休眠运行锁。
- 系统电源状态查询。
电源管理子系统之电源管理服务组件架构图:
代码目录:
/base/powermgr/power_manager
├── figures # 架构图
├── frameworks # Framework层
│ ├── napi # NAPI层
│ └── native # Native层
├── interfaces # 接口层
│ └── inner_api # 内部接口
├── sa_profile # SA 配置文件
├── services # 服务层
│ ├── native # Native 层
│ └── zidl # Zidl 接口层
├── test # 测试用例
│ ├── fuzztest # Fuzz 测试
│ ├── unittest # 单元测试
│ ├── systemtest # 系统测试
│ └── utils # 测试工具
└── utils # 工具和通用层
2.1.电源管理策略
- OpenHarmony标准系统的统一电源管理策略配置,见 power_mode_config.xml (/base/powermgr/power_manager/services/native/profile/)文件,不同的配置对应不同的功耗情况。
17 <!--
18 Power Mode Definitions: // 电源模式定义
19 MODE_NORMAL = 600, // 正常模式
20 MODE_POWER_SAVE = 601, // 省电模式
21 MODE_PERFORMANCE = 602, // 性能优先
22 MODE_EXTREME_POWER_SAVE = 603,// 超级省电
23 -->
24 <!--
25 Action Definitions: // 行为定义
26 DisplayOffTime = 101, // 息屏时间控制
27 SystemAutoSleepTime = 102, // 系统自动睡眠时间控制
28 AutoAdjustBrightness = 103, // 亮度自动调整时间控制
29 AutoWindowRotation = 107, // 窗口自动旋转时间控制
30 SystemBrightness = 115, // 系统亮度调节
31 VibratorsState = 120, // 马达(震动)状态
32 -->
33 <switch_proxy version="1">
34 <proxy id="600">
<!-- value[单位:ms],-1表示不设置,如DisplayOffTime设为-1表示不息屏 -->
35 <switch id="101" value="30000" recover_flag="0"/>
36 <switch id="102" value="0" recover_flag="0"/>
37 <switch id="103" value="-1" recover_flag="0"/>
38 <switch id="107" value="1" recover_flag="0"/>
39 <switch id="115" value="102" recover_flag="0"/>
40 <switch id="120" value="1" recover_flag="0"/>
41 </proxy>
42 <proxy id="601">
43 <switch id="101" value="10000" recover_flag="0"/>
44 <switch id="102" value="5000" recover_flag="0"/>
45 <switch id="103" value="-1" recover_flag="0"/>
46 <switch id="107" value="-1" recover_flag="0"/>
47 <switch id="115" value="50" recover_flag="0"/>
48 <switch id="120" value="-1" recover_flag="0"/>
49 </proxy>
50 <proxy id="602">
51 <switch id="101" value="-1" recover_flag="0"/>
52 <switch id="102" value="-1" recover_flag="0"/>
53 <switch id="103" value="-1" recover_flag="0"/>
54 <switch id="107" value="1" recover_flag="0"/>
55 <switch id="115" value="255" recover_flag="0"/>
56 <switch id="120" value="1" recover_flag="0"/>
57 </proxy>
58 <proxy id="603">
59 <switch id="101" value="5000" recover_flag="0"/>
60 <switch id="102" value="1000" recover_flag="0"/>
61 <switch id="103" value="-1" recover_flag="0"/>
62 <switch id="107" value="-1" recover_flag="0"/>
63 <switch id="115" value="25" recover_flag="0"/>
64 <switch id="120" value="-1" recover_flag="0"/>
65 </proxy>
66 </switch_proxy>
备注:
修改电源管理策略参考:https://ost.51cto.com/posts/22630
- 唤醒源配置,见power_wakeup.json(base/powermgr/power_manager/services/native/profile/)
OpenHarmony支持多种唤醒源,如电源键、键盘、鼠标等,并提供了定制开启和关闭的方式。当设备进入休眠状态后,用户可以通过按电源键、按键盘、鼠标事件、轻触屏幕等,来点亮屏幕并唤醒设备。但不同的产品可能支持不同的外设,比如无手写笔、无皮套等。为此,OpenHarmony提供唤醒源的定制方式,产品可以根据具体的设计规格来定制此特性。
1 {
2 "powerkey": {
3 "enable": true //是否开启唤醒监听
4 },
5 "keyborad": {
6 "enable": true
7 },
8 "mouse": {
9 "enable": true
10 },
11 "touchscreen": {
12 "enable": true,
13 "click": 2 //点击次数
14 },
15 "touchpad": {
16 "enable": true
17 },
18 "pen": {
19 "enable": true
20 },
21 "lid": {
//lid 皮套唤醒
22 "enable": true
23 },
24 "switch": {
//switch 盖子唤醒
25 "enable": true
26 }
27 }
备注:
定制唤醒源参考:
https://www.seaxiang.com/blog/263c5f62883e453285ff757552c44a61
https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/subsystems/subsys-power-wakeup-source-customization.md
2.2.Power Manager Service 服务启动
源代码位置:
- base/powermgr/power_manager/services/native/src/power_state_machine.cpp
- base/powermgr/power_manager/services/native/src/power_mgr_service.cpp
2.2.1.Power Manager Service 注册
base/powermgr/power_manager/services/native/src/power_mgr_service.cpp:
auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
//调用SystemAbility接口注册PowerMgrService实例
const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(pms.GetRefPtr());
//构建入参为serviceid、runoncreate
PowerMgrService::PowerMgrService() : SystemAbility(POWER_MANAGER_SERVICE_ID, true) {
}
System Ability 管理模块调用 PowerMgrService 的启动函数实现电源管理服务组件的启动:
硬件上电后,电源管理服务被打包到 foundation 进程,将会进行 PowerMgrService 初始化。其中 powerStateMachine 也在 PowerMgrService 中进行初始化。详细启动流程看 System Ability 管理相关的资料。System Ability 管理模块调用 PowerMgrService 的启动函数 OnStart(),实现电源管理服务组件的启动。
2.2.2.Power Manager Service 启动
启动函数 OnStart() 最终分别通过调用 PowerStateMachine: Init()-> InitStateMap() 和 PowerStateMachine::InitState(),实现状态机的初始化和状态机的初态的设置。主要流程有:
-
调用 Init()函数,实现 PowerStateMachine 状态机的初始化;
-
调用 AddSystemAbilityListener(),监听依赖的服务,在 OnAddSystemAbility 中调用 RegisterBootCompletedCallback(),并根据具体的设备信息, 设置状态机的初始状态。
void PowerMgrService::OnStart()
{
POWER_HILOGD(COMP_SVC, "Power Management startup");
if (ready_) {
POWER_HILOGW(COMP_SVC, "OnStart is ready, nothing to do");
return;
}
// Init()方法,进行PowerStateMachine初始化,并根据设备信息,设置初始状态。
if (!Init()) {
POWER_HILOGE(COMP_SVC, "Call init fail");
return;
}
/* 监听依赖的服务:DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID/DISPLAY_MANAGER_SERVICE_ID
*/
AddSystemAbilityListener(DEVICE_STANDBY_SERVICE_SYSTEM_ABILITY_ID);
AddSystemAbilityListener(DISPLAY_MANAGER_SERVICE_ID);
// 注册HdiStatusListener
SystemSuspendController::GetInstance().RegisterHdiStatusListener();
if (!Publish(DelayedSpSingleton<PowerMgrService>::GetInstance())) {
POWER_HILOGE(COMP_SVC, "Register to system ability manager failed");
return;
}
ready_ = true;
POWER_HILOGI(COMP_SVC, "Add system ability success");
}
- PowerMgrService::Init()
调用PowerMgrService::PowerStateMachineInit(),对 PowerStateMachine 的初始化。
88 bool PowerMgrService::Init()
89 {
90 POWER_HILOGI(COMP_SVC, "Init start");
91 if (!runningLockMgr_) {
92 runningLockMgr_ = std::make_shared<RunningLockMgr>(pms);
93 }
94 if (!runningLockMgr_->Init()) {
95 POWER_HILOGE(COMP_SVC, "Running lock init fail");
96 return false;
97 }
98 if (!shutdownController_) {
99 shutdownController_ = std::make_shared<ShutdownController>();
100 }
// PowerStateMachine初始化 见下面
101 if (!PowerStateMachineInit()) {
102 POWER_HILOGE(COMP_SVC, "Power state machine init fail");
103 }
104
105 RegisterBootCompletedCallback();
106 POWER_HILOGI(COMP_SVC, "Init success");
107