网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.

Windows驱动程序DPC定时器

DPC定时器icon

在上一篇文章http://www.youranshare.com/codeorg/sid/130.html中介绍了驱动程序中I/O定时器的使用方法,但是对于I/O定时器来说其精度只有1S,使用较为不方便,本文中将会介绍驱动程序中定时器的另一种实现方式,DPC定时器,DPC定时器精度为100ns,相比I/O定时器来说使用更为灵活.

DPC定时器

DCP是一种使用更加灵活的定时器,可以对任意间隔时间进行定时。DPC定时器的内部使用了一个定时器对象KTIMER,当你设定了定时器之后,从设定开始起经过这个时间之后操作系统会将一个DPC定时器的例程插入到DPC的队列,操作系统读取DPC队列的时候定时器例程就能够被执行。这里的DPC定时器例程就相当于一个定时器的回调函数。

 

和I/O定时器类似,在使用之前你需要一些相关的初始化操作,你需要初始化DPC对象和定时器对象。

初始化DPC使用内核函数KeInitializeTimer,他的声明如下:

VOID
KeInitializeTimer (
    __out PKTIMER Timer
    );


其中参数Timer是定时器的指针,它是一个输出值.

 

初始化DPC对象使用内核函数KeInitializeDpc,它的声明如下:

VOID
KeInitializeDpc (
    __out __drv_aliasesMem PRKDPC Dpc,
    __in PKDEFERRED_ROUTINE DeferredRoutine,
    __in_opt __drv_aliasesMem PVOID DeferredContext
);


参数1:Dpc是输入参数DPC的对象指针

参数2:DeferredRoutine是一个与DPC关联的定时器例程函数,当定时器被触发的时候这个例程函数就会被执行调用

参数3:DeferredContext是一个传入定时器例程的参数.

 

当初始化完成之后使用函数KeSetTimer函数开启定时器,它的声明如下:

BOOLEAN
KeSetTimer (
    __inout PKTIMER Timer,
    __in LARGE_INTEGER DueTime,
    __in_opt PKDPC Dpc
);


参数1:Timer是定时器对象的指针.

参数2:DueTimer这个参数是设定的时间间隔.

参数3:Dpc表示传入定时器例程的参数.

返回值:BOOL类型的,表示成功或者失败.

 

取消定时器使用内核函数KeCancelTimer,它的声明如下:

BOOLEAN
KeCancelTimer (
    __inout PKTIMER
);


参数:在调用KeSetTimer函数之后,经过DueTime的时间,操作系统会调用一次定时器的例程,其中如果DueTime是一个正整数,则会代表绝对时间,也就是相对于1601年1月1日到触发DPC定时器的那个时刻,如果DueTime是负数,那它表示的是间隔多长时间,这里需要说的是DueTime的单位可不是1ns,它的单位是100ns。

 

    在调用了KeSetTimer之后,只会触发一次DPC定时器例程,如果想要周期的触发DPC定时器例程,则需要在DPC定时器例程被触发后再次调用KeSetTimer函数。

 

说一下代码中我们需要做的工作,然后附上代码的下载地址

首先定义两个IOCTL,用于控制定时器的开启和取消

在你的设备扩展中添加上KDPC对象和KTIMER成员,以备后用

直接使用设备扩展中的KDPC和KTIMER对象完成初始化,

并将设备扩展的指针作为定时器例程的参数.

在IRP_MJ_DEVICE_CONTROL例程中完成对定时器的开启和关闭.

附加一段我们的设备扩展的结构体:

typedef struct _DEVICE_EXT{
   //指向设备的
   PDEVICE_OBJECT pDevice;
   UNICODE_STRING USzDeviceName;//设备名称
   UNICODE_STRING USzSymLinkName;//符号链接名称
 
   KDPC pollingDPC;//DPC对象
   KTIMER pollingTimer;//定时器对象
   LARGE_INTEGER pollingInterval;//定时器间隔
}DEVICE_EXTENSION,*PDEVICE_EXTENSION;


    需要说明的几点:DPC的定时器和I/O定时器一样也是可以运行于任意线程中的,并且定时器例程的IRQL中断请求级是DISPATH_LEVEL,需要使用非分页内存的.

 

下面是示例代码工程的下载地址:

解压密码 yscode

百度网盘地址http://pan.baidu.com/s/1ntiauSx



  • 标签:
  • DPC定时器
  • windows驱动定时器
  • 定时器
网站已经改版为Wordpress版本,这里是旧版本的快照,请不要在页面中留言.