使用计时器

本主题介绍如何使用框架的内置计时器支持。 它适用于 Kernel-Mode Driver Framework (KMDF) 驱动程序,以及从版本 2 开始的 User-Mode Driver Framework (UMDF) 驱动程序。

框架提供了一个 计时器对象 ,使驱动程序能够创建计时器。 在驱动程序创建计时器对象并启动计时器的时钟后,框架会在经过指定时间量后调用驱动程序提供的回调函数。 (可选)驱动程序可以设置计时器,以便框架在经过指定时间时重复调用回调函数。

若要创建框架计时器对象,驱动程序必须调用 WdfTimerCreate 方法。 此方法注册 EvtTimerFunc 回调函数和定期时间间隔。 如果希望框架只调用回调函数一次,驱动程序会为定期时间间隔指定零。

通常,你将知道驱动程序需要为每个设备使用的计时器数。 因此,驱动程序可以通过在其 EvtDriverDeviceAdd 回调函数中调用 WdfTimerCreate 来创建计时器对象,并且可以将计时器对象句柄存储在设备或队列对象的上下文空间中。

若要启动计时器,驱动程序会调用 WdfTimerStart,传递“到期时间”。 框架启动计时器的时钟,并在指定的时间量已过时调用 EvtTimerFunc 回调函数。

如果驱动程序在调用 WdfTimerCreate 时提供了定期时间间隔,则计时器称为 定期计时器。 在初始“到期时间”过后,定期计时器的时钟将继续运行,并且每当经过定期时间间隔时,框架会重复调用驱动程序的回调函数。 定期计时器不会自动启动。 与非定期计时器一样,驱动程序在创建计时器后仍必须调用 WdfTimerStart ,以便第一次启动它。

驱动程序可能从其 EvtTimerFunc 回调函数调用 WdfTimerStart,以便在非定期计时器过期后重新启动它。

若要停止计时器,驱动程序可以调用 WdfTimerStop。 驱动程序可以通过重复启动和停止计时器来重复使用计时器。

驱动程序创建计时器对象时,必须指定父对象。 框架在删除父级时停止计时器并删除计时器对象。 若要获取计时器对象的父对象,驱动程序可以调用 WdfTimerGetParentObject

在版本 1.9 之前的 KMDF 版本中,如果希望驱动程序的所有回调函数在 IRQL = PASSIVE_LEVEL 运行,则无法轻松使用计时器对象。 框架将计时器对象的 EvtTimerFunc 回调函数实现为延迟过程调用, (在 IRQL = DISPATCH_LEVEL调用的 DPC) 。 因此,如果希望计时器过期代码在PASSIVE_LEVEL 则 EvtTimerFunc 回调函数必须将在 PASSIVE_LEVEL 运行 的工作项 排队。

在 KMDF 版本 1.9 及更高版本中,可以创建 被动级别计时器,即在 PASSIVE_LEVEL 运行的计时器。 若要创建被动级别计时器,请在驱动程序调用 WdfTimerCreate 时指定 WdfExecutionLevelPassive 执行级别。 因此,框架将 EvtTimerFunc 回调函数实现为在PASSIVE_LEVEL运行的工作项。 请注意,被动级别计时器不能是定期计时器。

从 UMDF 版本 2.0 开始,框架将计时器对象的 EvtTimerFunc 回调函数实现为用户模式线程池中的工作线程。 因此,UMDF 驱动程序的计时器回调函数始终在PASSIVE_LEVEL运行。

无唤醒计时器

反复导致系统从低功耗状态恢复的计时器会降低系统电源效率。 延长电池使用时间的一种方法是延迟非关键定期操作,而不是唤醒系统。 从 Windows 8.1 开始,可以使用任何唤醒计时器在 KMDF 或 UMDF 驱动程序中执行此类非关键操作。 当系统处于低功耗状态时,无唤醒计时器不会唤醒系统。 相反,当系统下次完全处于 S0 状态时,框架会调用驱动程序的 EvtTimerFunc 回调函数。

从 KMDF 版本 1.13 和 UMDF 版本 2.0 开始,没有可用的唤醒计时器。

若要创建无唤醒计时器,请将 WDF_TIMER_CONFIGTolerableDelay 成员设置为 TolerableDelayUnlimited

有关无唤醒计时器的详细信息,请参阅 无唤醒计时器

高分辨率计时器

标准框架计时器的准确度与系统时钟计时周期间隔匹配,默认情况下为 15.6 毫秒。 从 Windows 8.1 开始,可以创建高分辨率计时器。 高分辨率计时器的准确度为 1 毫秒。 对于需要精确、可预测的过期时间的关键操作,可以使用高分辨率计时器。 由于需要频繁维护,高分辨率计时器可能会导致电池使用时间缩短。

高分辨率计时器仅适用于 KMDF 驱动程序,从 KMDF 版本 1.13 开始。

若要创建高分辨率计时器,请将 WDF_TIMER_CONFIGUseHighResolutionTimer 成员设置为 WdfTrue,然后将 Period 值调整为所需的分辨率。

下表显示了基于驱动程序为 Period 提供的不同值的计时器行为示例。 这些示例假定系统时钟计时周期间隔为 15 毫秒。

Period,以毫秒为单位 标准计时器 高分辨率计时器

10

计时器在 0 毫秒到 25 毫秒之间过期。

计时器在 10 毫秒后尽快过期。

16

计时器在 15 毫秒到 30 毫秒之间过期。

计时器在 16 毫秒后尽快过期。

有关高分辨率计时器的详细信息,请参阅 高分辨率计时器

有关计时器准确性如何与系统时钟粒度相关的详细信息,请参阅 计时器准确性