Uart latecy

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Uart latecy

1,748 Views
andreacelani
Contributor II

We are using an IMX8M-MINI QUAD Core 1.8GHz, and kernel version 4.14.78.

We have discovered a problem of latency in the software driver of the uart device "/dev/ttymxc1".

 

We have checked the round trip delay of a byte transmitted and received on the uart device. The ttymxc1 was configured 8N1 with a custom baud rate of 31250, that is the frequency of a MIDI device (Musical Instrument Device Interface). We have measured a round trip delay of 13 ms. This delay is not acceptable for a MIDI device.

After some brief analysis, we have discovered that the problem was related to the file /driver/tty/serial/imx.c of the kernel (4.14.78). Moreover, the delay is located in the rx part of the uart driver (not in the tx part).


We have changed the define RXTL_UART from 16 to 1, in order to reduce the latency of the uart. After this modification we have measured a round trip delay of 10 ms. So, the modification of the RXTL_UART have reduced the delay, but has not solved the issue at all.

After that, we have changed the device tree and we have disabled the sdma for the uart2. So, finally, we have measured a round trip delay of 1 ms. This is the same round trip delay that we have measure with older hardware (imx6, with kernel version 3.10.17).

So, why the use of sdma on the uart2 introduce a round trip delay of 10ms?
Is there any way to get low latency with the sdma enabled?

As additional information we have discovered (with sdma) that the latency depend on baud rate:
- at 31250 we have measured a round trip delay of 10 ms
- at 115200 we have measured a round trip delay of 4 ms
So, in some way the sdma adds an rx delay that depends on frequency of the uart.

Thank you.

Labels (1)
0 Kudos
5 Replies

1,737 Views
ceggers1
Contributor IV

I guess that most of the latency is related to the aging time of the UART:

"The receiver block also includes the possibility to detect when at least one character has
been sitting into the RxFIFO for a time corresponding to 8 characters."

I personally use custom SDMA scripts for receiving time-critical UART data. With this custom scripts I am able to detect the end of a received message (by examining "length" fields from the telegram or using EOF characters). So the SDMA can pass the whole UART frame to the OS with only one interrupt and with minimal extra latency.

Additionally I use a preempt-rt kernel in order to minimize latency.

regards
Christian

0 Kudos

1,723 Views
andreacelani
Contributor II

The  aging time is not the reason of the Uart latency.

8 Characters of delay at 31250 produce only a delay of 2.5 ms. We have already solved this delay by putting the RXTL_UART from 16 to 1. Anyway the delay of 10 ms is still remaining.

So I think the delay is related to the sdma driver and uart driver only.

0 Kudos

1,718 Views
ceggers1
Contributor IV

I had a short look an the MIDI-Protocol (on the german Wikipedia). As MIDI messages can have different lengths, I would either...

  1. use the SDMA with a custom script (which detects status bytes and SysEx messages)
  2. not use the SDMA at all

regarding option 1)
It is definitely not useful to use the SDMA for receive single bytes. In this case there is not benefit (but a lot of overhead) compared to directly reading from the UART. Additionally the UART driver tries to receive 1024 byte blocks from the SDMA, independent of the buffer size you passed to the read() function. I am unsure where the 10ms latency comes from after you already set RXTL to 1. Maybe it is related to CONFIG_HZ.

Using a custom SDMA script which receives whole MIDI frames can reduce the interrupt load on the CPU (but not necessarily the latency).

Is there a way to detect the start/end of all possible MIDI message types? I read that status bytes can be detected by the highest bit (1). Usually MIDI messages have two additional data bytes, but with "running status" the number seems to be infinite. Probably the SDMA needs to create a new "frame" for every pair of two consecutive data bytes. SysEx messages seems to be easy as they end with 0xF7.

When using the SDMA for "reconstructing" MIDI frames, I wouldn't use the TTY layer as interface to the application, as this is "byte orientated". In my application (DMX), I use the network layer instead which allows passing whole frames to the application.

regarding option 2)
You already tested this option. Not using the SDMA will create a higher CPU load as you need one interrupt and one syscall for every single byte. But for low latency, this option may be better than SDMA.

regards
Christian

0 Kudos

1,710 Views
andreacelani
Contributor II

It is not possible to use solution 1. MIDI must be parsed byte after byte. We do the MIDI parser in user space after opening and reading from the tty port.

We have already tested the solution 2 and it is the final solution.

0 Kudos

1,707 Views
ceggers1
Contributor IV

ok, that's fine.

In my project,  DMX/RDM must also be parsed byte-by-byte. But due to the high baud rates (250k) I don't want to do this in user space. I do the parsing inside the SDMA.

regards
Christian

0 Kudos