阅读:2302回复:16
应用程序在读usb数据时,如果没有数据可读,程序就被阻塞了,为何?
我是参照ddk的一个Bulk_usb驱动例子写了一个usb驱动程序,现在我想在应用层通过ReadFile()去读取usb上的数据,当有数据读时倒还好,如果usb设备没有数据时,ReadFile()就不能立即返回了,程序被阻塞在ReadFile()这个地方,以至于整个应用程序都不能退出,只有重启机器才行,请问有什么办法让ReadFile()在读usb数据时不阻塞吗?就是说调用ReadFile()时有多少数据就返回多少数据,没有数据就返回0,而不要阻塞在这里,什么事情都做不了。
|
|
最新喜欢:![]()
|
沙发#
发布于:2003-07-02 08:26
没有数据是不能自动返回的,不过你可以用RESET实现啊,让USB重新枚举一下应该可以的。
|
|
板凳#
发布于:2003-07-02 08:59
加上超时控制,超时 reset 设备。
|
|
|
地板#
发布于:2003-07-02 10:20
可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。
有更好的办法,欢迎补充. |
|
|
地下室#
发布于:2003-07-02 15:07
ap 中用异步读,ReadFileEx。
|
|
|
5楼#
发布于:2003-07-02 16:29
ap 中用异步读,ReadFileEx。 这种方式我试了一下,结果是一样的,仍然不行。 |
|
|
6楼#
发布于:2003-07-02 16:33
可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。 看得出来,你是个高手,请教你一下: 1、“改用ISO同步方式”是指应用程序还是指驱动程序,该怎么改? 2、如何实现“当底层有数据时通过其它端点发送接收通知”? 麻烦你了! |
|
|
7楼#
发布于:2003-07-02 21:42
改用isochronous方式或使用额外的endpoint通知都需要硬件、驱动
都支持才行。 使用异步读应该是可以避免ReadFile阻塞的问题的, 你有在CreateFile时指明使用异步方式吗? |
|
8楼#
发布于:2003-07-03 09:12
用户被禁言,该主题自动屏蔽! |
|
9楼#
发布于:2003-07-03 09:44
有一个简单的办法。我也是你这样想的,可我在WDM driver中怎么知道底层有多少字节的数据要传输呢? |
|
|
10楼#
发布于:2003-07-03 10:10
用户被禁言,该主题自动屏蔽! |
|
11楼#
发布于:2003-07-03 10:21
不是你的WDM driver知道,而是让你的WDM driver通过ep0问你的Device有多少东西要传,然后在ReadFile.你说的“让你的WDM driver通过ep0问你的Device有多少东西要传”是怎么实现的呢?就是说我怎么知道device有多少数据要传呢? |
|
|
12楼#
发布于:2003-07-03 10:54
可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。 \"当底层有数据时通过其它端点发送接收通知然后才Readfile。\",这样的方法会不会太慢了,用在测试还可以,实际中不可能吧。 我觉得是不是可以这样,在readfile的响应函数中先读一下缓冲区数据长度,为0直接退出。 |
|
|
13楼#
发布于:2003-07-03 10:59
[quote]可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。 \"当底层有数据时通过其它端点发送接收通知然后才Readfile。\",这样的方法会不会太慢了,用在测试还可以,实际中不可能吧。 我觉得是不是可以这样,在readfile的响应函数中先读一下缓冲区数据长度,为0直接退出。 [/quote]你说的“先读一下缓冲区数据长度”我不懂,怎么读到缓冲区数据的长度,请问??? |
|
|
14楼#
发布于:2003-07-03 11:54
这个问题我也遇到了,而且驱动我是直接用芯片公司的,我是否可以只是通过应用程序来个超时等待,因为我问过cypress公司了,他们的回答就是这样,但是超时等待怎么着手啊。
|
|
15楼#
发布于:2003-07-03 16:35
[quote]可以有两个方法:改用ISO同步方式,或者当底层有数据时通过其它端点发送接收通知然后才Readfile。 \"当底层有数据时通过其它端点发送接收通知然后才Readfile。\",这样的方法会不会太慢了,用在测试还可以,实际中不可能吧。 我觉得是不是可以这样,在readfile的响应函数中先读一下缓冲区数据长度,为0直接退出。 [/quote] 这个方法倒不慢,只是使用的场合是偶而突发的数据传输,而不是频频传输。 读取缓冲区数据长度好像是不可行的。如果要改为向固件要数据长度,还不如由固件主动发送传输开始通知和数据长度为好,PC有一线程始终处于监听该通知状态。 |
|
|
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; |
|
|