MTK Fuel Gauge算法分析重点讲义_第1页
MTK Fuel Gauge算法分析重点讲义_第2页
MTK Fuel Gauge算法分析重点讲义_第3页
MTK Fuel Gauge算法分析重点讲义_第4页
MTK Fuel Gauge算法分析重点讲义_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、SW FG 算法分析目录1, Battery架构简析2, MTK 电量算法简析3, 72/82平台SW FG算法分析4, 误差和消除误差Battery架构简析MTK平台Battery软件架构基本如下图所示。具体过程:硬件ADC读取Battery的各路信息:包括温度,电压等。MTK开发的电量算法分析得到的数据。Kernel层将电量信息通过写文件节点的方式更新,并通过UEVENT通知上层。上层Service开启UEVENT LISTENER,监听到UEVENT后,读取battery相关文件节点,获取电量信息。Service更新数据后,通过Broadcast通知所有开启了相关listener的act

2、ivities。根据不同的电量读取和计算的策略,第一步的读取和第二步的算法部分会有比较大的差异,而后面的数据更新和事件通知部分一致性较高。本篇重点分析72/82平台SW FG算法实现,对比SW_FG 和HW_FG在硬件及软件上的部分差异,分析电量误差形成的一些原因和MTK已经采取的消除误差的措施。对于Battery数据更新和充电流程则粗略分析。 充电状态机,battery充电的逻辑,就依赖于这张图,如果是用的external charger ic,则应当参考该IC的充电逻辑。linear charging下 cc转 cv,是通过ADC读取电压后,软件切换。而使用charger ic 则很可能是

3、硬件直接切换。这部分的相关代码路径在:alps/mediatek/kernel/drivers/power/linear_charging.calps/mediatek/kernel/drivers/power/switching_charging.ckernel层battery驱动工作的流程,Bat_thread是工作的重点,通过单独的线程依赖10s定时器,更新battery相关信息。电量算法分析后得到的数据也不会直接update,Information Processing还会针对一些特殊情况对显示电量做调整,比如0%tracking&100%tracking。除了10s一次的定时

4、器更新,插拔充电器会触发中断,中断处理时同样会更新battery数据。所有和 电池 充电相关的数据都存储在power_supply类型的结构体中,这是linux标准的电源子系统体系。MTK电量算法简析为了得到较为精确的电量数据,需要改善测量方式和计算方法,并针对已知误差采取优化手段。一下介绍MTK平台下采用的一些电量算法。AUX ADC算法:事实上,所有算法都要依赖ADC读取电量信息,这边的AUX ADC算法指只依赖ADC读值,然后查表读取电量的算法。这种算法只重构了ZCV table,误差会很大。库仑积分法:通过开路电压查表得到初始电量D0,后续电量通过电流积分累积,通用性强,依赖初始电量的

5、精确度。混合型算法:SW FG算法和HW FG算法。事实上MTK平台项目通常采用的是混合型算法。 SW FG的参考电路:HW FG的参考电路:相同点: NTC电阻用于测量温度,ADC测量各路信号。不同点: HW FG有单独的ADC和20毫欧的电阻作电流的侦测。HW FG 和SW FG最大差异就是电流的获取方式。混合算法的流程,HW FG通过FG ADC读取FG电阻两端电压获得电流, 而SW FG则结合库伦算法通过SW方式算得。这部分会详细介绍。72/82平台SW FG算法分析主要分析上图黄色部分大部分项目都采用混合算法,下面从算法初始化开始介绍下SW FG的算法实现。battery_meter

6、.c这个C文件 主要负责电池电量算法的实现 向上主要承接battery_common.c 向下调用battery_meter_hal.c中的接口,以读取电池的各路信号。=>battery_meter_initial首先看下调用这个func的timing。显然 在开机初始化阶段,就会进入该函数,且只会运行一次。针对AUXADC SW_FG HW_FG三种不同的电池算法方案,分别初始化,因为82平台采用的SW_FG, 所以接下去先主要分析SW_FG的流程。SW_FG的准备工作 分为两步: table_init oam_init先看table_init首先要获取当前的温度信息=> for

7、ce_get_tbatADC读值这边就是MTK为了结合实际温度 获取较为精确的电池信息 而采取的线性平均值法。原理是利用预先测得的分布在-10 0 25 50 摄氏度下的ZCV表,结合真实温度,动态重构一张当前温度下的ZCV表格。TEMPERATURE对应预留的空ZCV表格,如下构造新表的函数如下采用线性平均法 填补了有效温度内所有的ZCV对应值 但与真实曲线必然存在一定的误差。=>oam_init常见的指针函数 传参比较有趣 vol_bat这个参数下传给底下pmic做count,然后被重新赋值成读取的v_bat值 之所以能这样做 是因为这两块代码 同处在kernel层 并地址传参 ba

8、ttery_meter_hal.c 虽然顶着hal的名头,其实是驱动程序,工作在内核层,主要实现上表各结构体 针对MTK不同种的充电方案 读取各项参数,包括v_bat temperature v_i_sense 等这边走pmic这个函数也是起分流作用的 通过dwchannel,分到不同的处理函数去。硬件上,ADC通过一个mux 数据选择器 对各路模拟信号进行切换 有点类似cpu的时间片和移动通信的时隙切换。 vbat是channel 5, 要等到adc数据ready 才能去读寄存器,看一下pmic的手册精度15bit的ADC 其中14bit用来存储数据 1个bit做ready信号 ,似乎ADC

9、3 和我们之前的dwchannel number有点对不上? 可以看到 dwchannel 5 最终访问的仍是ADC3,另外可以直接比较下寄存器地址。和datasheet左上角的寄存器地址一致最后还要做次数值转换,公式如下:分辨率计算:测量电压范围/(2AD位数-1)另外,对于同为电压值的v_bat 和 v_i_sense,可能会出现adc量程不够的问题 这时候需要通过电阻分压。 所以case 6 和 7 的r_val_temp为分压比和前面一样 ADC读值 但是6320的spec上对于PCHR没有说明 从函数定义的名称上看 是开路电压 但是如何在一个闭路的环境中通过ADC读取ocv,有些不解

10、。 查了下读这个值的timing,只有在init suspend 和resume的时候才去获取.猜想 一是可能 利用linear charging这种充9停1的方式,在第10s读取电压 作为OCV 也可能是因为刚开机时 电流还不大 读到的电压值 可用作OCV 总之 这个值应该是真实的开路电压的一个近似值。=> oam_init根据电压读表获取电量可以看到 用的是table_init时重构的新表Ok 这边再一次 利用线性平均法 这一次是针对ADC读到测到的电压 线性平均后 得到一个较精准的电量=> oam_init首先判断是否插着充电器,读PMU寄存器实现为什么 需要判断有没有插着充

11、电器呢?我是这么理解的,之前通过ADC读取了两个电压值 其中一个是V_BAT 另一个是hw_ocv 是在闭路环境下读取的开路电压近似值, 如果此时插着充电器,会有充电电流通过 这个hw_ocv的值和开路电压的误差会增大,因此需要做进一步的处理。插入充电器时,电量误差不大于30 满电误差不大于10 否则hw_ocv无效=>oam_init Dod是指用电深度,100-dod = 电池剩余容量看一下 dod_init的实现ð dod init首先看g_rtc_fg_soc这个变量 MTK的策略是 每隔一段时间将当前电量存储到RTC寄存器中,在开机时读取该电量。主要目的是改善用户体验

12、。看下这个值是何时被写入的:电池信息 10s update 1次 同样UI 电量 10s 存入RTC寄存器一次。用7个bit 存储 电量信息。开机时直接显示关机时保存的电量,会增强用户体验性,但是如果是更换电池或其他情况 造成关机电量和开机电量相差过大,显然应该采用开机电量,否则后续电池电量跳变反而会影响用户体验。Normal boot下忽略|后面的条件 主要就是要求没有插入充电器 不处于低电量 误差不超过40%经过前面所有的判断 最终得到了gFG_capacity 这个电量,也就是开机电量 因为开机电量在整个电量计算中相当重要并且又要结合用户体验 所以之前会有很多的条件分支。Q_MAX_PO

13、S_25 是常温下电池容量 因为FG算法计算电池容量 会用到库伦积分 所以需要关注电池容量的问题。这个值需要根据实际电池容量客制化。即 25度用标准容量 其他温度下需要乘上一个比例值。oam_v_ocv_1 和oam_v_ocv_2 现在是根据 dod_init的结果取得的 大部分情况下就是关机电量查表得到的ocv电压值 而注释掉的原方案 直接采用hw_ocv的值这边是算 ocv1 和 ocv2 对应的电池内阻 r,通过查表的方式获取 因为r和v的对应表 也是开路条件下测得 所以用hw_ocv查表获取的值 比 原先通过vbat 取平均要精准些。其他一些oam 电量算法 需要的参数初始化oam_

14、init 后, oam_run这个func负责 电量的计算,看一下调用的时机。=>mt_battery_GetBatteryData显然也是10s 轮询一次,get_percentage这个func 多个分支对应不同的电量算法=>oam_run先看下MTK SW FG算法的原理图SW FG的核心 在于 通过两种方式更新电压,去逼近真实开路电压 最终查表获取近似真实的电量值。ocv1 被假定为开路电压 ocv2则是闭路电压,以下结合实际代码和上述流程图分析下SW_FG 算法流程D0 D1 D2 D3 D4 D5 代表不同的放电深度这个算法的思路是这样的: 最终通过开路电压oam_v_

