What is the right way to make a bulk read without overflow error?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
beskc_1176496
Level 1
Level 1

The FX3 SDK for Linux v 1.3.3 includes the example 07_bulkreader.c in which the API uses libusb_bulk_transfer (trivially wrapped) to receive 64 bytes from the device.

r = cyusb_bulk_transfer(h1, 0x83, buf, 64, &transferred, timeout * 1000);

Here a request is being made to fill buf with at most 64 bytes.

The documentation for libusb states that to avoid an overflow situation, the buffer and max length provided should be a multiple of the wMaxPacketSize attribute of the endpoint to avoid an overflow where the device returns more data than libusb can handle given the size of the buffer provided. Here, the right way to handle this according to libusb, is to make repeated calls to libusb_bulk_transfer with buffer size as a multiple of wMaxPacketSize. Unless the actual data returned is this wMaxPacketSize, the call will time out with the actual number of bytes transferred. A check needs to be made of the actual number of bytes returned and if this is less than expected, then the call has to be repeated until all the data has been read.

Not using a buffer that is a multiple of wMaxPacketSize, according to libusb, risks an overflow and this is something that I have seen.

lsusb reports that for the FX3 in our system, wMaxPacketSize is 1024 bytes.

Why doesn't the example included in the FX3 SDK use a multiple of wMaxPacketSize as recommended by libusb? Is this an oversight, or is this the right way and if it's the right way, then how can I avoid overlfows?

What is the right way to make a bulk read of a lot of data that avoids the risk of overflow?

0 Likes
1 Solution

Hi,

When the max packet size is 1024. Let's say you request 10KB from the Host, then

1) If the device responds with data less than 10KB but a multiple of 1024bytes, then the API will return only after timeout value

2) If the device responds with data less than 10KB but NOT a multiple of 1024 bytes, then API will return immediately with the data received and does not wait for the timeout.

So, in your case, when the 'size of data' of one set is less than 1024 then the API would return immediately so that you can make a new call immediately.

Please test the above cases.

Regards,

Hemanth

Hemanth

View solution in original post

0 Likes
3 Replies
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

Hi,

Since your wMaxPacketSize is 1024, you can make your buffer size a multiple of 1024 and request for a multiple of 1024 bytes of data (which is less than or equal to your buffer size)

If the device returns only partial data than requested but a multiple of 1024 bytes, then your libusb read request times out and you can get the partial data in your application. When time out happens it may mean that device currently has no further data. So further action in this case depends on your application.

If the device returns complete data which is requested, then get the data in your application and you can start queue new requests again.

Regards,

Hemanth

Hemanth
0 Likes

Thanks Hemanth

my application basically has two different sizes of data. A small size of data less than wMaxPacketSize and some other data much larger than wMaxPacketSize.

For the small data set, the libusb call will timeout then because the size returned is less than wMaxPacketSize. Is it correct to set a small timeout here so that the application doesn’t need to wait longer than needed? Perhaps in this case I’ll need to make multiple reads to get all the data because I timed out before the device had it all, but is it correct that this is the right way and there is just a tuning situation to balance the timeout provided vs the chance that I need to make multiple calls to get all the data?

Another possibility would be to reduce wMaxPacketLength to the size of the small data set. In this case we’d avoid the timeout situation above. If my large data is already orders of magnitude larger than wMaxPacketLength=1024 and I reduce wMaxPacketLength as explained, then am I correct in assuming that all this does is mean than for my large data I’ll need more packets for the transfer which will mean more overhead on the bus and longer duration.

Thank you for your guidance.

0 Likes

Hi,

When the max packet size is 1024. Let's say you request 10KB from the Host, then

1) If the device responds with data less than 10KB but a multiple of 1024bytes, then the API will return only after timeout value

2) If the device responds with data less than 10KB but NOT a multiple of 1024 bytes, then API will return immediately with the data received and does not wait for the timeout.

So, in your case, when the 'size of data' of one set is less than 1024 then the API would return immediately so that you can make a new call immediately.

Please test the above cases.

Regards,

Hemanth

Hemanth
0 Likes