WinCE6.0 DEVICEEMULATOR BSP的BatteryDriver驱动简析

WinCE6.0 DEVICEEMULATOR BSP的Battery驱动,位于/SRC/DRIVERS/BATTDRVR下,只有一个battif.c,内容比较简单.实际上是电池驱动的PDD层,实现PDD层中的一个接口函数,这里简要来分析一下.其中MDD层代码位于/WINCE600/PUBLIC/COMMON/OAK/DRIVERS/BATTDRVR下.
电池Battery驱动由Device Manager加载,导出了一个流接口. 该流接口使OS不在让GWES来访问电池驱动函数.此流接口在系统启动早期能够提供电池信息,能够比标准函数报告更多不同的电池信息.
1. 注册表设置
位于/WINCE600/PUBLIC/COMMON/OAK/DRIVERS/BATTDRVR/battdrvr.reg,在platform.reg中通过#include "$(DRIVERS_DIR)/battdrvr/battdrvr.reg"添加到最终的注册表中.
IF BSP_NOBATTERY !

; HIVE BOOT SECTION

[HKEY_LOCAL_MACHINE/System/Events]
    "SYSTEM/BatteryAPIsReady"="Battery Interface APIs"

; END HIVE BOOT SECTION

; These registry entries load the battery driver.  The IClass value must match
; the BATTERY_DRIVER_CLASS definition in battery.h -- this is how the system
; knows which device is the battery driver.  Note that we are using
; DEVFLAGS_NAKEDENTRIES with this driver.  This tells the device manager
; to instantiate the device with the prefix named in the registry but to look
; for DLL entry points without the prefix.  For example, it will look for Init
; instead of BAT_Init.  This allows the prefix to be changed in the registry (if
; desired) without editing the driver code.
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Battery]
   "Prefix"="BAT"
   "Dll"="battdrvr.dll"
   "Flags"=dword:8                      ; DEVFLAGS_NAKEDENTRIES
   "Order"=dword:0
   "IClass"="{DD176277-CD34-4980-91EE-67DBEF3D8913}"

ENDIF BSP_NOBATTERY !

2. BatteryPDDInitialize
BatteryPDDInitialize用来进行硬件相关的初始化,这里没有做任何实质性工作.

3. BatteryPDDDeinitialize
BatteryPDDDeinitialize用来进行硬件相关的资源释放.
if (g_pBatteryRegs)
    {
        MmUnmapIoSpace((PVOID)g_pBatteryRegs, sizeof(DEVICEEMULATOR_BATTERY_REGS));
    }
这里释放了Battery寄存器的映射的虚拟地址空间.

4. BatteryPDDResume
BatteryPDDResume在系统继续时在线程中进行硬件相关的电池操作.
这里没有做任何实质性工作.

5. BatteryPDDPowerHandler
BatteryPDDPowerHandler是电池驱动电源的回调函数,用来进行进行硬件相关的电池操作.在该回调中,只有有限的系统服务可以使用,如果要处理更多更复杂的动作,可以使用BatteryPDDResume

6. BatteryPDDGetStatus
BatteryPDDGetStatus获取当前电池/电源的大部分状态信息,并填充给参数传递的结构体SYSTEM_POWER_STATUS_EX2中.
SYSTEM_POWER_STATUS_EX2原型如下:
typedef 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; // Add any extra information after the BatteryChemistry member. } SYSTEM_POWER_STATUS_EX2, *PSYSTEM_POWER_STATUS_EX2, *LPSYSTEM_POWER_STATUS_EX2;
如果是第一次运行,则调用InitBatteryDriver来分配电池物理地址相应的虚拟地址空间.
void InitBatteryDriver() { if (g_pBatteryRegs == NULL) { PHYSICAL_ADDRESS ioPhysicalBase = { BSP_BASE_REG_PA_BATTERY, 0}; ULONG inIoSpace = 0; if (HalTranslateBusAddress(Internal,0, ioPhysicalBase,&inIoSpace,&ioPhysicalBase)) { // Map it if it is Memeory Mapped IO. g_pBatteryRegs = (volatile DEVICEEMULATOR_BATTERY_REGS *)MmMapIoSpace(ioPhysicalBase, sizeof(DEVICEEMULATOR_BATTERY_REGS),FALSE); } } }
接下来获取状态:
PowerStatus = IsACOnline(); sample = g_pBatteryRegs->ChargePercent; if (sample > 100) { sample = 100; } sample = 100-sample; // convert from the emulators "0=fully charged, 100=fully discharged" to "100=fully charged, 0=fully discharged"
判断AC电源状态:
if (PowerStatus) { pstatus->ACLineStatus = AC_LINE_ONLINE; ChargePercent = sample; if (sample > ChargePercent) // AC ON, Battery OFF { BatteryFlag |= BATTERY_FLAG_CHARGING; } } else { pstatus->ACLineStatus = AC_LINE_OFFLINE; ChargePercent = sample; }
设置电池电量百分比状态,
if(ChargePercent >= 65) BatteryFlag |= BATTERY_FLAG_HIGH; else if ((ChargePercent < 65) && (ChargePercent >= 20)) BatteryFlag |= BATTERY_FLAG_LOW; else BatteryFlag |= BATTERY_FLAG_CRITICAL;
最后将这些状态填充到SYSTEM_POWER_STATUS_EX2结构中去.

pstatus->BatteryFlag = BatteryFlag; pstatus->BatteryLifePercent = ChargePercent; pstatus->Reserved1 = 0; pstatus->BatteryLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->BatteryFullLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->Reserved2 = 0; pstatus->BackupBatteryFlag = BATTERY_FLAG_UNKNOWN; pstatus->BackupBatteryLifePercent = 0; pstatus->Reserved3 = 0; pstatus->BackupBatteryLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->BackupBatteryFullLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->BatteryChemistry = BATTERY_CHEMISTRY_LION; pstatus->BatteryVoltage = (((unsigned long)ChargePercent * 41)/1000); pstatus->BatteryCurrent = 0; pstatus->BatteryAverageCurrent = 0; pstatus->BatteryAverageInterval = 0; pstatus->BatterymAHourConsumed = 0; pstatus->BatteryTemperature = temperature; pstatus->BackupBatteryVoltage = 0;

7. BatteryPDDGetLevels
BatteryPDDGetLevels用来获得电池电源级数(电池和备用电池),这里各设了3级:
 LONG lLevels = MAKELONG (3 /* main battery levels   */, 
                             3 /* backup battery levels */);

8. BatteryPDDSupportsChangeNotification
该函数报告驱动是否支持电池更换的通知.这里不支持,返回False.

通过KTIL下载到开发板,可以看到我们添加的打印信息,BatteryPDDGetStatus会被周期性的调用来获得电池的状态.由于我们的开发板直接连AC电源,因此显示的是AC_ONLINE,充电状态也是100%.

你可能感兴趣的:(manager,System,dll,byte,interface,WinCE)