android电池管理系统
原文: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文件系统访问驱动层中电池相应的状态进行更新的。

3、BatteryService
代码路径:
frameworks/base/services/java/com/android/server/BatteryService.java
BatteryService 作为电池及充电相关的服务,主要作了如下几件事情: 监听 UEvent、读取sysfs 中的状态 、广播Intent.ACTION_BATTERY_CHANGED。
3.1、监听UEvent:

BatteryService实现了两个UEvenObserver mUEventObserver(如上代码所示)。uevent是Linux 内核用来向用户空间主动上报事件的机制,对于JAVA程序来说,只实现 UEventObserver的虚函数 onUEvent,然后注册即可。
3.2、读取sysfs电池状态

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

通过广播Intent.ACTION_BATTERY_CHANGED,将电池状态、电池电量、电池工艺等属性打包,发送给其它的使用者,也就是说,只要在app程序里监听了Intent.ACTION_BATTERY_CHANGED这个广播,就能获取到电池的各种状态属性!
4、本地代码-jni
代码路径:
frameworks/base/services/jni/com_android_server_BatteryService.cpp
这是battery用户空间的本地代码,调用sys文件系统访问驱动程序,并向上层BatteryService封装本地方法以隔离平台化的差异。
在这个文件的头部有如下定义:

这个就是底层battery驱动所生成的sys文件系统路径。
在这个文件里封装了一个本地方法:

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

关于java与c/c++互调的问题,这里就不再赘诉了,网上有很多的资料。
在这个文件里通过操作相应的sys文件系统来获取电池的各种属性值,看看如下这段代码:

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 ,其中的每个子目录表示一种能源供应设备。

5.2、驱动头文件
Power Supply驱动程序头文件kernel/include/linux/power_supply.h,注册和注销驱动程序的函数如下:
intpower_supply_register(struct device *parent,struct power_supply *psy);
voidpower_supply_unregister(struct power_supply *psy);
structpower_supply {
constchar *name; /*设备名称*/
enumpower_supply_type type; /* 类型 */
enumpower_supply_property *properties; /* 属性指针 */
size_tnum_properties; /*属性的数目*/
char**supplied_to;
size_tnum_supplicants;
int(*get_property)(struct power_supply *psy, /*获得属性*/
enumpower_supply_property psp,
unionpower_supply_propval *val);
void(*external_power_changed)(struct power_supply *psy);
/* ...... 省略部分内容 */
};
5.3、power supply core
对应的驱动程序:power_supply

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

这些uevent节点不一定都会创建,节点创建与否还和具体的电源设备驱动传进来的num_properties和properties有关,在创建uevent函数power_supply_uevent中可以很容易的看出这一点:

5.4、battery driver
目前项目(T808、T828)中所使用的电池检测与管理方式是POC ADC方式,对应的驱动文件是:
mediatek/kernel/drivers/power/battery_common.c
在此文件的probe函数里有如下内容:

可以看出,在这里将ac、usb及battery三种电源供应设备注册到了power supply core中去了,而相应的全局结构体变量ac_main、usb_main及battery_main作了如下定义:


各个电源设备所需要创建的uevent节点由这里传入的xx_props决定,相应的定义如下:

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

该函数在power supply sysfs中show property的时候得到调用,而AC_ONLINE作为ac电源唯一的属性会在ac_update中得到更新:

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


chr_control_interface函数原型如下:

对应文件路径:
mediatek/platform/mt6572/kernel/drivers/power/charging_hw_pmic.c
charging_func函数指针数组定义如下:

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

最终会调用到由:

这些枚举类型所一一对应的函数中去,如上面调用关系CHARGING_CMD_GET_CHARGER_TYPE,则是获取charger type,函数原型如下:
在这里通过pmic的硬件状态来获取相应的信息。
5.5、充电误差纠正
理想中的电池是没有内阻的,电池电压的消耗都在外部的负载上。

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

那么针对电池内阻导致的这个误差,完全可以通过数学方式进行纠正。

通过上图可知,只要知道了电池内阻,就可以很容易地纠正这种误差。但电池的内阻不是不变的,而是随着电池电量的变化而变化的,不同型号的电池,这种特性还不一样,那么要想得到比较准确的电池电量,就很有必要让电池厂提供一组完整的电池电压与电池内阻的关系表了!
充放电过程中误差的纠正代码:
mediatek/kernel/drivers/power/battery_meter.c
在oam_run中有如下代码:

