MTKプラットフォームの下でのバッテリドライバ解析と充電プロセス

1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...

転送元:http://blog.csdn.net/baidu_34021173/article/details/51105223

主にコードに関与する:

カーネル:

Kernel-3.10 \ drivers \ power \ mediatek \

Kernel-3.10 \ drivers \ misc \ mediatek \ mach \ mt6580 \ <project_name> \ power \

MTKバッテリーフレーム構造

上位層から読み取って一連のデバイスノードを作成し、バッテリ関連のステータス情報を取得する

Androidの電源管理システム
/ sys / class / power_supply / ac / online // AC電源接続の状態AC電源は電源ソケットです

/ sys / class / power_supply / usb / online // USB電源接続ステータス

/ sys / class / power_supply / battery / status //充電ステータス

/ sys / class / power_supply / battery / health //バッテリーの状態

/ sys / class / power_supply / battery / present //ステータスを使用する

/ sys / class / power_supply / battery / capacity //バッテリーレベル

/ sys / class / power_supply / battery / batt_vol //バッテリ電圧

/ sys / class / power_supply / battery / batt_temp //バッテリー温度

/ sys / class / power_supply / battery / technology //バッテリーテクノロジー

コードフレームワーク:

Battery_common.c

バッテリドライバモジュールでは、battery_probe関数でいくつかのデバイスノードが作成され、バッテリ関連のデータ情報を取得するためにスレッドbat_thread_kthreadが実行されます。

Battery_kthread_hrtimer_init(); //バッテリーの挿入/取り出しを検出する

Kthread_run(bat_thread_kthread、NULL、 "bat_thread_kthread");

bat_thread_kthreadスレッド

[ objc ] プレーン コピーを 表示する int bat_thread_kthread(voidvoid * x){ktime_t ktime = ktime_set(3、0); / * 10s、10 * 1000ms * / #ifdef BATTERY_CDP_WORKAROUND if(is_usb_rdy()== KAL_FALSE){battery_log(BAT_LOG_CRTI (BAT_LOG_CRTI、 "CDP、PASS \ n");バッテリー・ログ(BAT_LOG_CRTI、 "CDP、ブロック\ n")、バッテリー・ログ(BAT_LOG_CRTI、 "CDP、 (chargin_hw_init_done == KAL_TRUE)&&(battery_suspended == KAL_FALSE))||((chargin_hw_init_done == KAL_TRUE);});} #endif / *プロセスコンテンツで実行する* / while(1){mutex_lock(&bat_mutex) fg_wake_up_bat == KAL_TRUE); fg_wake_up_bat = KAL_FALSE; battery_log(BAT_LOG_CRTI、 "unlock battery_fg_lock \ n");(fg_wake_up_bat == KAL_TRUE))&fug_wake_up_bat = ; Bat_thread_timeout = KAL_FALSE; hrtimer_start(&battery_kthread_timer、ktime、HRTIMER_MODE_REL); ktime = ktime_set(BAT_TASK_PERIOD(BAT_thread_timeout == KAL_TRUE)); bst_thread_timeout = KAL_FALSE; / * 10s、10 * 1000ms時間を10秒に設定する* / if(chr_wake_up_bat == KAL_TRUE && g_smartbook_update!= 1)/ *充電器のプラグイン/アウト用* / {#if defined(CONFIG_MTK_DUAL_INPUT_CHARGER_SUPPORT) DISO_data.chr_get_diso_state){DISO_data.chr_get_diso_state = KAL_FALSE; battery_charging_control(CHARGING_CMD_GET_DISO_STATE、&DISO_data);} #endifのg_smartbook_update = 0;定義された(CUST_CAPACITY_OCV2CV_TRANSFORM)battery_meter_set_reset_soc(KAL_FALSE)の#if; battery_meter_reset #endifの(); chr_wake_ BMT_status.UI_SOC);}} return 0;このスレッドでは、10秒ごとに呼び出されます(これは、コールバック関数の呼び出しによって呼び出されます)Up_bat = KAL_FALSE; battery_log(BAT_LOG_CRTI、 "[BATTERY]関数BAT_Threadはバッテリーのデータを取得する

BAT_Thread

起動時の時間を短縮するためにbattery_probe()から移動する場合は、関数を最初に入力するときに関数をいくつか実行します(この関数を使用して関数を呼び出すことはできません) (初期電力、ビルディングカーブなど)の初期値設定table_init、oam_init * / BMT_status.nPercent_ZCV ​​= battery_meter_get_battery_nPercent_zcv(); battery_meter_initilized = KAL_TRUE;} mt_battery_charger_detect_check(); //挿入するかどうかのチャージャーモデル、mt_battery_GetBatteryData(); //バッテリの温度を検出してブートモードにするmt_battery_notify_check(); //バッテリ電圧、電流を検出する場合は、バッテリデータを取得するためのコア関数(BMT_status.charger_exist == KAL_TRUE){check_battery_exist();} mt_battery_thermal_check() Etif(BMT_status.charger_exist == KAL_TRUE){mt_battery_CheckBatteryStatus(); //課金異常チェック Measure mt_battery_charging_algorithm(); //充電モードを切り替えるPre_CC-> CC-> CV-> Full} mt_battery_update_status(); //バッテリデータを報告するmt_kpoc_power_off_check();

