關於Android電池管理系統(一)Linux驅動部分

來源:互聯網
上載者:User

標籤:

一、概述android系統電池部分的驅動程式,繼承了傳統linux系統下的Power Supply驅動程式架構,Battery驅動程式通過Power Supply驅動程式產生相應的sys檔案系統,從而向使用者空間提供電池各種屬性的介面。Linux標準的 Power Supply驅動程式所使用的檔案系統路徑為:/sys/class/power_supply ,其中的每個子目錄表示一種能源供應裝置。

二、驅動標頭檔

Power Supply驅動程式標頭檔kernel/include/linux/power_supply.h,註冊和登出驅動程式的函數如下:

intpower_supply_register(struct device *parent,struct power_supply *psy);

voidpower_supply_unregister(struct power_supply *psy);

structpower_supply {

constchar *name; /*裝置名稱*/

enumpower_supply_type type; /* 類型 */

enumpower_supply_property *properties; /* 屬性指標 */

size_tnum_properties; /*屬性的數目*/

char**supplied_to;

size_tnum_supplicants;

int(*get_property)(struct power_supply *psy, /*獲得屬性*/

enumpower_supply_property psp,

unionpower_supply_propval *val);

void(*external_power_changed)(struct power_supply *psy);

/* ...... 省略部分內容 */

};

三、power supply core

對應的驅動程式:power_supply


來看看power_supply_sysfs.c這個檔案。這裡主要是對諸如如下這些電源裝置屬性建立uevent!


這些uevent節點不一定都會建立,節點建立與否還和具體的電源裝置驅動傳進來的num_properties和properties有關,在建立uevent函數power_supply_uevent中可以很容易的看出這一點:


四、battery driver

目前項目(T808、T828)中所使用的電池檢測與管理方式是POC ADC方式,對應的驅動檔案是:

mediatek/kernel/drivers/power/battery_common.c

在此檔案的probe函數裡有如下內容:


可以看出,在這裡將ac、usb及battery三種電源供應裝置註冊到了power supply core中去了,而相應的全域結構體變數ac_main、usb_main及battery_main作了如下定義:


 

各個電源裝置所需要建立的uevent節點由這裡傳入的xx_props決定,相應的定義如下:



可發現:ac和usb只建立了一個online屬性,上層app通過判斷ac和usb的online狀態便可知道當前系統是由什麼裝置在充電了;而battery則建立了如:status、health、present、capacity、batt_vol等等和電池相關的諸多屬性,上層app通過這些電池屬性uevent便可監控電池的當前工作狀態了。

舉例說明一下這些屬性的狀態改變後是如何向系統發送更新訊息的,來看看ac online的狀態更新。


該函數在power supply sysfs中show property的時候得到調用,而AC_ONLINE作為ac電源唯一的屬性會在ac_update中得到更新:


ac_update則最終會在bat_thread_kthread中進行輪循,在這裡有一個全域的BMT_status,作為整個電源供應裝置的各種屬性傳達!另外再來看看CHARGING_CONTROL battery_charging_control這個全域的函數指標,原型定義如下:


chr_control_interface函數原型如下:


對應檔案路徑:

mediatek/platform/mt6572/kernel/drivers/power/charging_hw_pmic.c

charging_func函數指標數組定義如下:


可以看出通過如下的調用關係:


最終會調用到由:


這些枚舉類型所一一對應的函數中去,如上面調用關係CHARGING_CMD_GET_CHARGER_TYPE,則是擷取charger type,函數原型如下:

在這裡通過pmic的硬體狀態來擷取相應的資訊。

五、充電誤差糾正

理想中的電池是沒有內阻的,電池電壓的消耗都在外部的負載上。


但實際情況卻不是這樣的,正由於電池內阻的存在,通過直接測量電池電壓(ADC)的方式獲得的電池電量都會存在一定的誤差,不管電池是處於供電還是放電的狀態,這種誤差都會存在,特別是在電池電量滿、電池電量空及關機充電的情況下這種誤差很容易被使用者察覺,從而帶來不好的使用者體驗。


那麼針對電池內阻導致的這個誤差,完全可以通過數學方式進行糾正。


通過可知,只要知道了電池內阻,就可以很容易地糾正這種誤差。但電池的內阻不是不變的,而是隨著電池電量的變化而變化的,不同型號的電池,這種特性還不一樣,那麼要想得到比較準確的電池電量,就很有必要讓電池廠提供一組完整的電池電壓與電池內阻的關係表了!

充放電過程中誤差的糾正代碼:

mediatek/kernel/drivers/power/battery_meter.c

在oam_run中有如下代碼:


函數mtk_imp_tracking就是針對充放電過程中電池內阻所產生的壓降所作的一個△V的修正。

另外一個是,由於電池特性,在開關機的時候會出現電量跳變的問題,在系統中採用了將關機時的UI電量儲存到RTC中,在下次開機的過程中用實際檢測到的電量值與儲存到RTC中的UI電量值進行比較判斷,由於使用者可能會更換電池,這兩者之間的差值控制在了20%的範圍內,也就是說:實際檢測到的電量值在RTC中儲存的UI電量值的20%範圍內則使用儲存在RTC中的UI電量值作為當前電池的電量值;如果實際檢測到的電量值超過了RTC中UI電量值的20%,則認為使用者更換了電池,用實際檢測到的電量值作為當前電池的電量值。

相應的判斷代碼如下:


在標頭檔:

mediate/custiom/mt6572/kernel/battery/battery/cust_battery_meter.h

中有如下定義

 

各能源裝置屬性概況如下:

/sys/class/power_supply/ac/online 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 電池 level

/sys/class/power_supply/battery/batt_vol 電池電壓

/sys/class/power_supply/battery/batt_temp 電池溫度

/sys/class/power_supply/battery/technology 電池技術

當供電裝置的狀態發生變化時,driver會更新這些檔案

 

關於Android電池管理系統(一)Linux驅動部分

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.