⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 battdrvr.c

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

//
// This module contains a sample battery driver for windows CE.  It
// exposes its interface to the system via a set of IOCTLs which device.exe
// invokes on its behalf when one of the battery APIs are invoked.  The
// following APIs are modeled in this way:
//
//      GetSystemPowerStatusEx
//      GetSystemPowerStatusEx2
//      BatteryGetLifeTimeInfo
//      BatteryDrvrSupportsChangeNotification
//      BatteryDrvrGetLevels
//      BatteryNotifyOfTimeChange
//
// When it initializes, this driver is responsible for setting the battery
// API ready event to indicate it is ready to receive IOCTLs in response
// to these APIs.
// 
// This example driver comes with a stubbed-out implementation of the
// low-level battery interfaces.  OEMs that wish to produce their own
// battery driver can write a module containing the low-level entry points
// in their platform and simply link with the library containing this module.
// The linker will bring in the rest of the driver as an MDD.
//
// The low-level interfaces necessary that must be overridden to produce
// a platform-specific PDD are:
//
//      BatteryPDDInitialize
//      BatteryPDDDeinitialize
//      BatteryPDDGetStatus
//      BatteryPDDGetLevels
//      BatteryPDDSupportsChangeNotification
//      BatteryPDDPowerHandler
//      BatteryPDDResume
//

#define BATTERY_DATA_DEF    // global battery driver variables defined here

#include <battimpl.h>
#include <nkintr.h>
#include <devload.h>
#include <pmpolicy.h>
#include <pm.h>
#include ".\inc\power.h"
#include ".\inc\charge.h"
#include "hw_lib.h"

extern void SaveQAcc(void);
extern void ShowPicture(void);

#define DEF_BATTERYPOLLTIMEOUT          30000//300000         // in milliseconds

// this structure contains startup parameters for the battery monitor thread
typedef struct _batteryContext_tag {
    DWORD       dwPollTimeout;
    int         iPriority;
    SYSTEM_POWER_STATUS_EX2 st;
} BATTERY_CONTEXT, * PBATTERY_CONTEXT;

// global variables
CRITICAL_SECTION gcsBattery;
PFN_BATTERY_PDD_IOCONTROL gpfnBatteryPddIOControl;
HANDLE ghevResume;
HANDLE ghtBattery;
BOOL gfExiting;
BATTERY_CONTEXT gBatteryContext;

// This thread handles resume notifications for the battery driver.  It will
// also poll the battery for status updates at regular intervals, depending
// on the poll interval configuration in the registry.
DWORD WINAPI 
BatteryThreadProc(PVOID pvParam)
{
    BOOL fDone = FALSE;
    BOOL fOk;
    PBATTERY_CONTEXT pbc = (PBATTERY_CONTEXT) pvParam;
    SETFNAME(_T("Battery: BatteryThreadProc"));
    
    DEBUGCHK(ghevResume != NULL);
    PREFAST_DEBUGCHK(pbc != NULL);
    
    // set my thread priority
    DEBUGMSG(ZONE_RESUME, (_T("%s: thread priority is %d, timeout is %u, ID is 0x%08x\r\n"), 
        pszFname, pbc->iPriority, pbc->dwPollTimeout, GetCurrentThreadId()));
    CeSetThreadPriority(GetCurrentThread(), pbc->iPriority);
    
    // tell the Power Manager to initialize its battery state
    fOk = PowerPolicyNotify(PPN_POWERCHANGE, 0);
    DEBUGCHK(fOk);

    // wait for the system to resume
    while(!fDone) {
        DWORD dwStatus = WaitForSingleObject(ghevResume, pbc->dwPollTimeout);
        switch(dwStatus) {
        case WAIT_TIMEOUT:
            {
                SYSTEM_POWER_STATUS_EX2 tmpst;
                
                // update battery status information
                LOCKBATTERY();
                dwStatus = BatteryAPIGetSystemPowerStatusEx2(&tmpst, sizeof(tmpst), TRUE);
                DEBUGCHK(dwStatus == sizeof(pbc->st));
                UNLOCKBATTERY();
                
                // has anything changed?
                if(memcmp(&tmpst, &pbc->st, sizeof(pbc->st)) != 0) {
                    // yes, update our global variable and notify the power manager
                    pbc->st = tmpst;
                    fOk = PowerPolicyNotify(PPN_POWERCHANGE, 0);
                    DEBUGCHK(fOk);
                }
            }
            break;
        case WAIT_OBJECT_0:	// system has resumed
            // GetTickCount() stops incrementing during suspends, so we can
            // stop and restart the battery stopwatch during resume.
            DEBUGMSG(ZONE_RESUME, (_T("%s: system has resumed\r\n"), pszFname));
            BatteryAPIStopwatch(FALSE, FALSE);
            BatteryAPIStopwatch(TRUE, FALSE);
            BatteryPDDResume();
            break;
        default:
            DEBUGMSG(ZONE_RESUME, (_T("%s: WaitForSingleObject() returned %d, error %d\r\n"), pszFname,
                dwStatus, GetLastError()));
            fDone = TRUE;
            break;
        }
        
        // check whether we're supposed to exit
        if(gfExiting) fDone = TRUE;
    }
    
    DEBUGMSG(ZONE_RESUME, (_T("%s: exiting\r\n"), pszFname));
    return 0;
}

