一、电源管理子系统架构图

 

目录:

/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

https://gitee.com/openharmony/powermgr_power_manager

https://gitee.com/openharmony/powermgr_battery_manage

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