MT8735 andorid7.0 充电调试总结(2)——电池驱动流程关键代码分析

来源:互联网 发布:cpb 面膜 知乎 编辑:程序博客网 时间:2024/05/21 01:30

battery_common.c首先是进行电池驱动的一些初始化工作,之后调用函数

kthread_run(bat_thread_kthread,NULL, "bat_thread_kthread");创建一个线程。这个线程每10秒钟执行一次,里面会调用BAT_thread();在这个函数里面完成的电池驱动的大部分主要事务。

//Battery_common.c (drivers\kernel-3.18\drivers\power\mediatek)1548442017/11/1

void BAT_thread(void)
{
static kal_bool battery_meter_initilized = KAL_FALSE;
static int first_time_update;


if (battery_meter_initilized == KAL_FALSE) {
battery_meter_initial();/* move from battery_probe() to decrease booting time */
BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv();
battery_meter_initilized = KAL_TRUE;
}


mt_battery_charger_detect_check();
if (fg_battery_shutdown)
return;


mt_battery_GetBatteryData();
if (fg_battery_shutdown)
return;


if (BMT_status.charger_exist == KAL_TRUE)
check_battery_exist();


mt_battery_thermal_check();
mt_battery_notify_check();



if (first_time_update == 0) {
mt_battery_update_status();
if (BMT_status.charger_exist == KAL_TRUE) {
mt_battery_CheckBatteryStatus();
mt_battery_charging_algorithm();

}
first_time_update = 1;
} else {
if (BMT_status.charger_exist == KAL_TRUE && !fg_battery_shutdown) {
mt_battery_CheckBatteryStatus();
mt_battery_charging_algorithm();

}
mt_battery_update_status();
}


mt_kpoc_power_off_check();
}

下面着重分析这里面的函数

battery_meter_initial();完成电池电量、zcv和电池内阻的初始化工作。

signed int battery_meter_initial(void)
{
#if defined(CONFIG_POWER_EXT)
return 0;
#else
static kal_bool meter_initilized = KAL_FALSE;


mutex_lock(&FGADC_mutex);
if (meter_initilized == KAL_FALSE) {
#ifdef MTK_MULTI_BAT_PROFILE_SUPPORT
fgauge_get_profile_id();
#endif


#if defined(SOC_BY_AUXADC)
g_auxadc_solution = 1;
table_init();
bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_AUXADC done\n");
#endif


#if defined(SOC_BY_HW_FG)
fgauge_initialization();
fgauge_algo_run_init();

bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_HW_FG done\n");
#endif


#if defined(SOC_BY_SW_FG)
g_auxadc_solution = 1;
table_init();
oam_init();
bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_SW_FG done\n");
#endif


meter_initilized = KAL_TRUE;
}
mutex_unlock(&FGADC_mutex);
return 0;
#endif

我们先看一下有硬件电量计(定义SOC_BY_HW_FG)的执行流程。

函数fgauge_initialization和fgauge_algo_run_init做的工作有一些重复,主要完成的操作有:

1.      初始化电量计

2.      在fgauge_construct_battery_profile_init里面根据cust_battery_meter_table.h里面的信息重构zcv表格,分50个等级,每2%一级。

3.      读取电池温度,电池容量等信息。并根据当前温度重构电池内阻表和zcv表。

4.      读取闭路电压,并用函fgauge_compensate_battery_voltage_recursion计算出开路电压,主要是做了一个电压补偿,具体的原理我现在也不是很明白,大家有空的话,可以研究一下。之后用开路电压查找zcv表计算电池剩余容量。

5.      调用函数battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV,&gFG_voltage),直接从PMIC读取电池的开路电压,并计算电池剩余容量。

6.      读取rtc里面保存的电量值和从4和5里面计算出来的电量值做对比判断,选择合适的电量值作为电池的初始电量。

 

(a)函数mt_battery_charger_detect_check完成充电器是否插入的判断。

 

 (b)函数mt_battery_GetBatteryData主要完成电池信息的获取,获取电池电压,电流和温度等信息。过程中会调用函数fgauge_algo_run,此函数输出的log信息对调试电池电量不准的问题有很大的帮助。

mt_battery_GetBatteryData()读取电池相关信息:电压、电流、充电器电压、电池温度,通过SOC = battery_meter_get_battery_percentage();来获取电池电量百分比。里面会调fgauge_algo_run()这个函数来循环获取电量值,原理上与dod0值的获取类似


这个log打印了大部分我们需要的信息,有充电状态,电流,电量计数值,zcv计算电量,电量计计算电量等等。当机器用的是硬件电量计的时候,zcv计算的电量实际上在这里只是起到参考作用,并不会影响系统的电量显示和使用。如果软件zcv表格是正确的,但这里的zcv计算电量和电量计计算电量相差比较大,这时候就要考虑调节电池容量的大小,一般在放电过程中zcv计算电量比电量计计算电量大,就要适当的增加电池容量,反之则减少。

         电池容量设的太小,会出现电量显示1%时还能用很久的现象,太大则会出现低电量时电量下降的很快,或还没到0%就关机了

 

         (c)函数mt_battery_thermal_check则实现温度的监控,当电池问题高于设定温度,一般是60度时系统会强制关机。

 

         (d)函数mt_battery_notify_check则实现温度,电压和电量等一些异常并通知android层,最终提示给用户。

 

         (e)当有充电器插入时,系统会运行mt_battery_CheckBatteryStatus检查电池的一些状态,从而决定充电与否,里面包含了高低温,充电器电压,是否在通话状态和充电时间等检测。

         (f)函数mt_battery_charging_algorithm完成充电算法。这里两种充电方式,一是PMIC充电的Liner_charging和外部充电IC的Switch_charging。一般来说Switch_charging的充电电流要比Liner_charging大。mt_battery_charging_algorithm()完成充电算法PMIC充电的Liner_charging和外部充电ICSwitch_charging

         两种充电方式的主流程其实区别不大,基本都包含了预充电,恒流充电,满电判断和二次充电。

    有时候会出现充满电时,电池电压偏低的情况,这时候可以适当提高充电电压或者减少充电截止电流。

 

Liner_charging主流程:

 Swicth_charging主流程:


 

(e)函数mt_battery_update_status主要实现将电池,充电等状态更新到android层,如电量,充电器是否插入等等。

当电量比较低的时候battery_update里面会调用到mt_battery_0Percent_tracking_check 电池电压小于SYSTEM_OFF_VOLTAGE时,BMT_status.UI_SOC减少到0,这时android上层会接收到电量等于0的更新,并发送命令关闭机器。

(f)mt_kpoc_power_off_check()实现关机充电时对charger的检测


 

以上就是电池驱动的大体流程


总结:

     大家只要搞清楚BAT_thread()这个函数,应该对整个充放电流程就比较清晰了。至于HW/SWFuelgague这两种电量计在软件上的具体区别:




阅读全文
0 0
原创粉丝点击