windows网络适配器驱动开发-开发 WiFiCx 客户端驱动程序(八)

windows网络适配器驱动开发-开发 WiFiCx 客户端驱动程序(八)
电源策略更改

对于电源管理,客户端驱动程序使用 NETPOWERSETTINGS 对象 ,例如其他类型的 NetAdapterCx 客户端驱动程序。

为了在系统处于工作状态(S0)状态时支持设备闲置,驱动程序调用 WdfDeviceAssignS0IdleSettings 并将 WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS的 IdleTimeoutType 成员设置为 SystemManagedIdleTimeoutWithHint:

const ULONG WIFI_DEFAULT_IDLE_TIMEOUT_HINT_MS = 3u * 1000u; // 3 seconds ... WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings; WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings,IdleCanWakeFromS0); idleSettings.IdleTimeout = WIFI_DEFAULT_IDLE_TIMEOUT_HINT_MS; // 3 seconds idleSettings.IdleTimeoutType = SystemManagedIdleTimeoutWithHint; status = WdfDeviceAssignS0IdleSettings(DeviceContext->WdfDevice, &idleSettings);

关于电源策略更改,WiFiCx 客户端驱动程序在电源管理方面使用 NETPOWERSETTINGS 对象,这与其它类型的 NetAdapterCx 客户端驱动程序是相同的。

为了在系统处于工作状态(即 S0 状态)时支持设备闲置,驱动程序需要调用 WdfDeviceAssignS0IdleSettings 函数,并将 WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS 结构中的 IdleTimeoutType 成员设置为 SystemManagedIdleTimeoutWithHint。

当驱动程序这样配置后,会产生一个关键效果:WDF 框架会代表驱动程序向 Windows 电源管理框架(简称 PoFx)进行注册。注册之后,设备空闲电源管理的主导权就从驱动程序移交给了 PoFx。驱动程序不再直接控制设备何时进入或退出低功耗状态,而是由 PoFx 根据系统整体的电源状态和活动情况来统一决策和管理。

这种设计实现了职责分离:PoFx 负责全局决策,即决定何时让设备空闲;驱动程序则负责执行具体的电源状态切换操作,即如何进入或退出 Dx 状态。作为注册的一部分,驱动程序需要提供一系列回调函数,例如 EvtDeviceWdmPostPoFxRegisterDevice 等。当 PoFx 决定改变设备电源状态时,会通过这些回调通知驱动程序执行相应操作。

接下来解释 SystemManagedIdleTimeoutWithHint 中 Hint 的含义。这个 Hint 指的是驱动程序提供的 IdleTimeout 值,在示例中为 3000 毫秒,也就是 3 秒。这个值并不是一个绝对的超时时间,而是给 PoFx 的一个参考建议。PoFx 在决定设备是否空闲时,会综合考虑系统内所有组件的状态,驱动程序提供的这个超时值只是其中的一个输入,PoFx 可能会基于更全局的考量而忽略它。设置此值的主要目的是“防止设备过早进入空闲状态”,通过提供一个合理的超时值,驱动程序可以避免在短暂的数据传输间隙就频繁地进入和退出低功耗状态,从而减少不必要的性能开销。

在具体的代码实现中,标准流程包括:首先使用初始化宏对 WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS 结构进行初始化,并指定 IdleCanWakeFromS0,表明设备在 S0 空闲状态下具备唤醒能力。然后将 IdleTimeout 成员设置为三秒的超时提示值,再将 IdleTimeoutType 设置为 SystemManagedIdleTimeoutWithHint,这是启用 PoFx 管理的关键步骤。最后调用 WdfDeviceAssignS0IdleSettings 将配置应用到 WDF 设备对象。

需要说明的是,这段电源策略配置属于 WiFiCx 驱动电源管理的一部分。一个完整的电源管理方案通常还包括:注册电源事件回调以接收电源状态转换通知;调用 NetAdapterCx 提供的 API 来声明硬件支持的唤醒事件和低功耗协议卸载能力;以及通过标准化 INF 关键字允许用户或系统对网络设备的空闲行为进行更精细的控制。

在调用 WdfDeviceAssignS0IdleSettings 时还需要注意几个问题:调用驱动必须是设备的电源策略所有者,否则会返回 STATUS_INVALID_DEVICE_REQUEST;如果提供的结构体参数无效,会返回 STATUS_INVALID_PARAMETER;另外,在 Windows 8 及之后的系统中,框架会检查系统固件是否支持在 S0 状态下处理唤醒信号,如果检查失败,函数会返回 STATUS_POWER_STATE_INVALID。此时设备将保持 D0 状态,无法进入低功耗模式,但驱动程序不应将此视为致命错误,可记录日志后继续运行。