WDF pci驱动开发的若干总结

最近在调试一套windows下的PCIE板卡驱动,采用的是WDF的驱动框架,驱动实现了阻塞式的读操作、写操作和IOCTL等三类操作,在实际的应用过程中,遇到了如下问题:

1、驱动加载后,PCI分配的IO和Mem对应地址内的内容完全变成了0xFF,无法进行驱动的配置;

2、应用程序中,开启两个任务分别进行设备的读和写的操作,发现写的任务也会进行阻塞,必须等到read返回之后才能调度,导致没法并行处理。

 

针对第一个问题,同样的程序在win xp上可以正常运行,win7 32和64位的版本均不能运行,经过长时间的排查,以及借助RW工具进行直接辅助调试,在一次偶发情况下,发现地址内对应的值不再是全0xFF,通过对这次正常的情况分析,发现COMMAND寄存器中的IO enable和memory enable这两个bit位都已经配置为了1,也就是允许IO和MEM操作,在驱动程序中添加COMMAND寄存器的配置后,一切都可以正常运行。

 

针对第二个问题,微软官方文档描述的是,device的默认队列可以配置为WdfIoQueueDispatchParallel(并行)、WdfIoQueueDispatchSequential(串行)、WdfIoQueueDispatchManual(手动)这三种方式的队列,通过配置为WdfIoQueueDispatchParallel能够并行的分发IRP,但是无论是配置为并行的还是串行的方式,实际应用的时候,都还是串行分方式,必须要等到一个IRP处理完成之后才能处理下一个IRP。

此外,针对第二个问题,很多网友以及微软的官方手册还建议使用多个队列的方式进行处理,即device统一使用默认队列进行IRP的接收,然后再将需要耗时比较长或者需要阻塞的等待的请求放入额外的队列进行处理,即通过WdfRequestForwardToIoQueue进行消息的转移处理,结果在实际过程中也并没有起到作用,跟踪发现,在处理请求的过程中,调用WdfRequestForwardToIoQueue后,并没有立即返回,官方文档以及部分网友的说明是此函数类似IrpMarkPending,即WDF下类似WDM中的的挂起操作,在此过程中可以调度新的IO请求,然而,实际使用过程中系统并没有进行二次调度和分发,同样还是没法解决问题。

偶然在网上看到可以将应用层的Handle传递到内核层进行处理,由此产生了一个新的想法,可以在应用层创建一个事件Event,初始化为无信号状态,将其传递到内核,在数据满足读取的时候,将此信号设置为有效,从而可以唤醒应用程序继续执行,这样在每次read之前等待此Event,等到之后再进行read操作,解决问题;部分实现见下图:

内核处理部分:

 

 

        KeSetEvent(pChan->rdReady, IO_NO_INCREMENT, FALSE);  //触发事件

 

应用层的操作:

创建

传递到内核

等待

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值