linuxserial-porttermios

How to set Inter-Byte Delay Timeout to milliseconds?


I'm currently working with termios for serial communication in Linux.

I need to set an intercharacter timeout to 5ms.

I found a way to set intercharacter timeout using VMIN and VTIME where VMIN has to be VMIN > 0 and VTIME > 0.

The problem is that i need to set the VTIME to 5ms, but the VTIME is expressed in tenths of a second.

VTIME data type is unsigned char, so i can't just set it to 0.05.

Does anyone know if there is some way around this?


Solution

  • I need to set an intercharacter timeout to 5ms.
    ...
    Does anyone know if there is some way around this?

    No, there is no way to set a shorter termios timeout than 100 ms.
    Depending on your hardware and kernel configuration, this timeout may not be reliable at all, especially if you are trying to detect time-separated messages.
    The termios handling is at least a full layer above the UART device driver (see Linux serial drivers).
    Unless your kernel is configured to ensure that the bottom-half of the UART driver and the kworker threads for termios are high priority and low latency, then short intercharacter intervals cannot be accurately or reliably determined.

    If the UART utilizes a FIFO to buffer incoming data, then that hardware obscures the intercharacter spacing that the software can detect.
    Similarly when the UART driver is using DMA to store the received data, intercharacter timing will be obscured.
    With DMA the CPU is not involved with handling the received data until the DMA operation is complete, and all temporal information about any intercharacter separation is gone.
    (Crucial information such as framing error and/or parity error is difficult/impossible to pinpoint to a specific byte when using DMA.)
    Even without DMA, termios will only be able to use timing based on the transfer of data through the tty flip buffers (which is a layer removed from the timing on the wire).

    Some UARTs do have hardware that assist in detecting the end-of-message by idle line.
    For example Atmel/Microchip ATSAMA5 and AT91SAM9 SoCs have USARTs with a Receiver Timeout feature that measures the idle time after each received frame.
    When this idle line time exceeds a specified value, an interrupt can be generated.
    The Linux driver for the Atmel USART typically uses the receiver-timeout interrupt to (prematurely) terminate the current DMA receive operation, and copy the contents of the DMA buffer to the tty flip buffer.

    In summary you cannot or should not rely solely on VMIN and VTIME settings to detect time-separated messages. See Parsing time-delimited UART data.
    The message packets need to have delimiter/sentinel characters/bytes so that messages can be reliably parsed and validated.
    See parsing complete messages from serial port for an example of efficient use of syscalls with a local buffer.