Windows CE 电源管理介绍
时间:04-11
来源:
点击:
打开系统电源
当系统被挂起,应用程序将不再运行,因此当系统唤醒时,应用程序看起来没有被控制。然而,有一些方式来唤醒一个挂起的设备。首先,一个应用程序通过给定一个时间,并使用11章提到的消息API(Notification API)做系统被唤醒的计划。在一般情况下,OEM厂商会分配一些中断条件,以便管理系统电源打开,或唤醒。这种方式的一个例子是一个系统当防止了一个同步架(synchronization cradle)时被唤醒。
防止系统关闭电源
相反的情况,防止系统挂起也是一个问题。Windows CE系统通常被设置为当一段时间没有用户输入就自动挂起。要防止自动挂起,一个应用程序可以周期性地调用一下函数:
void WINAPI SystemIdleTimerReset (void);
这个函数重设Windows CE用来监视用户输入的定时器。如果定时器到达预先的没有用户输入的间隔,系统会自动挂起。因为挂起超时值可以被改变,一个应用程序需要知道超时值,这样就要多一点调用SystemIdleTimerReset。系统维护三个超时值,这些都能够使用SystemParametersInfo来查询。传递给SystemParametersInfo的常量的不同表现,显示如下:
SPI_GETBATTERYIDLETIMEOUT
当系统运行在电池电源状态下,离用户最后输入的时间
SPI_GETEXTERNALIDLETIMEOUT
当系统运行在AC电源状态下,离用户最后输入的时间
SPI_GETWAKEUPIDLETIMEOUT
在系统再次挂起时离系统被自动唤醒的时间
要防止电源被自动挂起,你需要查询这三个值,并在最短时间内返回之前调用SystemIdleTimerReset。如果超时值被设置为0,表示超时值被禁止。
电源管理程序
一个新的,独立的电源管理组件在Windows CE .NET 4.0中被引入了。这个电源管理程序替代了许多GWES以前完成的函数。电源管理程序定义了一系列的电源状态,如D0,D1,D2,和D3。这些看起来神秘的名字被对应于一些友好的系统级别名称。
对嵌入式系统来说,OEM厂商定义了系统的电源状态。例如,电源状态可能是打开(On),空闲(Idle)和挂起(Suspend)。其他电源状态也被定义了,像ScreenOff, InCradle, 和 OnBattery。
从应用程序的观点看,新的电源管理程序提供了通知电源状态改变的能力以及通过一系列的函数统一改变电源状态的能力。
系统的电源状态被定义在注册表中,SDK定义了PWRMGR_REG_KEY,以致你不得不知道注册表的字符串,但是当常量没定义的时间,电源管理程序注册数据被保留在HKEY_LOCAL_MACHINESystemCurrentControlSetControlPower。电源状态被定义作为子键,位于Key State。
电源通知
电源管理程序一个十分受欢迎的特点是,可以在系统电源状态改变时通知应用程序。这可以让应用程序从手动检测电源状态中解脱出来。一个应用程序可以通过调用RequestPowerNotifications请求电源管理程序当电源状态改变的时候发送一个通知给应用程序。电源管理程序会通过一个由应用程序前面建立的消息队列发送通知。
RequestPowerNotifications原型如下。
HANDLE RequestPowerNotifications (HANDLE hMsgQ, DWORD Flags);
第一个参数是一个应用程序在之前建立的消息队列的句柄。第二个参数是一系列参数,表示应用程序想接收的通知。
PBT_TRANSITION
接受系统电源状态改变的通知。例如,当系统从On到Suspend。
PBT_RESUME
当系统resume的时候接收通知。
PBT_POWERSTATUSCHANGE
当系统在AC和电池之间切换的时候接收通知。
PBT_POWERINFOCHANGE
当系统电池级数变化时接收通知。
POWER_NOTIFY_ALL
接收所有的通知。
RequestPowerNotifications函数返回一个电源通知的句柄,失败返回NULL。消息队列建立的时候必须使应用程序有读权限,因为应用程序将从消息队列中读取电源通知。
要接收通知,应用程序必须使用WaitForSingleObject来阻塞消息句柄。像第10章所讨论的,当通知被放在队列中时,句柄将被signaled。实际的通知将由结构POWER_BROADCAST表中被接收到。
typedef struct _POWER_BROADCAST {
DWORD Message;
DWORD Flags;
DWORD Length;
WCHAR SystemPowerState[1];
} POWER_BROADCAST, *PPOWER_BROADCAST;
第一个要注意的是,这个结构长度是可变的。最后一个字段,SystemPowerState,是被定义为WCHARs类型,但是可以填上非字符串数据。第一个字段是通知自己的标识,这个字段可以填前面PBT_标志列表之一。Flags区可以包括以下标志,依赖于被接收的通知:
POWER_STATE_ON
系统处于on状态。
POWER_STATE_OFF
系统处于off状态。
POWER_STATE_CRITICAL
系统进入了一个临界off状态。
POWER_STATE_BOOT
系统正在启动。
POWER_STATE_IDLE
系统进入idle状态。
POWER_STATE_SUSPEND
系统被挂起。
POWER_STATE_RESET
系统被复位。
最后两个字段是相互关联的。Length字段是SystemPowerState字段数据的长度。SystemPowerState中包含的数据依赖于被发送的通知。对于PBT_TRANSITION通知来说,SystemPowerState字段包含一个新电源状态的标识字符串。这个字符串是以非0结尾的。为了结束字符串,使用Length字段来指出字符串的长度。注意,Length字段是以字节为单位的,当字符是双字节的Uncode字符时,需要获得字符串字符的长度,就需要用Length字段去除TCHAR的size。
对于PBT_POWERINFOCHANGE通知来说,SystemPowerState字段包含一个PPOWER_BROADCAST_POWER_INFO结构:
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;
注意,这里有一些字段的名字和函数十分相似于前面讨论的SYSTEM_POWER_STATUS_EX2结构。
当系统被挂起,应用程序将不再运行,因此当系统唤醒时,应用程序看起来没有被控制。然而,有一些方式来唤醒一个挂起的设备。首先,一个应用程序通过给定一个时间,并使用11章提到的消息API(Notification API)做系统被唤醒的计划。在一般情况下,OEM厂商会分配一些中断条件,以便管理系统电源打开,或唤醒。这种方式的一个例子是一个系统当防止了一个同步架(synchronization cradle)时被唤醒。
防止系统关闭电源
相反的情况,防止系统挂起也是一个问题。Windows CE系统通常被设置为当一段时间没有用户输入就自动挂起。要防止自动挂起,一个应用程序可以周期性地调用一下函数:
void WINAPI SystemIdleTimerReset (void);
这个函数重设Windows CE用来监视用户输入的定时器。如果定时器到达预先的没有用户输入的间隔,系统会自动挂起。因为挂起超时值可以被改变,一个应用程序需要知道超时值,这样就要多一点调用SystemIdleTimerReset。系统维护三个超时值,这些都能够使用SystemParametersInfo来查询。传递给SystemParametersInfo的常量的不同表现,显示如下:
SPI_GETBATTERYIDLETIMEOUT
当系统运行在电池电源状态下,离用户最后输入的时间
SPI_GETEXTERNALIDLETIMEOUT
当系统运行在AC电源状态下,离用户最后输入的时间
SPI_GETWAKEUPIDLETIMEOUT
在系统再次挂起时离系统被自动唤醒的时间
要防止电源被自动挂起,你需要查询这三个值,并在最短时间内返回之前调用SystemIdleTimerReset。如果超时值被设置为0,表示超时值被禁止。
电源管理程序
一个新的,独立的电源管理组件在Windows CE .NET 4.0中被引入了。这个电源管理程序替代了许多GWES以前完成的函数。电源管理程序定义了一系列的电源状态,如D0,D1,D2,和D3。这些看起来神秘的名字被对应于一些友好的系统级别名称。
对嵌入式系统来说,OEM厂商定义了系统的电源状态。例如,电源状态可能是打开(On),空闲(Idle)和挂起(Suspend)。其他电源状态也被定义了,像ScreenOff, InCradle, 和 OnBattery。
从应用程序的观点看,新的电源管理程序提供了通知电源状态改变的能力以及通过一系列的函数统一改变电源状态的能力。
系统的电源状态被定义在注册表中,SDK定义了PWRMGR_REG_KEY,以致你不得不知道注册表的字符串,但是当常量没定义的时间,电源管理程序注册数据被保留在HKEY_LOCAL_MACHINESystemCurrentControlSetControlPower。电源状态被定义作为子键,位于Key State。
电源通知
电源管理程序一个十分受欢迎的特点是,可以在系统电源状态改变时通知应用程序。这可以让应用程序从手动检测电源状态中解脱出来。一个应用程序可以通过调用RequestPowerNotifications请求电源管理程序当电源状态改变的时候发送一个通知给应用程序。电源管理程序会通过一个由应用程序前面建立的消息队列发送通知。
RequestPowerNotifications原型如下。
HANDLE RequestPowerNotifications (HANDLE hMsgQ, DWORD Flags);
第一个参数是一个应用程序在之前建立的消息队列的句柄。第二个参数是一系列参数,表示应用程序想接收的通知。
PBT_TRANSITION
接受系统电源状态改变的通知。例如,当系统从On到Suspend。
PBT_RESUME
当系统resume的时候接收通知。
PBT_POWERSTATUSCHANGE
当系统在AC和电池之间切换的时候接收通知。
PBT_POWERINFOCHANGE
当系统电池级数变化时接收通知。
POWER_NOTIFY_ALL
接收所有的通知。
RequestPowerNotifications函数返回一个电源通知的句柄,失败返回NULL。消息队列建立的时候必须使应用程序有读权限,因为应用程序将从消息队列中读取电源通知。
要接收通知,应用程序必须使用WaitForSingleObject来阻塞消息句柄。像第10章所讨论的,当通知被放在队列中时,句柄将被signaled。实际的通知将由结构POWER_BROADCAST表中被接收到。
typedef struct _POWER_BROADCAST {
DWORD Message;
DWORD Flags;
DWORD Length;
WCHAR SystemPowerState[1];
} POWER_BROADCAST, *PPOWER_BROADCAST;
第一个要注意的是,这个结构长度是可变的。最后一个字段,SystemPowerState,是被定义为WCHARs类型,但是可以填上非字符串数据。第一个字段是通知自己的标识,这个字段可以填前面PBT_标志列表之一。Flags区可以包括以下标志,依赖于被接收的通知:
POWER_STATE_ON
系统处于on状态。
POWER_STATE_OFF
系统处于off状态。
POWER_STATE_CRITICAL
系统进入了一个临界off状态。
POWER_STATE_BOOT
系统正在启动。
POWER_STATE_IDLE
系统进入idle状态。
POWER_STATE_SUSPEND
系统被挂起。
POWER_STATE_RESET
系统被复位。
最后两个字段是相互关联的。Length字段是SystemPowerState字段数据的长度。SystemPowerState中包含的数据依赖于被发送的通知。对于PBT_TRANSITION通知来说,SystemPowerState字段包含一个新电源状态的标识字符串。这个字符串是以非0结尾的。为了结束字符串,使用Length字段来指出字符串的长度。注意,Length字段是以字节为单位的,当字符是双字节的Uncode字符时,需要获得字符串字符的长度,就需要用Length字段去除TCHAR的size。
对于PBT_POWERINFOCHANGE通知来说,SystemPowerState字段包含一个PPOWER_BROADCAST_POWER_INFO结构:
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;
注意,这里有一些字段的名字和函数十分相似于前面讨论的SYSTEM_POWER_STATUS_EX2结构。