Creating symlinks for UART in Jetson Nano and Xavier NX

Hi Team,

I have a situation where a user application could be run on either Nano or Xavier NX.

This application is supposed to communicate with a UART device connected to -

  1. Pins 8 and 10 on the J41 Header if device = Nano
  2. Pins 8 and 10 on the J12 Header if device = Xavier NX

However they map to different devices under /dev.

  1. Pins 8 and 10 on the J41 Header, device = Nano maps to /dev/ttyTHS1
  2. Pins 8 and 10 on the J12 Header, device = Xavier NX maps to /dev/ttyTHS0

I wanted to create symlink to map them to a symbolic path. (say /dev/uart/mydevice)
But I am not sure how I can check automatically within my user application whether the device is Nano or Xavier NX and deploy the appropriate udev rules file accordingly.
Is there any way to check this?


Just as a caution, many of the Jetsons will already be using this for serial console (if you use “ls -l /dev/ttyTHS*” and your device has group “tty”, then it is serial console). In such a case you can disable serial console in Linux without much effort, but disabling it in the bootloader might be a more involved effort. Under the assumption that serial console won’t interfere, then what you want is fairly easy via the “udev” system.

udev” can monitor for creation of various device special files, and trigger actions such as renaming or adding additional names via symbolic link. A good example is that human interface devices (such as mouse or keyboard) will produce many generically named “/dev/input/event*” files, but will also produce symbolic links with more easily identified names in “/dev/input/by-id/*”.

The system has a number of udev rules in the form of small human readable files. It is a simple matter to put a custom file in “/etc/udev/rules.d/”. Files there which are the same name as some unmodified version of the file take precedence; removing the “/etc” version reverts back to the original udev as if no change was ever made. Thus you can experiment with copies of existing system files added into the “/etc/udev/rules.d/” location, and then disable the file via something as simple as either deleting the custom file or using gzip to compress the file (rendering it inert so far as udev is concerned).

Check out udev for what you wish to do. Just a general list of such tutorials:
(Jetsons are no different than any other Linux computer with regard to udev)

Thanks a lot for the information.

Actually, the udev file for the user application has already been created. It gets deployed when the application is installed on the Jetson.
It has the following lines in it pertaining to THS0 and THS1.

SUBSYSTEMS==“tty”, KERNEL==“ttyTHS0”, ACTION==“add”, MODE=“666”, SYMLINK+=“uart/mydevice”, GROUP=“dialout”
SUBSYSTEMS==“tty”, KERNEL==“ttyTHS1”, ACTION==“add”, MODE=“666”, SYMLINK+=“uart/mydevice”, GROUP=“dialout”

The problem I am facing here is this sometimes leads to the symlink /dev/uart/mydevice->/dev/ttyTHS0 and sometimes it leads to a symlink /dev/uart/mydevice->ttyTHS1.
And obviously if it creates the incorrect symlink then the devices cannot communicate.

In order to solve this, I had the idea of creating 2 different udev files -

  1. For Jetson Nano which only has the udev rule for ttyTHS1
  2. For Jetson Xavier NX which only has the udev rule for ttyTHS0

and checking within the deployment scripts whether the system being deployed on is a Nano or Xavier NX and deploying the appropriate udev file. This is why i wanted to know if there is any way to programatically differentiate whether the device is Nano of Xavier NX.

I am not sure if this is the best solution or if there’s a better way to resolve this. Is there?

FYI I found a way to differentiate between Jetson Nano and Xavier NX over the terminal.
These details are present under system->product in the results of lshw.

sudo lshw -c system | grep -E ‘product:’

It does sound like the installed udev specification was written on one type of Jetson, and as you say, it would blindly assume the particular device tty. Whoever wrote the original udev spec for the device did not take into account any Jetson model other than the one the udev script was for.

You will probably find the “udevadm” tool of use. The tool can provide information which udev is capable of using. So for example, depending on which system you are on, try one of these for more information about the particular device:
sudo udevadm /dev/ttyTHS0
sudo udevadm /dev/ttyTHS1

Perhaps the “path” ("DEVPATH") could be used to differentiate. Can you verify you want “ttyTHS1” on the Nano, but device “ttyTHS0” on the Xavier NX? If it turns out that the path for ttyTHS0 and ttyTHS1 are the same, then this won’t help much, but if one of the platforms uses a different path for a specific ttyTHS0 or ttyTHS1, then you’ve found a way to tell udev which to use (you’d go by path instead of the name “ttyTHS0” or “ttyTHS1”, though you could specify both device and path). Basically, run the above “udevadm” commands for both ttyTHS0 and ttyTHS1 on both systems, and look for a difference.