編輯:關於Android編程
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
來看看power_supply_sysfs.c這個文件。這裡主要是對諸如如下這些電源設備屬性創建uevent!
這些uevent節點不一定都會創建,節點創建與否還和具體的電源設備驅動傳進來的num_properties和properties有關,在創建uevent函數power_supply_uevent中可以很容易的看出這一點:
目前項目(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會更新這些文件
打開谷歌api,對widget小部件做如下說明:App Widgets are miniature application views that can be embed
前言:看過很多精彩的文章,作者寫的非常好,但總覺得文字描述沒有圖片或圖表說明來得直觀,因為圖片可以化抽象為具體。語言是有區域性的,而圖片則是全世界通用的,即使語言不通,卻
什麼是Glide?Glide是一個加載圖片的庫,作者是bumptech,它是在泰國舉行的google 開發者論壇上google為我們介紹的,這個庫被廣泛的運用在googl
從開源項目中看到 這個,就不由自主的收藏了~