mt_battery_GetBatteryData:

[静的] kal_int32 batteryVoltageBuffer [BATTERY_AVERAGE_SIZE];静的なkal_int32 batteryCurrentBuffer(静的な) 【BATTERY_AVERAGE_SIZE];静的kal_int32 batteryTempBuffer [BATTERY_AVERAGE_SIZE];静的kal_uint8 batteryIndex = 0;静的kal_int32 previous_SOC = -1; bat_vol = battery_meter_get_battery_voltage(KAL_TRUE); Vsenseの= battery_meter_get_VSense();(upmu_is_chr_det()== KAL_TRUE){ICharging = battery_meter_get_charging_current場合battery_meter_get_charger_voltage(); temperature = battery_meter_get_battery_temperature(); temperatureV = battery_meter_get_tempV(); temperatureR = battery_meter_get_tempR(temperatureV); if(bat_meter_timeout == KAL_TRUE || bat_spm_timeout == TRUE || fg_wake_up_bat == KAL_TRUE){SOC = battery_meter_get_battery_percentage(); //バッテリ電力を取得する// if(bat_spm_timeout == true)//BMT_status.UI_SOC = battery_meter_get_battery_percentage(); BMT_status.ICharging = mt_battery_average_method(BATTERY_AVG_CURRENT、&batteryCurrentBuffer [0]、BATTERY_AVG_CURRENT、&amp; batteryCurrentBuffer [0]、BATTERY_AVG_CURRENT、&amp; batteryCurrentBuffer [0]、Bat_meter_timeout = KAL_FALSE; bat_spm_timeout = FALSE; (バッテリ電圧が低すぎる、ZCVを使用して平均データを初期化する)、BMT_status.bat_vol =(バッテリ電圧が低すぎる、初期化データを初期化するためにZCVを使用する)、BMT_status.bat_vol = mt_battery_average_method(BATTERY_AVG_VOLT、&batteryVoltageBuffer [0]、ZCV、&bat_sum、batteryIndex);}他{BMT_status.bat_vol = mt_battery_average_method(BATTERY_AVG_VOLT、&batteryVoltageBuffer [0]、bat_vol、&bat_sum、batteryIndex);}もし(battery_cmd_thermal_test_mode == 1){battery_log( BMT_status.Vsense = Vsense; BMT_status.charger_vol = BMT_status.temperature = mt_battery_average_method(BATTERY_AVG_TEMP、&batteryTempBuffer [0]、temperature、&temperature_sum、batteryIndex);} BMT_status.Vsense = Charger_vol; BMT_status.temperatureV = temperatureV; BMT_status.temperatureR = temperatureR; BMT_status.SOC = SOC; BMT_status.ZCV = ZCV; #if!defined(CUST_CAPACITY_OCV2CV_TRANSFORM)if(BMT_status.charger_exis (batteryIndex> = BATTERY_AVERAGE_SIZE)batteryIndex = 0; if(g_battery_soc_ready); if(BMT_status.SOC> previous_SOC && previous_SOC> = 0)BMT_status.SOC = previous_SOC;} #endif previous_SOC = BMT_status.SOC; batteryIndex ++; Vgr =(%d)、AvgT =(%d)、AvgT = (%d)、ZCV =(%d)、BMT_status.bat_vol、bat_vol、BMT_status.ICharging、ICharging、BMT_status。 Charger_vol、BMT_status.temperature、temperature、previous_SOC、BMT_status.SOC、BMT_status.ZCV);} battery_meter_get_battery_percentage:

(bat_is_charger_exist()== KAL_FALSE)fg_qmax_update_for_aging_flag = 1; oam_run(); //コア関数return(100-oam_d_5);} oam_run:無効なコードを削除します。

int ob_c_value = 0; / / * int d_hw_ocv = 0; * / int charge_current = 0; int ret = 0; / * kal_uint32 now_time; / / delta_time = now_time – last_oam_run_time; * / delta_time = now_time.tv_sec – last_oam_run_time.tv_sec; last_oam_run_time = now_time; * / struct timespec now_time; kal_int32 delta_time = 0; / * now_time = rtc_read_hw_time(); * / get_monotonic_boottime(&now_time); / /バッテリの電圧を最初に取得するVbat oam_i_1 =(((oam_v_ocv_1 – vol_bat))/ *バッテリが充電されている場合は、テーブルを再構成する; / fgauge_construct_table_by_temp(); vol_bat = 15; / *バッテリ時間を測定する* / ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE、&vol_bat) * 1000)* 10)/ oam_r_1; / * 0.1mA計算された電流oam_v_ocv_1は、最後に測定された開回路電圧* / oam_i_2 =(((oam_v_ocv_2 – vol_bat)* 1000)* 10)/ oam_r_2; / * 0.1mA * / OAM_car_1 =(oam_i_1 * delta_time / 3600)+ oam_car_1; / * 0.1mAh損失/取得電力= i * tは放電の深さ、oam_car_1> 0は放電、そうでない場合は充電* / oam_car_2 =(oam_i_2 * delta_time / 3600)+ oam_car_2; / * 0.1mAh * / oam_d_1 = oam_d0 +(oam_car_1 * 100/10)/ gFG_BATT_CAPACITY_aging; //バッテリーのgFG_BATT_CAPACITY_aging> <span style = "font-family:Arial、Helvetica、sans-serif; (oam_d_1> 100)oam_d_1 = 100; oam_d_2 = oam_d0 +(oam_car_2 * 100/10)/ gFG_BATT_CAPACITY_aging; if(oam_d_1 <0)oam_d_1 = 100の場合、oam_init < 0)oam_d_2 = 100; oam_d_2 = 100; oam_v_ocv_1 = vol_bat + mtk_imp_tracking(vol_bat、oam_i_2、5); oam_d_3 = fgauge_read_d_by_v(oam_v_ocv_1); //計算された開回路電圧テーブルは、(oam_d_3 <0)oam_d_3 = 0; if(oam_d_3> 100)oam_d_3 = 100; oam_r_1 = fgau ge_read_r_bat_by_v(oam_v_ocv_1); oam_v_ocv_2 = fgauge_read_v_by_d(oam_d_2); oam_r_2 = fgauge_read_r_bat_by_v(oam_v_ocv_2); oam_d_4 = oam_d_3; gFG_columb = oam_car_2 / 10; / * *ミリアンペア/ IF((oam_i_1 <0)||(oam_i_2 <0))gFG_Is_Charging (OAM_d_3> oam_d_5){if(oam_d_3> oam_d_5){//放電された状態では、oam_d_3は、より大きい値になります(= gALS_CHUNT == KAL_FALSE) (oam_d_5> oam_d_3){// <span style = "1">}}}}}}}}}}} "font-family:Arial、Helvetica、sans-serif;">充電状態では、oam_d_3が最後の充電量oam_d_5よりも小さい場合、電池残量は+1です。</ span> OAM_d_5 = 1;}}} d5_count = 0; oam_d_3_pre = oam_d_3; oam_d_4_pre = oam_d_4;}}