// This routine initializes the battery driver.  Since it should only be
// loaded once, it returns an error if this routine is called more than
// once.
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);
        gpfnBatteryPddIOControl = NULL;     // must be initialized by the PDD
        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;
                    }
                    
                    RegCloseKey(hk);
                }
                
                // 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(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);
        }
    }
    
    DEBUGMSG(ZONE_INIT, (_T("%s: returning %d\r\n"), pszFname, dwHandle));
    
    return dwHandle;
}


BOOL
Deinit(
           DWORD dwContext
           )
{
    DEBUGMSG(ZONE_INIT, (_T("Battery: Deinit: invoked w/ context 0x%08x\r\n"),
        dwContext));
    
    DEBUGCHK(dwContext == 1);
    DEBUGCHK(ghevResume != NULL);
    
    // notify the PDD
    BatteryPDDDeinitialize();
    
    // clean up global variables
    if(ghtBattery != NULL) {
        gfExiting = TRUE;
        SetEvent(ghevResume);
        WaitForSingleObject(ghtBattery, INFINITE);
        CloseHandle(ghtBattery);
        ghtBattery = NULL;
    }
    if(ghevResume != NULL) {
        CloseHandle(ghevResume);
        ghevResume = NULL;
    }
    DeleteCriticalSection(&gcsBattery);
    
    DEBUGMSG(ZONE_INIT, (_T("Battery: Deinit: all done\r\n")));
    return TRUE;
}


BOOL
IOControl(
              DWORD  dwContext,
              DWORD  Ioctl,
              PUCHAR pInBuf,
              DWORD  InBufLen, 
              PUCHAR pOutBuf,
              DWORD  OutBufLen,
              PDWORD pdwBytesTransferred
              )
{
    DWORD  dwErr = ERROR_INVALID_PARAMETER;
    BOOL   bRc = FALSE;
    SETFNAME(_T("IOControl"));

    DEBUGMSG(ZONE_FUNCTION, (_T("%s: IOCTL:0x%x, InBuf:0x%x, InBufLen:%d, OutBuf:0x%x, OutBufLen:0x%x)\r\n"),
        pszFname, Ioctl, pInBuf, InBufLen, pOutBuf, OutBufLen));

    switch (Ioctl) {
    case IOCTL_POWER_SET :
		  if(pOutBuf != NULL && OutBufLen == sizeof(CEDEVICE_POWER_STATE) && pdwBytesTransferred != NULL)
		  {
			// allow a set to any state, but if requested to go to D3, go to D4 instead.
			// Since our device doesn't touch any hardware, we just set its CurrentDx
			// member to update the power setting.  A real device driver would probably 
			// need to touch hardware.
			__try {
				CEDEVICE_POWER_STATE NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf;
				if(VALID_DX(NewDx))
				{
					if(NewDx > D0)
					{
						//close backlight
//						PM_BackLight(OFF);
						RETAILMSG(1, (_T("IOCTL_POWER_SET:Close bklight\r\n")));
					}
					else
					{
						//open backlight
//						PM_BackLight(ON);
						RETAILMSG(1, (_T("IOCTL_POWER_SET:Open bklight\r\n")));
				  }
  			}
  		} 
			__except(EXCEPTION_EXECUTE_HANDLER) {
				DEBUGMSG(ZONE_IOCTL, (_T("%s: exception in ioctl\r\n")));
			}
		 }
    	break;
    case IOCTL_BATTERY_GETSYSTEMPOWERSTATUSEX2:
        // sanity check parameters
        if(pOutBuf != NULL && OutBufLen == sizeof(SYSTEM_POWER_STATUS_EX2)
            && pInBuf != NULL && InBufLen == sizeof(BOOL) && pdwBytesTransferred != NULL) {
            BOOL fOk = FALSE;
            BOOL fForce;

            // get the force parameter
            __try {
                fForce = *((BOOL *) pInBuf);
                fOk = TRUE;
            } 
            __except(EXCEPTION_EXECUTE_HANDLER) {
                DEBUGMSG(ZONE_WARN, 
                    (_T("%s: exception reading fForce in IOCTL_BATTERY_GETSYSTEMPOWERSTATUSEX\r\n"), pszFname));
            }

            // did we get the force parameter?
            if(fOk) {
                DWORD dwStatus = 0;
                DEBUGCHK(fForce == TRUE || fForce == FALSE);

                // get the data
                LOCKBATTERY();
                __try {
                    dwStatus = BatteryAPIGetSystemPowerStatusEx2((PSYSTEM_POWER_STATUS_EX2) pOutBuf, OutBufLen, fForce);
                }
                __except(EXCEPTION_EXECUTE_HANDLER) {
                    DEBUGMSG(ZONE_WARN, 
                        (_T("%s: exception reading status in IOCTL_BATTERY_GETSYSTEMPOWERSTATUSEX2\r\n"), pszFname));
                    dwErr = ERROR_GEN_FAILURE;
                }
                UNLOCKBATTERY();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -