chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2302回复:16

应用程序在读usb数据时,如果没有数据可读,程序就被阻塞了,为何?

楼主#
更多 发布于:2003-07-01 21:24
我是参照ddk的一个Bulk_usb驱动例子写了一个usb驱动程序,现在我想在应用层通过ReadFile()去读取usb上的数据,当有数据读时倒还好,如果usb设备没有数据时,ReadFile()就不能立即返回了,程序被阻塞在ReadFile()这个地方,以至于整个应用程序都不能退出,只有重启机器才行,请问有什么办法让ReadFile()在读usb数据时不阻塞吗?就是说调用ReadFile()时有多少数据就返回多少数据,没有数据就返回0,而不要阻塞在这里,什么事情都做不了。

最新喜欢:

bearsammibearsa...
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
luckyjm
驱动中牛
驱动中牛
  • 注册日期2002-12-19
  • 最后登录2004-03-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-07-02 08:26
没有数据是不能自动返回的,不过你可以用RESET实现啊,让USB重新枚举一下应该可以的。
swf2003
驱动中牛
驱动中牛
  • 注册日期2003-02-13
  • 最后登录2011-10-28
  • 粉丝1
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-07-02 08:59
加上超时控制,超时 reset 设备。
你的认可是对我最大的鼓励!
xjLegend
驱动小牛
驱动小牛
  • 注册日期2002-11-04
  • 最后登录2005-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-07-02 10:20
可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。

有更好的办法,欢迎补充.
我想要点分,这样才有成就感嘛!
swf2003
驱动中牛
驱动中牛
  • 注册日期2003-02-13
  • 最后登录2011-10-28
  • 粉丝1
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-07-02 15:07
ap 中用异步读,ReadFileEx。
你的认可是对我最大的鼓励!
chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-07-02 16:29
ap 中用异步读,ReadFileEx。

这种方式我试了一下,结果是一样的,仍然不行。
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-07-02 16:33
可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。

有更好的办法,欢迎补充.

看得出来,你是个高手,请教你一下:
1、“改用ISO同步方式”是指应用程序还是指驱动程序,该怎么改?
2、如何实现“当底层有数据时通过其它端点发送接收通知”?
麻烦你了!
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
testing
驱动牛犊
驱动牛犊
  • 注册日期2003-06-15
  • 最后登录2003-08-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-07-02 21:42
改用isochronous方式或使用额外的endpoint通知都需要硬件、驱动
都支持才行。

使用异步读应该是可以避免ReadFile阻塞的问题的,

你有在CreateFile时指明使用异步方式吗?
wolfwoo22
禁止发言
禁止发言
  • 注册日期2003-03-11
  • 最后登录2016-04-11
  • 粉丝0
  • 关注0
  • 积分930分
  • 威望8970点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-07-03 09:12
用户被禁言,该主题自动屏蔽!
chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-07-03 09:44
有一个简单的办法。
每次ReadFile之前先发一自定的DeviceIOControl给WDM driver.其发一个Bulk方式的命令包询问USB设备有多少字节准备传输。在用ReadFile读不就行了么。
我也是你这样想的,可我在WDM driver中怎么知道底层有多少字节的数据要传输呢?
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
wolfwoo22
禁止发言
禁止发言
  • 注册日期2003-03-11
  • 最后登录2016-04-11
  • 粉丝0
  • 关注0
  • 积分930分
  • 威望8970点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-07-03 10:10
用户被禁言,该主题自动屏蔽!
chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-07-03 10:21
不是你的WDM driver知道,而是让你的WDM driver通过ep0问你的Device有多少东西要传,然后在ReadFile.
你说的“让你的WDM driver通过ep0问你的Device有多少东西要传”是怎么实现的呢?就是说我怎么知道device有多少数据要传呢?
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
Always!978
驱动小牛
驱动小牛
  • 注册日期2002-05-09
  • 最后登录2005-04-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-07-03 10:54
可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。

有更好的办法,欢迎补充.

 \"当底层有数据时通过其它端点发送接收通知然后才Readfile。\",这样的方法会不会太慢了,用在测试还可以,实际中不可能吧。
  我觉得是不是可以这样,在readfile的响应函数中先读一下缓冲区数据长度,为0直接退出。

 
Tomorrow Never Die
chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-07-03 10:59
[quote]可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。

有更好的办法,欢迎补充.

 \"当底层有数据时通过其它端点发送接收通知然后才Readfile。\",这样的方法会不会太慢了,用在测试还可以,实际中不可能吧。
  我觉得是不是可以这样,在readfile的响应函数中先读一下缓冲区数据长度,为0直接退出。

  [/quote]你说的“先读一下缓冲区数据长度”我不懂,怎么读到缓冲区数据的长度,请问???
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
hemu
驱动小牛
驱动小牛
  • 注册日期2002-04-10
  • 最后登录2004-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-07-03 11:54
这个问题我也遇到了,而且驱动我是直接用芯片公司的,我是否可以只是通过应用程序来个超时等待,因为我问过cypress公司了,他们的回答就是这样,但是超时等待怎么着手啊。
xjLegend
驱动小牛
驱动小牛
  • 注册日期2002-11-04
  • 最后登录2005-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2003-07-03 16:35
[quote]可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。

有更好的办法,欢迎补充.

 \"当底层有数据时通过其它端点发送接收通知然后才Readfile。\",这样的方法会不会太慢了,用在测试还可以,实际中不可能吧。
  我觉得是不是可以这样,在readfile的响应函数中先读一下缓冲区数据长度,为0直接退出。

  [/quote]

这个方法倒不慢,只是使用的场合是偶而突发的数据传输,而不是频频传输。

读取缓冲区数据长度好像是不可行的。如果要改为向固件要数据长度,还不如由固件主动发送传输开始通知和数据长度为好,PC有一线程始终处于监听该通知状态。
我想要点分,这样才有成就感嘛!
chrys
驱动小牛
驱动小牛
  • 注册日期2002-05-30
  • 最后登录2008-07-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2003-07-03 16:38
这个问题我已经解决了,代码如下:
m_hRead = CreateFile(
zjHMCFUsbFullName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
OVERLAPPED ol;
memset(&ol, 0, sizeof(OVERLAPPED));
ol.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
BOOL bRet = ReadFile(m_hRead,
data,
size,
(LPDWORD)&nBytesTransferred,
&ol);
if( !bRet && ERROR_IO_PENDING != GetLastError())
{
return -1;
}
if ( WaitForSingleObject ( ol.hEvent, 1000 ) != WAIT_OBJECT_0 )  //超时
return -1;
天才来自勤奋 知识要靠学习 [url= http://ndxz.126.com]――欢迎来我家做客――[/url]
游客

返回顶部