Using debug serial port for data on Orin NX JetPack 6.2.1

I want to use the serial debug port of the Orin NX 16GB as a data port. I noticed that there are many topics handing this already, but i was not able to follow them, perhaps because they relate to Xavier NX or JetPack V5.

Module: Jetson Orin NX 16GB
Carrier: reComputer J40 (Seed Studio)
Jetpack Version: V6.2.1

Threads that are related:

Here is what i tried so far:

  1. I tried to modify the file bootloader/tegra234-mb2-bct-common.dtsi
    enable_combined_uart = <0>
    spe_uart_instance = <0xff>
    
    Using this modification i am not able to complete the flashing process. I am using the kernel_flashing process so, after it tries to connect to the target over ssh it fails, as the target never boots-up.
    ***************************************
    *                                     *
    *  Step 3: Start the flashing process *
    *                                     *
    ***************************************
    Waiting for target to boot-up...
    Waiting for target to boot-up...
    Waiting for target to boot-up...
    Waiting for target to boot-up...
    Waiting for target to boot-up...
    Waiting for target to boot-up...
    
  2. Trying to modify the device tree on the live system
    On the live system i disabled the nvgetty service like it was documented elsewhere.
    sudo systemctl disable nvgetty
    sudo systemctl stop nvgetty
    
    Then i made a kernel device-tree overlay like this:
    /dts-v1/;
    /plugin/;
    
    / {
        compatible = "nvidia,tegra234";
    
        fragment@0 {
            target-path = "/chosen";
            __overlay__ {
                stdout-path = "";
            };
        };
        fragment@1 {
            target-path = "/serial";
            __overlay__ {
                status = "disabled";
            };
        };
    };
    
    I compiled it and copyed it into the system.
    dtc -@ -H epapr -I dts -O dtb -o activate_2nd_uart.dtbo activate_2nd_uart.dts
    sudo mkdir -p /boot/dtb/overlays/
    sudo cp activate_2nd_uart.dtbo /boot/dtb/overlays/
    
    This is my /boot/extlinux/extlinux.conf
    TIMEOUT 30
    DEFAULT primary
    
    MENU TITLE L4T boot options
    
    LABEL primary
          MENU LABEL primary kernel
          LINUX /boot/Image
          INITRD /boot/initrd
          FDT /boot/dtb/kernel_tegra234-p3768-0000+p3767-0000-nv.dtb
          OVERLAYS /boot/dtb/overlays/activate_2nd_uart.dtbo
          APPEND ${cbootargs} root=UUID=0ecd6cfe-0f16-4aa2-a9e7-9a8dad69556e rw rootwait rootfstype=ext4 mminit_loglevel=4 firmware_class.path=/etc/firmware fbcon=map:0 video=efifb:off console=tty0 
    
    I noticed that here the node is called serial not combined-uart like mentioned elsewhere. After disabling it /dev/ttyTHS0 disappeared. I tried all available serial ports, however i was not able to send any data out or in.

How should i proceed to be able to see it in the system as a normal /dev/ttyTHS serial port? Do i have to modify the pinmux?

nvidia@ubuntu:~$ sudo cat /sys/kernel/debug/pinctrl/2430000.pinmux/pinconf-groups | grep uart
88 (uart2_tx_px4): 
	function=uartb
89 (uart2_rx_px5): 
	function=uartb
90 (uart2_rts_px6): 
	function=uartb
91 (uart2_cts_px7): 
	function=uartb
92 (uart5_tx_py5): 
93 (uart5_rx_py6): 
94 (uart5_rts_py7): 
95 (uart5_cts_pz0): 
120 (uart1_cts_pr5): 
121 (uart1_rts_pr4): 
122 (uart1_rx_pr3): 
	function=uarta
123 (uart1_tx_pr2): 
	function=uarta
125 (uart4_cts_ph6): 
126 (uart4_rts_ph5): 
127 (uart4_rx_ph4): 
128 (uart4_tx_ph3):

I tried enabling the serial@3110000 in the device-tree. However after enabling the board was not booting properly.

When just removing the console argument in extlinux.conf i am able to receive and send data on /dev/ttyTHS0 but the baudrate is fixed to 115200bps and i need to change that.

This is the device tree:
device_tree.dts.zip (33.0 KB)
Any help is appreciated

Hi erik_abt,

Do you want to use debug UART for custom use case?
If so, we don’t suggest/support for this as it is a Tegra Combined UART, which means it outputs logs from several firmwares. You are not able to disable them in each firmware.
Could you use the other 2 UART interface instead?
One is from 40-pins expansion header, another is from M.2 Key E.

Hello KevinFFF,

unfortunately the M.2 Key E slot is taken in my application. Also i am not using the debug port really. It would be of big help to be able to repurpose it as a serial uart. I noticed that the bootloader is doing some print statements while its booting. That would be not a problem in case of my application, because the serial communication we plan on doing is a binary protocol and using checksums. Thats why i tried to follow the instructions for JetPack 5 and Xavier NX but, unfortunately i was not able to apply them to Jetpack 6.2.1 and Orin NX.

Is it true that the TCU serial port is being used during the flashing process? I tried to disable it inside of the mb2 firmware (bootloader/tegra234-mb2-bct-common.dtsi), but it seemed to break the flashing process. Same happens if i disable the tcu serial port in the kernel device tree (kernel/dtb/tegra234-p3768-0000+p3767-0000-nv-super.dtb). However if i just do the modification on the live device, but not during the flashing process i can boot the device at least. I tried to do the following modification to the device tree but it does not succeed to send out any data and when closing the serial port the os crashes because of a wrong file descriptor.

		serial@3120000 {
			compatible = "nvidia,tegra194-hsuart";
			reg = <0x00 0x3120000 0x00 0x10000>;
			interrupts = <0x00 0x72 0x04>;
			clocks = <0x03 0x9d>;
			resets = <0x03 0x66>;
			status = "okay";
			reset-names = "serial";
			phandle = <0x400>;
		};

I inferred the register, interrupt, clock and reset entries from looking at the other serial nodes. I made up phandle after making sure there is no duplicate. Is this the correct approach?

I am trying to understand the structure here. I get that the bpmp bootloader is grabbing the serial port and that the THS driver is sending it to bpmp over mailbox communication. Does the serial port need to be disabled inside of the bootloader first for it to be able to be addressed directly by the kernel? That seems to be impossible at the moment with the current flashing process.

This is the current device tree modification for the runtime system that i am using:
tegra234-p3768-0000+p3767-0000-nv-super.dts.txt (316.8 KB)

As I mentioned that it is a debug UART, it will output log from several cores at anytime.
There definitely are many logs output during flash.
Some of them are configured in each firmware itself rather than able to switch from configuration simply.

It is not the one used by UART2(uartc).
Maybe you can try adding serial@c280000 in device tree for UART2 if you don’t care about other debug messages affecting custom your UART usage after boot up.

Hello, thanks for your answer. I tried this definition now:

		serial@c280000 {
			compatible = "nvidia,tegra194-hsuart";
			reg = <0x00 0xc280000 0x00 0x10000>;
			interrupts = <0x00 0x72 0x04>;
			clocks = <0x03 0x9d>;
			resets = <0x03 0x66>;
			status = "okay";
			reset-names = "serial";
			phandle = <0x400>;
		};

However if i am actually opening the serial port and sending data out nothing is visible on the pins. Not in tx and not in rx direction. And when closing the serial port i get a “Bad File Descriptor” error. (The os is not crashing anymore like before with the wrong address). Could this be because the bootloader is grabbing onto the serial port? I tried to disable the serial port in kernel device-tree during flashing or in the mb2 configuration. But as i said before, whenever i do this i am not able to complete the flashing process.

It is not enough that you just disable it in kernel device tree.
That’s why we don’t suggest using the debut UART for other use case since it has been used by many firmeware and it might affect the functionality.

What’s the exact commands you run to send data form Orin NX?
Have you confirmed that you use the correct /dev node?
Please also share the full dmesg for further check.

Hello KevinFFF,

This is the full dmesg after trying to send serial data:
dmesg.txt (60.0 KB)

This is the script that i use to test the serial port. I verified it to work on another serial port.
serial_ping.py.txt (1.6 KB)

This is the device tree and extlinux.conf that i am using:
extlinux.conf.txt (968 Bytes)
kernel_tegra234-p3768-0000+p3767-0000-nv-super.dts.txt (316.6 KB)

This is the output of the serial port after applying the given device-tree:
serial_log.txt (37.0 KB)

This is the exception that is raised by the serial ping tester:
log.txt (1.9 KB)

From the dmesg you shared, it seems the driver has probed for serial@c280000
We cannot debug your custom python script directly.

I would suggest simply shorting TX/RX and run the following command to verify.

$ sudo su
# stty -F /dev/ttyTHS0 115200 raw -echo
# cat /dev/ttyTHS0 &
# echo "test" > /dev/ttyTHS0

Or you can try using legacy UART driver instead of Tegra High Speed UART driver.

		serial@c280000 {
+			compatible = "nvidia,tegra194-hsuart";
+			compatible = "nvidia,tegra20-uart";
			reg = <0x00 0xc280000 0x00 0x10000>;
			interrupts = <0x00 0x72 0x04>;
			clocks = <0x03 0x9d>;
			resets = <0x03 0x66>;
			status = "okay";
			reset-names = "serial";
			phandle = <0x400>;
		};

The node for serial@c280000 should become /dev/ttyS0.

I tried using your approach for testing the serial port. I connected a jumper cable between the tx and rx pin.

With both the tegra194-hsuart and the tegra20-uart i don’t get any data over the serial port.

root@ubuntu:/home/nvidia# stty -F /dev/ttyS0 115200 raw -echo
root@ubuntu:/home/nvidia# cat /dev/ttyS0 &
[2] 3902
root@ubuntu:/home/nvidia# echo "test" > /dev/ttyTHS0
root@ubuntu:/home/nvidia# echo "test" > /dev/ttyTHS0
root@ubuntu:/home/nvidia# echo "test" > /dev/ttyTHS0
root@ubuntu:/home/nvidia# echo "test" > /dev/ttyTHS0
root@ubuntu:/home/nvidia#

Any other suggestions what i could try?

Sorry that I can give you limited help for this as we don’t verify it locally.
It may still be affected by other firmwares.
Could you use other UART interface instead? Or using USB to serial devices?

I am trying to, but the M2 slot is not very practical for connecting a serial port. I will need a custom made pcb. USB connection can be unreliable some time in case of Drone application. And actually in my application all USBs are taken and i would like to avoid a usb hub. The pinout for the serial port exists so the idea would be to just repurpose it. And have a reliable hard-wired serial port.

There may be also some module like SPI-to-Serial which may help for your case.
For the debug UART port, I don’t think it is a reliable UART as many firmware still output logs there.
You might need to enable HW flow control (RTS/CTS) for the reliable UART transaction.

What’ your use case of the UART1 from 40-pins expansion header(J12)?

It might not be reliable. I still would have liked to try it out. Unfortunately i wasn’t able to get any data out at all. The only case was when i just disabled the output from the system and used baudrate 115200 using /dev/ttyTCU0. But apart from that whatever i tried to get /dev/ttyTHS0 to work failed.

UART1 is used for a telemetry connection. I have actually 4 serial devices connected to the board, which i have to connect through usb adapters. Would be really beneficial to have more hardware serial available.

This is for Tegra Combined UART and you should use Tegra High Speed UART driver with serial@c280000 instead.

I would suggest using AGX Orin instead, there are 5 UART interfaces and 4 of them can be used for custom usage.