quakeforever
驱动牛犊
驱动牛犊
  • 注册日期2004-05-09
  • 最后登录2005-01-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3034回复:12

求助:usb异步读写数据

楼主#
更多 发布于:2004-07-20 14:46
最近搞一个usb设备,直接使用Cypress的那个usb驱动示例ezusbsys.sys作为驱动,读写数据都可以,但如果usb设备没有数据,则DeviceIoControl函数无法返回,即便关闭程序也没有用,除非拔了设备,或让usb设备发送数据――请大家帮忙:怎样能够使得读不到数据也能让DeviceIoControl返回。

打开设备如下所示:
char szDeviceName[256] = ".Ezusb-0";
m_hIDComDev = CreateFile(szDeviceName, GENERIC_READ | GENERIC_WRITE,  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
memset( &m_OverlappedRead,  0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_OverlappedRead.hEvent  = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

下面开始读数据:
BYTE pBuffer[1024];
DWORD nBufferSize = 4;
BULK_TRANSFER_CONTROL btc;
btc.pipeNum = 1;
if (!DeviceIoControl(m_hIDComDev, IOCTL_EZUSB_BULK_READ, &btc,sizeof (BULK_TRANSFER_CONTROL),pBuffer, nBufferSize,&nBufferSize,&m_OverlappedRead))
//这里,如果usb没有数据则函数无法返回
{
if( GetLastError() == ERROR_IO_PENDING )
{
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}

while(WaitForSingleObject(m_OverlappedRead.hEvent,100)==WAIT_TIMEOUT)
{
if(!m_bOpened)
{
//Cancel the pending read
CancelIo(m_hIDComDev);
return 0;
}
}

if(!GetOverlappedResult(m_hIDComDev, &m_OverlappedRead, &dwBytesRead, FALSE))
{
return 0;
}


[编辑 -  7/20/04 by  quakeforever]

最新喜欢:

worldwarworldw...
tomjin
驱动牛犊
驱动牛犊
  • 注册日期2002-12-16
  • 最后登录2006-03-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-07-20 16:15
你说的:
----------------------------------------------------------
但如果usb设备没有数据,则DeviceIoControl函数无法返回,即便关闭程序也没有用
---------------------------------------------------------
应用程序造成死机乐吗??
quakeforever
驱动牛犊
驱动牛犊
  • 注册日期2004-05-09
  • 最后登录2005-01-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-07-20 16:22
如果使用DeviceIoControl读数据时,usb设备没有数据可读,则DeviceIoControl就不会返回,此时关闭程序(即使是杀进程)都无法退出程序,一直等到从usb设备能够读到数据或者将设备从pc上拔出。
tomjin
驱动牛犊
驱动牛犊
  • 注册日期2002-12-16
  • 最后登录2006-03-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-20 16:28
DeviceIoControl这个函数我没有用过,不过按照你的说法,这种IO
读取是一种阻塞式的,应用程序发出io请求后等到有数据才完成返回
。你可以试一试改异步IO读取方式。
quakeforever
驱动牛犊
驱动牛犊
  • 注册日期2004-05-09
  • 最后登录2005-01-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-07-20 16:32
对,我是想用异步IO读取方式
但看msdn上帮助,我现在用的应该是异步读取,不知道是不是还有什么操作没有执行或什么参数没有设置正确?
lejianz
驱动中牛
驱动中牛
  • 注册日期2003-03-05
  • 最后登录2023-11-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望145点
  • 贡献值0点
  • 好评度116点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2004-07-20 16:33
你可以开一个线程来读数据,当然用OVERLAPPED的方式也不错,找一个好的例子来参考一下吧。
一起交流,共同提高!
quakeforever
驱动牛犊
驱动牛犊
  • 注册日期2004-05-09
  • 最后登录2005-01-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-07-20 16:39

-----------------------------------------------------------
lejianz

你可以开一个线程来读数据,当然用OVERLAPPED的方式也不错,找一个好的例子来参考一下吧。
-----------------------------------------------------------

这个估计和开线程没有关系,我在网上找过,但没找到什么例子,所以到这儿来请教大家。
tomjin
驱动牛犊
驱动牛犊
  • 注册日期2002-12-16
  • 最后登录2006-03-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-07-20 16:56
线程的开辟好像能保证你能连续不断的读数据,
如果仅仅为了读数据,可以用函数ReadFile啊,在其参数中要用OVERLAPPED的
quakeforever
驱动牛犊
驱动牛犊
  • 注册日期2004-05-09
  • 最后登录2005-01-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-07-20 17:44
使用线程应该只能保证不会因为读usb数据而导致主线程阻塞吧?
使用DeviceIoControl是因为我用到
BULK_TRANSFER_CONTROL btc;
btc.pipeNum = 1;//为1时用来读数据,为0用来写数据,
作为参数传递给DeviceIoControl,而使用ReadFile、WriteFile我不清楚该如何操作,请高手指点一二!
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-07-20 22:11
你的driver要先返回STATUS_PENDING然后再发送urb。

[编辑 -  7/20/04 by  rayyang2000]
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
windrv
驱动牛犊
驱动牛犊
  • 注册日期2004-07-05
  • 最后登录2004-07-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-07-21 09:18
The multi-thread doesn't matter and asynchronous ReadFile(), WriteFile() do not help either.

The problem is that EZUSB.sys blocks IRP/URB reading/writing operations if device doesn't respond. User mode solution helps nothing.

To fix the problem, you have to improve the Cypress driver EZUSB.sys to add a "timeout" feature of reading/writing pipes in the driver. ( function Ezusb_CallUSBD())

Another solution is, when your application calls DeviceIoControl(), it finally calls function Ezusb_CallUSBD() in the driver. On this code path, if IoCallDriver() returns STATUS_PENDING in Ezusb_CallUSBD(), don't wait for the event, return to caller directly. So you is able to use your asynchronous DeviceIoControl() in application level, but you must pay attention on IRP cleanup when it is completed.


[编辑 -  7/21/04 by  windrv]
quakeforever
驱动牛犊
驱动牛犊
  • 注册日期2004-05-09
  • 最后登录2005-01-27
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-07-21 09:42
感谢各位的帮助,我现在已经解决了这个问题(应该说是绕过了这个问题)
方法是
将读数据放在一个线程里进行,

当要停止读usb数据时,主线程调用
ULONG pipe = 1;
DWORD nBufferSize = 0;
DeviceIoControl(m_hIDComDev, IOCTL_EZusb_ABORTPIPE, &pipe,sizeof(ULONG),NULL, 0,&nBufferSize, NULL);
DeviceIoControl(m_hIDComDev, IOCTL_EZusb_RESETPIPE, &pipe,sizeof(ULONG),NULL, 0,&nBufferSize, NULL);

这样就可以取消阻塞住的读数据操作了,这样我关闭程序也可以退出了,开线程来读数据可以使得主线程不会因此而阻塞。

再次感谢各位的帮助!
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-07-21 10:54
如果你想尝试异步方式,可以参考DDK的例子Bulkusb里的Bulkusb_Read和Bulkusb_Write函数
游客

返回顶部