Wednesday, August 6, 2008

WinCE / PocketPC / Windows Mobile Power Battery Timeout - Solution

Hello Folks,

I am back with yet another WinCE / Windows Mobile Solution this time it is something exciting and it is on Power Batter Suspend timeout related stuff. It is really challenging task to optimize battery life of any embedded device. Sometimes we want to control back light and battery suspend related activities through our program.

OK .. here is simple question how do you control Back light, suspend timeout .. etc event through program ? To answer this question one has to understand "How WinCE operates w.r.t Power driver and what exactly happens behind the scenes".

To simplify things ... i am going to divide whole things in three parts

1. WinCE OS Part whihc include Power / Battery drivers.
2. Application
3. Registry

Registry: It is the place where all values gets stored i.e it acts as media for storing and retrieving values. I hope it is clear that Registry is nothing but global storage media and it has NO power to trigger anything. So that means it is of new use if we simply change values at registry and we need to do something extra to inform Drivers to read new values from registry.

Application: It could be system application like Control Panel Backlight / Power OR your own application. Essentially it is the place where you want to trigger power related event to let Driver / OS know that there are new values available in the registry.

WinCE OS / Power Driver: Main piece of component responsible for reading values from registry and act accordingly. The way many Microsoft drivers work is that they read settings from the registry when they start. So changing the values in the registry will NOT make those changes take effect until the driver reloads them. Warm booting will do that, but that is an understandably undesirable requirement.

So how to get past this situation where one want to change these backlight / Battery power values take effect when application running? To answer this, we need to understand how Windows Mobile / WinCE control panel application works i.e In settings -> control panel
we have application like backlight and power. If you observer them closely if you change values at respective application changes are immediate and we don't require to do warm reboot or soft reset. So, we need to use similar API which are used by these control panel applications.

OK OK ... enough of theory .. let me jump into code snippets and APIs.

When the Microsoft control panel applet is run, it reads the values from the registry and writes the changes back to the registry. It then signals the driver to re-load those values from the registry through the use of a pre-defined (but poorly documented) named event.

The event name for the inactivity timeouts is "PowerManager/ReloadActivityTimeouts". If this named event is created using CreatEvent() and then signalled using SetEvent(), the SysPwr driver will reload the activity timeouts from the registry. This is what the Microsoft control panel applet does when the timeout values are changed.

Here is code snippet ... please remember that following code snippet only for Battery power timeouts and its corresponding event name is ,
"PowerManager/ReloadActivityTimeouts". If you want to change backlight settings you need to use event called "BackLightChangeEvent".

void PowerSet()
{
WCHAR wszPowerValue[5] = L"\0";
INT nPowerValue;
DWORD dwValueChecked ;
HKEY hKey;
BYTE* byteData;
HRESULT hRes;
HANDLE hEvent;
BOOL bResult;
DWORD dwDisp;
WCHAR wszImageVersion[MAX_PATH] = L"\0";

dwValueChecked = 120 ; // Hard coded value to 120 sec .. battery timeout

hRes = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Power\\Timeouts", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisp);

if ( hRes == ERROR_SUCCESS ) {
RegSetValueExW(hKey,L"BattSuspendTimeout",0,REG_DWORD,(LPBYTE)&dwValueChecked,sizeof(DWORD));

}
RegCloseKey(hKey);

WCHAR wszEvent[] = L"PowerManager/ReloadActivityTimeouts";

// WCHAR wszEvent[] = _T("BackLightChangeEvent"); // In case of backlight
// For backlight reg key is @ HKEY_CURRENT_USER\ControlPanel\Backlight

hEvent = CreateEventW( NULL, FALSE, TRUE, wszEvent );

if (hEvent != NULL ) {
if (SetEvent( hEvent )) {
wsprintf(wszImageVersion,L"SUCCESS: Value set to %d secs",dwValueChecked);
MessageBox( wszImageVersion , L"Event Set");
}
}
CloseHandle( hEvent );

PostMessageW( WM_SETTINGCHANGE, 0, 0);

}


Please let me know if you need any help w.r.t this article. Have good one !!!!!!!!!!!