《关于Android系统的电量问题》

日期:2015.11.02    星期一
平台:MTK6735m, android 5.1
项目:K561WP-2
一、导言
        前几天得到一个项目任务,要将最新测试出来的电池曲线合进到K561WP-2项目中。曲线表部分如下图所示:

1,首先要知道在那里合进这个电池曲线参数,是在 cust_battery_meter_table.h  的文件里修改的。具体这个文件在那个路径下,各个平台不尽相同。你可以这样找出来,回到根目录下用如下的shell命令: 
find  ./  -name  "cust_battery_meter_table.h"
android 5.1,MTK6735M 的平台下是在以下目录:
apls/kernel-3.10/drivers/misc/mediatek/mach/mt6735/project_name/power/

2,再回来看看这张电池曲线表,DOD、R(x1000)这两个好理解,分别表示百分点和它所对应的内阻值。那么 OCV和VC呢?要以那一个为准呢?VC应该就是ADC得到的电压值吧,那么OCV呢?在网上查了一下,是这样解释的:OCV是Open circuit voltage = 开路电压,指的是电池不放电开路时,两极之间的电位差。以OCVO为准吗?感觉应该要以ADC的值经过MTK特有的电量算法后得到的值为准啊,怎么会是开路电压呢?这一点是很不理解的,但问同事都说是以OCV的参数为准。那么接下来就是仔细填入对应的参数了。

3,如果出了些比较奇怪的问题首先会去看看 battery_profile_t0[]、battery_profile_t1[]、battery_profile_t2[]、battery_profile_t3[]等各个数组是否等长,这个我一开始时还真没太注意这个问题,后来我一步步去跟读代码才知道为什么。
跟读:
battery_common.c  --->
module_init(battery_init); ---> 
static int __init battery_init(void){.....} ---->
///分别作平台设备和驱动的注册  ---->
ret = platform_device_register(&battery_device);  &&
ret = platform_driver_register(&battery_driver); ///这里是battery_driver的动作;
ret = platform_device_register(&MT_batteryNotify_device);  &&
ret = platform_driver_register(&mt_batteryNotify_driver);  ///这里是对 mt_batteryNotify_driver 的动作。
我们先跟 battery_driver   ------->
static struct platform_driver battery_driver = {
    .probe = battery_probe,
    .remove = battery_remove,
    .shutdown = battery_shutdown,   
    .driver = {
            .name = "battery",
            .pm = &battery_pm_ops,
    },
};

struct platform_device battery_device = {
        .name   = "battery",  ///-------->     它们一匹配成功后就会执行 battery_probe 这个函数.
        .id        = -1,
};
static int battery_probe(struct platform_device *dev) {......}   ----------> 
kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");     ---------->
int bat_thread_kthread(void *x) {...................}            ---------->   
BAT_thread();                                                    ---------->
void BAT_thread(void) {....................}                     ---------->    
battery_meter_initial();                                         ---------->
battery_meter.c                                                  ----------> 
kal_int32 battery_meter_initial(void) {.....................}    ---------->   
fgauge_initialization();    &&    table_init();                  ---------->

void table_init(void){..............}                            ---------->
fgauge_construct_r_table_profile(temperature, profile_p_r_table);---------->
low_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T1);
high_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T2);

void fgauge_initialization(void) {..................}            --------->
fgauge_construct_battery_profile_init();

void fgauge_construct_battery_profile_init(void) {............}  ---------->
profile_p[0] = fgauge_get_profile(TEMPERATURE_T0);    && 
saddles = fgauge_get_saddles();                                  ---------->  
int fgauge_get_saddles(void)
{
        return sizeof(battery_profile_t2) / sizeof(BATTERY_PROFILE_STRUC);  
        --------> 现在明白了吧,为什么这些数组一定要等长呢?
}

BATTERY_PROFILE_STRUC_P fgauge_get_profile(kal_uint32 temperature) {............}  
        case TEMPERATURE_T0:
                return &battery_profile_t0[0];
                break;
--------->  
cust_battery_mater_table.h
// T0 -10C
BATTERY_PROFILE_STRUC battery_profile_t0[] =
{
    {0  , 4328 },
    {2  , 4304 },
    {3  , 4285 },
    {5  , 4266 },
    {6  , 4248 },
            ....................
};

                    