函数mtk_imp_tracking就是针对充放电过程中电池内阻所产生的压降所作的一个△V的修正。
另外一个是,由于电池特性,在开关机的时候会出现电量跳变的问题,在系统中采用了将关机时的UI电量保存到RTC中,在下次开机的过程中用实际检测到的电量值与保存到RTC中的UI电量值进行比较判断,由于用户可能会更换电池,这两者之间的差值控制在了20%的范围内,也就是说:实际检测到的电量值在RTC中保存的UI电量值的20%范围内则使用保存在RTC中的UI电量值作为当前电池的电量值;如果实际检测到的电量值超过了RTC中UI电量值的20%,则认为用户更换了电池,用实际检测到的电量值作为当前电池的电量值。
相应的判断代码如下:

在头文件:
mediate/custiom/mt6572/kernel/battery/battery/cust_battery_meter.h
中有如下定义

6、写在最后
关于电池电量检测的算法过程,这里不再赘述,在MTK发布的Customer_Training_Battery_Charging.pdf这个文件中有比较详细的讲述。
android电池管理系统的更多相关文章
- Android 电池管理系统架构总结 Android power and battery management architecture summaries
文章目录 1 整体架构 2 设计构架 2.1 driver 2.1.1 Charger.ko 2.1.2 Battery.ko 2.2 power supply 2.2.1 基础架构 2.2.2 代码 ...
- android电池管理系统从上层的java到底层驱动的调用(转载)
1.概述 随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统对电源管理的合理与否直接影响到电池的续航能力,而电池系统作为其中的一部分,主要用于对电池状 ...
- 【转】android电池(五):电池 充电IC(PM2301)驱动分析篇
关键词:android 电池 电量计 PL2301任务初始化宏 power_supply 中断线程化 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 ...
- 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇
关键词:android 电池 电量计 MAX17040 任务初始化宏 power_supply 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台: ...
- 【转】android 电池(三):android电池系统
关键词:android电池系统电池系统架构 uevent power_supply驱动 平台信息: 内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV3 ...
- 【转】android 电池(二):android关机充电流程、充电画面显示
关键词:android 电池关机充电 androidboot.mode charger关机充电 充电画面显示 平台信息:内核:linux2.6/linux3.0系统:android/android4. ...
- 【转】android 电池(一):锂电池基本原理篇
关键词:android 电池关机充电 androidboot.mode charger 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV3 ...
- Android 电池系列
android 电池(一):锂电池基本原理篇 android 电池(二):android关机充电流程.充电画面显示 android 电池(三):android电池系统 android电池(四):电池 ...
- GBT27930-2015电动汽车非车载传导式充电机与电池管理系统之间的通信协议
本标准规定了电动汽车非车载传导式充电机(简称充电机)与电池管理系统(Battery Management System,简称BMS)之间基于控制器局域网(Control Area NetWork,简称 ...
随机推荐
- HDU_1018_n(1e7)的阶乘的结果的位数
http://acm.hdu.edu.cn/showproblem.php?pid=1018 Big Number Time Limit: 2000/1000 MS (Java/Others) ...
- Objective-C中copy 、retain以及ARC中新加入的strong、weak关键字的含义
copy: 创建一个引用计数为1的对象,然后释放旧的对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的引用计数为 1 Copy其实是建立了一个相同的对象,而retain不是: ...
- MFC_1.3 控件子类化 消息反射
控件子类化 如果想要在默认的控件类中添加一些功能,就需要子类化一个控件类 在类内可以响应控件所有的消息,并且可以添加自己的函数和数据 通过类向导子类化控件的步骤 打开类向导,创建一个 MFC 类,不要 ...
- 事件的节流(throttle)与防抖(debounce)
事件的节流(throttle)与防抖(debounce) 有些浏览器事件可以在短时间内快速触发多次,比如调整窗口大小或向下滚动页面.例如,监听页面窗口滚动事件,并且用户持续快速地向下滚动页面,那么滚动 ...
- spring源码下载链接
http://www.blogjava.net/zhyiwww/archive/2014/10/17/418809.html
- springBoot启动及发布
1.在项目编辑器(IDEA)中启动 运行springBoot项目Application类中main方法,这两个按钮都可以.如下图: 当然还有我们配置的启动按钮,这是最常用的启动方式,不再赘述,如下图: ...
- 第九节:web爬虫之urllib(五)
第四个模块 robotparser: 主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬的,其实用的比较少.
- 勇者斗恶龙 UVA 11292
Once upon a time, in the Kingdom of Loowater, a minor nuisance turned into a major problem. The shor ...
- spring boot 的使用(一)
1. 启动spring-boot项目 mvn spring-boot:run cd target java -jar xxxx.jar xxxx代表生成的jar包
- App后台开发运维和架构实践学习总结(3)——RestFul架构下API接口设计注意点
1. 争取相容性和统一性 这里就要求让API设计得是可预测的.按照这种方式写出所有接口和接口所需要的参数.现在就要确保命名是一致的,接口所需的参数顺序也是一致的.你现在应该有products,orde ...