Skip to main content
Open a streaming session against a serial port on the box and drive your DUT’s console from a test.

Enabling the feature

UART sessions ride on Socket.IO, so they are behind a cargo feature:
The uart feature implies blocking. For AsyncUart, enable uart and async together. AsyncLagerBox::uart() and uart_with() open it, and its methods match Uart, with read, wait_for, write and stop awaited.

Handle

uart() and uart_with() are the only handle constructors that return a Result. Every other net handle is inert until you call a method. They connect the session and start streaming immediately, so they can fail right here.
To open with different serial settings for this session, pass a UartConfig:
Fields left None keep the net’s saved settings, and the saved net is never changed.

Methods

Types

UartConfig

UartSession

lager.uart_sessions() returns one UartSession for each session holding a net. It has netname, device_path, sid, heartbeat_age_seconds, client_connected and reader_alive.

Method Reference

read(timeout: Duration) -> Result<Vec<u8>>

Bytes arriving within timeout. The call can return an empty vector.
read() waits out the full timeout when the device is idle. Use try_read() in a poll loop, or every iteration costs the whole timeout.

try_read() -> Result<Vec<u8>>

Bytes already received, without waiting.

wait_for(needle: &[u8], timeout: Duration) -> Result<Vec<u8>>

Accumulate until needle appears. Returns: everything up to and including the needle; the remainder stays buffered. An empty needle returns immediately; a miss is Error::Timeout.

write(data: &[u8]) -> Result<()> and write_str(s: &str) -> Result<()>

Write to the device.

last_status() -> Option<&str>

The most recent session status notification, updated during reads. While a USB serial adapter re-enumerates — because a hub port was cycled, or the DUT was reflashed — this reads "reconnecting" and then "reconnected". Checking it distinguishes “the DUT is quiet” from “the adapter went away”.

stop() -> Result<()>

Stop cleanly and close the port on the box. Consumes the session. Dropping it also stops the session, but stop() surfaces errors.

LagerBox::uart_sessions() -> Result<Vec<UartSession>>

List the sessions holding a net, with liveness detail. Requires box software 0.46.0 or later. An older box gives Error::UnsupportedByBox.

LagerBox::release_uart_session(name: &str) -> Result<Vec<String>>

Force-release the session holding a net. Requires box software 0.46.0 or later.

Examples

Wait for a boot banner, then drive the console

Survive a reflash without losing the session

Free a net held by a leaked session

Supported Hardware

Notes

  • The box owns the port exclusively, and only one session per net or device is allowed. A second opener gets Error::UartInUse. That includes a session your own previous test leaked — call stop(). held_by names the net to release (box 0.49.0 or later). When two nets share one device, that is the other net.
  • The connect confirmation timeout is 15 seconds; failing it is Error::Timeout.
  • Bytes are raw. There is no line discipline, no echo handling and no encoding conversion; wait_for works on bytes.
  • Sessions carry the gateway bearer token on the Socket.IO handshake, so a gated box needs no extra setup.
  • On FTDI multi-channel parts, UART works on all four channels, unlike the MPSSE protocols (debug, spi, i2c) which are limited to channels A and B. On a single-channel FT232H, claiming UART makes the MPSSE roles unavailable and vice versa.