Project

General

Profile

Actions

Feature #14169

open

usbftdi should set/support setting the FTDI latency timer

Added by Thirteen Oxide over 1 year ago. Updated over 1 year ago.

Status:
New
Priority:
Normal
Category:
driver - device drivers
Start date:
Due date:
% Done:

0%

Estimated time:
Difficulty:
Bite-size
Tags:
Gerrit CR:
External Bug:

Description

FTDI's USB serial chips support a pair of control commands to get and set the latency timer. The default is 16 ms, which seems to end up in the total latency of sending or receiving data; one can read a bit about this at https://projectgus.com/2011/10/notes-on-ftdi-latency-with-arduino/ and https://www.ftdichip.com/Support/Knowledgebase/index.html?an232beffectbuffsizeandlatency.htm (a more formal app note is at http://www.ftdichip.com/Documents/AppNotes/AN232B-04_DataLatencyFlow.pdf), and https://github.com/torvalds/linux/blob/8fe31e0995f048d16b378b90926793a0aa4af1e5/drivers/usb/serial/ftdi_sio.h#L302-L350. As you'd expect from the last link, the Linux driver supports these commands and exposes them to userland rather unhelpfully via their sysfs.

Why is this important? It has a very substantial effect on performance, at least with some traffic patterns. The default value of 16 ms allows Xmodem transmission using 1 KiB blocks over a 3 Mbit/s link at approximately 60 KiB/s; at 1 ms the same link and protocol will support ~220-250 KiB/s. This is because Xmodem has no sliding window or deferred acknowledgement: after each 1 KiB block is sent, the sender waits for a 1-byte ack from the receiver. Other applications (including interactive ones) with similar properties will suffer similarly from this added latency.

It's be nice to expose this as an ioctl, or perhaps to try setting it ourselves heuristically based on baud rate, but unfortunately an ioctl would require changing user software so I'm not sure what the most useful way is to expose it. The grossest kludge, similar to Linux's, would be a driver.conf parameter; note that we already have a comparable kludge there in the form of ignore-cd.

Actions #1

Updated by Joshua M. Clulow over 1 year ago

  • Assignee set to Joshua M. Clulow
Actions #2

Updated by Joshua M. Clulow over 1 year ago

I have produced a test program that uses two FTDI devices wired together on the same host. It sends a single byte ping with a random value into the first port, and waits for it to arrive on the second port. We confirm that the sent value matches the received value and then aggregate timing statistics in a sliding window.

With the stock driver, one can definitely see the 16ms timer in effect:

$ /tmp/serialping
ping/sec   64 avg  15.81   max  16.01   min   8.82   cur  15.92
ping/sec   63 avg  15.87   max  16.01   min   8.82   cur  15.94
ping/sec   63 avg  15.92   max  15.97   min  15.68   cur  15.93
ping/sec   63 avg  15.92   max  15.98   min  15.68   cur  15.92
ping/sec   63 avg  15.93   max  15.99   min  15.86   cur  15.93
ping/sec   63 avg  15.93   max  15.99   min  15.84   cur  15.93
ping/sec   63 avg  15.92   max  15.98   min  15.84   cur  15.92
ping/sec   63 avg  15.92   max  16.03   min  15.83   cur  15.93
ping/sec   63 avg  15.92   max  16.03   min  15.82   cur  15.92
ping/sec   63 avg  15.92   max  16.00   min  15.79   cur  15.93
ping/sec   63 avg  15.92   max  16.00   min  15.79   cur  15.93
ping/sec   63 avg  15.93   max  16.01   min  15.83   cur  15.95
ping/sec   63 avg  15.93   max  16.01   min  15.83   cur  15.92
ping/sec   63 avg  15.92   max  15.99   min  15.84   cur  15.92

With a modified driver, with the timer set to its minimum value of 1ms, the situation is much improved:

$ /tmp/serialping
ping/sec  753 avg   0.97   max   0.99   min   0.90   cur   0.97
ping/sec 1002 avg   0.97   max   0.99   min   0.91   cur   0.97
ping/sec 1002 avg   0.97   max   0.99   min   0.91   cur   0.97
ping/sec 1002 avg   0.97   max   0.98   min   0.92   cur   0.98
ping/sec 1002 avg   0.97   max   0.98   min   0.90   cur   0.96
ping/sec 1002 avg   0.97   max   0.98   min   0.91   cur   0.97
ping/sec 1002 avg   0.97   max   0.98   min   0.91   cur   0.97
ping/sec 1002 avg   0.97   max   0.98   min   0.91   cur   0.97
ping/sec 1002 avg   0.97   max   0.98   min   0.91   cur   0.91
ping/sec 1002 avg   0.97   max   0.98   min   0.90   cur   0.97
Actions

Also available in: Atom PDF