NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

Linux Core UART User's Guide

From Texas Instruments Wiki
Jump to: navigation, search

Introduction[edit]

Top level kernel user's guide can be found here http://processors.wiki.ti.com/index.php/Linux_Kernel_Users_Guide
This guide covers 8250 OMAP serial driver found at drivers/tty/serial/8250/8250_omap.c. It supports UART IP found on TI's AM335x, AM437x, AM57xx and DRA7xx SoCs. These SoCs have 8250 compliant UART IPs and hence use common 8250 serial driver framework support of Linux kernel.
This documentation applies to Kernel v4.14 and higher.

Suppported Devices[edit]

  • AM335x
  • AM437x
  • AM57xx
  • DRA7xx

Driver Features[edit]

Driver supports following features:

  • Hardware flow control
  • Standard Baudrates upto 3MBuad
  • DMA support (except AM437x)

Driver Configuration[edit]

Driver Source Location: drivers/tty/serial/8250/8250_omap.c

Kernel configuration options[edit]

UART1.PNG
UART.PNG
Configs to be enabled in kernel
CONFIG_SERIAL_8250 (8250 core support)
CONFIG_SERIAL_8250_CONSOLE (for console on 8250 UARTs)
CONFIG_SERIAL_8250_DMA (for DMA support)
SERIAL_8250_OMAP (Enable 8250 based driver for TI SoCs)



Example DT configuration[edit]

From dra7.dtsi:

aliases {
		...
		serial0 = &uart1;
		serial1 = &uart2;
               ...
};
		uart1: serial@4806a000 {
			compatible = "ti,dra742-uart", "ti,omap4-uart";
			reg = <0x4806a000 0x100>;
			interrupts-extended = <&crossbar_mpu GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
			ti,hwmods = "uart1";
			clock-frequency = <48000000>;
			status = "disabled";
			dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
			dma-names = "tx", "rx";
		};



Driver Usage[edit]

Once, the driver is probed, each of serial ports are exposed as a character device file by kernel to be used by userspace:

/dev/ttySX        X- Serial port number (zero indexed)

Therefore UART0 -> /dev/ttyS0

Reading from serial port:

cat /dev/ttyS0

Writing to serial port:

echo "hello" > /dev/ttyS0

Changing serial port baudrate:

stty -F /dev/ttyS0 <baudrate>
stty -F /dev/ttyS0 115200

Testing UART communication[edit]

Either connect two UART ports to one other with flow control lines. Or connect single UART in external loopback mode(RTS-CTS, RX-TX). Internal loopback mode cannot be used for testing UART as there is no gurantee that HW flow control will work reliabily.

Basic External loopback testing[edit]

stty -F /dev/ttySX 115200 /* Set baudrate to 115200: */
cat /dev/ttySX &
echo hello > /de/ttySX

This should print "hello" on the shell. That verifies RX-TX external loopback

Testing UART communication with HW flow control[edit]

Make sure all the pins are connected properly (RTS-CTS, RX-TX) and pinmux is setup. Clone the following repo for tool to test serial port:

https://github.com/nsekhar/serialcheck

Compile serialcheck tool:

~/serialcheck$ gcc -o serialcheck serialcheck.c CROSS_COMPILE=arm-linux-gnueabihf-

Compile serialstats tool:

~/serialcheck$ gcc -o serialstats serialstats.c CROSS_COMPILE=arm-linux-gnueabihf-

serialcheck: Used to configure UART and then send/receive data over UART. The tool reports any inconsistencies observed while UART transfer by comparing it with reference file
For more information run

serialcheck --help

serialstats: Prints UART statistics provided by Kernel's tty layer. For more information run

serialstats --help

- Create a random file.

 dd if=/dev/urandom of=binary count=1 bs=4096

- Copy the random file to both nodes(TX side and RX side).

- Start serialstats in the background to collect stats/errors

 serialstats -d /dev/ttySX -i 1 &

- Start the test (with HW flow control enabled at 3MBaud)

 receiving node(-m r):
 	serialcheck -h -d /dev/ttyS0 -f binary -m r -l 10 -b 3000000
 sending node(-m t):
 	serialcheck -h -d /dev/ttyS0 -f binary -m t -l 10 -b 3000000

Start the receiving side before the sending side. This will transfer the "binary" file 10 times and the other side will expect the file 10 times.
Once the program completes both sides should write something similar to if the test was successful

 Needed 0 reads 1 writes loops 10 / 10
 cts: 3 dsr: 0 rng: 0 dcd: 0 rx: 40960 tx: 40960 frame 0 ovr 0 par: 0 brk: 0 buf_ovrr: 0

