天天看點

Windows CE 5.0電池驅動剖析

  一.概述 Windows CE電池驅動屬于分層驅動,由MDD層和PDD層組成。驅動示例代碼位于%_WINCEROOT%/Public/Common/Oak/Drivers/Battdrvr。其中battdrvr.c是MDD層代碼,sbattif.c是PDD層代碼。MDD層代碼微軟已經搭好架構,一般不需要修改,我們要實作的是PDD層的代碼。   二.MDD層 電池驅動對外接口函數沒有“BAT_”字首,因為HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Battery/Flags系統資料庫項設定了DEVFLAGS_NAKEDENTRIES屬性,表示“Init”代替“BAT_Init”,這樣修改系統資料庫“Prefix”項的值時不需要修改驅動代碼。 MDD層函數包括:Init、Deinit、Open、Close、Read、Write、Seek、PowerDown、PowerUp、IOControl。我們主要分析一下Init和IOControl函數。 先來看一下初始化函數Init,它所做的工作主要如下: 1.判斷ghevResume事件是否為NULL,條件成立表示驅動還未加載繼續執行,否則表示驅動已經加載跳出執行。 2.打開一個名為“SYSTEM/BatteryAPIsReady”的事件。“SYSTEM/BatteryAPIsReady”事件在系統資料庫HKEY_LOCAL_MACHINE/System/Events下面,在核心初始化的時候由filesys.exe建立。 3.建立ghevResume事件。 4.調用BatteryPDDInitialize初始化電池資訊,這個函數在下面的PDD層介紹。 5.調用BatteryAPIGetSystemPowerStatusEx2函數更新電池最新資訊。BatteryAPIGetSystemPowerStatusEx2函數主要調用BatteryPDDGetStatus函數擷取電池資訊,這個函數在PDD層介紹。 6.建立一個電池監控線程,處理系統resume消息,定時查詢電池狀态并通知系統。 7.設定“SYSTEM/BatteryAPIsReady”事件,通知系統電池驅動已經正常運作。 IOControl函數用來與其他驅動通訊或供應用程式調用。IOCTL_BATTERY_GETSYSTEMPOWERSTATUSEX2和IOCTL_BATTERY_GETSYSTEMPOWERSTATUSEX控制碼得到系統電源狀态。IOCTL_BATTERY_GETLIFETIMEINFO控制碼得到電池剩餘使用時間。IOCTL_BATTERY_GETLEVELS控制碼得到電池報告級别,具體在BatteryPDDGetLevels中說明。IOCTL_BATTERY_SUPPORTSCHANGENOTIFICATION控制碼報告當電池狀态變化時是否通知系統。IOCTL_BATTERY_NOTIFYOFTIMECHANGE控制碼表示如果系統時間改變,則更新電池相關資訊。另外還預留了一個gpfnBatteryPddIOControl函數指針用來處理使用者定義的IOCTL碼。   三.PDD層        PDD層函數包括:BatteryPDDInitialize、BatteryPDDDeinitialize、BatteryPDDResume、BatteryPDDPowerHandler、BatteryPDDGetStatus、BatteryPDDGetLevels、BatteryPDDSupportsChangeNotification。 PDD層代碼完成電池資訊的采集傳遞到MDD層供系統調用。電池資訊資料結構如下 struct SYSTEM_POWER_STATUS_EX2 {     BYTE ACLineStatus;     BYTE BatteryFlag;     BYTE BatteryLifePercent;     BYTE Reserved1;     DWORD BatteryLifeTime;     DWORD BatteryFullLifeTime;     BYTE Reserved2;     BYTE BackupBatteryFlag;     BYTE BackupBatteryLifePercent;     BYTE Reserved3;     DWORD BackupBatteryLifeTime;     DWORD BackupBatteryFullLifeTime;     DWORD BatteryVoltage;     DWORD BatteryCurrent;     DWORD BatteryAverageCurrent;     DWORD BatteryAverageInterval;     DWORD BatterymAHourConsumed;     DWORD BatteryTemperature;     DWORD BackupBatteryVoltage;     BYTE BatteryChemistry; } 其中ACLineStatus、BatteryFlag、BatteryLifePercent最重要。ACLineStatus表示外接AC電源的狀态,可以取下面的值:AC_LINE_OFFLINE、AC_LINE_ONLINE、AC_LINE_BACKUP_POWER、AC_LINE_UNKNOWN。BatteryFlag表示電池狀态,可以取下面的值:BATTERY_FLAG_HIGH、BATTERY_FLAG_LOW、BATTERY_FLAG_CRITICAL、BATTERY_FLAG_CHARGING、BATTERY_FLAG_NO_BATTERY、BATTERY_FLAG_UNKNOWN。BatteryLifePercent表示目前電池剩餘電量百分比,。 BatteryPDDGetStatus的主要工作是填充上面的電池資訊結構。在這裡需要實作電池硬體驅動,讀取電池狀态資訊。 BatteryPDDGetLevels傳回電池資訊結構SYSTEM_POWER_STATUS_EX2中BatteryFlag和BackupBatteryFlag成員的電池狀态級别。傳回值為雙字,低字表示主電池報告級别MainLevel,取值0~3;高字表示主電池報告級别BackLevel,取值0~3。如果BatteryFlag隻取值BATTERY_FLAG_HIGH,則MainLevel為1;如果BatteryFlag取值BATTERY_FLAG_HIGH、BATTERY_FLAG_LOW,則MainLevel為2;如果BatteryFlag取值BATTERY_FLAG_HIGH、BATTERY_FLAG_LOW、BATTERY_FLAG_CRITICAL,則MainLevel為3。 另外,充電管理一般也在電池驅動PDD層實作,這裡不再介紹,有興趣的同學可以和我交流。   四.硬體解決方案        電池充電管理晶片MAX8677A和電池監控晶片DS2786構成一套完整的裝置電池管理方案。MAX8677A和DS2786是Maxim(美信)公司生産的晶片,晶片詳細資料請參考 http://www.maxim-ic.com.cn。   五.其他 當電池狀态改變時,調用SetEvent一個命名為“SSUpdatePower”的事件強制shell立即更新電池狀态。電池驅動還有與電源管理互動的部分,放到電源管理部分介紹。  

繼續閱讀