Apalis i.MX6 UART latency

Hello,

I want to use my Apalis i.MX6 to communicate with external devices via UART. I am using the kernel version 3.14.52-rt.
In order to test the latency i connected TX and RX to create a loop (in fact this will be the case in the real design later on). I wrote a test code (attached below) which basically configures the UART and sends one byte via write(), waits until commit via tcdrain() and reads back via read().
My serial configuration is 115200 8N1, so one message byte should need around 90µs for transfer but it takes several milliseconds. So i configured a GPIO pin to go high before read and low after tcdrain and i see that tcdrain takes most of the time (see first picture). Even when i remove tcdrain and just use a “blocking” read() it takes about 700µs to recognize the message byte (see second picture).

Question is: Why do i get get such a high latency?

Note: I already edited the dtb so that the uart does not use dma (with dma its even worse).

[upload|4SAqRnVzJcYasuHDhebqni4BXxE=]

[upload|zztWAbvynF13hWCiGM46Q3L136k=]

Minimal C Code

Same effect when using an USB-to-Serial adapter…

Hi

I guess (without testing) that this is caused by the receiver only triggering an interrupt when the RX FIFO is filled up to a certain level(RXTL) or no character has been received for some time (AGTIM).

http://git.toradex.com/cgit/linux-toradex.git/tree/drivers/tty/serial/imx.c?h=toradex_imx_3.14.52_1.1.0_ga-next#n947

Is the delay way smaller if you send 16 bytes and does filling the FIFO to its interrupt level?

Does the delay stay constant when you send between 2 and 16 bytes, e.g. the ageing timer constantly waits 8 character times idle until it fires?

Max

Hi, In fact, the “delay” isn’t that big. The additional bytes filling up the gap. Please see the picture that shows 16 transmitted bytes. I thought setting tty.c_cc[VMIN] andtty.c_cc[VTIME] would be sufficiant to recognize every byte?

Is there a way to immediatly send and read every byte?

Best regards

Hi

I thought setting tty.c_cc[VMIN]
andtty.c_cc[VTIME] would be sufficiant
to recognize every byte?

That likely depends on the driver.

Is there a way to immediatly send and read every byte?

Yes, changing the kernel sources. That is why I added to source references above.

Likely, if you need to implement a protocol over UART for which reaction time to received characters are part of the specification you should consider writing your specialized protocol driver in the kernel on top of the iMX UART driver imx.c or maybe even as a replacement of it.

Max

Hi, Thanks a lot! I was alle to reduce the latency to a good level (mean: 100µs). Unfortunately there are still some runs with horrible delays of several milliseconds. Any hint to resolve this issue would be welcome.

Hi

How to did your reduce the latency?

Max

Hi,

I just set RXTL to 1 instead of 16. It works fine for me, but as i said, 1 out of 1000 runs needs significantly more time (abouve 1ms, sometime even 6ms).