Power Management

< BACK  NEXT >
[oR]

Windows CE carefully monitors and controls the power consumption of the device to ensure maximum battery life. Windows CE makes the following assumptions about typical use when adopting a power management strategy:

  • Typical use is less than two hours a day in bursts from five minutes to one hour at a time.

  • The display is on 100 percent of the time during use.

  • The CPU is on less than 10 percent of the time during typical use.

Battery life can be severely impacted by PCMCIA and Compact Flash modems and network cards. Serial communications can also drain the battery, especially if the device being communicated with does not supply power for the serial lines.

Power Management States

Windows CE automatically selects the appropriate power management state for a device, depending on how the device is being used. Applications do not have much control over the change from one state to another. A Windows CE device can be in one of four different states:

  • Dead. The Windows CE device has no batteries (either primary or backup) and no data is maintained. Windows CE devices are typically delivered in the dead state and, it is hoped, do not return to that state.

  • On. Windows CE and its applications are operating in the normal, full-speed state.

  • Idle. Windows CE decreases power consumption by reducing the processor speed. The change from On to Idle is transparent to the user and to applications.

  • Suspend. This is the minimum power mode in Windows CE. The display is turned off, and everything except memory maintenance is suspended.

Your applications must allow Windows CE to change from On to Idle and from Idle to Suspend as appropriate to minimize battery use. This is described in the next two sections.

Changing from On to Idle State

Windows CE switches to Idle state when all applications are idle. An application is considered Idle when it has returned control to Windows CE (that is, when it has finished processing a message) or when a thread is suspended, blocked, or sleeping. The switch from On to Idle occurs very quickly, in about 10 microseconds.

