Low USB connection latency on Teensy 3.5

Status
Not open for further replies.

MrQz

New member
Hi,

I am measuring Round Trip times (RTT) for the USB connection between an Android phone and Teensy 3.5 (with the USB type set as "Serial"). The "problem" I’d like to understand is why the minimum latency is generally between 170-300us which is far less than the expected >1ms (which is the USB polling interval defined for the full-speed USB, as available in the Teensy). I’ve established a bulk transfer connection type between the devices (through the on-the-go USB cable, hosted by the phone). The USB interface towards the Teensy is the following:

Code:
UsbInterface[mId=1,mAlternateSetting=0,mName=null,mClass=10,mSubclass=0,mProtocol=0,mEndpoints=[
                                         UsbEndpoint[mAddress=3,mAttributes=2,mMaxPacketSize=64,mInterval=0]
                                         UsbEndpoint[mAddress=132,mAttributes=2,mMaxPacketSize=64,mInterval=0]]

The polling interval (mInterval) is set to "0" but based on USB specifications it is ignored for the bulkTransfer type so apparently this does not contribute to the issue.

Latency is measured in phone as the interval between timestamps taken immediately before sending a USB package and immediately after receiving the corresponding response from the Teensy. Only one byte of data is transmitted from Android to Teensy. Teensy responds to the request by sending a timestamp (as a String) using
Code:
Serial.write(data.c_str(), data.length());
followed by
Code:
Serial.send_now();
A random delay of 2-10ms (or even more!) between each RTT measurement round is added in the phone to eliminate the effect of a possible data buffering.

I’m more than happy to achieve such a small connection latency between the devices and would like to understand why this is possible. Does it have something to do with the way the USB serial communication has been implemented in Teensy? There is a lot of related information available (for example at https://www.pjrc.com/teensy/td_serial.html) but unfortunately I haven’t been able find any documentation which would explain latencies under 1ms for this kind of setup.


Thank you in advance!

Br, -=Markus=-
 
The "problem" I’d like to understand is why the minimum latency is generally between 170-300us which is far less than the expected >1ms

USB serial uses bulk endpoints for data transfer.

The USB host controller allocates nearly all of the USB bandwidth not consumed by interrupt and isochronous pipes to round-robin style polling of bulk and control pipes. On a light loaded USB controller, on average a bulk endpoint will be polled many times per frame.

There are a pretty incredible number of complex details at play. Even the type of controller can be different, usually OHCI if directly connected versus EHCI if connected through a hub. EHCI (480 Mbit/sec) schedules bandwidth in 125 us microframes, and communication to slower devices is actually done in split transactions to a hub, where the transaction translator within the hub actually does the communication with Teensy.

Non-realtime scheduling of user level processes also can play a big factor.
 
Hi,

Thank you for your answers and the links! The big picture is getting clearer now! Just like you Paul said, different controllers contribute to the equation as well as based on the reference from "USB Complete Fourth Edition : The Developer's Guide (Complete Guides series)" by Jan Axelson:

when the bus is otherwise idle, bulk transfers can use the most bandwidth of any type and have low overhead and thus are the fastest of all. When a full-speed bulk endpoint’s maximum packet size is less than 64, some host controllers schedule no more than one packet per frame even if more bandwidth is available.
She later clarifies that
a UHCI driver attempts no more than one transaction per frame, while an OHCI driver may schedule additional transactions in a frame
. The outcome:
Thus for best performance, a full-speed bulk endpoint should have a maximum packet size of 64.
Luckily packet size is set as 64 for the USB serial type in our case.

Maybe we could list prerequisites for a full speed USB device (like Teensy 3.5) to achieve sub-millisecond communication latencies:

- a high speed USB hub on the host device (to enable utilisation of the higher polling interval, ie. 125us per microframe)
- a device compatible with bulk transfer communication (Teensy using the USB serial communication [USB device class 02h: communication device class, CDC] and a full-speed bulk endpoint set with a maximum packet size of 64)
- perform data exchange between devices using bulk transfers
- otherwise idle bus (to allocate rest of the bandwidth for bulk transfers and use split transactions [in the microframe granularity])
- use Serial.send_now() to transmit any buffered data from Teensy as soon as possible


Please feel free the add/modify/remove items if something is missing/doesn't make sense/is irrelevant. I hope this helps others in achieving sub-millisecond latency in data communication!


Br,
-=Markus=-
 
Last edited:
Not a big deal, certainly not offended. ;)

But I see so many people in the tech community extrapolate the gender imbalance to assume women don't make meaningful contributions. They may be a minority, but many women like Jan have indeed done a lot of good for everyone. The women who do weather the social challenges tend to be very exceptional people.

I believe it's worthwhile to at least recognize their valuable contributions, which so often invisible, mistakenly assumed to be the work of men.
 
Status
Not open for further replies.
Back
Top