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.
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
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_bytesattribute 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
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.