2007年3月31日星期六

PowerButton高频率点击

变态的测试人员,居然会把高频率点击powerbutton也变为他们的测试项目。可是更有“高水平”开发人员为了迎合这种测试,“自以为是”对wince的电源状态转换进行改动。比如为了切换速度快,按power button让系统先进入unattended mode,再按power button系统又切到on。的确是切换速度快了很多,但是他们欺骗了用户,让用户以为unattended就是suspend。哈哈,可是问题接踵而来,suspend该有的系统行为,unattend模式怎么可能有,结果更多的bug由然而生。

还有人会说PowerPolicyNotify(PPN_POWERBUTTONPRESSED, 0)不怎么好用,认为SetSystemPowerState好用,可以直接使系统变到自己想要的状态。不要以为看了public下面的code就以为自己了解了PM,光说这“看”与“看”还有区别呢,你到底消化了多少??!

我们是谁?开发人员,我们可以改变用户的习惯,不要惯了他们的“毛病”。我们可以定义如:
1. power button 最高速度一秒按一下
2. 连续按住power button达一秒,才产生一次power button消息

请你们平时多提升一下个人的专业水平,理解软件架构的意义。

2007年3月16日星期五

Windows Mobile Activity timer

Activity Timers也不是什么新鲜东西。这个东东真的很难懂,连续看了MSDN的解释不下20遍,也还是没弄懂怎么回事,说得太抽象了。希望这里我能帮大家有个形象的理解。

我们都知道在PocketPC上,我们点击touch panel,如果机器没有睡觉,那么屏幕就会亮起来。这其实是系统backlight offon的一次电源状态转换,这个动作是由pm.dll来完成的。

那么pm.dll是如何“感知”到这种“user activity”的呢?其实就是这个activity timer

touch panel为例,当有点击事件时,会SetEvent()来通知Pm.dll,这个event的名字由注册表HKEY_LOCAL_MACHINE\System\GWE\ActivityEvent的键值指明,其值一般为PowerManager/ActivityTimer/UserActivity ,这个event是被pm.dll随时“监视”的。也就是说如果你setEventpm.dll就会认为是“user activity”,然后再做相应得电源状态转换。

2007年3月12日星期一

[新手上路]在你的WinCE应用程序中映射硬件物理地址

在你的WinCE应用程序中映射硬件物理地址,下面是个例子

void * MapPhys(UINT32 addr,int size)
{
BYTE * Buffer=NULL;

//分配size大小虚拟地址空间
Buffer = (BYTE *)VirtualAlloc(0, size, MEM_RESERVE, PAGE_NOACCESS);
if(!Buffer)
{
MessageBox(NULL, _T("mem map error"), _T("Error"), MB_OK|MB_TOPMOST);
goto cleanup;
}
//映射物理地址(传给内核的地址总是要右移8位)
if (!VirtualCopy(Buffer, (void *)(addr>>8),size,PAGE_READWRITE | PAGE_PHYSICAL | PAGE_NOCACHE))
{
MessageBox(NULL, _T("mem copy error"), _T("Error"), MB_OK|MB_TOPMOST);
goto cleanup;
}
cleanup:
return (void*)Buffer;
}


这个函数返回的地址你就可以用了。Good luck!

2007年3月9日星期五

Wince shell 电池指示器反应慢?

Windows Mobile桌面上的电池图标有时会更新的太慢,我们知道可以用
hevent = CreateEvent(NULL, FALSE, FALSE, TEXT("SSUpdatePower"));
SetEvent(hevent);
CloseHandle(hevent);
来强制shell去更新电池状态。可是你会发现即时这样做,有时还是达不到目的。
为什么?
shell必然是调用GetSystemPowerStatusEx或GetSystemPowerStatusEx2来询问电池状态,这两个函数都用一个共同的参数BOOL fUpdate,据我了解到,shell正是传了FALSE进这个函数,结果导致,读到的是battery驱动中cache的信息,因此会表现出反应慢。
那么我们可以在battery驱动中强制调用GetSystemPowerStatusEx(TRUE),来达到目的

unattended mode不是驱动玩的东西

我们在写wince驱动的时候,千万不要自己去调用PowerPolicyNotify( PPN_UNATTENDEDMODE),永远要记住,整个操作系统中除了驱动程序,更重要的还有应用程序,他们才是上帝,是需求的提交者。
总感觉自己的废话很多,但是无论我重复多少遍,还有很多程序员犯这样的错误。

2007年3月2日星期五

wince电源管理框图


流接口驱动程序总是通过IOCTL接收系统对自己的设置。IOCTL_POWER_SET就是系统把设备的状态设置成D0D1D2D3D4其中之一。可以想象,设备驱动自己如果想主动的改变自己的状态,那么很容易可以在自己的代码中调用自己的IOCTL。可是,如果这样做,设备的状态是不被系统知道的,我们必须通知系统。DevicePowerNotify()就是用于通知系统,再由系统决定当前是否需要改变设备的电源状态。注意,千万不要假设,当你call DevicePowerNotify(),你一定会收到IOCTL_POWER_SET。因为系统会根据应用程序的需求决定当前是否改变设备状态。