Try to avoid using loops that do not relinquish control in your applications. These loops stop Windows CE from entering Idle state and, hence, do not allow good power management. The following code sample uses the GetTickCount function (which returns the number of milliseconds that have elapsed since Windows CE started) to pause the application for five seconds. In doing so, your application uses valuable processing time and stops Windows CE from entering the Idle state.

 DWORD dwTime = GetTickCount(); while(GetTickCount() - dwTime < 5000) {    // do nothing } 

Instead of using the GetTickCount function, use the Sleep function (described in Chapter 5). To pause the application for five seconds, use the following code:

 //Pause for 5 seconds Sleep(5000); 

An application does not know when Windows CE changes from the On state to the Idle state, or vice versa. However, if the application is executing code, Windows CE must be in the On state.

Changing from Idle to Suspend State

Windows CE enters the Suspend state when one of these situations occurs:

  • When the user turns off the device

  • When the user suspends the device from the shell

  • When the computer detects a critically low power condition

  • When the activity timer times out

The activity timer monitors the time since the last key press or stylus tap event. When Windows CE detects a key press or tap event, the timer is reset to the value specified by the use in the Control Panel's Power section this value is typically two or three minutes.

The activity timer counts down the time since the last key press or tap event occurred, and when the timer reaches 0, Windows CE enters the Suspend state. Applications are not notified when Windows CE enters this state, but device drivers are.

Applications are frozen and do not execute when Windows CE is in the Suspend state. They resume execution when the state switches from Suspend to On.

Most applications are not affected by entering the Suspend state. The exceptions are those applications that use the Sleep function to pause the current thread for a specified number of milliseconds. Note that the sleep counter does not increment when Windows CE is in Suspend mode, so the thread does not continue executing when Windows CE returns to the On mode.

Sometimes you will need to ensure that the device does not enter the Suspend state until some operation (such as serial communications) has completed. You can do this by simulating a keystroke that is ignored by applications using the keybd_event function:

 keybd_event(VK_F24, 0,    KEYEVENTF_KEYUP | KEYEVENTF_SILENT, 0); 

This function call should be made frequently (say, every 30 seconds) during your critical task. The KEYEVENTF_SILENT flag ensures that the device does not click whenever this function is executed.

Monitoring Battery Status

The function GetSystemPowerStatusEx2 can be used to return battery and power information in a SYSTEM_POWER_STATUS_EX2 structure. As you can see from Listing 13.3, the SYSTEM_POWER_STATUS_EX2 structure contains copious amounts of battery information. However, many devices do not return all the information, and many of the fields are empty or have default values.

Listing 13.3 Battery and power status information
 void Listing13_3() {    SYSTEM_POWER_STATUS_EX2 sps;    if(GetSystemPowerStatusEx2(&sps, sizeof(sps),TRUE)            == 0)       cout   _T("Could not get power status")   endl;    else    {       cout   _T("AC Line: ");       switch(sps.ACLineStatus)       {          case AC_LINE_OFFLINE:            cout   _T("Offline")   endl;            break;          case AC_LINE_ONLINE:            cout   _T("Online")   endl;            break;          case AC_LINE_BACKUP_POWER:            cout   _T("Backup power")   endl;            break;          case AC_LINE_UNKNOWN:            cout   _T("Unknown")   endl;            break;       }       cout   _T("Battery: ");       switch(sps.BatteryFlag)       {          case BATTERY_FLAG_HIGH:            cout   _T("High")   endl;            break;          case BATTERY_FLAG_LOW:            cout   _T("Low")   endl;            break;          case BATTERY_FLAG_CRITICAL:            cout   _T("Critical")   endl;            break;          case BATTERY_FLAG_CHARGING:            cout   _T("Charging")   endl;            break;          case BATTERY_FLAG_NO_BATTERY:            cout   _T("No battery")   endl;            break;          case BATTERY_FLAG_UNKNOWN:            cout   _T("Unknown")   endl;            break;       }       cout   _T("BatteryLifePercent: ")              sps.BatteryLifePercent   endl;       cout   _T("BatteryLifeTime: ")              sps.BatteryLifeTime   endl;       cout   _T("BatteryFullLifeTime : ")              sps.BatteryFullLifeTime   endl;       cout   _T("BackupBatteryFlag: ");       switch(sps.BackupBatteryFlag)       {          case BATTERY_FLAG_HIGH:            cout   _T("High")   endl;            break;          case BATTERY_FLAG_LOW:            cout   _T("Low")   endl;            break;          case BATTERY_FLAG_CRITICAL:            cout   _T("Critical")   endl;            break;          case BATTERY_FLAG_CHARGING:            cout   _T("Charging")   endl;            break;          case BATTERY_FLAG_NO_BATTERY:            cout   _T("No battery")   endl;            break;          case BATTERY_FLAG_UNKNOWN:            cout   _T("Unknown")   endl;            break;       }       cout   _T("BackupBatteryLifePercent : ")              sps.BackupBatteryLifePercent   endl;       cout   _T("BackupBatteryLifeTime : ")              sps.BackupBatteryLifeTime   endl;       cout   _T("BackupBatteryFullLifeTime : ")              sps.BackupBatteryFullLifeTime   endl;       cout   _T("BatteryVoltage : ")              sps.BatteryVoltage   endl;       cout   _T("BatteryCurrent : ")              sps.BatteryCurrent   endl;       cout   _T("BatteryAverageCurrent : ")              sps.BatteryAverageCurrent   endl;       cout   _T("BatteryAverageInterval : ")              sps.BatteryAverageInterval   endl;       cout   _T("BatterymAHourConsumed : ")              sps.BatterymAHourConsumed   endl;       cout   _T("BatteryTemperature : ")              sps.BatteryTemperature   endl;       cout   _T("BackupBatteryVoltage : ")              sps.BackupBatteryVoltage   endl;       cout   _T("BatteryChemistry: ");       switch(sps.BatteryChemistry)       {          case BATTERY_CHEMISTRY_ALKALINE:            cout   _T("Alkaline")   endl;            break;          case BATTERY_CHEMISTRY_NICD:            cout   _T("NICD")   endl;            break;          case BATTERY_CHEMISTRY_NIMH:            cout   _T("NIMH")   endl;            break;          case BATTERY_CHEMISTRY_LION:            cout   _T("LION")   endl;            break;          case BATTERY_CHEMISTRY_LIPOLY:            cout   _T("LIPOLY")   endl;            break;          case BATTERY_CHEMISTRY_UNKNOWN:            cout   _T("Unknown")   endl;            break;       }    } } 

The most important values returned in the SYSTEM_POWER_STATUS_EX2 structure are the following:

  • ACLineStatus The value AC_LINE_OFFLINE indicates that the device is operating using battery power, and the value AC_LINE_ONLINE is returned when the device is connected to AC power.

  • BatteryLifePercent A percentage value indicating how much charge is left in the main battery (100 percent indicates the battery is fully charged).

  • BackupBatteryLifePercent A percentage value indicating how much charge is left in the backup or secondary battery (100 percent indicates the battery is fully charged).

  • BatteryChemistry The type of battery technology used by the device (if you are interested in that type of thing).

The third parameter passed to GetSystemPowerStatusEx2 should be TRUE if the function should interrogate the battery status for the latest values, or FALSE if cached information should be used. Cached information can be a few seconds out of date.

Powering Off a Device

If an application has been performing an unattended task, such as downloading data, it may want to power down the device immediately without waiting for the activity timer to power down the device. In this case, the keybd_event function can be used to simulate the "Off" key being pressed. The "Off" key has the virtual key code "VK_OFF", and Listing 13.4 shows how keybd_event can be called twice to simulate the key being pressed down and then released.

Listing 13.4 Powering off a device
 void Listing13_4() {    keybd_event(VK_OFF, 0, KEYEVENTF_SILENT, 0);    keybd_event(VK_OFF, 0,         KEYEVENTF_KEYUP | KEYEVENTF_SILENT, 0); } 

< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net