4.7 电源管理 第五部分 ---- Windows CE设备驱动开发之电源管理

2019-07-14 03:32发布

Windows CE设备驱动开发之电源管理 第五部分 4.7.1、活动定时器(Activity Timers) 在初始化时,电源管理器从注册表中读取活动定时器名称列表。对于每个定时器,电源管理器都会检查其超时时间(以秒为单位)以及可选的唤醒源列表。然后创建下列事件: l         定时器重置事件 l         活动状态手动重置事件 l         手动重置事件 如果超时与不产生重置事件的定时器到期关联,电源管理器将重置活动事件并设置非活动事件。如果重置事件产生,电源管理器重置非活动事件并设置活动事件。 下列示例代码是配置一个活动计时器的注册表设置: [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/ActivityTimers/SystemActivity]     "Timeout"=dword:A "WakeSources"=multi_sz:"0x20" 上面注册表设置会引发电源管理器创建三个事件,分别名为:PowerManager/ActivityTimer/SystemActivityPowerManager/SystemActivity_Active PowerManager/SystemActivity_Inactive。第一个事件是一个自动重置事件,任何驱动程序都可能通过发送信号表明系统处于活动状态。支持重置活动定时器的驱动程序应从注册表中读取定时器的重置事件名称。其他两个是手动重置事件,这两个事件在同一时刻只会产生一个,而不会同时发生。驱动程序、应用程序或电源管理器自身都可能打开这些事件的句柄,以便确定定时器是否到期。这些事件表明了活动定时器的状态。重置事件是活动定时器的输入,状态事件是其对应的输出。 除了创建事件,这一注册表设置项还将一个唤醒源与此活动定时器关联。如果系统恢复,并且电源管理器确定系统是由此活动定时器对应的唤醒源所唤醒,那么此活动定时器将被置为活动。电源管理器使用IOCTL_HAL_GET_WAKE_SOURCE内核IOCTL来确定是什么设备唤醒了系统。---- In addition to creating events, this set of registry entries associates a wake source identifier with the activity timer. If the OS resumes and the Power Manager determines that the wake source corresponding to this ID caused the system to resume, it will set the associated activity timer toactive. The Power Manager uses the IOCTL_HAL_GET_WAKE_SOURCE kernel IOCTL to determine what woke the system. The active timer allows the development workstation that is in finite state to manage OS power state transitions to use the activity timer as input. It then uses that input to make a decision as to which system power state is the most appropriate to enter during the resume process. For example, the Power Manager might enter an OS power state in which the display and backlight are off. The Power Manager enters this state so that network synchronization can occur without disturbing the user. 驱动程序可以在适当的时候重置活动定时器,而在同一时刻可能有多个驱动打开句柄来重置活动定时器事件。驱动在重置活动定时器时需要从注册表读取事件名称。OEM厂商可以对注册表进行定制,通过定制注册表,OEM厂商可以决定电源管理器如何理解驱动程序的活动。潜在的活动源包含打开句柄重置活动定时器事件的所有驱动。 会有多个线程打开句柄手动重置活动/非活动事件并等待其确定系统状态。例如,屏幕背光驱动可以使用为活动定时器创建的一对事件来判断如何控制背光的电源及亮度。 当系统挂起时,电源管理器重置正在活动的与活动定时器关联的手动重置事件。在系统恢复时,电源管理器会检测所有活动定时器,来判断是否是由与活动定时器关联的唤醒源引发了系统恢复。如果找到匹配项,就表明系统恢复是由其对应的唤醒源产生的活动事件引发的。   4.7.5.1              活动定时器行为(Activity Timer Behavior 各种驱动程序都可以重置活动定时器,但是重置活动定时器会导致电源管理器产生一个定时器管理线程。这会给目标设备CPU造成额外负担。为了解决这个问题,当活动事件从非活动状态变位活动状态时,电源管理器在定时器超时前不会再检测重置事件。如果在此期间产生了活动事件,电源管理器不会处理而会持续等待。如果直到定时器超时都没有重置事件,那么活动定时器会到期,同时手动重置事件的状态会改变。   4.7.5.2              活动定时器超时及控制面板的电源选项(Activity Timer Time-outs and the Power Control Panel Utility   活动定时器超时表示电源管理器在等待多长时间后可以判定某一活动源是非活动的。这会引发一个非活动事件。控制面板中的设置工具可以确定在保持非活动状态多长时间后,电源管理器会进行系统电源状态切换。 活动定时器超时时间应小于系统电源状态超时时间,但应大于预期的活动时间间隔。例如,系统状态超时可能是几分钟,而用户活动定时器可能是10秒。这样可以预防在正常操作时频繁的进行活动定时器状态切换。 控制面板的电源选项工具中列出的超时时间是累加的。也就是说,如果每个超时时间都设置为1分钟,系统会在3分钟后挂起。因为每个超时时间表示一次系统电源状态切换,而系统直到挂起会进行3次状态切换。   4.7.5.3              活动定时器事件(Activity Timer Events   开发者可以设置在驱动程序中活动定时器事件。电源管理器在等待定时器到期期间不会等待定时器重置事件。在活动定时器超时后,电源管理器会检测在此期间是否有重置事件被设置。如果没有设置重置事件,定时器会被认为已经到期。如果有重置事件被设置,电源管理器将在此等待定时器。电源管理器仅在定时器到期且在此期间没有产生重置事件,或在非活动期间第一次产生重置事件时更新手动重置定时器事件。 如果驱动程序线程运行在较高优先级时,电源管理器的活动定时器线程不会运行,即使电源管理器正在等待定时器重置事件。默认情况下,活动定时器线程运行在THREAD_PRIORITY_ABOVE_NORMAL优先级,而大多数驱动程序运行在THREAD_PRIORITY_HIGHEST或更高优先级。这将导致活动定时器线程不能抢占驱动程序线程。   4.7.5.4              活动定时器重置(Activity Timer Resets 可以设置电源管理器来监测哪些应用程序正在使用socket,这比仅监测socket是否连接要好。网络协议栈并没有直接支持此功能。当然,你可以创建一个线程,周期性的循环调用GetTcpStatisticsGetUdpStatistics函数来确定是否有TCPUDP报文收发操作。如果收到或发送了报文,线程可以重置活动定时器。此线程可以实现为作为电源管理器一部分的可安装设备驱动程序;或作为某应用程序的一部分来实现。 注意:如果本地应用程序使用socket进行进程间通讯(IPC)时,GetTcpStatisticsGetUdpStatistics函数可能会返回环回通讯数据。   4.7.2、            挂起超时支持(Suspend Time-out Support 你可能需要使WindowsCE设备处于非活动状态一段时间后进入挂起状态。可以使用以下方式进入挂起状态: l         GWES会维持一个依据用户输入的空闲定时器(Idle timer),并在其处于非活动状态一段时间后挂起系统。这种方法用于Windows CE .NET 4.1 之前版本。 l         电源管理器可以根据活动定时器、输入电源及其他输入来管理系统电源状态。开发者可以定制电源管理器,使其能在你选择挂起(如开始菜单的挂起按钮)时挂起系统。 l         可以编写一个独立的应用程序来决定什么时候挂起系统。这种情况下,GWES和电源管理器都必须配置为不对挂起状态进行管理。 上述三种情况下,都是通过调用PowerOffSystem从而使电源管理器来挂起系统。三种情况的不同之处在于如何使系统进入挂起状态。开发者应只使用其中一种方法,以便避免GWES、电源管理器及应用程序间的冲突。 如果电源管理器正在管理系统超时,SystemIdleTimerReset函数会通知GWES不应出现屏幕保护程序。 4.7.6.1              GWES挂起超时(GWES Suspend Time-outs 下表列出控制系统进入挂起状态的注册表键值。这些值以DWORD类型保存在注册表HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power键下。如果值为0,表示禁用此功能。 注册表值名称 默认值 描述 BattPowerOff 300 (5分钟) 表示当系统使用电池供电时,在多少秒无用户输入后会挂起系统。 ExtPowerOff 0 (禁用) 表示当系统使用外接电源供电时,在多少秒无用户输入后会挂起系统。 WakeupPowerOff 60 (1分钟) 表示当系统被非用户输入事件唤醒后(例如闹钟),在多少秒无活动时会挂起系统。 ScreenPowerOff 0 (禁用) 在GWES发送APM_POWERBROADCAST, PBT_APMUSERIDLE消息给任务栏前,多少秒无用户输入。 为了使GWES控制挂起超时,必须使用这些注册表设置。同时必须防止电源管理器控制系统挂起状态。在示例电源管理器实现中,可以通过从注册表中移除电源管理器超时定义来实现此功能。当GWES管理系统挂起超时时,它通过调用SetSystemPowerState函数使电源管理器将系统切换到挂起状态。   4.7.6.2              电源管理器挂起超时(Power Manager Suspend Time-outs   示例电源管理器的实现依据系统电源、用户活动及系统活动进行挂起超时管理。示例电源管理器实现了超时可配置。由于电源管理器可以被OEM厂商定制,所以下列描述并不适用于所有Windows CE设备。OEM控制电源管理器如何、在什么时候改变系统电源状态。 下面列出了控制电源管理器进行系统电源状态切换的注册表值: ACUserIdle ACSystemIdle ACSuspend BattUserIdle BattSystemIdle BattSuspend BatteryPoll 这些DWORD值保存在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/Timeouts注册表键下。0值表示不会产生超时。示例电源管理器并没有提供忽略系统电源状态的方法,OEM可以选择实现此类方法。 为了使电源管理器能更好的管理系统电源状态,这些设置必须在注册表中出现。示例电源管理器是根据ACUserIdle进行电源管理的。 注意:为了防止GWES与电源管理器间的冲突,应禁用GWES电源管理。在电源管理器管理系统电源时,可能会限制应用程序不能进入某些系统电源状态。 Note   To prevent conflicts between GWES and the Power Manager, you need to disable GWES power management as described previously. When the Power Manager is actively managing system power, it may restrict applications from entering arbitrary system power states. 如果要刷新系统状态切换定时器,应创建一个名为PowerManager/ReloadActivityTimeouts的自动重置事件,并在此事件的处理过程中调用SetEvent。这样可以使电源管理器再次从注册表中读取状态切换定时器设置。 注册表设置: [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Power/Timeouts]     "ACUserIdle"=dword:3c; 以秒为单位     "ACSystemIdle"=dword:12c; 以秒为单位     "ACSuspend"=dword:0; 以秒为单位     "BattUserIdle"=dword:3c; 以秒为单位     "BattSystemIdle"=dword:b4; 以秒为单位     "BattSuspend"=dword:12c; 以秒为单位     "BatteryPoll"=dword:1f4; 电池轮询间隔时间,以毫秒为单位     4.7.6.3              应用程序挂起超时(Application Suspend Time-outs OEM厂商有可能会编写应用程序直接对系统电源状态进行管理,而这样就不需要定制电源管理器。为此,应用程序必须禁用GWES及电源管理器的电源管理功能,并自行处理电源状态切换。禁用电源管理器及GWES电源管理功能的更多信息,参见6.2 电源管理器挂起超时。 电源管理器可能不能确定从挂起状态恢复时,应恢复到哪个电源状态。如果OEM厂商允许系统在挂起后完全恢复,那么可以不考虑这个问题。但是,如果OEM厂商需要部分唤醒系统,就可能需要修改电源管理器。