--------------->>>>>>好了,以上这些都只是一些较为疑惑的问题,下面就是真正地一步一步去跟进MTK是如何计算电量的!
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
battery_common.c  ------> 
module_init(battery_init); ------> 
static int __init battery_init(void){.....} ------>
分别作平台设备和驱动的注册            ------>
它们一匹配成功后就会执行battery_probe 这个函数
static int battery_probe(struct platform_device *dev) {.........}   ------>
kthread_run(bat_thread_kthread, NULL, "bat_thread_kthread");        ------>
int bat_thread_kthread(void *x) {.........}                         ------>
    1,设置10秒钟的内核定时时间。
    2,while(1) { 
            如果系统不在休眠的状态: {BAT_thread();} 
            wait_event(bat_thread_wq, (bat_thread_timeout == KAL_TRUE));
            //每10s就会判断一下要不要执行  BAT_thread();
        }

void BAT_thread(void)
{
    1,如果是刚开机:
    {
        1, 执行 kal_int32 battery_meter_initial(void)
        {
            .........
            table_init();//这个比较重要了,它的作用是创建和初始化电池曲线表
            oam_init();//在这里面会读出各种和电池相关的全局变量
        }    
        2, 执行 BMT_status.nPercent_ZCV = battery_meter_get_battery_nPercent_zcv();
            //读出电池电量为 15%时的电压值
    }

    2, 查看是否有连接充电或USB。

    3, void mt_battery_GetBatteryData(void)
    {//读取各和电压相关的值
        1, bat_vol = battery_meter_get_battery_voltage(KAL_TRUE);//读取电池5次的平均ADC电压
        2, Vsense = battery_meter_get_VSense();//读取1次 VSense的电压
        3, 如果正在充电,即读取一下当前的充电电流
        4, charger_vol = battery_meter_get_charger_voltage();//读取5次当前的平均充电电压
        5, temperature = battery_meter_get_battery_temperature();//读取当前电池的温度
        6, temperatureV = battery_meter_get_tempV();//读取1次当前电池的电压值
        7, temperatureR = battery_meter_get_tempR(temperatureV);//读取当前电池的内阻值
        如果到了10秒的定时或其它条件:
        {
            SOC = battery_meter_get_battery_percentage();//读出电池电压百分比
            kal_int32 battery_meter_get_battery_percentage(void)
            {
                …………
                oam_run();//这个函数比较重要,主要是更新oam相关的全局变量,
                为 mt_battery_update_status();里边的函数调用服务;
                #if (OAM_D5 == 1)
                    return (100 - oam_d_5);
                #else
                    return (100 - oam_d_2);
            }
        }
        8, ZCV = battery_meter_get_battery_zcv();//获取ZCV的值,即 gFG_voltage;
        9, 求出BMT_status.ICharging在经过平均算法后的值;
        10, 求出 BMT_status.bat_vol 在经过平均算法后的值;
        11, 求出 BMT_status.temperature 在经过平均算法后得到的值;
        12, 将之前所求得的各种值赋给 BMT_status 全局变量
            BMT_status.Vsense = Vsense;
            BMT_status.charger_vol = charger_vol;
            BMT_status.temperatureV = temperatureV;
            BMT_status.temperatureR = temperatureR;
            BMT_status.SOC = SOC;
            BMT_status.ZCV = ZCV;
    }

    4, mt_battery_thermal_check();//检查温度是否有过高的,如果有,即会重启关机。

    5, mt_battery_notify_check();//检测电池是否有各种异常的通知。

    6, 如果当前正在充电,即:
    if (BMT_status.charger_exist == KAL_TRUE)
    {
        mt_battery_CheckBatteryStatus();//检测电池的各个状态是否正常
        mt_battery_charging_algorithm();//根据当前是那一类的充电类型去执行它相对应的充电方法
    }

    7, mt_battery_update_status();//更新电池的各种状态数据

    8, mt_kpoc_power_off_check();//轮询查看是否有操作关机键的动作
}

跳到 battery_meter.c文件中的battery_meter_initial();函数。
kal_int32 battery_meter_initial(void) {.........}    --------> 

table_init(); && oam_init();                         -------->

oam_init(void) {..........}   在这里面会读出 gFG_voltage、g_booting_vbat、gFG_capacity_by_v、gFG_BATT_CAPACITY_aging、oam_v_ocv_init等等的全局变量。

oam_init(void)                                       -------->

dod_init();                                          -------->  

void dod_init(void)
{
    g_rtc_fg_soc = get_rtc_spare_fg_value();//在这里先读一次rtc上记录的后备电压值,赋给  g_rtc_fg_soc 
    .....................
    这里主要是初始化了一些 gFG_capacity_by_c_init、gFG_capacity、gFG_capacity_by_c、gFG_capacity_by_v 等 battery_meter.c 里边的全局变量。
    其中还有一个较为重要的动作,就是算出当前电池剩余 15%电量的电压值 gFG_15_vlot,默认为3700。

}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值