android电池管理系统

◇◆丶佛笑我妖孽 提交于 2020-03-15 09:06:50

原文:http://www.2cto.com/kf/201408/326462.html

 

1、概述

随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统对电源管理的合理与否直接影响到电池的续航能力,而电池系统作为其中的一部分,主要用于对电池状态的监控(电池电量、电池状态及电池温度等)。下面将详细分析android的电池系统架构。

2、Android电池系统架构

Android系统中对电池的管理驱动层继承了linux下的power supply class,而在用户层则是在BatteryService.java中通过广播的方式将如下一些电池相关的属性上报给上层app使用。这些属性都是在java中声明,在jni中调用更新的。

 

而这些属性都是在com_android_server_BatteryService.cpp这个本地代码-jni中通过调用sys文件系统访问驱动层中电池相应的状态进行更新的。

代码路径:

frameworks/base/services/java/com/android/server/BatteryService.java

BatteryService 作为电池及充电相关的服务,主要作了如下几件事情: 监听 UEvent、读取sysfs 中的状态 、广播Intent.ACTION_BATTERY_CHANGED。

3.1、监听UEvent:

update读取sysfs文件做到同步取得电池信息,然后根据读到的状态更新BatteryService 的成员变量,并广播一个Intent来通知其它关注电源状态的组件。当kernel有power_supply事件上报时,mUEventObserver调用update()函数,然后update 调用native_update从sysfs中读取相关状态(com_android_server_BatteryService.cpp)。

3.3、广播Intent.ACTION_BATTERY_CHANGED

代码路径:

frameworks/base/services/jni/com_android_server_BatteryService.cpp

这是battery用户空间的本地代码,调用sys文件系统访问驱动程序,并向上层BatteryService封装本地方法以隔离平台化的差异。

在这个文件的头部有如下定义:

供上层BatteryService使用。另外,在这个文件中通过GetFieldID,得到BatteryService.java类中声明的电池属性ID,如下:

POWER_SUPPLY_PATH已经在文件头部定义过了,对应路径:/sys/class/power_supply,然后遍历整个文件夹,查找各个能源供应设备的各种属性,如上选中部分是用来查找交流设备的属性的。

各能源设备属性概况如下:

/sys/class/power_supply/ac/online AC 电源连接状态

/sys/class/power_supply/usb/online USB电源连接状态

/sys/class/power_supply/battery/status 充电状态

/sys/class/power_supply/battery/health 电池状态

/sys/class/power_supply/battery/present 使用状态

/sys/class/power_supply/battery/capacity 电池 level

/sys/class/power_supply/battery/batt_vol 电池电压

/sys/class/power_supply/battery/batt_temp 电池温度

/sys/class/power_supply/battery/technology 电池技术

当供电设备的状态发生变化时,driver会更新这些文件,然后通过jni中的本地方法android_server_BatteryService_update向java层发送信息。

5、驱动

5.1、驱动概述

android系统电池部分的驱动程序,继承了传统linux系统下的Power Supply驱动程序架构,Battery驱动程序通过Power Supply驱动程序生成相应的sys文件系统,从而向用户空间提供电池各种属性的接口。Linux标准的 Power Supply驱动程序所使用的文件系统路径为:/sys/class/power_supply ,其中的每个子目录表示一种能源供应设备。

来看看power_supply_sysfs.c这个文件。这里主要是对诸如如下这些电源设备属性创建uevent!

5.4、battery driver

目前项目(T808、T828)中所使用的电池检测与管理方式是POC ADC方式,对应的驱动文件是:

mediatek/kernel/drivers/power/battery_common.c

在此文件的probe函数里有如下内容:



可发现:ac和usb只创建了一个online属性,上层app通过判断ac和usb的online状态便可知道当前系统是由什么设备在充电了;而battery则创建了如:status、health、present、capacity、batt_vol等等和电池相关的诸多属性,上层app通过这些电池属性uevent便可监控电池的当前工作状态了。

举例说明一下这些属性的状态改变后是如何向系统发送更新消息的,来看看ac online的状态更新。

ac_update则最终会在bat_thread_kthread中进行轮循,在这里有一个全局的BMT_status,作为整个电源供应设备的各种属性传达!另外再来看看CHARGING_CONTROL battery_charging_control这个全局的函数指针,原型定义如下:

chr_control_interface函数原型如下:

可以看出通过如下的调用关系:


这些枚举类型所一一对应的函数中去,如上面调用关系CHARGING_CMD_GET_CHARGER_TYPE,则是获取charger type,函数原型如下:

但实际情况却不是这样的,正由于电池内阻的存在,通过直接测量电池电压(ADC)的方式获得的电池电量都会存在一定的误差,不管电池是处于供电还是放电的状态,这种误差都会存在,特别是在电池电量满、电池电量空及关机充电的情况下这种误差很容易被用户察觉,从而带来不好的用户体验。

通过上图可知,只要知道了电池内阻,就可以很容易地纠正这种误差。但电池的内阻不是不变的,而是随着电池电量的变化而变化的,不同型号的电池,这种特性还不一样,那么要想得到比较准确的电池电量,就很有必要让电池厂提供一组完整的电池电压与电池内阻的关系表了!

充放电过程中误差的纠正代码:

mediatek/kernel/drivers/power/battery_meter.c

在oam_run中有如下代码:

在头文件:

mediate/custiom/mt6572/kernel/battery/battery/cust_battery_meter.h

中有如下定义

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!