jonathanfoo
驱动牛犊
驱动牛犊
  • 注册日期2003-10-13
  • 最后登录2004-06-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2434回复:10

OVERLAPPED方式的Readfile不是立即返回吗?

楼主#
更多 发布于:2004-03-05 16:48
    我的PCI驱动程序中没有计时器例程,也没有Cancel例程。
Readfile发送IRP给DispatchRead例程,DispatchRead例程会
等待中断发生从而获取数据,然后调用IoCompleteRequest完成
该例程。
    我做了这样一个试验:不使中断发生,DispatchRead将会永
远等待,处于停滞状态。在应用层,通过OVERLAPPED方式调用
Readfile读数据,为什么Readfile不是立即返回呢?
    理论上异步方式应该立即返回吧?
    在什么情况下,异步的Readfile函数才能够顺利返回?
    什么情况下Readfile返回False,而GetLastError返回
ERROR_IO_PENDING,开始IO pending操作?

最新喜欢:

mapoflmapofl
newhand
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
沙发#
发布于:2004-03-05 17:05
   我的PCI驱动程序中没有计时器例程,也没有Cancel例程。
Readfile发送IRP给DispatchRead例程,DispatchRead例程会
等待中断发生从而获取数据,然后调用IoCompleteRequest完成
该例程。
    我做了这样一个试验:不使中断发生,DispatchRead将会永
远等待,处于停滞状态。在应用层,通过OVERLAPPED方式调用
Readfile读数据,为什么Readfile不是立即返回呢?
    理论上异步方式应该立即返回吧?
    在什么情况下,异步的Readfile函数才能够顺利返回?
    什么情况下Readfile返回False,而GetLastError返回
ERROR_IO_PENDING,开始IO pending操作?


这是驱动的原因。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
jonathanfoo
驱动牛犊
驱动牛犊
  • 注册日期2003-10-13
  • 最后登录2004-06-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-03-05 17:48
楼上的高手,能不能说的详细一些,
是驱动程序的什么问题造成了这个问题?

异步IO何时出IO pending 的情况?
在我的PCI卡上,如果发生中断,异步Readfile可以正常返回,
请问:驱动程序应该做如何改动?

Readfile靠获取什么信号从而顺利返回?

newhand
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
地板#
发布于:2004-03-05 20:04
你的驱动需要支持队列。具体怎么作,找一本书看看。推荐 Walter Oney 的 《Programming the Microsoft Windows Driver Model》
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
jonathanfoo
驱动牛犊
驱动牛犊
  • 注册日期2003-10-13
  • 最后登录2004-06-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-03-08 17:25
DispatchRead调用IoMarkIrpPending(Irp)和IoStartPacket()之后返
回 STATUS_PENDING,应用层的Readfile就异步返回了。请问:这就可
以实现应用层正确的异步操作了吧?

还有一个问题:从内核空间到用户空间的数据复制操作应该在哪里实现?
DispatchRead立即返回了,在DPC中实现又有点不安全,是不是只能开辟
新的线程来完成数据复制了?
newhand
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
5楼#
发布于:2004-03-08 17:43
DispatchRead调用IoMarkIrpPending(Irp)和IoStartPacket()之后返
回 STATUS_PENDING,应用层的Readfile就异步返回了。请问:这就可
以实现应用层正确的异步操作了吧?

还有一个问题:从内核空间到用户空间的数据复制操作应该在哪里实现?
DispatchRead立即返回了,在DPC中实现又有点不安全,是不是只能开辟
新的线程来完成数据复制了?


1. 是的

2. 你只需要将数据放到内核空间的Buffer, Io Manager回帮你将数据从内核空间Buffer复制到用户空间Buffer。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
jonathanfoo
驱动牛犊
驱动牛犊
  • 注册日期2003-10-13
  • 最后登录2004-06-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-03-09 09:42
    我目前使用的是Direct IO,而不是Buffered IO,采集到的数据首
先放在内核空间分配的存储区域,然后,再手动将选定的内核空间存储区
复制到用户空间,所以,复制的操作不能依靠IO manager完成。在这种
情况下,是不是只能把复制的操作另开辟线程来完成啊?还有其他的解决
办法吗?


    还有,我看到书上说采用Direct IO方式,IO Manager首先将整个
用户缓冲区锁定到内存中,如果,目前用户需求的数据量比内存容量要大
的话,用户缓冲区也需要开辟的足够大,可不可以超出内存容量啊?
newhand
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
7楼#
发布于:2004-03-09 15:07
   我目前使用的是Direct IO,而不是Buffered IO,采集到的数据首
先放在内核空间分配的存储区域,然后,再手动将选定的内核空间存储区
复制到用户空间,所以,复制的操作不能依靠IO manager完成。在这种
情况下,是不是只能把复制的操作另开辟线程来完成啊?还有其他的解决
办法吗?


    还有,我看到书上说采用Direct IO方式,IO Manager首先将整个
用户缓冲区锁定到内存中,如果,目前用户需求的数据量比内存容量要大
的话,用户缓冲区也需要开辟的足够大,可不可以超出内存容量啊?
 


Direct IO不需要复制Buffer, 而是使用MDL直接操作用户Buffer。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
jonathanfoo
驱动牛犊
驱动牛犊
  • 注册日期2003-10-13
  • 最后登录2004-06-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-03-09 17:39
    我的想法是这样的,使用DMA方式从设备传输数据,需要连续的物理
内存存储收到的数据,尽管Direct IO方式的用户缓冲区可以直接访问,
但是并不能保证用户缓冲区在物理上是连续的(用户缓冲区在物理上不一
定连续,这一点正确吗?)。所以,还是需要在内核空间开辟连续的缓冲
区,于是,最终还是需要将数据从内核空间复制到用户缓冲区的。这就又
回到了以前的问题,是不是只能另外开辟线程完成这个复制的操作呢?谢
谢。
newhand
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
9楼#
发布于:2004-03-09 18:02
   我的想法是这样的,使用DMA方式从设备传输数据,需要连续的物理
内存存储收到的数据,尽管Direct IO方式的用户缓冲区可以直接访问,
但是并不能保证用户缓冲区在物理上是连续的(用户缓冲区在物理上不一
定连续,这一点正确吗?)。所以,还是需要在内核空间开辟连续的缓冲
区,于是,最终还是需要将数据从内核空间复制到用户缓冲区的。这就又
回到了以前的问题,是不是只能另外开辟线程完成这个复制的操作呢?谢
谢。


如果你使用的是Windows的DMA模型,根本不需拷贝buffer。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
jonathanfoo
驱动牛犊
驱动牛犊
  • 注册日期2003-10-13
  • 最后登录2004-06-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-03-10 09:24
    我目前没有采用DMA模型,所以复制数据的操作看来只能够手动完成
了,我现在想了解的是,在之前我们探讨的那些问题的基础上,除了新开
辟一个线程完成这个操作以外,还有没有其他可行的方法呢?使用线程调
度会不会有哪些不利的因素存在?
newhand
游客

返回顶部