Workaround-to-reload-the-Power-Manager-activity-timeout-upon-every-booting-in-Hive-based-Registry

Power management is an important aspect of the modern embedded devices. Flexibility in the OS Power Manager is the key driver to meet the requirements of myriad of devices. Windows CE offers this flexibility, though developer has to do a quick tweak to use it effectively. This blog describes the power manager in Windows CE, problem faced and how to overcome it.

Windows CE power manager is a flexible and customizable driver. Power manager is a state machine and performing state transition between various power states beginning from “On” to “Suspend”. The state transition is controlled by the activity timers and timeout of activity timers initiate the state transition from on, user idle, system idle and suspend. These timeout values are maintained in the following registry settings and it will be used by the PM driver.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\Timeouts]
“ACUserIdle”=dword:3c ; in seconds
“ACSystemIdle”=dword:12c ; in seconds
“ACSuspend”=dword:0 ; in seconds
“BattUserIdle”=dword:3c ; in seconds
“BattSystemIdle”=dword:b4 ; in seconds
“BattSuspend”=dword:12c ; in seconds

Modifying the corresponding registry values varies the timeout for each state accordingly. Users can change these settings to change the various timeout values. Application can change the registry values using the registry API provided by Windows CE.

But merely changing the registry values will not reload the timeout values of the Power Manager. Following procedure can be used to update the timeouts in the PM.

1) Change the necessary timeouts in the above listed registry.
2) Open the “PowerManager/ReloadActivityTimeouts” event and set the event as shown in the bellow code snip.

HANDLE hevReloadActivityTimeouts = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T(“PowerManager/ReloadActivityTimeouts”));
if (hevReloadActivityTimeouts)
{
SetEvent(hevReloadActivityTimeouts);
CloseHandle(hevReloadActivityTimeouts);
return TRUE;
}
else
{
return FALSE;
}
This will update the Power Manager to use the new timeouts to enter the respective power states. If the platform has hive based registry, then there comes the glitch.

Hive Based Registry
Majority of the customers require persistent registry support to maintain their custom registry or configuration settings upon every boot. Windows CE supports hive based registry for registry persistency.
Hive based registry consists of two – boot registry and system registry. Boot registry is the read only registry and values can’t be changed after image is built. Boot registry contains the registry settings, which are necessary to load the file system. System registry contains the remaining registry settings, that are all used to load the remaining drivers and applications etc.

Issue
Power manager driver is a “primary driver” and it is loaded before the file system driver. The kernel directly calls the PM_Init () to initialize the power manager. Or in other words, it is not initialized by the device manager, as any other secondary drivers for peripherals. There is no “Builtin” registry entry for the power manager driver. So these registry settings are stored in boot registry section as given below:
; HIVE BOOT SECTION
<>
; END HIVE BOOT SECTION
Registries between these two tags will be added in the boot registry. All the power manager registries are wrapped between these tags. When any of these registries modified, the specific registry is copied from boot registry to system registry, so that these changes are affected.

We can change the above mentioned power management timeout registry through the registry API and it will be stored in the system registry not in the boot registry. These values will be updated to the power manager by only after signaling the “PowerManager/ReloadActivityTimeouts” event. Once this event is signaled to the power manager, the power manager reloads its local timeouts with the updated values from the system registry.
These changes will be maintained in the system registry. But upon next reboot or successive reboots, the PM driver will be loaded/initialized with the timeout values programmed in the read-only boot registry. This is because, PM driver cannot access the system registry when it is loaded, as file system driver for accessing the system registry is not yet loaded.

This means that, the change in timeout settings is lost after the reboot. And the user has lost his/her preferred timeout settings that had been programmed earlier. But, the programmed values are not lost; rather they are not loaded in to the Power Manager. If you open the power applet in the control panel, you can see the values which have been programmed earlier. But if you check the timeouts using the clock you can find that the timeouts do not occur as per the programmed values, but the timeouts occur as per the build-time values stored in boot hive.

In order to reload these programmed values in the local copy of the Power Manager, you need to tap the OK button. Once OK button, is clicked, the programmed settings from the system registry is reloaded in to the Power Manager. A normal user will not prefer to do this every reboot to have his programmed timeouts loaded in the Power Manager. This should be automated.

Workaround
We can perform this in three ways.
1) Add the code that programs and signals the event to Power Manager in any of your driver initialization code, provided you have a BSP source code.
2) Develop a separate application say, “ReloadPMTimeout.exe” that programs and signals the event to Power Manager. This can be added in platform.reg, as given below, to get it launched automatically on every boot. Don’t forget to add an entry in platform.bib to embed the ReloadPMTimeout.exe, with your NK.bin.

[HKEY_LOCAL_MACHINE\init]
“Launch99″=”\\Windows\\ReloadPMTimeout.exe”
“Depend99″=hex:40,00
3) You can integrate the above snippet at the start of your application code.