Power Management
Windows CE is a typical battery-powered system. This makes the right operating system very critical. applications do not need to pay attention to the power loss of Windows CE devices most of the time, but in some cases, you may need to pay attention to these losses.
When a user disables a battery Windows CE device, the power supply system does not turn off the PC power. In fact, the system is suspended: this is like some pocketpc put the power off in the SIM card pulling out, the SIM card is actually off the power. However, currently, smartphone is included because hardware devices, such as CPUs, cannot access low power consumption. To save power, you need to disable the application processor and power supply for most devices, then wake up with a timer or wireless module. So it is not absolute if the power supply is not disabled .) When the user powers on the device, the device will not be restarted like a PC, but will be awakened and returned to the same status as before the system hangs. This causes an application to run as before being suspended after being awakened. In fact, the application does not know that it is suspended unless it explicitly requests to notify the system when it is suspended. From the application perspective, there are three ways to manage power: querying Power status, changing power status, and preventing power status changes.
Query Power status
To query the current power status, you must call
DWORD getsystempowerstatusex2 (psystem_power_status_ex2 psystempowerstatusex2, DWORD dwlen, bool fupdate );
The function has three parameters: a pointer to the system_power _ status_ex2 structure, the length of the structure, and a Boolean value, indicates whether the operating system should query the battery driver to obtain the final information or directly return the information in the battery cache. The system queries the battery status every five seconds. Therefore, if the third difference is false, the obtained data will not be too old. The system_power_status_ex2 structure is defined
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;
Word batteryvoltage;
DWORD batterycurrent;
DWORD batteryaveragecurrent;
DWORD batteryaverageinterval;
DWORD batterymahourconsumed;
DWORD batterytemperature;
DWORD backupbatteryvoltage;
Byte batterychemistry;
} System_power_status_ex2;
Before I describe this huge structure, I must warn you that the data returned by this structure is exactly the same as that returned by the battery drive. The same structure is sent to the battery drive to query its status. Windows CE does not verify the data returned by the battery drive. The data returned by this function depends on the battery drive, so different systems have different changes. For example, many systems do not report accurate power levels when using AC power, while others do. The application uses getsystempowerstatusex2 to automatically prevent and detect whether the system can run applications.
The first region, aclinestatus, contains a flag indicating whether the system is connected to the AC power supply. If the value is ac_line_offline, the system does not use the AC power; ac_line_online indicates that the system uses the AC power; ac_line_backup_power and ac_line_unknown indicates the standby power supply and unknown power supply. In the batteryflag area, a general identifier is provided to indicate the battery status of the current system, which can have the following values:
Battery_flag_high
The battery is full or close to full.
Battery_flag_low
The battery remains a little left.
Battery_flag_critical
The battery power is in a critical state.
Battery_flag_charging
The battery is currently charging.
Battery_flag_no_battery
The system has no battery.
Battery_flag_unknown
Unknown Battery status
The batterylifepercent area contains the estimated percentage of battery power that can be maintained. A value may be between 0 and 100, or 255 indicates that the percentage is unknown. The batterylifetime area indicates the number of seconds that can be maintained before the battery is exhausted. If this value cannot be estimated, enter battery_life_unknown in the region. The batteryfulllifetime area contains the time required to fully fill the battery. If this value cannot be estimated, enter battery_life_unknown. Note that these values may be difficult to measure in many systems. Most OEMs simply enter battery_life_unknown in each region.
The fourth region (not the reserved region) repeats the previous statement, except for the system backup battery. Because most of these values are difficult to measure, many systems simply return "unknown" to these regions.
The remaining areas describe the power status of the battery and backup battery because many systems lack the ability to measure these values, and these areas are simply defaulted to "unknown ". The last region, batterychemistry, contains a flag indicating the type of battery in the system. The currently defined values include
· Battery_chemistry_alkaline
· Battery_chemistry_nicd
· Battery_chemistry_nimh
· Battery_chemistry_lion
· Battery_chemistry_lipoly
· Battery_chemistry_unknown
Change Power status
Applications can change the power status of the system in a series of ways. In newer Systems Based on Windows CE. net, the preferred approach is to use the power management program, which will be discussed later. However, a large number of systems based on earlier Windows CE versions and Windows CE. Net do not contain the power management program version. The following technologies are very convenient for these systems.
Power off
Applications can suspend the system by calling a rare gwespoweroffsystem function. This function can be used in most versions of Windows CE, but has recently been made public. In fact, most sdks do not include the prototype of this function. You may need to provide the prototype. This function is defined
Void gwespoweroffsystem (void );
Gwespoweroffsystem is easy to use: the system suspends after a simple call.
If you want to avoid using functions with very little information, you can simply simulate the user to close the system by pressing the close button. You can easily allow your application to suspend the system by using the keybd_event function, as shown below:
Keybd_event (vk_off, 0, keyeventf_silent, 0 );
Keybd_event (vk_off, 0, keyeventf_silent │ keyeventf_keyup, 0 );
The two keybd_event calls simulate the press and release power button. The virtual key value of the power button is vk_off. Executing the preceding two lines of code suspends the system. Because the virtual key code is executed by GWES, the two functions may be in a certain state before the system is suspended, the image is the same as that of the actually pressed button ). If your program cannot stop working before the keybd_event function, add a sleep call to suspend the application for several milliseconds so that GWES can actually suspend the system.
Close Screen
If the system displays colored backlights, the main power consumption is not CPU but backlight. In some environments, an application needs to run without being displayed on the screen. One example is the music player application. When users listen to music, they do not pay attention to the screen. In these cases, the ability to turn off the backlight will increase battery life.
Of course, when users want to view the screen, any shutdown backlight application requires a simple user-friendly way to re-open the screen. Likewise, you may think that the screen is turned off when the screen turns black, so consider this. For example, a user may attempt to power on the system when the system is running, but unexpectedly finds that the power of the device is disabled. Similarly, when the system closes the display in this case, it also closes the touch screen. This means that you cannot tell the user to tap the screen to open it. Instead, you need to use other events, such as setting the time, completing the task, or clicking a button. Finally, the method discussed here is useful for most versions based on Windows CE 3.0 or later and is replaced by the Power Management Program in Windows CE. Net 4.0. For newer systems, first check whether the power management program is available and then use it to control the screen. If it fails, the extescape method may work.
In Windows CE, the display control is through the extescape function. This is a backdoor for displaying and printer drivers. The Windows CE display driver supports many device escape codes (Escape codes), which are published in platform builder. For our purpose, only two escape codes are used: setpowermanagement to set the displayed Power status and queryescsupport to check whether setpowermanagement is supported by the driver. The following example shows how to enable or disable the system display through the display driver and supports full escape code:
//
// Defines and structures taken from pwingdi. h In the Platform Builder
//
# Define queryescsupport 8
# Define setpowermanagement 6147
# Define getpowermanagement 6148
Typedef Enum _ video_power_state {
Videopoweron = 1,
Videopowerstandby,
Videopowersuspend,
Videopoweroff
} Video_power_state, * pvideo_power_state;
Typedef struct _ video_power_management {
Ulong length;
Ulong dpmsversion;
Ulong powerstate;
} Video_power_management, * pvideo_power_management;
//----------------------------------------------------------------------
// Setvideopower-turns on or off the display
//
Int setvideopower (bool Fon ){
Video_power_management VPM;
Int RC, fqueryesc;
HDC;
// Get the display DC.
HDC = getdc (null );
// See if supported.
Fqueryesc = setpowermanagement;
Rc = extescape (HDC, queryescsupport, sizeof (fqueryesc ),
(Lpstr) & fqueryesc, 0, 0 );
If (rc = 0 ){
// No support, fail.
Releasedc (null, HDC );
Return-1;
}
// Fill in the power management structure.
VPM. Length = sizeof (VPM );
VPM. dpmsversion = 1;
If (Fon)
VPM. powerstate = videopoweron;
Else
VPM. powerstate = videopoweroff;
// Tell the driver to turn on or off the display.
Rc = extescape (HDC, setpowermanagement, sizeof (VPM ),
(Lpstr) & Vpm, 0, 0 );
// Always release what you get.
Releasedc (null, HDC );
Return 0;
}
The preceding Code calls the extescape and queryescsupport commands to check whether code transfer is supported. The queried command is first sent to the input buffer. If the setpowermanagement command is supported, the program fills in the video_power_management structure and calls extescape again to set the power status.
Although these escape codes allow applications to turn on or off the display, Windows CE does not have a uniform way to control the brightness of the backlight. Each system has its own OEM-specific method to control the brightness of the backlight. If there is a standard backlight brightness control method in the future, it is likely to be placed in the extescape function.
Turn on system power
When the system is suspended, the application will no longer run, so when the system wakes up, the application does not seem to be under control. However, there are some ways to wake up a suspended device. First, an application uses the notification API mentioned in Chapter 11 to Schedule System wake-up by giving a time. In general, OEMs allocate some conditions for interruption so that the management system can be powered on or awakened. An example of this method is that a system is awakened when synchronization cradle is prevented.
Prevent system power-off
On the contrary, Preventing System suspension is also a problem. Windows CE is usually set to automatically suspend when user input is not input for a period of time. To prevent automatic suspension, an application can periodically call the following functions:
Void winapi systemidletimerreset (void );
This function resets Windows CE to monitor user input timers. If the timer reaches a pre-defined interval without user input, the system automatically suspends. Because the pending timeout value can be changed, an application needs to know the timeout value, so it needs to call systemidletimerreset a little more. The system maintains three timeout values, which can be queried using systemparametersinfo. Different manifestations of constants passed to systemparametersinfo are shown as follows:
Spi_getbatteryidletimeout
The last input time when the system is running on battery power
Spi_getexternalidletimeout
The last input time when the system is running on the AC power supply.
Spi_getwakeupidletimeout
The time when the system is automatically woken up when the system is suspended again
To prevent the power supply from being automatically suspended, you need to query these three values and call systemidletimerreset in the shortest time. If the timeout value is set to 0, the timeout value is disabled.
Power Management Program
A new, independent power management component is introduced in Windows CE. Net 4.0. This power management program replaces many functions previously completed by GWES. The power management program defines a series of Power states, such as D0, D1, D2, and D3. These seemingly mysterious names are mapped to some friendly system-level names.
For embedded systems, OEMs define the power status of the system. For example, the power status may be on, idle, or suspend ). Other power statuses are also defined, such as screenoff, incradle, and onbattery.
From the application's point of view, the new power management program provides the ability to notify the power status change and the ability to change the power status through a series of functions.
The system's power status is defined in the registry. The SDK defines pwrmgr_reg_key, so that you have to know the registry string, but when the constant is not defined, the Power Manager registration data is retained in hkey_local_machinesystemcurrentcontrolsetcontrolpower. The power status is defined as a sub-key in key state.
Power supply notification
A very popular feature of the Power Management Program is the ability to notify the application when the system power status changes. This frees applications from manual power detection. An application can send a notification to the application when the power status changes by calling requestpowerconfigurications to request the Power Manager. The power management program sends notifications through a message queue established before the application.
The following is a prototype of requestpowerconfigurications.
Handle requestpowerconfigurications (handle hmsgq, DWORD flags );
The first parameter is the handle of a previously created message queue by an application. The second parameter is a series of parameters, indicating the notification that the application wants to receive.
Pbt_transition
Receive notifications of system power status changes. For example, when the system is from on to suspend.
Pbt_resume
Receive notifications when the system resume.
Pbt_powerstatuschange
The system receives notifications when switching between the AC and the battery.
Pbt_powerinfochange
Receive notifications when the system battery level changes.
Power_policy_all
Receive all notifications.
The requestpowernotifications function returns a power notification handle, and a failure returns NULL. When a message queue is created, the application must have the read permission because the application will read the power notification from the message queue.
To receive notifications, the application must use waitforsingleobject to block the message handle. As discussed in Chapter 10th, when a notification is placed in a queue, the handle is signaled. The actual notifications will be received in the power_broadcast table.
Typedef struct _ power_broadcast {
DWORD message;
DWORD flags;
DWORD length;
Wchar systempowerstate [1];
} Power_broadcast, * ppower_broadcast;
The first thing to note is that the structure length is variable. The last field, systempowerstate, is defined as wchars type, but can be filled with non-string data. The first field is the ID of the notification, which can be filled in with one of the previous PBT _ flag lists. The flags area can contain the following flag, depending on the notification to be received:
Power_state_on
The system is in the on status.
Power_state_off
The system is off.
Power_state_critical
The system enters a critical off state.
Power_state_boot
The system is starting.
Power_state_idle
The system enters the idle status.
Power_state_suspend
The system is suspended.
Power_state_reset
The system is reset.
The last two fields are correlated. The length field is the Data Length of the systempowerstate field. The data contained in systempowerstate depends on the notification to be sent. For pbt_transition notifications, the systempowerstate field contains an identifier string for the new power status. This string ends with a non-zero value. To end a string, use the length field to specify the length of the string. Note that the length field is in bytes. When the character is a double-byte uncode character, you must use the length field to remove the size of tchar.
For pbt_powerinfochange notifications, the systempowerstate field contains a ppower_broadcast_power_info structure:
Typedef struct _ power_broadcast_power_info {
DWORD dwnumlevels;
DWORD dwbatterylifetime;
DWORD dwbatteryfulllifetime;
DWORD dwbackupbatterylifetime;
DWORD dwbackupbatteryfulllifetime;
Byte baclinestatus;
Byte bbatteryflag;
Byte bbatterylifepercent;
Byte bbackupbatteryflag;
Byte bbackupbatterylifepercent;
} Power_broadcast_power_info, * ppower_broadcast_power_info;
Note that the names of some fields and functions are very similar to the system_power_status_ex2 structure discussed earlier.
Set Power status
The function provided by the Power Management Program also allows the application to control the power status. There are two ways to control the power supply. The first way is to give the application a power setting. The second method is that the application requests the power status not lower than the given level.
An application can request a specific power status by calling the setsystempowerstate function. The function is prototype as follows.
DWORD setsystempowerstate (lpcwstr psstate, DWORD stateflags, DWORD options );
The power status can be requested to specify the first two parameters. If the first parameter is a non-zero value, it points to a string to identify the requested status. This string must match one of the power States listed in the registry.
If psstate is null, the second parameter stateflags defines the request Power status. This parameter is one of the statuses from power_state_on to power_state_reset, which are described in the previously mentioned power_broadcast structure.
Specifically, the power_state_reset flag. This indicates that the request system is restarted. Using the setsystempowerstate method is better than calling kerneliocontrol by using the ioctl_hal_reboot command directly. Call setsystempowerstate to save any data in the buffer to the file system before the device is restarted.
Calling setsystempowerstate is a method that directly changes the power status. The more clever way is to call setpowerrequirement to request the system to maintain the minimum power status required by the application. Setsystempowerstate assumes that the application knows the desired state, and the call to setpowerrequirement allows the system to optimize the power supply settings to meet the needs of the application. One example that makes it easier to use setpowerrequirement is that an application using the serial port needs to maintain the power status during the serial port communication. Setpowerrequirement is defined as follows.
Handle setpowerrequirement (pvoid pvdevice,
Cedevice_power_state devicestate,
Ulong deviceflags, pvoid pvsystemstate,
Ulong stateflags );
The first parameter specifies the device in which the application needs to maintain the power status. The devicestate parameter defines the power status of the device. Cedevice_power_state specifies the status range from D0 (meaning the device is in the maximum power consumption state) to D4 (indicating that the device is disabled, it is completely customizable by OEM vendors. For application developers, for example, whether the LCD backlight is switched on d1 or on D2 is not certain. Microsoft only provides the standard definition, instead of the actual definition ). The deviceflags parameter is composed of two flags: power_name, indicating that the device name is valid; power_force, indicating that the device should be in the current State or even when the system is suspended. If pvsystemstate is not null, it indicates that it is valid only for power requests named in pvsystemstate. The device may not be able to change the Request status.
The application should cancel the request by calling releasepowerrequirement. The prototype is as follows.
DWORD releasepowerrequirement (handle hpowerreq );
The unique parameter here is the handle returned from setpowerrequirement.
In the next chapter, I will continue to discuss about the drivers and services of Windows CE streaming devices. Although most application developers may not need to write some device drivers or services, it is inspiring to know how they work with the program. Let's take a look.