1. 程式人生 > >Android 電池管理系統

Android 電池管理系統

一、Android 電池服務

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

二、Healthd

該模型向下監聽來自底層的電池事件,向上傳遞電池資料資訊給Framework層的BatteryService用來計算電池電量相關資訊,

BatteryService通過傳遞來的資料來計算電池電量等資訊,因此healthd在電池管理系統中起著承上啟下的作用。

三、驅動

Android電源管理底層用的是Linux power_supply框架,核心提供給電池驅動的介面是結構體power_supply結構體。

  1. struct power_supply {  
  2.     const char *name;  
  3.     enum power_supply_type type;  
  4.     enum power_supply_property *properties;  
  5.     size_t num_properties;  
  6.     char **supplied_to;  
  7.     size_t num_supplicants;  
  8.     int (*get_property)(struct power_supply *psy,  
  9.                 enum power_supply_property psp,  
  10.                 union power_supply_propval *val);  
  11.     int (*set_property)(struct power_supply *psy,  
  12.                 enum power_supply_property psp,  
  13.                 const union power_supply_propval *val);  
  14.     int (*property_is_writeable)(struct power_supply *psy,  
  15.                      enum power_supply_property psp);  
  16.     void (*external_power_changed)(struct power_supply *psy);  
  17.     void (*set_charged)(struct power_supply *psy);  
  18.     /* For APM emulation, think legacy userspace. */  
  19.     int use_for_apm;  
  20.     /* Driver private data */  
  21.     void *drv_data;//add by bhj  
  22.     /* private */  
  23.     struct device *dev;  
  24.     struct work_struct changed_work;  
  25.     spinlock_t changed_lock;  
  26.     bool changed;  
  27.     struct wake_lock work_wake_lock;  
  28.     struct delayed_work deferred_register_work;  
  29. #ifdef CONFIG_LEDS_TRIGGERS  
  30.     struct led_trigger *charging_full_trig;  
  31.     char *charging_full_trig_name;  
  32.     struct led_trigger *charging_trig;  
  33.     char *charging_trig_name;  
  34.     struct led_trigger *full_trig;  
  35.     char *full_trig_name;  
  36.     struct led_trigger *online_trig;  
  37.     char *online_trig_name;  
  38.     struct led_trigger *charging_blink_full_solid_trig;  
  39.     char *charging_blink_full_solid_trig_name;  
  40. #endif  
  41. };</span>  

 核心主要通過get_property這個函式指標來獲得驅動中的有關電池的資訊,而這個函式在核心中只給出了宣告,我們在寫驅動的

時候要自己實現這個函式,即將自己寫的函式賦值給這個函式指標,當核心需要驅動中電源資訊的時候就回調這個get_property函式

。另外,我們寫驅動程式的時候又要給使用者提供介面,核心中提供給使用者的介面就是sysfs,通過讀取sysfs檔案系統中檔案內容,就

可以得到電源的資訊。核心主要通過兩個檔案power_supply_class.c和power_supply_core.c,我們呼叫其中的函式就可以把電源(電

池,USB或AC)的資訊展現給使用者,有關電源的屬性寫在/sys/class/powersupply資料夾下(此資料夾為程式執行後所生成的)。

電池系統從底層向Framework層上報資料的流程: