Verdin UART1 issue on yocto build

I’m in the process of moving my project from Torizon OS to a Yocto build. I have a Python application that talks to a peripheral using /dev/verdin-uart. On Torizon OS, I ran a docker container for this application and passed the device to the container using these lines in a docker-compose file

devices:
    - /dev/verdin-uart1:/dev/verdin-uart1

I use the pyserial library to initialize communication.

serial.Serial(port="/dev/verdin-uart1", baudrate=9600)

Using this configuration, I was able to send and receive messages over uart1. However, on Yocto, using the same application source code, I can’t send/receive messages.

I thought it might be an issue with default port settings, but they appear the same between torizon

root@verdin-am62-15207092:~# stty -F /dev/verdin-uart1 -g
0:0:cbd:0:3:1c:7f:15:4:0:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

and yocto

root@verdin-am62:~# stty -F /dev/verdin-uart1 -g
0:0:cbd:0:3:1c:7f:15:4:0:0:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

I also thought it could be a device tree issue, so I generated a device tree from each using this command

dtc -I fs -O dts -o extracted_proc.dts /proc/device-tree

Initially, there was a difference. On my module running torizon OS, the u-boot variable fdtfile was set to k3-am625-verdin-wifi-dev.dtb, and there was no reference to rs485

        serial@2810000 {
            clock-names = "fclk";
            interrupts = <0x00 0xb3 0x04>;
            compatible = "ti,am64-uart\0ti,am654-uart";
            power-domains = <0x03 0x98 0x01>;
            reg = <0x00 0x2810000 0x00 0x100>;
            phandle = <0xac>;
            pinctrl-names = "default";
            status = "okay";
            pinctrl-0 = <0x19>;
            clocks = <0x02 0x98 0x00>;
        };

While on the yocto build, there were 2 extra parameters related to rs485 (which I do not want for my application). The fdtfile was also set to ‘k3-am625-verdin-wifi-dev.dtb’

                serial@2810000 {
                        power-domains = <0x03 0x98 0x01>;
                        pinctrl-names = "default";
                        rs485-rx-during-tx;
                        pinctrl-0 = <0x19>;
                        clock-names = "fclk";
                        interrupts = <0x00 0xb3 0x04>;
                        clocks = <0x02 0x98 0x00>;
                        linux,rs485-enabled-at-boot-time;
                        compatible = "ti,am64-uart\0ti,am654-uart";
                        status = "okay";
                        reg = <0x00 0x2810000 0x00 0x100>;
                        phandle = <0xac>;
                };

However, I changed fdtfile to k3-am625-verdin-wifi-dahlia.dtb (which is what I actually want to use) on the yocto module, and now its entry for serial@2810000 looks the same as that of the one running torizon OS. But that doesn’t fix the problem.

I also verified that both modules have the same symlink for /dev/verdin-uart1, and that they are being assigned to the same serial ports during boot

root@verdin-am62-15207092:~# ls -al /dev/verdin-uart*
lrwxrwxrwx 1 root root 5 Sep  6 20:47 /dev/verdin-uart1 -> ttyS0
lrwxrwxrwx 1 root root 5 Sep  6 20:47 /dev/verdin-uart2 -> ttyS1
lrwxrwxrwx 1 root root 5 Sep  6 20:47 /dev/verdin-uart3 -> ttyS2
lrwxrwxrwx 1 root root 5 Sep  6 20:47 /dev/verdin-uart4 -> ttyS3
root@verdin-am62-15207092:~# dmesg | grep ttyS
[    1.217772] 4a00000.serial: ttyS3 at MMIO 0x4a00000 (irq = 289, base_baud = 3000000) is a 8250
[    1.219262] 2800000.serial: ttyS2 at MMIO 0x2800000 (irq = 290, base_baud = 3000000) is a 8250
[    1.226522] printk: console [ttyS2] enabled
[    1.228400] 2810000.serial: ttyS0 at MMIO 0x2810000 (irq = 291, base_baud = 3000000) is a 8250
[    1.229896] 2850000.serial: ttyS4 at MMIO 0x2850000 (irq = 292, base_baud = 3000000) is a 8250

The 2 modules are running a slightly different version of linux, but I don’t think that should matter…
torizon os:

root@verdin-am62-15207092:~# uname -a
Linux verdin-am62-15207092 6.1.46-6.5.0+git.8e6a2ddd4fe6 #1-TorizonCore SMP PREEMPT Thu Dec 21 17:08:38 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

yocto:

root@verdin-am62:~# uname -a
Linux verdin-am62 6.1.80+git.0d9f1748ac17 #1 SMP PREEMPT Thu Mar 28 13:48:11 UTC 2024 aarch64 GNU/Linux

I can’t think of any other possible differences in configuration between the modules, other than that obviously one is running docker and the other is running just on linux. Are there any other types of configuration I should be aware of for this uart interface? Or anything else I should explicitly include in my Yocto build to allow this to work?

Hi, I’m the Toradex AI Assistant. The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


It seems like you’ve done a thorough job of comparing the configurations between your Torizon OS and Yocto builds. Given the information provided, here are a few additional steps and considerations that might help you troubleshoot and resolve the UART communication issue on your Yocto build:

  1. Check UART Driver and Device Tree Configuration:

    • Ensure that the UART driver is correctly loaded and that the device tree configuration is accurate. Since you mentioned that the device tree entries look the same, double-check that the UART driver is indeed being loaded correctly in the Yocto build. You can verify this by checking the output of dmesg for any UART-related messages.
  2. Permissions and User Groups:

    • On Torizon OS, the torizon user is part of several groups that allow access to hardware interfaces. Ensure that the user running your application on Yocto has the necessary permissions to access /dev/ttyS0. You can add the user to the dialout group, which typically has access to serial ports:
      usermod -aG dialout <your-username>
      
  3. Serial Port Initialization:

    • Sometimes, the serial port might need to be explicitly initialized or configured. You can use the stty command to set the correct parameters for the serial port. For example:
      stty -F /dev/ttyS0 9600
      
  4. Check for Conflicting Services:

    • Ensure that no other services or applications are using /dev/ttyS0. You can use the lsof command to check if the device is being used by another process:
      lsof /dev/ttyS0
      
  5. Test Serial Communication:

    • Use a simple serial communication test to verify that the UART interface is working correctly. You can use tools like minicom or screen to manually send and receive data over the serial port:
      minicom -D /dev/ttyS0 -b 9600
      
  6. Kernel Configuration:

    • Ensure that the kernel configuration in your Yocto build includes support for the necessary UART drivers and features. You can check the kernel configuration file (.config) for UART-related options.
  7. Compare Kernel Modules:

    • Compare the loaded kernel modules between Torizon OS and Yocto. Use the lsmod command to list the loaded modules and ensure that the necessary UART modules are loaded in Yocto.
  8. Debugging with PySerial:

    • Add some debugging statements in your Python application to log the status of the serial port initialization and communication. This can help identify where the issue might be occurring.

If none of these steps resolve the issue, it might be helpful to provide more detailed logs or error messages from your application and the system. This can give more insight into what might be going wrong.

Please, also check if these links can help you solve your problem:

Issue receiving data on IMX8MM UARTs.

An update - I have done some more testing with pyserial and microcom, and a debug version of the peripheral’s firmware. I am able to send some data back and forth, but it seems that bytes can be dropped, possibly in both directions.

There are some differences in kconfig, but they don’t seem relevant to me. I’m not currently using bluetooth.

yocto

#
# Serial drivers
#
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_16550A_VARIANTS=y
# CONFIG_SERIAL_8250_FINTEK is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_RSA is not set
CONFIG_SERIAL_8250_FSL=y
# CONFIG_SERIAL_8250_DW is not set
# CONFIG_SERIAL_8250_RT288X is not set
CONFIG_SERIAL_8250_OMAP=y
CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP=y
CONFIG_SERIAL_8250_PRUSS=m
CONFIG_SERIAL_OF_PLATFORM=y
sarah@ubuntu:~$ cat yocto-config | grep UART
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_SERDEV=y
CONFIG_BT_HCIUART_H4=y
# CONFIG_BT_HCIUART_NOKIA is not set
# CONFIG_BT_HCIUART_BCSP is not set
# CONFIG_BT_HCIUART_ATH3K is not set
CONFIG_BT_HCIUART_LL=y
# CONFIG_BT_HCIUART_3WIRE is not set
# CONFIG_BT_HCIUART_INTEL is not set
CONFIG_BT_HCIUART_BCM=y
# CONFIG_BT_HCIUART_RTL is not set
CONFIG_BT_HCIUART_QCA=y
# CONFIG_BT_HCIUART_AG6XX is not set
CONFIG_BT_HCIUART_MRVL=y
# CONFIG_BT_MTKUART is not set
CONFIG_BT_NXPUART=m
CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
# CONFIG_SERIAL_UARTLITE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
CONFIG_SERIAL_FSL_LPUART=y
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_FSL_LINFLEXUART=y
CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
# CONFIG_SDIO_UART is not set

And on torizon

#
# Serial drivers
#
CONFIG_SERIAL_EARLYCON=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_16550A_VARIANTS=y
# CONFIG_SERIAL_8250_FINTEK is not set
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_EXAR=y
CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
# CONFIG_SERIAL_8250_RSA is not set
CONFIG_SERIAL_8250_FSL=y
# CONFIG_SERIAL_8250_DW is not set
# CONFIG_SERIAL_8250_RT288X is not set
CONFIG_SERIAL_8250_OMAP=y
CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP=y
CONFIG_SERIAL_8250_PERICOM=y
CONFIG_SERIAL_8250_PRUSS=m
CONFIG_SERIAL_OF_PLATFORM=y
sarah@ubuntu:~$ cat torizon-config | grep UART
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_SERDEV=y
CONFIG_BT_HCIUART_H4=y
# CONFIG_BT_HCIUART_NOKIA is not set
CONFIG_BT_HCIUART_BCSP=y
CONFIG_BT_HCIUART_ATH3K=y
CONFIG_BT_HCIUART_LL=y
CONFIG_BT_HCIUART_3WIRE=y
CONFIG_BT_HCIUART_INTEL=y
CONFIG_BT_HCIUART_BCM=y
# CONFIG_BT_HCIUART_RTL is not set
CONFIG_BT_HCIUART_QCA=y
# CONFIG_BT_HCIUART_AG6XX is not set
CONFIG_BT_HCIUART_MRVL=y
# CONFIG_BT_MTKUART is not set
CONFIG_BT_NXPUART=m
CONFIG_SERIAL_8250_NR_UARTS=6
CONFIG_SERIAL_8250_RUNTIME_UARTS=6
# CONFIG_SERIAL_UARTLITE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_XILINX_PS_UART is not set
CONFIG_SERIAL_FSL_LPUART=y
CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
CONFIG_SERIAL_FSL_LINFLEXUART=y
CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
# CONFIG_SDIO_UART is not set

Hey @sarah,

Your yocto build is defaulting to the development carrier board. That is why you see the extra parameters for the serial port (RS485)…

k3-am625-verdin-wifi-dev.dtb → eventually includes #include k3-am62-main.dtsi
where we see these values come from…

	main_uart1: serial@2810000 {
		compatible = "ti,am64-uart", "ti,am654-uart";
		reg = <0x00 0x02810000 0x00 0x100>;
		interrupts = <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>;
		power-domains = <&k3_pds 152 TI_SCI_PD_EXCLUSIVE>;
		clocks = <&k3_clks 152 0>;
		clock-names = "fclk";
		status = "disabled";
	};

and

&main_uart1 {
  1     linux,rs485-enabled-at-boot-time;
  2     rs485-rx-during-tx;
  3     status = "okay";
  4 };

The “dev” part of the dts file names is referring to the development board, that has the RS485. So When you switch over to dahlia. This is a different device tree file and doesn’t not have this modifier for RS485.

From your second comment, It sounds like your port is working, but the information is being dropped? Can you elaborate a bit more on this. What are you trying to do, and what are the results.

-Eric

Thanks for your reply Eric! My application is working now.

I’m using the dahlia device tree, plus a custom overlay that removes rts and cts from the uart1 pinctrl group (as suggested in this other post: Issue receiving data on IMX8MM UARTs - #16 by spencerarrasmith)

&main_pmx0 {
	pinctrl_uart1_no_rts: main-uart1-pins-no-rts-default {
		pinctrl-single,pins = <
			AM62X_IOPAD(0x01ac, PIN_INPUT_PULLUP, 2) /* (E19) MCASP0_AFSR.UART1_RXD  */ /* SODIMM 129 */
			AM62X_IOPAD(0x01b0, PIN_OUTPUT,       2) /* (A20) MCASP0_ACLKR.UART1_TXD */ /* SODIMM 131 */
		>;
	};
};

/* Verdin UART_1 */
&main_uart1 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_uart1_no_rts>;
	status = "okay";
};

There was also an issue in my application code that resulted from switching from a docker container running python3.12 to kirkstone yocto, which provides python3.10. After fixing these 2 issues, communication is restored.