Jetson Nano UART

On power up of the Nano dev kit, there is a burst of information sent out on the UART #2 TxD pin on J41. We are trying to use UART #2 (TxD is on pin #8 on the J41 header) for communicating with an external board, and this power-up burst is causing our communication to be corrupted. I can solve this by just ignoring the power-up burst, but if it ever repeats (ie, if the Nano is reset but the external board is not) then we get the data corruption problem again.

What is actually being sent, what causes it to be sent, exactl when is it sent, and is that burst of info exactly the same every time or does it vary? The more I know about what it is, the more likely I can manage our response to it when it occurs.

Thank you

What you’re seeing is that this is used for the serial console. Normal UARTs, which are free, are group “dialout”, while a console is group “tty”. Take a close look at what is group “dialout” versus “tty” from:
ls -l /dev/ttyS* /dev/ttyTHS*

Within Linux (there are also bootloader stages) you can disable serial console with:

sudo systemctl stop nvgetty.service
sudo systemctl disable nvgetty.service

(then check group of the UART and it should once more be dialout)

You might need to alter device tree and “/boot/extlinux/extlinux.conf” if you want to disable this during earlier boot stages.

Thank you; that worked for me. All I had to do was use the 2 sudo commands and the burst of info on the UART line at powerup was permanently disabled.

However, I am not completely understanding what this is all about . What was the source of the info being sent out originally on the serial console, and was it triggered by the OS starting or something else? Also, is there something I can read to get more background on tty vs ttyTHS and ngetty.service,or whatever else is relevant?

Yes, the kernel produces log messages about its progress and features during boot. If something were to go wrong, then those log messages are quite useful. That function was 2-way, and you could have logged in and worked on the system with serial console as a very simple text-only interface. It is in fact one of the most useful debug tools you will find in the embedded world. This is what owned the UART, and your program was intruding on it, basically typing whatever it did into a login prompt. Now the serial console program no longer owns this UART so it is free to use (you might still get a boot hang if your program outputs to the UART at just the wrong moment during boot since boot stages likely still see input).

Most any UART can be used as serial console. The topic of ttyS# versus ttyTHS# is almost unrelated. The ttyS# designation is the original legacy driver, and this does not use DMA. The ttyTHS# driver is the “Tegra High Speed” driver, a version of the ttyS# legacy driver. Both drivers often run on the same UART, although you should not (but could) use both simultaneously. The hardware is compatible with both drivers, but the THS driver might be more efficient. The reason why the THS driver is not used in serial console is because the boot stages are not Linux, and they do not have the THS driver; those stages have been around a very very long time and use the legacy driver. One would lose boot message content if the transition from boot to Linux kernel required resetting the UART/driver. Using the ttyS# driver even after boot implies continuity of service for serial console. Still, both a legacy device and THS device are the same device, they just use different drivers at the same time (serial console only uses one at a time, this is good; mixing a second application at the same time is bad regardless of whether or not they both use legacy or THS, but not knowing THS is the same physical device tricks people into thinking they can do it).

You could just do a Google search for “linux serial console”. This is in general quite common in the embedded world, although it can be used in a PC as well. Since all it does is take a series of bytes and write them or read them it is far simpler than installing a graphics driver or networking; when all else crashes and burns a serial console tends to work. An excellent way to debug broken hardware or software.

nvgetty.service is just the modern way of enabling serial console. When the kernel loads it is process ID 0 (PID 0). The kernel runs only one program, and that program is init (PID 1). init used to just be a series of shell programs and drivers not arranged in any particular way except by custom. systemd is a daemon replacing old style init. The tool for interacting with systemd is sysemctl. Systemd organizes a more modular way of specifying services and conditions used in boot or shutdown. One can specify some synthetic boot stage, and what prerequisites are needed, plus what is to run in that boot stage, followed by telling systemd to go to that state. Example: mutli-user.target is multiple user login, text-mode only, while graphical.target is multiple user login, but using the GUI. If you kill the system and shut it down via “sudo killall -HUP init”, then this is essentially systemd being told to go to the shutdown stage.

To see customization of the init process via systemd examine the human readable files at “/etc/systemd”. Some of these are just symbolic links into unmodified system files somewhere under “/lib/systemd/system”. As an example, the system will boot to a default target, and for a Jetson this is “graphical.target”. If you go to “/etc/systemd/system” you will find a symbolic link named “default.target”, and this points to the real file “/lib/systemd/system/graphical.target”. Looking under this you will find a set of specifications. Those specifications work with other systemd files to produce a chain of what services or targets produce the required chain of boot events. It is basically a solver of dependencies something like a Makefile, but it boots instead of compiling. nvgetty.service is optional and can be told to work or not work, and becomes a dependency in a chain when enabled.

OK, I really appreciate the detailed answer; thank you for taking time to explain that. I have a much better understanding of what is happening now.

We should be OK from this point on; our application won’t start sending data over the UART until at least 5+ seconds after the OS is up. The external board is ready to receive data from our app within 350 msec of powerup (Nano and external board power up at same time) and that is where the problem originally occurred.

If there is no output from your end of the UART during boot there isn’t anything to worry about. However, if this is at a remote location, and something were to go wrong, then there is a risk that reboot would fail, e.g., suppose it had to be rebooted at a remote location or on a drone in flight. Just beware that during early boot stages output at the wrong moment would cause this to go into a serial console boot prompt.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.