From 07d92f482ba4b5b717e9fd8ba099fd6d2195cd78 Mon Sep 17 00:00:00 2001 From: kai-morich Date: Sun, 6 Sep 2020 17:19:19 +0200 Subject: [PATCH] document read buffer sizing --- Troubleshooting.mediawiki | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/Troubleshooting.mediawiki b/Troubleshooting.mediawiki index de05f89..d0a9e61 100644 --- a/Troubleshooting.mediawiki +++ b/Troubleshooting.mediawiki @@ -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 \n (or any other "terminal" character). -== I observed read ''data loss'' with continuous transfer at high baud rates == +== I observed read ''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 … 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. -Using a higher thread priority for SerialInputOutputManager (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 onNewData 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 onNewData to other threads can mitigates the issue. + +''Data loss'' can also occur with inappropriate buffer size, as shown in next Question. -== Is write synchronous? == +== How to size the read 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, read 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 -# from usb device to serial port +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]. -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. +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. == How to set timeout in read/write methods? == @@ -90,6 +89,20 @@ If you read 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. +== Is write 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? == If your framework can import Java .jar files, look [[Build-Variants#Jar|here]] for instructions about creating a .jar file.