好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

mtk fuel gauge算法分析.doc

30页
  • 卖家[上传人]:mg****85
  • 文档编号:34186779
  • 上传时间:2018-02-21
  • 文档格式:DOC
  • 文档大小:2.55MB
  • / 30 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 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 的 activities根据不同的电量读取和计算的策略,第一步的读取和第二步的算法部分会有比较大的差异,而后面的数据更新和事件通知部分一致性较高本篇重点分析 72/82 平台 SW FG 算法实现,对比 SW_FG 和 HW_FG 在硬件及软件上的部分差异,分析电量误差形成的一些原因和 MTK 已经采取的消除误差的措施对于 Battery数据更新和充电流程则粗略分析。

      充电状态机,battery 充电的逻辑,就依赖于这张图,如果是用的 external charger ic,则应当参考该 IC 的充电逻辑linear charging 下 cc 转 cv,是通过 ADC 读取电压后,软件切换而使用 charger ic 则很可能是硬件直接切换这部分的相关代码路径在: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 一次的定时器更新,插拔充电器会触发中断,中断处理时同样会更新 battery 数据所有和 电池 充电相关的数据都存储在 power_supply 类型的结构体中,这是 linux 标准的电源子系统体系。

      MTK 电量算法简析为了得到较为精确的电量数据,需要改善测量方式和计算方法,并针对已知误差采取优化手段一下介绍 MTK 平台下采用的一些电量算法AUX ADC 算法:事实上,所有算法都要依赖 ADC 读取电量信息,这边的 AUX ADC 算法指只依赖 ADC 读值,然后查表读取电量的算法这种算法只重构了 ZCV table,误差会很大库仑积分法:通过开路电压查表得到初始电量 D0,后续电量通过电流积分累积,通用性强,依赖初始电量的精确度混合型算法 :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.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首先要获取当前的温度信息=> force_get_tbatADC 读值这边就是 MTK 为了结合实际温度 获取较为精确的电池信息 而采取的线性平均值法原理是利用预先测得的分布在-10 0 25 50 摄氏度下的 ZCV 表,结合真实温度,动态重构一张当前温度下的 ZCV 表格TEMPERATURE 对应预留的空 ZCV 表格,如下构造新表的函数如下采用线性平均法 填补了有效温度内所有的 ZCV 对应值 但与真实曲线必然存在一定的误差。

      >oam_init常见的指针函数 传参比较有趣 vol_bat 这个参数下传给底下 pmic 做 count,然后被重新赋值成读取的 v_bat 值 之所以能这样做 是因为这两块代码 同处在 kernel 层 并地址传参battery_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 信号 ,似乎 ADC3 和我们之前的 dwchannel number 有点对不上? 可以看到 dwchannel 5 最终访问的仍是 ADC3,另外可以直接比较下寄存器地址。

      和 datasheet 左上角的寄存器地址一致最后还要做次数值转换,公式如下:分辨率计算:测量电压范围/(2^AD 位数-1)另外,对于同为电压值的 v_bat 和 v_i_sense,可能会出现 adc 量程不够的问题 这时候需要通过电阻分压 所以 case 6 和 7 的 r_val_temp 为分压比和前面一样 ADC 读值 但是 6320 的 spec 上对于 PCHR 没有说明 从函数定义的名称上看 是开路电压 但是如何在一个闭路的环境中通过 ADC 读取 ocv,有些不解 查了下读这个值的 timing,只有在 init suspend 和 resume 的时候才去获取 .猜想 一是可能 利用linear charging 这种充 9 停 1 的方式,在第 10s 读取电压 作为 OCV 也可能是因为刚开机时 电流还不大 读到的电压值 可用作 OCV 总之 这个值应该是真实的开路电压的一个近似值> oam_init根据电压读表获取电量可以看到 用的是 table_init 时重构的新表Ok 这边再一次 利用线性平均法 这一次是针对 ADC 读到测到的电压 线性平均后 得到一个较精准的电量=> oam_init首先判断是否插着充电器,读 PMU 寄存器实现为什么 需要判断有没有插着充电器呢?我是这么理解的,之前通过 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 寄存器中,在开机时读取该电量主要目的是改善用户体验看下这个值是何时被写入的:电池信息 10s update 1 次 同样 UI 电量 10s 存入 RTC 寄存器一次用 7 个 bit 存储 电量信息开机时直接显示关机时保存的电量,会增强用户体验性,但是如果是更换电池或其他情况 造成关机电量和开机电量相差过大,显然应该采用开机电量,否则后续电池电量跳变反而会影响用户体验Normal boot 下忽略|| 后面的条件 主要就是要求没有插入充电器 不处于低电量 误差不超过 40%经过前面所有的判断 最终得到了 gFG_capacity 这个电量,也就是开机电量 因为开机电量在整个电量计算中相当重要并且又要结合用户体验 所以之前会有很多的条件分支Q_MAX_POS_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_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_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 求电流.上图 R 可以是电池内阻关键是 oam_i_2 这边的 I2 有几个作用:因为电流是通过上图的内阻 IR。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.