最近调了wince battery driver, 对电池驱动有了一点点了解,如下:

1.Windows CE电池驱动属于分层驱动,由MDD层和PDD层组成。微软给我们的代码在D:/WINCE600/PUBLIC/COMMON/OAK/DRIVERS/BATTDRVR 目录下,该目录MDD文件夹是MDD 代码,一般的我们都不用动,直接引用即可。而PDD文件夹下的sbattif.c 是PDD的框架代码,我们可以直接靠过来,针对具体硬件添加代码。

2.MDD层函数包括:Init、Deinit、Open、Close、Read、Write、Seek、PowerDown、PowerUp、IOControl。我主要分析一下Init。DWORD Init( PVOID Context ) { DWORD dwHandle = 0; // assume failure SETFNAME(_T("BattDrvr: Init")); DEBUGMSG(ZONE_INIT, (_T("%s: invoked w/ context 0x%08x/r/n"), pszFname, Context)); // have we already been loaded? if(ghevResume == NULL) { // get a handle to our API event HANDLE hevReady = OpenEvent(EVENT_ALL_ACCESS, FALSE, BATTERY_API_EVENT_NAME); if(hevReady == NULL) { DEBUGMSG(ZONE_ERROR || ZONE_INIT, (_T("%s: fatal error: can't open API event/r/n"), pszFname)); goto done; } // no, initialize global variables InitializeCriticalSection(&gcsBattery); InitializeCriticalSection(&gcsPddBuffer); gpfnBatteryPddIOControl = NULL; // must be initialized by the PDD gdwPddBufferSize = sizeof(SYSTEM_POWER_STATUS_EX2); gpPddBuffer = NULL; gpPddBufferTemp = NULL; ghevResume = CreateEvent(NULL, FALSE, FALSE, NULL); if(ghevResume == NULL) { DEBUGMSG(ZONE_ERROR || ZONE_INIT, (_T("%s: CreateEvent() failed/r/n"), pszFname)); } else { if(!BatteryPDDInitialize(Context)) { DEBUGMSG(ZONE_ERROR || ZONE_INIT, (_T("%s: BatteryPDDInitialize() failed/r/n"), pszFname)); } else { HKEY hk; DWORD dwLen; // init defaults gBatteryContext.dwPollTimeout = DEF_BATTERYPOLLTIMEOUT; gBatteryContext.iPriority = 249; // THREAD_PRIORITY_HIGHEST memset(&gBatteryContext.st, 0xFF, sizeof(gBatteryContext.st)); // get my thread priority configuration hk = OpenDeviceKey(Context); if(hk != NULL) { DWORD dwValue, dwType, dwSize, dwStatus; // get the thread priority dwSize = sizeof(dwValue); dwStatus = RegQueryValueEx(hk, _T("PollPriority256"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize); if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) { gBatteryContext.iPriority = (INT) dwValue; } // get the polling interval dwSize = sizeof(dwValue); dwStatus = RegQueryValueEx(hk, _T("PollInterval"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize); if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) { gBatteryContext.dwPollTimeout = dwValue; } // get the Pdd buffer size dwSize = sizeof(dwValue); dwStatus = RegQueryValueEx(hk, _T("PddBufferSize"), NULL, &dwType, (LPBYTE) &dwValue, &dwSize); if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) { if( dwValue > gdwPddBufferSize ) { gdwPddBufferSize = dwValue; } } RegCloseKey(hk); } gpPddBuffer = (BYTE*)LocalAlloc( LPTR, gdwPddBufferSize ); if( gpPddBuffer == NULL ) { DEBUGMSG(ZONE_ERROR || ZONE_INIT, (_T("%s: BatteryPDDInitialize() failed to allocate the Pdd buffer./r/n"), pszFname)); goto done; } gpPddBufferTemp = (BYTE*)LocalAlloc( LPTR, gdwPddBufferSize ); if( gpPddBufferTemp == NULL ) { DEBUGMSG(ZONE_ERROR || ZONE_INIT, (_T("%s: BatteryPDDInitialize() failed to allocate the Pdd temp buffer./r/n"), pszFname)); goto done; } // initialize battery update variables dwLen = BatteryAPIGetSystemPowerStatusEx2 (&gBatteryContext.st, sizeof(gBatteryContext.st), TRUE); DEBUGCHK(dwLen == sizeof(gBatteryContext.st)); // start the battery monitor/resume thread ghtBattery = CreateThread(NULL, 0, BatteryThreadProc, &gBatteryContext, 0, NULL); if(ghtBattery == NULL) { DEBUGMSG(ZONE_ERROR || ZONE_INIT, (_T("%s: CreateThread() failed %d/r/n"), pszFname, GetLastError())); } else { // notify the world that we're up and running SetEvent(hevReady); CloseHandle(hevReady); // return success dwHandle = 1; } } } done: // clean up if something went wrong if(dwHandle == 0) { if(gpPddBuffer != NULL) { LocalFree( gpPddBuffer ); gpPddBuffer = NULL; } if(gpPddBufferTemp != NULL) { LocalFree( gpPddBufferTemp ); gpPddBufferTemp = NULL; } if(ghtBattery != NULL) { DEBUGCHK(ghevResume != NULL); gfExiting = TRUE; SetEvent(ghevResume); WaitForSingleObject(ghtBattery, INFINITE); CloseHandle(ghtBattery); ghtBattery = NULL; } if(ghevResume != NULL) { CloseHandle(ghevResume); ghevResume = NULL; } DeleteCriticalSection(&gcsBattery); DeleteCriticalSection(&gcsPddBuffer); } } DEBUGMSG(ZONE_INIT, (_T("%s: returning %d/r/n"), pszFname, dwHandle)); return dwHandle; }

1.判断ghevResume事件是否为NULL,条件成立表示驱动还未加载继续执行,否则表示驱动已经加载跳出执行。
2.打开一个名为“SYSTEM/BatteryAPIsReady”的事件。“SYSTEM/BatteryAPIsReady”事件在注册表HKEY_LOCAL_MACHINE/System/Events下面,在内核初始化的时候由filesys.exe创建。
[HKEY_LOCAL_MACHINE/System/Events]
       "SYSTEM/BatteryAPIsReady"="Battery Interface APIs"
3.创建ghevResume事件。
4.调用BatteryPDDInitialize初始化电池信息,调用PDD层代码。
5.  打开注册表,获取轮询查询电池状态时间间隔,其默认的时间间隔为:
#define DEF_BATTERYPOLLTIMEOUT          (5*1000)         // in milliseconds
注册表设置的时间间隔:
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Battery]
       "PollInterval"=dword:3e8  ;in milliseconds
       "BattCalibrationPoint"=dword:7
       "BattCalibrationData"=hex:59,03,4b,03,32,03,1c,03,09,03,f5,02,e0,02
6.调用BatteryAPIGetSystemPowerStatusEx2函数更新电池最新信息。BatteryAPIGetSystemPowerStatusEx2函数主要调用BatteryPDDGetStatus函数获取电池信息,这个函数在PDD层实现。
7.创建一个电池监控线程,处理系统resume消息,定时查询电池状态并通知系统。
8.设置“SYSTEM/BatteryAPIsReady”事件,通知系统电池驱动已经正常运行。

3.    PDD层函数主要包括:BatteryPDDInitialize、BatteryPDDDeinitialize、BatteryPDDResume、BatteryPDDPowerHandler、BatteryPDDGetStatus、BatteryPDDGetLevels、BatteryPDDSupportsChangeNotification 等函数,个人觉得最重要的事BatteryPDDInitialize和BatteryPDDGetStatus。

下面是我的BatteryPDDInitialize 代码:BOOL WINAPI BatteryPDDInitialize(LPCTSTR pszRegistryContext) { BOOL fOk = TRUE; SYSTEM_POWER_STATUS_EX2 sps; WORD wMainLevels = 3, wBackupLevels = 0; BOOL fSupportsChange = FALSE; SETFNAME(_T("BatteryPDDInitialize")); DEBUGCHK(ghMutex == NULL); DEBUGCHK(ghFileMap == NULL); DEBUGCHK(gpStatus == NULL); DEBUGCHK(pszRegistryContext != NULL); DEBUGMSG(DBG_ATLAS_ZONE_INIT, (TEXT("%s:%d:+++++++++++++++/r/n"),_T(__FUNCTION__),__LINE__)); //----- 1. Map System Register if(!CspRegMap(TRUE)) { RETAILMSG(DBG_ATLAS_ZONE_ERROR, (TEXT("%s:%d:Failed to Map register!/r/n"),_T(__FUNCTION__),__LINE__)); goto _ERR_BATT; } //----- 2. Batt IC Init if(!BspBattInit(pszRegistryContext)) { RETAILMSG(DBG_ATLAS_ZONE_ERROR, (TEXT("%s:%d:BspBattInit Error!/r/n"),_T(__FUNCTION__),__LINE__)); goto _ERR_BATT; } //----- 3. Batt ADC Init if(!BspBattADCInit(pszRegistryContext)) { RETAILMSG(DBG_ATLAS_ZONE_ERROR, (TEXT("%s:%d:BspBattPMInit Error!/r/n"),_T(__FUNCTION__),__LINE__)); goto _ERR_BATT; } //----- 4. Batt PM Init if(!BspBattPMInit(pszRegistryContext)) { RETAILMSG(DBG_ATLAS_ZONE_ERROR, (TEXT("%s:%d:BspBattPMInit Error!/r/n"),_T(__FUNCTION__),__LINE__)); goto _ERR_BATT; } //----- 5. intialize the battery status structure -- assume AC power, no battery info (get from Wince6.0 Private Code) sps.ACLineStatus = AC_LINE_ONLINE; sps.BatteryFlag = BATTERY_FLAG_HIGH; sps.BatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN; sps.Reserved1 = 0; sps.BatteryLifeTime = BATTERY_LIFE_UNKNOWN; sps.BatteryFullLifeTime = BATTERY_LIFE_UNKNOWN; sps.Reserved2 = 0; sps.BackupBatteryFlag = BATTERY_FLAG_UNKNOWN; sps.BackupBatteryLifePercent = BATTERY_PERCENTAGE_UNKNOWN; sps.Reserved3 = 0; sps.BackupBatteryLifeTime = BATTERY_LIFE_UNKNOWN; sps.BackupBatteryFullLifeTime = BATTERY_LIFE_UNKNOWN; sps.BatteryChemistry = BATTERY_CHEMISTRY_UNKNOWN; sps.BatteryVoltage = 0; sps.BatteryCurrent = 0; sps.BatteryAverageCurrent = 0; sps.BatteryAverageInterval = 0; sps.BatterymAHourConsumed = 0; sps.BatteryTemperature = 0; sps.BackupBatteryVoltage = 0; g_PreACLineStatus = sps.ACLineStatus; //----- 6. Allocate resources (get code from Wince6.0 Private Code) if((ghMutex = CreateMutex(NULL, FALSE, BATTERY_FILE_MUTEX)) == NULL) { /* DEBUGMSG(DBG_ATLAS_ZONE_ERROR || DBG_ATLAS_ZONE_INIT , (_T("%s: Could not aquire battery info file mutex handle/n"), pszFname)); */ fOk = FALSE; } else { HINSTANCE hiCoreDll = NULL; BOOL fNewMapping = TRUE; // get pointers to file-mapping functions hiCoreDll = LoadLibrary(_T("coredll.dll")); if(hiCoreDll != NULL) { gpfnCreateFileMappingW = (PFN_CreateFileMappingW) GetProcAddress((HMODULE) hiCoreDll, _T("CreateFileMappingW")); gpfnMapViewOfFile = (PFN_MapViewOfFile) GetProcAddress((HMODULE) hiCoreDll, _T("MapViewOfFile")); gpfnUnmapViewOfFile = (PFN_UnmapViewOfFile) GetProcAddress((HMODULE) hiCoreDll, _T("UnmapViewOfFile")); } FreeLibrary(hiCoreDll); // we're already linked to coredll // serialize access to the mapping file LockBattery(); // create the mapping if(gpfnCreateFileMappingW == NULL ) { // no file mapping, use a global variable static BATTERY_STATUS sBatteryStatus; gpStatus = &sBatteryStatus; RETAILMSG(1,(TEXT("no file mapping, use a global variable!/r/n"))); } else if((ghFileMap = gpfnCreateFileMappingW((HANDLE)INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(BATTERY_STATUS), BATTERY_STATUS_FILE)) == NULL) { RETAILMSG(1,(TEXT("Could not create file mapping for battery info file!/r/n"))); /* DEBUGMSG(ZONE_ERROR || ZONE_PDD || ZONE_INIT, (_T("%s: Could not create file mapping for battery info file/n"), pszFname)); */ fOk = FALSE; } else { // is this a new mapping? if(GetLastError() == ERROR_ALREADY_EXISTS) { fNewMapping = FALSE; } // map the object into our address space if(gpfnMapViewOfFile == NULL || (gpStatus = (PBATTERY_STATUS) gpfnMapViewOfFile(ghFileMap, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(BATTERY_STATUS))) == NULL) { /* DEBUGMSG(ZONE_ERROR || ZONE_PDD || ZONE_INIT, (_T("Could not map view of battery info file into process address space/n"), pszFname)); */ fOk = FALSE; } } // should we initialize our structure? if(fOk && fNewMapping) { // initialize the memory mapped object memcpy(&gpStatus->sps, &sps, sizeof(gpStatus->sps)); gpStatus->fSupportsChange = fSupportsChange; gpStatus->fChanged = FALSE; gpStatus->wMainLevels = wMainLevels; gpStatus->wBackupLevels = wBackupLevels; } // allow access to the battery buffer UnlockBattery(); } //----- 7. clean up if necessary (get from Wince6.0 Private Code) if(!fOk) { if(gpStatus != NULL && gpfnUnmapViewOfFile != NULL) gpfnUnmapViewOfFile(gpStatus); if(ghFileMap != NULL) CloseHandle(ghFileMap); if(ghMutex != NULL) CloseHandle(ghMutex); gpStatus = NULL; ghFileMap = NULL; ghMutex = NULL; } //----- 8. Register a function to receive custom IOCTLs gpfnBatteryPddIOControl = BatteryPddIOControl; DEBUGMSG(DBG_ATLAS_ZONE_INIT,(TEXT("%s:%d:----------------/r/n"),_T(__FUNCTION__),__LINE__)); return fOk; _ERR_BATT: RETAILMSG(DBG_ATLAS_ZONE_ERROR,(TEXT("+Battery ERROR OR UNKNOWN STATUS... /r/n"))); BspBattPMDeinit(); BspBattADCDeinit(); BspBattDeinit(); CspRegUnMap(); SetLastError(ERROR_NOT_SUPPORTED); DEBUGMSG(DBG_ATLAS_ZONE_INIT,(TEXT("%s:%d:----------------/r/n"),_T(__FUNCTION__),__LINE__)); return FALSE; }

主要是硬件初始化和填充电池信息结构体SYSTEM_POWER_STATUS_EX2 ;电池获得电量是通过读ADC寄存器的值再转化为电量百分比,具体硬件不同可能实现的方法有所不同;

BatteryPDDGetStatus 主要是检查电池当前的状态,重新更新SYSTEM_POWER_STATUS_EX2 结构体,可以添加电池低电报警功能在这里,控制开机电池最低电量!

Wince Battery driver相关推荐

  1. android电源驱动程序,[转]Android虚拟电源管理驱动

    Android系统如果没有电源管理相关的驱动程序,在启动时将会提示如下错误: I/SystemServer(   50): Starting Battery Service. E/BatterySer ...

  2. mt6737电池状态监测

    这里分析下mt6735平台下的电池驱动,使用的bq24296芯片(开关模式的充电方式). kernel-3.18/drivers/power/mediatek/battery_common.c sta ...

  3. Linux内核配置(9)

    ISDN(综合数码网络服务,在法国称为RNIS) 一种特殊的数码电话服务类型.它用于将你的电脑连接到你的Internet服务供应商(用SLIP或者PPP).连接的速度快于通常的modem电话连接,在下 ...

  4. LINUX内核编译选项-5

    Device Drivers  ---> 驱动程序 Generic Driver Options  --->驱动程序通用选项 (/sbin/hotplug) path to uevent ...

  5. MTK 充电逻辑总结

    相关概念 懒的排版了,直接上图  相关文件关系 再来一发  杂项,电池温度检测原理图 发  充电流程 图样图森破  核心函数特写       /* 概念: ZCV:开路电压OCV: 开路电压VC:闭路 ...

  6. java手机电池充电代码,android电池管理系统从上层的java到底层驱动的调用(转载)...

    1.概述 随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统对电源管理的合理与否直接影响到电池的续航能力,而电池系统作为其中的一部分,主要用于对电池状 ...

  7. [RK3288][Android6.0] 调试笔记 --- 伪电池驱动添加

    Platform: ROCKCHIP OS: Android 6.0 Kernel: 3.10.92 由于电池部分是用户空间Service从另外一颗MCU获取,而Android需要显示电量, 所以按照 ...

  8. android电池管理系统

    原文:http://www.2cto.com/kf/201408/326462.html 1.概述 随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统 ...

  9. linux 电池驱动

    本驱动是方便大家讨论及理解,电池的参数如电压,电量百分,温度以及相关状态都是人为给定.实际中都是通过读取相应硬件(如axpxxx)的寄存器并按照相应的算法获取.但框架都是一致. 本驱动的开发平台为瑞萨 ...

最新文章

  1. PCL:官方程序 Region growing segmentation
  2. 100W无线电耦合功率测试实验
  3. 使用CreateFile函数打开COM10及以上串行口
  4. FPGA重要设计思想
  5. mvn install java版本,maven的打包命令--assemblyinstall和maven update之后jdk版本变回1.5的问题...
  6. c语言goto语句用法_C语言32个关键字9种控制语句34种运算符整理
  7. jdk1.5的类转换成jdk1.4的类文件
  8. 如何运行Spark程序
  9. 蓝桥杯 BASIC-24 基础练习 龟兔赛跑预测
  10. js固定小数位数 .toFixed()
  11. Java_cookie 和session 的区别详解
  12. HTML和CSS面试题
  13. Git ---- 解决coding:Permission denied(publickey)
  14. C# web 读取excel并导入数据库
  15. HTTP的REST服务简介
  16. Netty 解决TCP粘包/半包使用
  17. Python 技术篇-用PIL库修改图片尺寸实例演示,python调整图像大小方法
  18. 毕设论文-word格式问题
  19. 【EXLIBRIS】随笔记 008
  20. 地铁一公里造价达7亿元,大部分城市无法回本,为何还抢着建?

热门文章

  1. Linux下文件的备份
  2. Java中线程池详解
  3. 百度细雨算法,旨在提升用户浏览B2B信息体验
  4. SMP与AMP体系结构
  5. 海思Hi3519A开发(4.移植OpenCV4.0.1到Hi3519A开发板)
  6. opus 源码下载 以及 相关资料
  7. Matlab/Simulink中的S函数模块嵌入人工智能、神经网络算法设计仿真案例详解(以基于RBF神经网络算法的VSG转动惯量自调节为例)
  8. Android 学习(一)
  9. 常见ADSL管理入口和密码
  10. 大学生如何学习Java