1
0
mirror of https://github.com/mik3y/usb-serial-for-android synced 2025-09-10 17:37:40 +00:00

document read buffer sizing

kai-morich 2020-09-06 17:19:19 +02:00
parent 818e6da879
commit 07d92f482b

@ -46,28 +46,27 @@ For example, to receive a 100 byte string, you might read 64 bytes, then 36 byte
* Newline-terminated messages: Read until you see a <code>\n</code> (or any other "terminal" character). * Newline-terminated messages: Read until you see a <code>\n</code> (or any other "terminal" character).
== I observed read ''data loss'' with continuous transfer at high baud rates == == I observed <code>read</code> ''data loss'' with continuous transfer at high baud rates ==
Android is not a real time OS. The thread responsible for receiving data might not be scheduled by the OS or garbage collection might be ongoing or … Android is not a real time OS. The thread responsible for receiving data might not be scheduled by the OS or garbage collection might be ongoing or …
Therefore data loss can happen for continues read at high baud rates. If data is lost, typically some smaller fragments in the middle of the data are missing. Therefore data loss can happen for continues read at high baud rates. If data is lost, typically some smaller fragments in the middle of the data are missing.
This effect is more likely for slower Android device and USB devices with smaller buffer size and typically starts with higher baud rates like 115k2 baud, but is hardly predictable. For low baud rates or non-continuous transfers this issue was not observed as the USB device will not run into a read buffer overflow before the next USB read transfer. This effect is more likely for slower Android device and USB devices with smaller buffer size and typically starts with higher baud rates like 115k2 baud, but is hardly predictable. For low baud rates or non-continuous transfers this issue was not observed as the USB device will not run into a read buffer overflow before the next USB read transfer.
Using a higher thread priority for <code>SerialInputOutputManager</code> (as used [https://github.com/mik3y/usb-serial-for-android/blob/73d669c4dc9af4bccdfdd35b1ff4d8e6c9c16ce9/usbSerialForAndroid/src/androidTest/java/com/hoho/android/usbserial/util/UsbWrapper.java#L164 here] and offloading work from <code>onNewData</code> to other threads sometimes mitigates the issue. Using a higher thread priority (default since ''usb-serial-for-android v3.1.0'') and offloading work from <code>onNewData</code> to other threads can mitigates the issue.
''Data loss'' can also occur with inappropriate buffer size, as shown in next Question.
== Is <code>write</code> synchronous? == == How to size the <code>read</code> buffer? ==
It's typically not. All supported devices use a packet size of 64 bytes, so you should use a multiple of 64 bytes.
Write consists of 2 phases: A shorter size is ok, as long as the received messages fits into the buffer. If it doesn't fit into the buffer, <code>read</code> returns an empty result. Due to poor error propagation in Android USB code, this cannot be distinguished from timeout or real communication errors.
# from android to usb device Using a large buffer can make your app lagging. In particular FTDI devices tend to queue data until the buffer is completely filled on continous transfer at higher baud rates. This can be mitigated by choosing appropriate buffer sizes and setting the latency timer as also recommended by [https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjTp5fQ5tTrAhVP_KQKHQNcAwQQFjABegQIAxAB&url=http%3A%2F%2Fwww.ftdichip.com%2FSupport%2FDocuments%2FAppNotes%2FAN232B-04_DataLatencyFlow.pdf&usg=AOvVaw25BTFYId5BMobgEVDZblku FTDI].
# from usb device to serial port
If the send buffer on the usb device is not full, the write call returns after phase 1. If the buffer is full, e.g. your write is larger or older data is still to be send, the write call returns when enough data has been send over the serial port and the rest is in the buffer. For FTDI devices you have to take into account that each 64 byte response starts with 2 header bytes. The header bytes will be stripped from the final result.
Waiting for write completion is typically done with application specific protocols, like request-response pattern.
== How to set timeout in <code>read</code>/<code>write</code> methods? == == How to set timeout in <code>read</code>/<code>write</code> methods? ==
@ -90,6 +89,20 @@ If you <code>read</code> with very short timeout, e.g. 10 msec, the actual USB t
Android is not a realtime OS, e.g. garbage collection can easily take 100 msec. Android is not a realtime OS, e.g. garbage collection can easily take 100 msec.
== Is <code>write</code> synchronous? ==
It's typically not.
Write consists of 2 phases:
# from android to usb device
# from usb device to serial port
If the send buffer on the usb device is not full, the write call returns after phase 1. If the buffer is full, e.g. your write is larger or older data is still to be send, the write call returns when enough data has been send over the serial port and the rest is in the buffer.
Waiting for write completion is typically done with application specific protocols, like request-response pattern.
== Does this library work with Ionic/Cordova/Xamarin/App Inventor/... development framework? == == Does this library work with Ionic/Cordova/Xamarin/App Inventor/... development framework? ==
If your framework can import Java .jar files, look [[Build-Variants#Jar|here]] for instructions about creating a .jar file. If your framework can import Java .jar files, look [[Build-Variants#Jar|here]] for instructions about creating a .jar file.