电源电池驱动适配及代码流程介绍
一、电源管理子系统架构图目录: /base/powermgr ├── battery_lite # 轻设备电池服务 ├── battery_manager # 电池服务 ├── battery_statistics # 耗电统计服务 ├── display_manager # 显示能效管理服务 ├── power_manager # 系统电源管理服务 ├── powermgr_lite #
一、电源管理子系统架构图

目录:
/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 提供了软硬件耗电统计的功能,可以查询硬件耗电或者应用耗电情况
本文主要以社区3.2release版本,对power_manager和battery_manager的HDF适配及当前的代码接口调用流程进行简要的介绍。
二、电源管理服务
2.1 目录
/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.2 电源驱动适配
systemability注册
该模块用于管理系统基础能力,本服务需要向该模块注册,否则systemability管理模块不会注册该服务
//可以看出电源服务是被打包到foundation进程的 <info> <process>foundation</process> <systemability> <name>3301</name> <libpath>libpowermgrservice.z.so</libpath> <run-on-create>true</run-on-create> <distributed>false</distributed> <dump-level>1</dump-level> </systemability> </info>
驱动注册
//驱动服务加载
static struct HdfDriverEntry g_powerinterfaceDriverEntry = {
.moduleVersion = 1,
.moduleName = "power_interface_service",
.Bind = HdfPowerInterfaceDriverBind,
.Init = HdfPowerInterfaceDriverInit,
.Release = HdfPowerInterfaceDriverRelease,
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
HDF_INIT(g_powerinterfaceDriverEntry);
#ifdef __cplusplus
}
注册实现
//HdfPowerInterfaceDriverBind
static int HdfPowerInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("HdfPowerInterfaceDriverBind enter");
auto *hdfPowerInterfaceHost = new (std::nothrow) HdfPowerInterfaceHost;
if (hdfPowerInterfaceHost == nullptr) {
HDF_LOGE("%{public}s: failed to create HdfPowerInterfaceHost object", __func__);
return HDF_FAILURE;
}
hdfPowerInterfaceHost->ioService.Dispatch = PowerInterfaceDriverDispatch;
hdfPowerInterfaceHost->ioService.Open = NULL;
hdfPowerInterfaceHost->ioService.Release = NULL;
auto serviceImpl = IPowerInterface::Get(true);
if (serviceImpl == nullptr) {
HDF_LOGE("%{public}s: failed to get of implement service", __func__);
delete hdfPowerInterfaceHost;
return HDF_FAILURE;
}
hdfPowerInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
IPowerInterface::GetDescriptor());
if (hdfPowerInterfaceHost->stub == nullptr) {
HDF_LOGE("%{public}s: failed to get stub object", __func__);
delete hdfPowerInterfaceHost;
return HDF_FAILURE;
}
deviceObject->service = &hdfPowerInterfaceHost->ioService;
return HDF_SUCCESS;
}
static int32_t PowerInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
struct HdfSBuf *reply)
{
auto *hdfPowerInterfaceHost = CONTAINER_OF(client->device->service, struct HdfPowerInterfaceHost, ioService);
OHOS::MessageParcel *dataParcel = nullptr;
OHOS::MessageParcel *replyParcel = nullptr;
OHOS::MessageOption option;
if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
HDF_LOGE("%{public}s:invalid data sbuf object to dispatch", __func__);
return HDF_ERR_INVALID_PARAM;
}
if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
HDF_LOGE("%{public}s:invalid reply sbuf object to dispatch", __func__);
return HDF_ERR_INVALID_PARAM;
}
return hdfPowerInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
}
//HdfPowerInterfaceDriverBind
static int HdfPowerInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("HdfPowerInterfaceDriverBind enter");
auto *hdfPowerInterfaceHost = new (std::nothrow) HdfPowerInterfaceHost;
if (hdfPowerInterfaceHost == nullptr) {
HDF_LOGE("%{public}s: failed to create HdfPowerInterfaceHost object", __func__);
return HDF_FAILURE;
}
hdfPowerInterfaceHost->ioService.Dispatch = PowerInterfaceDriverDispatch;
hdfPowerInterfaceHost->ioService.Open = NULL;
hdfPowerInterfaceHost->ioService.Release = NULL;
auto serviceImpl = IPowerInterface::Get(true);
if (serviceImpl == nullptr) {
HDF_LOGE("%{public}s: failed to get of implement service", __func__);
delete hdfPowerInterfaceHost;
return HDF_FAILURE;
}
hdfPowerInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
IPowerInterface::GetDescriptor());
if (hdfPowerInterfaceHost->stub == nullptr) {
HDF_LOGE("%{public}s: failed to get stub object", __func__);
delete hdfPowerInterfaceHost;
return HDF_FAILURE;
}
deviceObject->service = &hdfPowerInterfaceHost->ioService;
return HDF_SUCCESS;
}
//HdfPowerInterfaceDriverRelease
static void HdfPowerInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
{
HDF_LOGI("HdfPowerInterfaceDriverRelease enter");
if (deviceObject->service == nullptr) {
HDF_LOGE("HdfPowerInterfaceDriverRelease not initted");
return;
}
auto *hdfPowerInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfPowerInterfaceHost, ioService);
delete hdfPowerInterfaceHost;
}
配置设备信息
在vendor\hihope\rk3568\hdf_config\uhdf\device_info.hcs下添加电源电池等信息:
power :: host {
hostName = "power_host";
priority = 50;
uid = "power_host";
gid = ["power_host", "system", "log"];
caps = ["BLOCK_SUSPEND"];
power_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
moduleName = "libpower_driver.z.so";
serviceName = "power_interface_service";
}
}
battery_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
moduleName = "libbattery_driver.z.so";
serviceName = "battery_interface_service";
}
}
thermal_device :: device {
device0 :: deviceNode {
policy = 2;
priority = 100;
moduleName = "libthermal_driver.z.so";
serviceName = "thermal_interface_service";
}
}
}
配置电源模式
在base\powermgr\power_manager\services\native\profile\power_mode_config.xml下对电源相关模式可进行配置:
<!-- Power Mode Definitions: MODE_NORMAL = 600, MODE_POWER_SAVE = 601, MODE_PERFORMANCE = 602, MODE_EXTREME_POWER_SAVE = 603, --> <!-- Action Definitions: DisplayOffTime = 101, SystemAutoSleepTime = 102, AutoAdjustBrightness = 103, AutoWindowRotation = 107, SystemBrightness = 115, VibratorsState = 120, --> <switch_proxy version="1"> <proxy id="600"> <switch id="101" value="30000" recover_flag="0"/> <switch id="102" value="0" recover_flag="0"/> <switch id="103" value="-1" recover_flag="0"/> <switch id="107" value="1" recover_flag="0"/> <switch id="115" value="102" recover_flag="0"/> <switch id="120" value="1" recover_flag="0"/> </proxy> <proxy id="601"> <switch id="101" value="10000" recover_flag="0"/> <switch id="102" value="5000" recover_flag="0"/> <switch id="103" value="-1" recover_flag="0"/> <switch id="107" value="-1" recover_flag="0"/> <switch id="115" value="50" recover_flag="0"/> <switch id="120" value="-1" recover_flag="0"/> </proxy> <proxy id="602"> <switch id="101" value="-1" recover_flag="0"/> <switch id="102" value="-1" recover_flag="0"/> <switch id="103" value="-1" recover_flag="0"/> <switch id="107" value="1" recover_flag="0"/> <switch id="115" value="255" recover_flag="0"/> <switch id="120" value="1" recover_flag="0"/> </proxy> <proxy id="603"> <switch id="101" value="5000" recover_flag="0"/> <switch id="102" value="1000" recover_flag="0"/> <switch id="103" value="-1" recover_flag="0"/> <switch id="107" value="-1" recover_flag="0"/> <switch id="115" value="25" recover_flag="0"/> <switch id="120" value="-1" recover_flag="0"/> </proxy> </switch_proxy>
//\drivers\peripheral\power\bundle.json
{
"name": "@ohos/drivers_peripheral_power",
"description": "power_hdf",
"version": "3.1",
"license": "Apache License 2.0",
"publishAs": "code-segment",
"segment": {
"destPath": "drivers/peripheral/power"
},
.........
.........
}
2.2 电源主要功能流程
关机流程

重启流程

休眠流程

唤醒流程

强制休眠流程

三、电池管理服务
电池管理服务主要是对电池信息查询的操作以及耗电情况的查询,其目录结构与上面的电源的是一致的。
电池HDI层服务,是打包在power_host进程,所以针对描叙配置查看电源里的即可。
3.1 驱动加载
//定义host结构对象
namespace {
struct HdfBatteryInterfaceHost {
struct IDeviceIoService ioService;
OHOS::sptr<OHOS::IRemoteObject> stub;
};
}
//服务加载
static struct HdfDriverEntry g_batteryInterfaceDriverEntry = {
.moduleVersion = 1,
.moduleName = "battery_interface_service",
.Bind = HdfBatteryInterfaceDriverBind,
.Init = HdfBatteryInterfaceDriverInit,
.Release = HdfBatteryInterfaceDriverRelease,
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
HDF_INIT(g_batteryInterfaceDriverEntry);
#ifdef __cplusplus
}
#endif /* __cplusplus */
//HdfBatteryInterfaceDriverBind驱动接口实例化绑定
static int32_t HdfBatteryInterfaceDriverBind(struct HdfDeviceObject *deviceObject)
{
auto *hdfBatteryInterfaceHost = new (std::nothrow) HdfBatteryInterfaceHost;
if (hdfBatteryInterfaceHost == nullptr) {
BATTERY_HILOGE(COMP_HDI, "%{public}s: failed to create HdfBatteryInterfaceHost object", __func__);
return HDF_FAILURE;
}
//此处绑定了BatteryInterfaceDriverDispatch作为消息处理函数。
hdfBatteryInterfaceHost->ioService.Dispatch = BatteryInterfaceDriverDispatch;
hdfBatteryInterfaceHost->ioService.Open = nullptr;
hdfBatteryInterfaceHost->ioService.Release = nullptr;
auto serviceImpl = IBatteryInterface::Get(true);
if (serviceImpl == nullptr) {
BATTERY_HILOGE(COMP_HDI, "%{public}s: failed to get of implement service", __func__);
delete hdfBatteryInterfaceHost;
return HDF_FAILURE;
}
hdfBatteryInterfaceHost->stub = OHOS::HDI::ObjectCollector::GetInstance().GetOrNewObject(serviceImpl,
IBatteryInterface::GetDescriptor());
if (hdfBatteryInterfaceHost->stub == nullptr) {
BATTERY_HILOGE(COMP_HDI, "%{public}s: failed to get stub object", __func__);
delete hdfBatteryInterfaceHost;
return HDF_FAILURE;
}
deviceObject->service = &hdfBatteryInterfaceHost->ioService;
return HDF_SUCCESS;
}
static int32_t BatteryInterfaceDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data,
struct HdfSBuf *reply)
{
auto *hdfBatteryInterfaceHost = CONTAINER_OF(client->device->service, struct HdfBatteryInterfaceHost, ioService);
OHOS::MessageParcel *dataParcel = nullptr;
OHOS::MessageParcel *replyParcel = nullptr;
OHOS::MessageOption option;
if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {
BATTERY_HILOGE(COMP_HDI, "invalid data sbuf object to dispatch");
return HDF_ERR_INVALID_PARAM;
}
if (SbufToParcel(reply, &replyParcel) != HDF_SUCCESS) {
BATTERY_HILOGE(COMP_HDI, "invalid reply sbuf object to dispatch");
return HDF_ERR_INVALID_PARAM;
}
return hdfBatteryInterfaceHost->stub->SendRequest(cmdId, *dataParcel, *replyParcel, option);
}
//HdfBatteryInterfaceDriverInit返回错误将会终止驱动加载
static int32_t HdfBatteryInterfaceDriverInit([[maybe_unused]] struct HdfDeviceObject *deviceObject)
{
return HDF_SUCCESS;
}
//HdfBatteryInterfaceDriverRelease驱动的卸载,释放资源
static void HdfBatteryInterfaceDriverRelease(struct HdfDeviceObject *deviceObject)
{
if (deviceObject->service == nullptr) {
BATTERY_HILOGE(COMP_HDI, "HdfBatteryInterfaceDriverRelease not initted");
return;
}
auto *hdfBatteryInterfaceHost = CONTAINER_OF(deviceObject->service, struct HdfBatteryInterfaceHost, ioService);
delete hdfBatteryInterfaceHost;
}
3.2 batteryInfo信息查询流程
| 属性名称 | 类型 | 说明 |
|---|---|---|
| batterySOC | number | 表示当前设备剩余电池容量 |
| chargingStatus | BatteryChargeState | 表示当前设备电池的充电状态。 |
| healthStatus | BatteryHealthState | 表示当前设备电池的健康状态。 |
| pluggedType | BatteryPluggedType | 表示当前设备连接的充电器类型。 |
| voltage | number | 表示当前设备电池的电压。 |
| technology | string | 表示当前设备电池的技术型号。 |
| batteryTemperature | number | 表示当前设备电池的温度。 |
此处就以第一个属性batterySOC获取剩余电池容量为例:
接口流程