15、ocv_1查ZCV表得到当前的电量值 -> 开路电压需要通过闭路电压v_bat 和 闭路电流oam_i_2 去回溯电池内阻 逐次逼近 > oam_i_2 通过 另一种方式 电量积分更新的电压oam_v_ocv_2总的来说:电压通过两种方式更新 电流积分求电量后查表 / 电池内阻回溯IR drop求得 电池内阻 更新方式只有一种 根据电压查表具体分析部分代码:闭路电压的更新 不需要算法支持 直接通过读寄存器实现,注意vol_bat这个参数被复用,下传表平均次数 返回时为最终的v_bat电压值ocv_1 和 ocv_2 分别是两种方式更新的电压 这边通过内阻的IR drop求电流.上图

16、R 可以是电池内阻关键是oam_i_2 这边的I2 有几个作用:<1>因为电流是通过上图的内阻IR drop得到的,而方式一内阻回溯逼近开路电压本质也是IR drop,如果使用oam_i_1 则没有意义,只能使用不同体系的I2.<2>方式二 电流积分求电量查表 同样依赖 oam_i_2 这个体系是累积积分 不需要引用其他体系的参数<3>I2的方向作为充电还是放电的依据而oam_i_1只有作用3oam_car_1/oam_car_2 是累积电量 显然oam_car_2是算法的有效参数gFG_BATT_CAPACITY_aging 是电池总容量 之前分析过了 根

17、据开机时读取的电池温度 会有所不同d2 为积分法算出的电池当前容量 d0为开机电量 不会更新 d1不重要内阻回溯 IR drop 逼近开路电压,具体分析下:主要是这个for循环,首先通过v_bat去查表得到电池内阻r 然后用另一种算法求得的电流I和内阻r 算出内阻分去的电压v,推算ocv_1.几次循环 反复这个过程 逼近真实的开路电压。有几个注意点:1,这边的电压单位到底是v 还是mv? 实际上是0.1mv2,gFG_resistance_bat和R_FG_VALUE 分别是指代 电池内阻和硬件FG 使用的FG电阻(一般是20毫欧) 这边是SW_FG 所以后一项为03,因为ret_compen

18、sate是int型变量 做除法时取整处理 会引入较大误差, 加上这个值使结果四舍五入实际做6次内阻回溯,这时的电压值已经和开路电压比较接近,查表得到D3,D3基本就能反映当前电量了。MTK在D3的问题上针对电量跳变的情况 又做了步优化得到D5,看下代码这部分代码比较简单,1分钟内电量值不会改变,且每分钟电量的变化不会大于1%,这样用户体验会比较好。防止因为低电压时陡峭的电量曲线,以及比较耗电的应用,或突然的大电流引起的电量跳变。当然特殊应用下应该取消这个功能,否则会带来电量变化延时等问题。这边的返回值将填充BMT_status.SOC ,这个参数再经过优化得到BMT_status.UI_SOC

19、就是菜单栏看到的电池电量了。误差和消除误差因为电量值本身不容易通过仪器直接测量,只能依赖开路电压与电量的关系即电量曲线或者电流积分公式演算,这样一个过程会有很多产生误差的点,MTK针对其中一些给出了优化方式。另外 由于电池特性 有些时候真实的电量数据反而使得用户体验下降,这时候还要针对电量数据做一些特殊处理,以满足用户的预期。以下是82平台 SW FG中部分电量误差产生的原因 以及 MTK用于消除/减小误差的方法。库伦积分时的电流:即使是cc状态,电流也是有波动的,而进入cv状态后,电流的变化会更大。因为这样一个电流变化并无规律,所以不可能导出电流公式用于电量积分。目前代码会把每10s 算一次

20、电流作为这10s的平均电流。这样会形成一个电量累积误差。MTK的观点: MTK认为电流误差既有正误差,也有负误差,在较长的一段时间内认为误差相互抵消。但实际进入恒压后 误差应该会稍大。电池内阻不稳定造成的误差:电池的内阻会随温度变化,且幅度很大,而在SW FG的算法中依赖电池内阻计算电流大小,如果使用固定值的电池内阻会严重影响电流的计算。MTK应对方案:1,建立zcv tableMTK的zcv table,建立了几个特定温度(-10,0,25,50)下的内阻r和开路电压ocv的关系,这样可以根据可量测的电压信号查表推算内阻2,线性平均值MTK在算法初始化时,读取温度信息,通过线性平均重构zcv table,这样可以覆盖从-10到50的所有温度点。82平台 MTK电量算法只会在初始化的时候去通过读取的温度重构zcv table,但假设使用者周围的温度在手机使用过程中变化比较大,或者电池本身发热很厉害,电池内阻值有了较大改变,则测出的电量偏差也会比较大。假设从高温环境到低温环境,根据电池特性,电池内阻会大幅增大,而电池可使用容量将会下降。实际耗流假设变化不大,由于还是用之前的zcv表格,用于计算的内阻比实际内阻小很多,则算出来的电流会偏大。这样显示电量会快速下降。开机电压的误差:由

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论