and in case of error:

Needed 20 reads 0 writes Oh oh, inconsistency at pos 2273 (0x8e1).
Original sample:
000008b0: 28 b2 18 c9 ec b5 2c b3  3a a1 29 b1 fc 27 20 7f   (.....,.:.)..' .
000008c0: 42 f8 d5 cb d8 52 ec b5  c8 76 d3 4b d2 57 44 6a   B....R...v.K.WDj
000008d0: 40 81 6a 82 27 fd 8d 50  84 70 bc 24 6b 3d 88 fd   @.j.'..P.p.$k=..
000008e0: 9f ac 78 a4 76 9b f9 1c  74 2c d6 79 22 60 c5 de   ..x.v...t,.y"`..
000008f0: 02 9c fb 52 21 4b 40 6f  80 69 2e 80 df 12 ba a0   ...R!K@o.i......
00000900: 75 57 d5 22 33 c0 f3 bc  94 f8 aa 22 9d 02 59 20   uW."3......"..Y 

Received sample:
000008b0: 28 b2 18 c9 ec b5 2c b3  3a a1 29 b1 fc 27 20 7f   (.....,.:.)..' .
000008c0: 42 f8 d5 cb d8 52 ec b5  c8 76 d3 4b d2 57 44 6a   B....R...v.K.WDj
000008d0: 40 81 6a 82 27 fd 8d 50  84 70 bc 24 6b 3d 88 fd   @.j.'..P.p.$k=..
000008e0: 9f 00 ac 78 a4 76 9b f9  1c 74 2c d6 79 22 60 c5   ...x.v...t,.y"`.
000008f0: de 02 9c fb 52 21 4b 40  6f 80 69 2e 80 df 12 ba   ....R!K@o.i.....
00000900: a0 75 57 d5 22 33 c0 f3  bc 94 f8 aa 22 9d 02 59   .uW."3......"..Y
loops 54878 / 4294967295

cts: 0 dsr: 0 rng: 0 dcd: 0 rx: 224792017 tx: 223379456 frame 0 ovr 1 par: 0 brk: 0 buf_ovrr: 0

Meaning of different counters

cts: Number of times flow control lines was asserted.

dsr/rng/dcd: correspond to Modem control line statistics

rx/tx: rx and tx counters. Denotes number of bytes sent/received in the session. A mismatch here would indicate data loss

frame: number of framing errors

ovr: Number of times UART HW FIFO overruns

par: Number of parity errors

brk: Number of times break character was received. (For more details on above errors see: https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter)

buf_ovrr: Number of bytes lost due to overrun software buffer at kernel's tty layer.

Standalone Testing of HW flow control[edit]

Start only TX side of serial check:

serialcheck -h -d /dev/ttySX -f binary -m t -l 10 -b 3000000

Run only serialstats on the RX side without starting RX receiver process

serialstats -d /dev/ttySX -i 1

If cts is non zero, ovr and buf_ovrr is not reported then, HW flow control is working.

Note

  • Make sure that start RX side first before starting TX
  • RX side waits for 100s before reporting timeout. Make sure TX side starts sending data before 100s
  • serialcheck tool does not support support duplex mode(-m d -> simulatenous RX and TX). Workaround would be to start second send/receive pair in reverse direction.



Probable reason for different errors[edit]

Frame error/parity error: Mostly due to fautly external loopback connection or signal interference on the wire
overruns: This overruns corresponds to HW FIFO overrun. TI's 8250 UART IP supports auto HW flow control. Hence, as long as flow control is enabled in IP by driver and RTS-CTS lines are connected. Overrun indicates either HW flow control lines are not connected or its not turned on by the userspace (pass -h option for in case of serialcheck)
buf_ovrr: indicates either a driver bug or tty ldisc driver bug(default ldisc is n_tty drivers/tty/n_tty.c). Its the duty of ldisc layer to call uart_throttle() function if the receiver is overwhelmed to avoid buf_ovrr

Note

  • It is always recommended to connect HW flow control lines while for UART communication. Also, software should enable HW flow control explicitly. Otherwise, there will be data loss and data corruption.
E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Linux Core UART User's Guide here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article Linux Core UART User's Guide here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article Linux Core UART User's Guide here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article Linux Core UART User's Guide here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article Linux Core UART User's Guide here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Linux Core UART User's Guide here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article Linux Core UART User's Guide here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article Linux Core UART User's Guide here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article Linux Core UART User's Guide here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity