电源电池驱动适配及代码流程介绍
一、电源管理子系统架构图目录: /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)