MTK/Android 充電邏輯

前言

加量不加價,更新來一波

整體框圖

不記得從哪保存的好圖了
在這裏插入圖片描述

硬件/內核相關

相關概念

懶的排版了,直接上圖
這裏寫圖片描述

相關文件關係

再來一發
這裏寫圖片描述

雜項,電池溫度檢測原理圖


這裏寫圖片描述

充電流程

圖樣圖森破
這裏寫圖片描述

核心函數特寫

這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述

Android 相關

Healthd 就是一個 daemon service,取代以前的 battery JNI ,
1.定期讀取 sys/class/power_supply 的檔案, 包含所有關於電池的必要資訊(電壓, 電流, 溫度,狀態 etc)
2.將上述讀取的資訊寫入至 battery property, 讓 android battery Service update

Healthd 啓動流程

// system\core\rootdir\init.rc
service healthd /sbin/healthd
    class core
    critical
    seclabel u:r:healthd:s0
    group root system wakelock
    

// 對應的代碼路徑爲:
// Healthd.cpp (system\core\healthd)
int main(int argc, char **argv)
		//////////////////////////////////////////////////////////////////////////////
		// 1. 根據不同的啓動模式,設置 healthd_mode_ops 爲不同的操作函數集
		//      當開機充電時變量賦值爲 &android_ops,關機充電時候變量賦值爲 &charger_ops
		//healthd_mode_ops = &android_ops;
		//
		// 2.用 epoll 監聽了:
		//      1. Binder 通信事件
		//      2. 定時器事件 
		//      3. Netlink 實現的 uevent 事件
		// 然後遍歷 /sys/class/power_supply/ 下的結點,設置全局變量 healthd_config
		//ret = healthd_init();
		//    // 創建了一個 epoll 輪詢象
		//    epollfd = epoll_create(MAX_EPOLL_EVENTS);
		//    // 這裏就開機充電的情況下分析,調用 android_ops->init()
		//    // 主要是進行了 Binder 相關初始化,並註冊了一個服務 "batteryproperties"
		//    // 到 servicemanager 中進行管理
		//    healthd_mode_ops->init(&healthd_config);
		//
		//    // 主要是創建了一個定時器,24小時執行一次?
		//    wakealarm_init();
		//
		//    // 用 epoll 監聽 netlink 上報的 uevent 事件        
		//    uevent_init();
		//
		//    // 創建 BatteryMonitor 的對象,並將其初始化。BatteryMonitor 
		//    // 主要接受 healthd 傳來的數據,做電池狀態的計算並更新       
		//    gBatteryMonitor = new BatteryMonitor();
		//
		//    // 主要是根據路徑下節點設置全局變量 healthd_config
		//    //   POWER_SUPPLY_SYSFS_PATH 定義爲 "/sys/class/power_supply",
		//    //   在 init 函數中打開系統該文件夾,然後一一讀取該文件夾下的文
		//    //   件內容,在 while 循環中判斷該文件夾下各個文件節點的內容,
		//    //   並將其初始化給相關的參數
		//    gBatteryMonitor->init(&healthd_config);
		//
		//
		// 3. 死循環,
		//    監聽 epoll 事件,並調用相應的回調函數進行處理:
		//      1> uevent_event() 處理內核 Netlink 上報的數據 
		//              // 當 sys 屬性變化時,寫入 log, 通知監聽者
		//      2> wakealarm_event(): 處理定時器喚醒
		//      3> binder_event(): 處理 Binder 通信
		//    如果沒有事件,則根據 sys 屬性變化,寫入 log, 通知監聽者 BatteryPropertiesRegistrar::notifyListeners() 
		//healthd_mainloop();

BatteryService

接口:frameworks\base\core\java\com\android\internal\app\IBatteryStats.aidl

【初始化流程】

zygote
	SystemServer
		// 入口函數
		main(String[] args) 
			new SystemServer().run();
				startBootstrapServices();
				startCoreServices();
					mSystemServiceManager.startService(BatteryService.class);
							////////////////////////////////////////////////////////////////////////////
							// frameworks\base\services\core\java\com\android\server\SystemServiceManager.java
							// 創建一個繼承 SystemService 的子類 
							public <T extends SystemService> T startService(Class<T> serviceClass)
											// 獲得 Class 名稱
											final String name = serviceClass.getName();
											// 獲得構造函數: public BatteryService(Context context) 
											Constructor<T> constructor = serviceClass.getConstructor(Context.class);
											// 調用構造函數,創建類對象
											service = constructor.newInstance(mContext);
                                                        ///////////////////////////////////////////////////////////////
														// frameworks\base\services\core\java\com\android\server\BatteryService.java
                                                        BatteryService::BatteryService()
                                                        	// LED 燈光顯示
                                                        	mLed = new Led(context, getLocalService(LightsManager.class));
															// 相關警告電量配置

											// 添加到鏈表中進行管理                                            
											mServices.add(service);
											// 啓動服務 
											service.onStart();
														// frameworks\base\services\core\java\com\android\server\BatteryService.java
														public void onStart()
																// 1. 首先將電池監聽註冊到底層去, 底層電量變化,會【調用 update()】
																IBinder b = ServiceManager.getService("batteryproperties");
																final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);
																//電池監聽,註冊到底層。當底層電量改變會調用此監聽。然後執行 update 
																batteryPropertiesRegistrar.registerListener(new BatteryListener());

																///////////////////////////////////////////////////////////
																// 2. 如果是 IPO 開關機的話,需要監聽廣播
																if (SystemProperties.get("ro.mtk_ipo_support").equals("1")) 。。。

																// 3. 將本地接口 publish 出去,                                                                
																// 創建一個內部類 BinderService 對象 
																mBinderService = new BinderService();

底層電量更新流程

// 當底層電池狀態更新時,healthd 會回調 BatteryPropertiesRegistrar::notifyListeners()    
// 而此類是通過 Binder 通信註冊了回調的,當有事件時會調用回調 update():
//      IBinder b = ServiceManager.getService("batteryproperties");     // BatteryPropertiesRegistrar.cpp  註冊的
//      final IBatteryPropertiesRegistrar batteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);     
//      batteryPropertiesRegistrar.registerListener(new BatteryListener());                                                                          
private final class BatteryListener extends IBatteryPropertiesListener.Stub 
	BatteryService.this.update(props);
		processValuesLocked(false);
			// //解析充電類型  
			if (mBatteryProps.chargerAcOnline) 。。。
			// 充電指示燈更新
			mLed.updateLightsLocked();
			// 沒電了
			shutdownIfNoPowerLocked();
			// 溫度過高  
			shutdownIfOverTempLocked();
			// 發送電池狀態變化的廣播
			sendIntentLocked();

#什麼!還要了解?請看源碼
地址:鏈接: http://pan.baidu.com/s/1kV3DKNX 密碼: uiyb

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章