Skip to content

Kernel generic API for low lever UART driver/HW Rx FIFO trig and or iddle timeout control #13

@ppisa

Description

@ppisa

There are many serial protocol which require response to received data to occur in predefined time interval which is often shorter than default/fixed Rx idle FIFO timeout. The LIN specific problem is then BREAK condition generation with predefined time followed by sync character. The LIN speed is low and fully preemptive kernel latencies are far bellow required reaction times but again FIFO makes problems there as well. We use more later described hacks for slLIN to switch FIFO to desired state for different UARTs.

The sending of break character directly followed by data characters is not easy through low level Linux serial API. Same difficulties apply to acting as slave and sending response frame without delay/gap.

The main problem in case of BREAK_BY_BAUD is delay between sending final bit and reporting receive interrupt to the driver. The delay corresponding to 3 or 4 characters is typically result of UART chip FIFO mode where non-empty Rx FIFO event is reported only when threshold level is reached or when line is idle for 4 characters. It is necessary to set UART into mode where Rx FIFO is disabled or Rx threshold is set to one. Unfortunately, there is no unified API for this parameter or even its availability which is supported across multiple/all UART drivers implementations.

PC style 8250/16[45679]50 allows to set FIFO trigger level to 1 for classic by

echo 1 >/sys/class/tty/ttyS0/rx_trig_bytes

which switches off FIFO if unavailable.

There is required function in 8250 driver linux/drivers/tty/serial/8250/8250_port.c

     do_serial8250_set_rxtrig()
     serial8250_set_attr_rx_trig_bytes()

and corresponding rx_trig_bytes attribute available for some of these ports.

But it is problem that there is no generic interface how to control this parameter on different UART flawors.

One some arch, rx_fifo_timeout can be used instead, which is even better because FIFO prevents lost of bytes when non RT kernel is used.

We have used some patches for Ti AM3 and for MPC5200.

On Texas Instruments AM[34]xxx chips next patch can be used

diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
index e14982f..13bbf90 100644
--- a/drivers/tty/serial/8250/8250_omap.c
+++ b/drivers/tty/serial/8250/8250_omap.c
@@ -80,7 +80,7 @@
 #define OMAP_UART_TX_WAKEUP_EN (1 << 7)
 
 #define TX_TRIGGER     1
-#define RX_TRIGGER     48
+#define RX_TRIGGER     1
 
 #define OMAP_UART_TCR_RESTORE(x)       ((x / 4) << 4)
 #define OMAP_UART_TCR_HALT(x)          ((x / 4) << 0)
@@ -380,7 +380,7 @@ static void omap_8250_set_termios(struct uart_port *port,
        up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
        if (termios->c_iflag & INPCK)
                up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (IGNBRK | PARMRK))
+       if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
                up->port.read_status_mask |= UART_LSR_BI;
 
        /*

But consequence is that Rx threshold level 1 is used on all serial ports then. Usually not a problem.

Generic API from line discipline to low level UART drivers to control FIFO and timeout would be great.
It should round trig level down if given value is not available or switch FIFO entirely. Same for timeout
which could be counted in number of character times or microseconds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions