wdm bulkusb or wdf usbsamp 问题,我将它改了,有时不会读到数据的大小为0

lovepingworking 2010-09-06 01:09:48
遇到一个问题,ReadFile的第三个参数(需要读取多长字节)小于设备实际返回长度的话,ReadFile函数返回的实际读取长度将是正确的(等于第三个参数的大小),但是当Usb 第3个参数大于实际返回的第4个参数时,则返回的实际读取长度始终为0,似乎是ReadFile就无法读取usb返回数据了。


/*****************************************************************************************
//函数功能:该函数的功能是通过异步的方式从端点6读取图像数据
*****************************************************************************************/
DWORD USB_Read(HANDLE handle, // Input 实参hPipe
PVOID pData, // Output 实参pBuff
DWORD dwLen, // Input //实参 size =一副图像的大小
PDWORD pLength, // Output //注意:实际传输的大小
DWORD dwMilliseconds) // Input 延迟
{
BOOL bResult;
DWORD nBytesRead;
OVERLAPPED gOverlapped;
DWORD dwResult;

dwResult = E_FALSE;

// set up overlapped structure fields
gOverlapped.Internal = 0;
gOverlapped.InternalHigh = 0;
gOverlapped.Offset = 0;
gOverlapped.OffsetHigh = 0;
gOverlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(pLength != NULL)*pLength = 0;

// attempt an asynchronous read operation
bResult = ReadFile(handle,pData,dwLen,&nBytesRead,&gOverlapped);
//现在的问题出在这里,由于某种原因,实际返回的字节<=dwlen ,当实际返回的字节=dwlen时,结果是正确的,能够正确读到数据,但是当实际返回的字节<dwlen 时,nBytesRead=0,即读不到任何数据.(此时bResult=1 nBytesRead=0)


//读是通过调用ReadFile函数异步调用的
if(!bResult)
{
// deal with the error code

switch (GetLastError())
{
case ERROR_HANDLE_EOF:
{
// we have reached the end of the file
// during the call to ReadFile
break;
}
case ERROR_IO_PENDING:
{
// asynchronous i/o is still in progress
switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds))
{
case WAIT_OBJECT_0:
// check on the results of the asynchronous read
// and update the nBytesRead...
bResult = GetOverlappedResult(handle, &gOverlapped,
&nBytesRead, FALSE);
if(bResult)
{
if(pLength != NULL)
*pLength = nBytesRead;
dwResult = E_OK;
}//end if else
break;
case WAIT_TIMEOUT:

CancelIo(handle);
break;
default: //switch(WaitForSingleObject(gOverlapped.hEvent, dwMilliseconds))
CancelIo(handle);
break;
}//end switch
break; //switch (GetLastError()) case ERROR_IO_PENDING
}//end case
default:
CancelIo(handle);
break;
}//end switch
}
else
{
if(pLength != NULL)
*pLength = nBytesRead;

dwResult = E_OK;
}//end if else

ResetEvent(gOverlapped.hEvent); //重设事件
CloseHandle(gOverlapped.hEvent);
return dwResult;
}


请高手帮忙看下,理论上,当nBytesRead 应该为实际读到的字节啊,怎么为0,难道当实际读到字节为0时,就不读吗,在这种情况下,如果我吧dwlen 改小,小于实际返回的字节时,就可以读到数据,此时nBytesRead =dwlen

不知道什么原因了,迷茫中,请大家帮忙看看。
...全文
289 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
smilestone322 2010-10-07
  • 打赏
  • 举报
回复
注意usb协议,usb传输结束有2种情况,一种是收据收全,一种是收到0包或者short包
OneOnce 2010-09-09
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 lovepingworking 的回复:]
OneOnce 我说的是超时时能否返回 实际独到的数据的长度,呵呵,麻烦试验一下。
[/Quote]

读到数据的长度?但是没有那么多数据?是不是这样理解?
lovepingworking 2010-09-08
  • 打赏
  • 举报
回复
OneOnce 我说的是超时时能否返回 实际独到的数据的长度,呵呵,麻烦试验一下。
OneOnce 2010-09-06
  • 打赏
  • 举报
回复
我下午也用异步读写试过了,如果超时时间为50ms的话,写30000个字节就会出现超时的问题,100ms就不会出现超时问题。
你有1-2帧收不到,试着把超时时间设长一些呢?
当然可以返回比端点Maxbuffer小的数据,我可以读写任意个字节数据。端点最大包多少基本没有太大关系。
lovepingworking 2010-09-06
  • 打赏
  • 举报
回复
呵呵,CreateFile 里面用了File_Flag_overlapped结构,这个我还是明白的,我的驱动不是每次都收不到数据,100帧里面有98帧是可以收到数据的,就1-2帧收不到数据而已,所以我搞不懂是什么原因,你的硬件能够返回小于端点Maxbuffer的包吗,比如说usb的端点的最大包是512个字节,你的硬件可以返回小于512字节的包,或者返回0的包也行。
OneOnce 2010-09-06
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lovepingworking 的回复:]
#define MAX_TRANSFER_SIZE 2014208
[/Quote]

你那个也太大了吧,不用那么大,你上面数据多可以for循环一下。
然后你CreateFile倒数第二个参数有没有使用FILE_FLAG_OVERLAPPED?因为你是异步操作的?
lovepingworking 2010-09-06
  • 打赏
  • 举报
回复
#define MAX_TRANSFER_SIZE 2014208
lovepingworking 2010-09-06
  • 打赏
  • 举报