接口实现
napi_value BatterySOC:
//.\base\powermgr\battery_manager\frameworks\napi\battery_info.cpp
static napi_value BatterySOC(napi_env env, napi_callback_info info)
{
napi_value napiValue = nullptr;
int32_t capacity = g_battClient.GetCapacity();
NAPI_CALL(env, napi_create_int32(env, capacity, &napiValue));
BATTERY_HILOGD(FEATURE_BATT_INFO, "capacity %{public}d", capacity);
return napiValue;
}
BatteryService::GetCapacity()
int32_t BatteryService::GetCapacity()
{
int capacity = BATTERY_FULL_CAPACITY;
BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter");
if (iBatteryInterface_ == nullptr) {
BATTERY_HILOGE(FEATURE_BATT_INFO, "iBatteryInterface_ is nullptr");
return ERR_NO_INIT;
}
iBatteryInterface_->GetCapacity(capacity);
return capacity;
}
BatteryInterfaceImpl::GetCapacity
int32_t BatteryInterfaceImpl::GetCapacity(int32_t& capacity)
{
return provider_->ParseCapacity(&capacity);
}
PowerSupplyProvider::ParseCapacity
int32_t PowerSupplyProvider::ParseCapacity(int32_t* capacity) const
{
char buf[MAX_BUFF_SIZE] = {0};
int32_t ret = ReadBatterySysfsToBuff(batterySysfsInfo_.capacityPath.c_str(), buf, sizeof(buf));
if (ret != HDF_SUCCESS) {
return ret;
}
int32_t value = ParseInt(buf);
*capacity = value;
return HDF_SUCCESS;
}
int32_t PowerSupplyProvider::ReadBatterySysfsToBuff(const char* path, char* buf, size_t size) const
{
int32_t ret = ReadSysfsFile(path, buf, size);
if (ret != HDF_SUCCESS) {
BATTERY_HILOGW(FEATURE_BATT_INFO, "read path failed, ret: %{public}d", ret);
return ret;
}
return HDF_SUCCESS;
}
int32_t PowerSupplyProvider::ReadSysfsFile(const char* path, char* buf, size_t size) const
{
int32_t fd = open(path, O_RDONLY, S_IRUSR | S_IRGRP | S_IROTH);
if (fd < NUM_ZERO) {
BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to open file");
return HDF_ERR_IO;
}
size_t readSize = read(fd, buf, size - 1);
buf[readSize] = '\0';
Trim(buf);
close(fd);
return HDF_SUCCESS;
}
3.3 batteryInfo信息刷新流程
//在battery启动初始化阶段创建了线程,接收处理驱动内核层的消息
int32_t BatteryThread::LoopingThreadEntry(void* arg)
{
int32_t nevents = 0;
size_t size = callbacks_.size();
struct epoll_event events[size];
while (true) {
if (!nevents) {
CycleMatters();
}
HandleStates();
int32_t timeout = epollInterval_;
int32_t waitTimeout = UpdateWaitInterval();
if ((timeout < 0) || (waitTimeout > 0 && waitTimeout < timeout)) {
timeout = waitTimeout;
}
nevents = epoll_wait(epFd_, events, static_cast<int32_t>(size), timeout);
if (nevents <= 0) {
continue;
}
for (int32_t n = 0; n < nevents; ++n) {
if (events[n].data.ptr) {
//消息回调用于处理电池信息的刷新
auto* func = const_cast<BatteryThread*>(this);
(callbacks_.find(events[n].data.fd)->second)(func, arg);
}
}
}
}
//回调函数的功能处理
void BatteryThread::UeventCallback(void* service)
{
char msg[UEVENT_MSG_LEN + UEVENT_RESERVED_SIZE] = { 0 };
ssize_t len = recv(ueventFd_, msg, UEVENT_MSG_LEN, 0);
if (len < 0 || len >= UEVENT_MSG_LEN) {
BATTERY_HILOGI(COMP_HDI, "recv return msg is invalid, len: %{public}zd", len);
return;
}
// msg separator
msg[len] = '\0';
msg[len + 1] = '\0';
if (!IsPowerSupplyEvent(msg)) {
return;
}
//电池信息的刷新
UpdateBatteryInfo(service);
}
//刷新的属性及实现
void BatteryThread::UpdateBatteryInfo(void* service)
{
BatteryInfo event = {};
std::unique_ptr<BatterydInfo> batteryInfo = std::make_unique<BatterydInfo>();
if (batteryInfo == nullptr) {
BATTERY_HILOGE(FEATURE_BATT_INFO, "make_unique BatterydInfo error");
return;
}
provider_->UpdateInfoByReadSysFile(batteryInfo.get());
event.capacity = batteryInfo->capacity_;
event.voltage= batteryInfo->voltage_;
event.temperature = batteryInfo->temperature_;
event.healthState = batteryInfo->healthState_;
event.pluggedType = batteryInfo->pluggedType_;
event.pluggedMaxCurrent = batteryInfo->pluggedMaxCurrent_;
event.pluggedMaxVoltage = batteryInfo->pluggedMaxVoltage_;
event.chargeState = batteryInfo->chargeState_;
event.chargeCounter = batteryInfo->chargeCounter_;
event.present = batteryInfo->present_;
event.technology = batteryInfo->technology_;
event.curNow = batteryInfo->curNow_;
event.remainEnergy = batteryInfo->remainEnergy_;
event.totalEnergy = batteryInfo->totalEnergy_;
if (g_callback != nullptr) {
g_callback->Update(event);
} else {
BATTERY_HILOGI(FEATURE_BATT_INFO, "g_callback is nullptr");
}
}
参考文档
https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/电源管理子系统.md
更多推荐

所有评论(0)