本文转载自:http://www.voidcn.com/blog/yanleizhouqing/article/p-6051912.html

上一篇主要讲电池相关的一些知识,上节忘记讲了,电池一般分为电量计电池和非电流计电池,电量计电池,就不需要用pmu8916的IC,当然这只是只,不需要BMS来计算soc,而jni层也需要读取电流计的电池相关属性。

这一节主要是根据代码进行相关的分析。

1. 先看probe的代码:

static int qpnp_vm_bms_probe(struct spmi_device *spmi)
{
...........
..........
...........
.......... //这里把电池的配置文件dtsi的读出来,并存到当前的结构体。
rc = set_battery_data(chip);
rc = config_battery_data(chip->batt_data);
..........
..........
//这个是核心的工作,一个线程,BMS的主要内容在此
INIT_DELAYED_WORK(&chip->monitor_soc_work, monitor_soc_work);
..........
.......... //电池一些常规的检测,主要从PMIC上读到的相关信息
battery_insertion_check(chip);
battery_status_check(chip); /* character device to pass data to the userspace */
rc = register_bms_char_device(chip);
if (rc) {
pr_err("Unable to regiter '/dev/vm_bms' rc=%d\n", rc);
goto fail_bms_device;
} the_chip = chip;
//这个也很重要,我们从上节知道,初值last_ocv_soc是非常重要的,决定着后面的soc估值算法
calculate_initial_soc(chip); //设置和注册电池的power supply
/* setup & register the battery power supply */
chip->bms_psy.name = "bms";
chip->bms_psy.type = POWER_SUPPLY_TYPE_BMS;
chip->bms_psy.properties = bms_power_props;
chip->bms_psy.num_properties = ARRAY_SIZE(bms_power_props);
chip->bms_psy.get_property = qpnp_vm_bms_power_get_property;
chip->bms_psy.set_property = qpnp_vm_bms_power_set_property;
chip->bms_psy.external_power_changed = qpnp_vm_bms_ext_power_changed;
chip->bms_psy.property_is_writeable = qpnp_vm_bms_property_is_writeable;
chip->bms_psy.supplied_to = qpnp_vm_bms_supplicants;
chip->bms_psy.num_supplicants = ARRAY_SIZE(qpnp_vm_bms_supplicants); rc = power_supply_register(chip->dev, &chip->bms_psy);
if (rc < 0) {
pr_err("power_supply_register bms failed rc = %d\n", rc);
goto fail_psy;
}
.....................
....................
....................
//这里启动工作线程
schedule_delayed_work(&chip->monitor_soc_work, 0);
..........................
....................... }

2. 分析如何确定初始的last_ocv_uv:

