Using i.MX 6ULL UART Ports in Linux Print

The i.MX 6ULL SoC implements 8 UART controllers (UART1-8). The default Linux kernel configuration for the Emcraft i.MX 6ULL SOM makes only ports UART1 and UART3 accessible from Linux. Other ports can also be enabled but some of them concur with other useful peripherals, such as SPI3, I2C1, RMII2, LCD.

In Linux, parameters of each UART controller (interrupt request numbers, DMA configuration, etc.) are specified in uartX child nodes of the soc node in the arch/arm/boot/dts/imx6ull.dtsi file located in the Linux kernel tree:

{ ... uart3: serial@021ec000 { compatible = "fsl,imx6ul-uart", "fsl,imx6q-uart", "fsl,imx21-uart"; reg = <0x021ec000 0x4000>; interrupts = ; clocks = <&clks IMX6UL_CLK_UART3_IPG>, <&clks IMX6UL_CLK_UART3_SERIAL>; clock-names = "ipg", "per"; dmas = <&sdma 29 4 0>, <&sdma 30 4 0>; dma-names = "rx", "tx"; status = "disabled"; }; ... };

Note that all UART ports are disabled by default in the above file, so arch/arm/boot/dts/imx6ull.dtsi rarely needs to be modified, and all detailed UART port configuration is performed by board specific device tree files (.dts).

For the Emcraft i.MX 6ULL SOM, configuration of the UART ports is performed in the projects/rootfs/rootfs.dts file. In particular, this file enables required ports as well as sets other UART related configuration parameters, such as presence of the flow control logic. Additionally, the projects/rootfs/rootfs.dts file defines which I/O pins are used by a specific UART port on the Emcraft i.MX 6ULL SOM. Since a single i.MX 6ULL I/O pin can be shared between several peripherals, a care must be taken while changing these parameters.

The UART configuration for the Emcraft i.MX 6ULL SOM enables UART1 and UART3 ports. The UART1 is used as the Linux console, while UART3 provides communication channel over the Raspberry Pi (P10) connector.

In the below .dts example, UART3 is enabled and configured for using by Linux on the Emcraft i.MX 6ULL SOM:

&uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; status = "okay"; }; ..... &iomuxc { imx6ul-evk { ..... pinctrl_uart3: uart3grp { fsl,pins = < MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX MX6UL_UART_PAD_CTRL MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX MX6UL_UART_PAD_CTRL >; }; ..... }; }

Whenever the Linux kernel finds an enabled UART port, it automatically creates a corresponding device node file, which can be used for accessing this port using standard Linux interfaces. For the i.MX 6ULL UART device node files have the following format: /dev/ttymxcX, where X starts from 0. Thus, for UART1 the kernel will create the /dev/ttymxc0 file, and so on.

Typically, UART ports are used to connect various equipment such as modems, sensors, additional computers and so on. In Linux, serial ports are accessed from C-level user space code using the standard POSIX APIs. These APIs are extensively defined in various materials available in the Internet. For instance, try googling for something like this "How to access serial ports in C".

As a simple test, the following commands can be used to send/receive text to/from UART.

  • Enable the UART port (UART3 in this example) in the projects/rootfs/rootfs.dts file, then build and update the DTB as described in Installing and Activating Cross Development Environment application note.
  • Connect the UART3 port to a host and open a serial terminal client on the host side. The UART3 port can be accessed on the Raspberry Pi (P10) connector on the Emcraft IMX6ULL-SOM-BSB board (P10.8UART3_TXD, P10.10UART3_RXD).
  • Configure the port on the i.MX 6ULL side and start the reader process:
  • ~ # stty -echo raw 115200 < /dev/ttymxc2
    ~ # cat /dev/ttymxc2

  • Write a string in the terminal client on the host side and observe the echo coming from reader process, started on the i.MX 6ULL side:
  • Hello from the host over UART

  • Stop the reader process on the i.MX 6ULL side by pressing Ctrl+C. Then send a string to the host and observe the string received by the terminal client on the host side:
  • ^C
    ~ # echo "Hello from the i.MX 6ULL over UART" > /dev/ttymxc2
    ~ #