I am writing software to communicate between tablet (Motorola Xoom with Android version 4.0.3 and Kernel version 2.6.39.4) and a peripheral device using USB Host API provided by Android. I use only two types of communication:
controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)
Control transfer works fine, but I have a problem with bulk transfer. I can use only 32768 as a size of the buffer for bulkTransfer function. It is not possible to use less or more. I know that I cannot use more because of the limit of the buffer pipe (size: 32769 bytes).
This peripheral device streams data which is not correctly read by bulkTranfer function. I suppose that some data is lost.
I find this: In Linux If a process attempts to read from an empty pipe (buffer), then read(2) will block until data is available. If a process attempts to write to a full pipe , then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete.
And based on that, my explanation of the problem is that some data is not written to pipe (buffer) because of blocking flag made by write(2) function. Am I correct? If this is true I could change pipe buffer.
fcntl(fd, F_SETPIPE_SZ, size)
but how can I find fd
(file descriptor) for
USB pipes? ulimit -p SIZE
but parameter p
for my kernel is not for pipe but process.Has anyone faced the same problem, any solutions?
You should get a USB data analyzer, Im using this one: http://www.ellisys.com/products/usbex200/index.php
Using something like this really helped me when I was doing the same type of thing, what I found was that you had to do some type of while loop.
For my device I had 64 bytes of data coming in packets to me, the packet would be two control bytes and 62 for data, so for my transfer I had to do something like
StringBuilder sb = new StringBuilder();
while(bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout) > 2){
for(int i = 2; i < buffer.length(); i++){
sb.append((char) buffer[i]);
}
}
something a long these lines worked good for me, i had exactly the same issue and this is how I fixed it. I have more information if you need it. Just comment :). I know this was really frustrating for me to. Im using an Acer Iconia A500 with Android 4.0.3 btw
Transferring larger amounts of data USB
Transferring data USB
According to the same .pdf gfour posted, I found this paragraph in there:
"The size of the packet will affect the performance and is dependent on the data rate. For very high speed, the largest packet size is needed. For 'real-time' applications that are transferring audio data at 115200 Baud for example, the smallest packet possible is desirable, otherwise the device will be holding up 4k of data at a time. This can give the effect of 'jerky' data transfer if the USB request size is too large and the data rate too low (relatively)."
I'm running into a situation similar to SmartLemon with a FTDI Serial device, so I've been recently looking up ways to alleviate it. This will require me to pretty much write my own functions from scratch while previously I was using a library.
However, it seems that in your case, you could try using bulkTransfer's lowest buffer size instead of shooting for the biggest. You may have tried this already, but maybe not. I see that you say 32768 is the only size, but maybe you only meant the max. It seems weird that it'd only allow one specific size.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With