回复
那个地方我已经改大了,呵呵,直接改成2014208了,两个都有问题,wdf和wdm
OneOnce 2010-09-06
  • 打赏
  • 举报
回复
BULKUSB_MAX_TRANSFER_SIZE改大点,直接改成1024吧

我看到你是使用异步的,这个我还没试过,异步会有一些问题。
你现在使用的是WDM还是WDF得?
OneOnce 2010-09-06
  • 打赏
  • 举报
回复
刚来啊
lovepingworking 2010-09-06
  • 打赏
  • 举报
回复
oneonce 人呢:
hello ,my dear friend,thank you for you answer in "is it the bug of wdk and
wdm",and now I post a new thread to summarize the subject which discussed some
day ago.

At first,I introduce the background of my driver. this is a Camera
driver,and I Communication with the hardware through communication
protocol,First i build a vendor request and Send a setup packet,and listen the
Endpoint ,then read the dada.The hardware receive my request and prepare send
dada.the hareware buffer is 2K,and every time fill 512 bytes in it ,and it fill
the buffer whether the data read or not. if the read speed is slower,then the
dada will be cover with,at this time,it will be receive not enough dada.
and the camera driver must judge whether the dada is enough or not ,when it not
enough ,I will send a request to the hardware ,and the hardware send the dada
again.

I change the wdk's usbsamp for my Camera driver,and use bulk transfer.
my application pragram set the buffer equal to the driver's
MAX_TRANSFER_SIZE, it is run well usually, but when the request timeout,I can
not receive any datas,the transfer size is zero.

And now ,there are some problem with it ?

(1) I am modify the wdk's usbsamp driver for my camera device ,and the
application buffer is 2014208 bytes. I change usbsamp's MAX_TRANSFER_SIZE to
2014208,and usually run well,but some time IO request timeout ,and at this time
,it can not receive any datas.

(2)if the device send dada size less than the MAX_TRANSFER_SIZE of driver,at
this time ,is it the driver can not receive any dada?

(3) I change MAX_TRANSFER_SIZE to 512,or 2048, It timeout every time ,but it
can return some data which less than 2014208. I am confused why
MAX_TRANSFER_SIZE influence the results? and when MAX_TRANSFER_SIZE is
smaller,it every time timeout ,is it stand for call Complete routine need much
time. so I modify MAX_TRANSFER_SIZE to 2014208,at this time ,only call complete
routine one time. but when it timeout ,will receive no dada.

(4)Chris Aseltine say" I suspect you've sent down a request for 2MB
down to USB, and the device has responded with some fraction of that which is an

exact multiple of the endpoint's maximum packet size. Since the device did not
send a short packet, the transfer never completed."
yes, the hardware not send a short packet or zero packet,but now the camera
usually run well ,and sometime can not receive any data? why?

(5)and thanks for Tim Roberts,you say "Well, here is a question for the KMDF
folks. If I submit a USB requestand set a timeout in the
WDF_REQUEST_SEND_OPTIONS, will I be able torecover whatever partial buffer had
been transferred by the time of the timeout? I've never had occasion to test
that." ,I think it is a good topic to discuss?

(6)Tim Roberts say "Interesting. There must be a solution for this, because
there are
situations in USB that cannot be reasonably handled in any other way. Consider a
device that sends between 100k and 200k bytes at random(potentially long)
intervals. You can't afford to send a bazillion 512-byte requests because of
the overhead. You need to send a larger request, but then you need a way to
bring back the partial buffer after
a timeout. " it is a good topic to discuss ,because my device run well in linux
,and my hardware team say it is not the device problem because of this ,and say
it driver problem or windows system problem.

(7)thank you Peter Viscarola,and you say "OR, he COULD just hang a bunch of 512
byte packets out there... since his device isn't transferring short blocks,
those packets would be completely filled by a transfer, right?? Isn't that what
we're talking about? ",to you answer,i will say ,though it not send a short
parket or zero parket ,but in my opinion,it will receive some dada,because It is
already send some dada before receive short parket or zero parket .

(8) and Hagen Patzke says
"Well, here Chris is backed by the USB 2.0 spec, section 5.8.3:
> A bulk transfer is complete when the endpoint does one of the
> following: ? Has transferred exactly the amount of data expected ?
> Transfers a packet with a payload size less than wMaxPacketSize or
> transfers a zero-length packet
" thank you Hagen Patzke ,I have a question ,if the device not send a short
packet or zero packet,and when it lose some dada ,is it the application program
can not receive any dada? thank you ?

(9)and some people suggest me to receive 512 bytes every time ,but I test it
,every time timeout ,and Tim Roberts says " For a 2M transfer, you'retalking
about 4,000 IRPs, and they will be completed at a rate of 120 per millisecond.
For one frame, you could do it, but if you're streaming, it can't be done. You
can't sustain it" and I say before ,I reduce the max_transfer_size to 512
bytes,and also timeout,because so many complete route.

(10)thank you Peter Viscarola ,you say "TOTALLY right. Shit flows down hill,
and it's us driver devs who are perennially at the bottom of that hill looking
up. OS problem? We get to work around it. Bug in the silicon? We get to
compensate for it. Firmware deficiency? Fix it up. And when these things
don't work, it's ALWAYS our fault."
I agree with you standpoint ,and my hardware say my device run well in linux
,so it you problem.

thank you ,every one,and welcome every body discuss this problem with me ?

thank you very much indeed.

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