Linux, USB serial, and MS/TP timing

MS/TP assumes a quiet, predictable serial path. On Linux that means: the right driver, a stable device path, and low USB-UART latency.

Stable device names

USB serial nodes renumber (ttyUSB0 → ttyUSB1) after replug or reboot. Persist only:

/dev/serial/by-id/usb-...

Record vendor/product IDs and the by-id link in lab notes. See Waveshare USB TO RS485 C.

Permission to open the port (dialout)

Linux often requires your user to be in the dialout group before a program can open /dev/ttyUSB*. After a fresh install or reboot, “Permission denied” usually means you are not in that group yet:

groups                    # look for dialout
sudo usermod -aG dialout $USER
# log out and back in, then retry

A full beginner story of a lab listen (including this gotcha) is How we prove the live MS/TP trunk.

Why USB latency matters

Many FTDI adapters default to a 16 ms latency_timer. For BACnet confirmed services over a router hop, that can turn into multi-second tool timeouts. This project ships:

  • a small helper (scripts/set-ftdi-latency.sh) that sets latency_timer to 1 ms
  • udev rules installed into the Buildroot image for common FTDI / WCH adapters

On a live lab host you can inspect:

ls -l /dev/serial/by-id/
cat /sys/bus/usb-serial/devices/*/latency_timer

Baud and topology

  • Allowed bauds in config: 9600…115200; lab default 38400.
  • Exactly one process should own the tty.
  • Endpoint termination (often 120 Ω) must match the physical trunk; do not add a third terminated adapter mid-span without a plan.
  • Passive decode / observe before transmitting on an unknown trunk.

BIP oracle host vs router host

When testing routed traffic, the BACnet/IP client (oracle, Workbench, bacpypes) must bind on a different host or IP than the router’s BACnet/IP socket. Same-host or macvlan-on-parent demux mistakes look like “Timeout” or “unknown route” even when the MS/TP side is fine.

Further reading