oam_runの全プロセスを以下に示します。

MTKはFuelスキームを使用してバッテリ残量を取得します

まず、電池Vbat端子の電圧値をadcで読み込み、閉路電圧値からR_Table(cust_battery_meter_table.h)を求め、現在の電圧、温度での電池の内部抵抗値を求めた後、再帰的なバックトラッキング法により開回路電圧OCVを求める。そして、このOCV電圧値で放電深度テーブルを求め、電池残量を算出することにより、現在の放電深度を求める。

ドライバをデバッグする際の注意点

1、バッテリーカーブ

2、充電電流のいくつかの設定(AC_CHARGER_CURRENT、NON_STD_AC_CHARGER_CURRENT、USB_CHARGER_CURRENTなど)、高電圧バッテリであるかどうかHIGH_BATTERY_VOLTAGE_SUPPORT

最高温度:MAX_CHARGE_TEMPERATURE
最大電圧:V_CHARGER_MAX

カットオフフルチャージストリームサイズ:CHARGING_FULL_CURRENT

バッテリのシャットダウン最大バッテリ差:CUST_POWERON_DELTA_CAPACITY_TOLRANCE(この値より小さい場合、次回のRTCに保存されたバッテリ残量)

シャットダウン電圧:SYSTEM_OFF_VOLTAGE

