BatteryProperty上报流程

  1. 本流程主要涉及文件:

 

kernel层:qpnp-smbcharger.c    qpnp-fg.c     dwc3-msm.c  power_supply_core.c   power_supply_sysfs.c

文件路径:kernel\drivers\power\

 

system/core/healthd层:healthd.cpp BatteryMonitor.cpp、BatteryPropertiesRegistrar.cpp 

文件路径:system\core\healthd

 

framework层:

\frameworks\native\services\batteryservice\IBatteryPropertiesRegistrar.cpp

\frameworks\base\services\core\java\com\android\server\batteryservice.java

\frameworks\base\core\java\android\os\batterymanager.java

 

  1. kernel层:

2.1、Power_supply子系统:

Power_supply子系统在power_supply_core.c中创建:

power_supply_class = class_create(THIS_MODULE, "power_supply");

Power_supply子系统节点:

BatteryProperty上报流程_第1张图片

power_supply子系统支持kobject结构,在power_supply_sysfs.c文件中,支持show、store属性:

.show = power_supply_show_property,                     \

.store = power_supply_store_property,                     \

当用户空间执行cat capacity读取电量的时候,会调用 power_supply_show_property,在函数中会调用get_property,通过指针会调用到qpnp-smbcharger.c文件中的smbchg_battery_get_property

case POWER_SUPPLY_PROP_CAPACITY:

        val->intval = get_prop_batt_capacity(chip);

        break;

从而读取寄存器的值获取到电量,当然也能在这个文件下通过POWER_SUPPLY_ATTR自己创建节点。

电池电量capacity显示:

BatteryProperty上报流程_第2张图片

2.2、充电部分主要包含USB驱动部分、charger部分、FG部分,

他们之间是如何协调工作的?

       ==》对于USB、charger和FG,三个驱动在power_supply子系统下对应的节点分别为usb、battery、bms。 USB驱动通过dwc3_msm_pm_power_supplied_to关联到battery和bms,FG通过fg_supplicants关联到battery、bcl、fg_adc,charger部分则充当suppied_from,被动接收某些电池属性的变化(某些battery本身属性自己会检测上报)。

例:

       在USB驱动dwc3-msm.c 文件中,当充电器插入的时候,会通过power_supply_set_online设置usb online的状态,然后通过power_supply_changed函数上报,同时通知到charger部分。

 

2.3、power_supply_changed如何实现上报?

       ==》在power_supply_core.c文件中,电池属性上报通过power_supply_changed(struct power_supply *psy),此时会:

 

psy->changed = true;                  ==》设置属性变化标志位

pm_stay_awake(psy->dev);             ==》阻止系统休眠

schedule_work(&psy->changed_work);   ==》启动psy->changed_work 工作队列

 

在power_supply_changed_work工作队列中:

psy->changed = false;                  ==》清除标志位

__power_supply_changed_work         ==》调用sypplied_to和sypplied_from

power_supply_update_leds             ==》更新led灯状态

kobject_uevent                       ==》上报uevent事件

 

2.3.1、__power_supply_changed_work

       ==》__power_supply_changed_work中会调用supplied_to和supplied_from,从而将USB、charger、FG关联起来,battery下没有注册supplied_to,则被动接收电池属性变化(目前没有看到有注册supplied_from),同时也会调用到supplied_from这边的external_power_changed指针。例如在charger的smbchg_external_power_changed中则会做一些设置充电电流等操作。

例:

       之前在smbchg_external_power_changed函数中添加了一个sleep(1000),导致手机开机过后出现死机现象,分析原因为external_power_changed函数处于自旋锁中,自旋锁的含义是一直占着进程资源不释放不让系统休眠,而sleep函数是让出当前CPU让系统进入休眠,从而导致冲突。

 

2.3.2、kobject_uevent上报uenevt事件

       ==》kobject_uevent函数会通过netlink_broadcast_filtered以netlink(一种socket通信)的方式上报,netlink能够实现内核空间与用户空间通信。

 