static int calculate_initial_soc(struct qpnp_bms_chip *chip)
{
........
........
//读当前电池温度
rc = get_batt_therm(chip, &batt_temp);
............
//读PON OCV
rc = read_and_update_ocv(chip, batt_temp, true);
..........
//读关机保存的soc和last_soc_uv rc = read_shutdown_ocv_soc(chip); //这里判断是使用估计soc还是估值soc。如果chip->warm_reset 为真
if (chip->warm_reset) {
if (chip->shutdown_soc_invalid) { //这个是dtsi的一个配置选项,若没有配置,
//则不使用关机soc
est_ocv = estimate_ocv(chip); //估值soc
chip->last_ocv_uv = est_ocv;
} else {
chip->last_ocv_uv = chip->shutdown_ocv;//使用关机的soc和ocv
pr_err("Hyan %d : set chip->last_ocv_uv = %d\n", __LINE__, chip->last_ocv_uv);
chip->last_soc = chip->shutdown_soc;
chip->calculated_soc = lookup_soc_ocv(chip,
chip->shutdown_ocv, batt_temp);
}
} else { if (chip->workaround_flag & WRKARND_PON_OCV_COMP)
adjust_pon_ocv(chip, batt_temp); /* !warm_reset use PON OCV only if shutdown SOC is invalid */
chip->calculated_soc = lookup_soc_ocv(chip,
chip->last_ocv_uv, batt_temp);
if (!chip->shutdown_soc_invalid &&
(abs(chip->shutdown_soc - chip->calculated_soc) <
chip->dt.cfg_shutdown_soc_valid_limit)) {
chip->last_ocv_uv = chip->shutdown_ocv;
chip->last_soc = chip->shutdown_soc;
chip->calculated_soc = lookup_soc_ocv(chip,
chip->shutdown_ocv, batt_temp);//使用估值soc } else {
chip->shutdown_soc_invalid = true; //使用关机soc }
}
.............
............
} //得到PON OCV
rc = read_and_update_ocv(chip, batt_temp, true);
ocv_uv = convert_vbatt_raw_to_uv(chip, ocv_data, is_pon_ocv);
uv = vadc_reading_to_uv(reading, true); //读ADC值
uv = adjust_vbatt_reading(chip, uv); //转化为soc_uv
rc = qpnp_vbat_sns_comp_result(chip->vadc_dev, &uv, is_pon_ocv); //根据IC的类型,进行温度补偿
//从寄存器中读到储存的soc和ocv
read_shutdown_ocv_soc
rc = qpnp_read_wrapper(chip, (u8 *)&stored_ocv,
chip->base + BMS_OCV_REG, 2);
rc = qpnp_read_wrapper(chip, &stored_soc, chip->base + BMS_SOC_REG, 1); adjust_pon_ocv(struct qpnp_bms_chip *chip, int batt_temp)
rc = qpnp_vadc_read(chip->vadc_dev, DIE_TEMP, &result);
pc = interpolate_pc(chip->batt_data->pc_temp_ocv_lut,
batt_temp, chip->last_ocv_uv / 1000); //根据ocv和temp,查表得PC(soc)。
rbatt_mohm = get_rbatt(chip, pc, batt_temp); //根据soc和temp,得电池内阻zhi
/* convert die_temp to DECIDEGC */
die_temp = (int)result.physical / 100;
current_ma = interpolate_current_comp(die_temp); //当前电流
delta_uv = rbatt_mohm * current_ma;
chip->last_ocv_uv += delta_uv; //修正last_ocv_uv //这个函数主要根据last_ocv_uv,计算出soc的
lookup_soc_ocv(struct qpnp_bms_chip *chip, int ocv_uv, int batt_temp)
//查表得到soc_ocv,soc_cutoff
soc_ocv = interpolate_pc(chip->batt_data->pc_temp_ocv_lut,
batt_temp, ocv_uv / 1000);
soc_cutoff = interpolate_pc(chip->batt_data->pc_temp_ocv_lut,
batt_temp, chip->dt.cfg_v_cutoff_uv / 1000); soc_final = DIV_ROUND_CLOSEST(100 * (soc_ocv - soc_cutoff),
(100 - soc_cutoff)); if (batt_temp > chip->dt.cfg_low_temp_threshold)
iavg_ma = calculate_uuc_iavg(chip);
else
iavg_ma = chip->current_now / 1000;
//查表得到FCC,ACC
fcc = interpolate_fcc(chip->batt_data->fcc_temp_lut,
batt_temp);
acc = interpolate_acc(chip->batt_data->ibat_acc_lut,
batt_temp, iavg_ma);
//计算出UUC
soc_uuc = ((fcc - acc) * 100) / fcc; if (batt_temp > chip->dt.cfg_low_temp_threshold)
soc_uuc = adjust_uuc(chip, soc_uuc);
//得到soc_acc
soc_acc = DIV_ROUND_CLOSEST(100 * (soc_ocv - soc_uuc),
(100 - soc_uuc)); soc_final = soc_acc; //这个为上报的soc
chip->last_acc = acc;

3. 看工作线程,monitor_soc_work(struct work_struct *work):

static void monitor_soc_work(struct work_struct *work)
calculate_delta_time(&chip->tm_sec, &chip->delta_time_s);
rc = get_batt_therm(chip, &batt_temp);
new_soc = lookup_soc_ocv(chip, chip->last_ocv_uv,batt_temp);
new_soc = clamp_soc_based_on_voltage(chip, new_soc);
report_vm_bms_soc(chip);//上报事件,上层得到消息,调用qpnp_vm_bms_power_get_property,获取相关的属性,计算出
last_ocv_uv,并通过qpnp_vm_bms_power_set_property方法,设置last_ocv_uv,并启动monitor_soc_work。

4. 待续

.........

高通8X16电池BMS算法(二)【转】的更多相关文章

  1. 高通8X16电池BMS算法(一)【转】

    本文转载自:http://www.voidcn.com/blog/yanleizhouqing/article/p-6037399.html 最近一直在搞电源管理相关内容,之前是8610的bms,现在 ...

  2. 高通电源管理qpnp-vm-bms驱动

    1. compatible节点: qpnp-vm-bms.c使用来控制电池曲线的和BMS功能的,其compatible节点是"qcom,qpnp-vm-bms" 2. probe函 ...

  3. 针对高通BMS的研究 高通电量计

    点击打开链接 高通8064 8974 8926等pm芯片都集成了电量计,估计后续芯片都会一直存在,现在许多项目UI状态栏电池都有百分比显示,所以需要深入分析BMS有助于解决电量方面的BUG. 一: S ...

  4. 高通电池管理基于qpnp-vm-bms电压模式

    CV:Constant Voltage恒压 SMMB charger:Switch-ModeBattery Charger and Boost peripheral开关模式电池充电器和升压外围设备 O ...

  5. linux驱动由浅入深系列:高通sensor架构实例分析之二(驱动代码结构)【转】

    本文转载自:https://blog.csdn.net/radianceblau/article/details/73498303 本系列导航: linux驱动由浅入深系列:高通sensor架构实例分 ...

  6. 【转】高通平台android 环境配置编译及开发经验总结

    原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...

  7. 高通开发笔记---yukon worknote

    点击打开链接 daily buildhttp://android-ci-platform.cnbj.sonyericsson.net/job/daily_build_jb-mr2-yukon/DL-C ...

  8. 高通开发笔记---Yangtze worknote

    点击打开链接 1. repo init -u git://review.sonyericsson.net/platform/manifest -b volatile-jb-mr1-yangtze 2. ...

  9. GJM : Unity3D 高通Vuforia SDK AR 开发

    一.AR概念: 增强现实(Augmented Reality,简称AR),是在虚拟现实的基础上发展起来的新技术,也被称之为混合现实.是通过计算机系统提供的信息增加用户对现实世界感知的技术,将虚拟的信息 ...

随机推荐

  1. ASP.NET CORE RAZOR :初始化数据库

    官方说法是:设定数据库种子https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/razor-pages/sql 应用背景:初次部署系统时,设定一 ...

  2. ssh隧道远程连接mysql

    有时候比如一些云主机,没有开放3306端口,这里可以用ssh隧道来连接数据库,更加安全 注意点: 1.本地ssh可以登录远程服务器,(密码或者秘钥) 2.远程数据库需要赋权限给隧道端的ip 命令: s ...

  3. emacs的常用配置备份

    据说有人搞丢了自己的emacs的配置,然后一怒之下抛弃了emacs投身vim,我还是做个emacs配置的备份吧, 虽然我现在也算不上emacs的发烧友. 这里的配置大多是从网上参考的,最多的是下面的链 ...

  4. Java之StringBuffer和StringBuilder的差别与联系

    2.StringBuilder,StringBuffer 字符串拼接时用这两个类,效率高.节约内存.假设用字符串 "+"号拼接 性能差.而且浪费空间,产生非常多垃圾 StringB ...

  5. 利用socket.io实现消息实时推送

    最近在写的项目中存在着社交模块,需要实现这样的一个功能:当发生了用户被点赞.评论.关注等操作时,需要由服务器向用户实时地推送一条消息.最终完成的项目地址为:socket-message-push,这里 ...

  6. X264学习1:简介

    H.264是视频编码标准. X264是它的开源实现,是视频编码器. 目录 [隐藏]  1 编码器特性 2 输入输出文件类型 2.1 输入 2.2 输出 3 preset和tune系统 3.1 --pr ...

  7. php 如何获取一个json文件

    function showupversion(){ #获取平台类型 $type='android'; #读取文件的路径 $url="D:/WWW/gm_lequ/gm_lequ"; ...

  8. java程序优化

    程序代码优化要点: 字符串优化:分析String源码,了解String常用方法,使用StringBuffer.StringBuilder. List.Map.Set优化:分析常用ArrayList.L ...

  9. 3s 简介

    "3S"技术是英文遥感技术(Remote Sensing RS).地理信息系统(Geographical information System GIS).全球定位系统(Global ...

  10. [原创]aaencode等类似js加密方案破解方法

    受http://tieba.baidu.com/p/4104806767 2L启发,不过他说的方法,我没有尝试成功,自己摸索出了一个新方法,在这里分享下. 首先拿aaencode官网的加密字符串作为例 ...