UIバッテリーの同期時間:SYNC_TO_REAL_TRACKING_TIME

バッテリ充電ドライバプロセス分析(battery_common.c):

/ * NVRAMと統合する* /
Ret = alloc_chrdev_region(&adc_cali_devno、0、1、ADC_CALI_DEVNAME);

/ /文字デバイスの登録、

Register_chrdev_region(dev_t first、符号なしint count、char * name)
最初に、割り当てられるデバイス番号の範囲の初期値(マイナーデバイス番号は常に0です)。
カウント:連続番号範囲。
名前:番号に関連付けられたデバイス名(/ proc / devices)。
動的割り当て:
int alloc_chrdev_region(dev_t * dev、unsigned int firstminor、unsigned int count、char * name);
Firstminor:通常0;
* dev:返されたデバイス番号を格納します。

カウント:連続番号範囲。
名前:番号に関連付けられたデバイス名(/ proc / devices)。

Adc_cali_cdev = cdev_alloc();

文字デバイスのために動的にメモリを要求する

Adc_cali_cdev-> owner = THIS_MODULE;
Adc_cali_cdev-> ops =&adc_cali_fops;
Ret = cdev_add(adc_cali_cdev、adc_cali_devno、1)// adc_cali_devno:デバイス番号、最初の20ビットはマスタデバイス、最後の12ビットはデバイス番号adc_cali_cdev:デバイスの構造

Adc_cali_major = MAJOR(adc_cali_devno); //メジャーデバイス番号を取得する
Adc_cali_class = class_create(THIS_MODULE、ADC_CALI_DEVNAME); 1);

Class_dev =(struct class_device *)device_create(adc_cali_class、
NULL、
Adc_cali_devno、NULL、ADC_CALI_DEVNAME);

Get_charging_control();

Battery_charging_control = chr_control_interface;

ステータス= charging_func [cmd](データ);

静的kal_uint32(* const charging_func [CHARGING_CMD_NUMBER])(void * data)=
{
Charging_hw_init
、charging_dump_register
、charging_enable
、charging_set_cv_voltage
、charging_get_current
、charging_set_current

……

}

/ * Androidバッテリーサービスと統合* /
Ret = power_supply_register(&(dev-> dev)、&ac_main.psy);

BMT_status.bat_charging_state = CHR_PRE;
BMT_status.bat_in_recharging_state = KAL_FALSE;
BMT_status.bat_full = KAL_FALSE;
BMT_status.nPercent_ZCV ​​= 0;初期化ステータス

Battery_kthread_hrtimer_init();タイマーの初期化

Kthread_run(bat_thread_kthread、NULL、 "bat_thread_kthread");スレッドを作成して常に実行させる

/ *ログシステムセット* /
Init_proc_log();

Bat_thread_kthread:

{

Wait_event(bat_thread_wq、(bat_thread_timeout == KAL_TRUE));

}

Void BAT_thread(void)
{
スタティックkal_bool battery_meter_initilized = KAL_FALSE;
if(battery_meter_initilized == KAL_FALSE){
Battery_meter_initial(); / * battery_probe()から移動して起動時間を短縮する* /
BMT_status.nPercent_ZCV ​​= battery_meter_get_battery_nPercent_zcv();
Battery_meter_initilized = KAL_TRUE;
}

Mt_battery_charger_detect_check();
mt_battery_GetBatteryData();
if(BMT_status.charger_exist == KAL_TRUE){
Check_battery_exist();
}
Mt_battery_thermal_check();
Mt_battery_notify_check();

if(BMT_status.charger_exist == KAL_TRUE){
mt_battery_CheckBatteryStatus(); //充電の状態を確認し、開始するCC_PREを選択するか、その他の異常な状態、
Mt_battery_charging_algorithm(); //実際の課金が開始され、常にCC_PRE状態の場合は、それが到達したかどうかが繰り返し判断されます。

CC状態に入る条件などは、このように状態が切り替わります
}

Mt_battery_update_status();
Mt_kpoc_power_off_check();
}


1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...
      この投稿は審査処理中  | 元のサイトへ