最后在if (likely(!psy->changed))

              pm_relax(psy->dev);         ==》上报完成过后释放锁,让系统休眠

 

2.4kernel部分小结:

kernel部分首先将USB、FG、charger几个部分通过sypplied_to关联起来,检测到任何一个部分电池属性有变化时,会调用power_supply_changed函数上报,同时更新信息到相关联模块,最终通过netlink上报uevent事件,在上报的整个过程中,系统保持唤醒状态。

 

3system/core/healthd

3.1、healthd收到uevent事件后如何处理?

       ==》在healthd.cpp文件中,healthd_mainloop函数中有while(1)一直等待EPOLL事件的发生,监听uevent事件。

       此函数会回调到uevent_event函数中,它会读取socket中的字符串,然后判断事件来源是否是由kernel的power_supply子系统发出的。

代码if (!strcmp(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) ,如果是,那就调用healthd_battery_update()更新电源状态,

 

healthd_battery_update函数中的gBatteryMonitor->update()为接口,真正实现在BatteryMonitor.cpp文件的update函数,此时会遍历power_supply子系统节点下所有电池属性(底层电池属性有变化时,会通过set_property写到节点里面去),在update最后会调用healthd_mode_ops->battery_update(&props);

此时又会调回到healthd.cpp中的healthd_mode_android_battery_update,

BatteryMonitor.cpp文件主要是对电池属性的汇总以及遍历电池属性。

 

3.1.1 在healthd_mode_android_battery_update函数中 notifyListeners通知正在监听的对象。

 if (gBatteryPropertiesRegistrar != NULL)

        gBatteryPropertiesRegistrar->notifyListeners(*props);

 

3.2 在BatteryPropertiesRegistrar.cpp文件中的 notifyListeners会触发batteryPropertiesChanged。

 

3.3  healthd部分小结:

healthd部分小结:在healthd中会一直循环监听kernel上报的uevent事件,当监听到有power_supply子系统上报的uevent事件时会遍历其目录下所有节点,之后又会通过 notifyListeners上报给正在监听battery属性变化的对象。

 

4framework

       4.1、当healthd上报监听过后,framework如何实现监听?

       ==》在BatteryPropertiesRegistrar.cpp文件中,除了能够接收healthd上报的notifyListeners之外,还会registerListener,上层根据自己的需要去实现监听接口即可监听电池属性的变化,对于batteryPropertiesChanged,真正的监听在batteryservice.java中实现,变化的属性通过Binder机制通信IBatteryPropertiesListener .cpp作为客户端,batteryservice作为服务端。

 

4.2、没有JNI,batteryservice.java如何访问BatteryPropertiesRegistrar.cpp?

==》实际上IBatteryPropertiesListener  、IBatteryPropertiesRegistrar 在framework层都有对应的aidl 文件。编译的时候通过aidl会自动生成 IBatteryPropertiesListener.java  与 IBatteryPropertiesRegistrar.java 文件。

 

aidl文件目录:

\frameworks\base\core\java\android\os\IBatteryPropertiesListener.aidl  

4.3、当batteryservice.java监听到相应属性变化时,如果是电池过温或者电量过低等情况,则会弹出相应的提示框。

 

4.4、同时在batterymanager.java中也会实现registerlistener监听电池属性的变化,用于上层充电图标的显示。

  public BatteryManager() {

        mBatteryStats = IBatteryStats.Stub.asInterface(

                ServiceManager.getService(BatteryStats.SERVICE_NAME));

        mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(

                ServiceManager.getService("batteryproperties"));

    }  

 

4.5 、framework层小结:

       framework层会根据自己的需要实现监听接口,一旦监听到healthd有上报电池属性变化,batteryservice.java则会根据具体情况弹出提示框,而batterymanager.java则会显示相应的充电图标、电量等。

 

 

你可能感兴趣的:(充电流程)