電池驅動除錯總結
1.概述:
Android電池服務,用來監聽核心上報的電池事件,並將最新的電池資料上報給系統,系統收到新資料後會去更新電池顯示狀態、剩餘電量等資訊。如果收到過溫報警和低電報警,系統會自動觸發關機流程,保護電池和機器不受到危害。
Android電池服務的啟動和執行流程:
Android電池服務的原始碼結構
Framework\base\services\java\com\android\server
├── SystemServer.java
建立BatteryServices、PowerManagerService、ActivityManagerService
├── BatterySevices.java
監聽底層上報的battery事件,廣播電池發生改變的訊息
Framework\base\services\java\com\android\server\am
├── ActivityManagerService.java
建立BatteryStatsService
├── BatteryStatsService.java
統計和記錄電池引數的資訊
Framework\base\services\java\com\android\server\power
├── PowerManagerService.java
監聽電池發生變化的廣播訊息,並調節系統的電源狀態,例如亮屏
Framework\base\core\java\com\internal\os\
├── BatteryStatsImpl.java
統計和記錄電池引數的資訊,並通知其他模組
System\core\healthd
├── healthd.cpp
建立uevent socket,監聽核心上報的核心事件
├── BatteryMonitor.cpp
初始化本地電池資料結構,將power_supply路徑下屬性節點路徑填充進去,
├── BatteryMonitor.h
├── BatteryPropertiesRegistrar.cpp
建立電池屬性監聽器,並將其註冊到Android的系統服務中
├── BatteryPropertiesRegistrar.h
核心主要通過get_property這個函式指標來獲得驅動中的有關電池的資訊,而這個函式在核心中只給出了宣告,我們在寫驅動的時候要自己實現get_property函式,當核心需要驅動中電源資訊的時候就回調這個get_property函式。例如當核心需要驅動中的電量值時,會呼叫get_property,傳入獲取電量別的標誌,我們就把從電量計中讀取到的電量值返回給核心。
。另外,我們寫驅動程式的時候又要給使用者提供介面,核心中提供給使用者的介面就是sysfs,通過讀取sysfs檔案系統中檔案內容,就可以得到電源的資訊。核心主要通過兩個檔案power_supply_class.c和power_supply_core.c,我們呼叫其中的函式就可以把電源(電池,USB或AC)的資訊展現給使用者,有關電源的屬性寫在/sys/class/powersupply資料夾下(此資料夾為程式執行後所生成的)。
/sys/class/power_supply資料夾存放的是,電池驅動通過power_supply_register函式註冊的各個電源屬性名稱。
在安卓系統的命令列下輸入: cat /sys/class/power_supply/rk-bat/uevent:
電池系統從底層向Framework層上報資料的流程:
2.除錯手段:
獲取手機電池資訊
adb命令:adb shell dumpsys battery
得到資訊如下:
AC powered: false
USB powered: true
Wireless powered: false
status: 1 #電池狀態:2:充電狀態 ,其他數字為非充電狀態
health: 2
present: true
level: 55 #電量: 百分比
scale: 100
voltage: 3977
current now: -335232
temperature: 335 #電池狀態
technology: Li-poly
改變手機電池狀態
切換手機電池為非充電狀態: adb shell dumpsys battery set status 1
改變手機電量
讓手機電量顯示百分百: adb shell dumpsys battery set level 100
讓手機電量顯示1: adb shell dumpsys battery set level 1
3.除錯遇到的問題:
1、現象:cw2015電池驅動編寫好後,電量一直顯示100不變,從電量暫存器中讀到的值也一直是100.
解決方法:cw2015電量計晶片, 不是上電就可以正常使用的,需要寫0xFF到0xA暫存器中,延遲10ms後,再寫0x0到0xA暫存器中,去啟動該晶片(晶片手冊並沒有說明此問題,自己寫了一個命令列讀寫電量計的程式,慢慢試出來的.)
2.現象:電池電量顯示正常,能正常更新, 驅動向電池的heathd層發的uevent事件中的,cw2015的充放電狀態和電量也都是正常的可以正常接收更新的狀態; 但是無論斷電還是上電,一直顯示是充電狀態的圖示。
解決方法:一開始以為是電池服務層有問題,追了很久。 後來發現是rk-816的電池驅動影響了電池充放電圖示的更新:
rk-816驅動,一直檢測我的整個電池是相當於一個ac電源插入, 當我使用電池給板卡供電時,rk-816就更新我的/sys/class/power_supply/ac下的online狀態為1,。
而我的cw2015驅動,在電源斷電和上電時, 實時更新的是/sys/class/power_supply/rk-ac下的online狀態為0和1;
當斷電時, 我的cw2015驅動更新的/sys/class/power_supply/rk-ac為0時,而rk-816的/sys/class/power_supply/ac為1,這時,上層系統判斷是有ac插入的,電池充放電狀態圖示仍為充電。
可以使用adb shell dumpsys battery命令來檢視是否有電源在供電