Ttl uart lost data error

I use serial communication, part of the data transmission error, especially over 10000 bytes of big data
If the odd or even party is open, the error rate is higher;

how can open the DMA mode for serial port communication,

I probably can’t answer what you really need to know, but realize that any given UART will typically have two different files for it in “/dev”. Each file is a different driver for the same UART (you would not want to mix back and forth between drivers…“bad things” might occur, it isn’t predictable when two drivers both try to operate on the same hardware at the same time).

When you see “/dev/ttyS2” and “/dev/ttyTHS2” you are looking at two drivers for a single UART. The “ttyS#” designation is the old style traditional driver, and is supported even in early boot stages prior to Linux loading. The “ttyTHS#” is the “Tegra High Speed” version of the driver, and this is DMA enabled. If you talk to “/dev/ttyS2”, then you are not using DMA; if you are talking to “/dev/ttyTHS2”, then you are talking to the same UART with DMA being used.

I won’t be able to answer the error question, but you’ll want to state which tty you are using. You’ll also want to run “ls -l /dev/tty...” (adjust for your particular tty) and make sure it is group “dialout”. If it is group “tty”, then you’re trying to use the serial console port (which is already in use).

I use port on the / dev / ttyths2 , because the hardware uses this port. Because my data is very large,so I need to start DMA node on the /dev/ttyTHS2. How can I modify the driver for serial dirver

kernel log output,
/media/uart$ [13245.203377] serial-tegra 70006200.serial: RxData PIO to tty layer failed

so, I think that it is PIO mode for ttyTHS2 port ,not open the DMA mode
the ttyTHS2 hw addr should be 70006040
the log :
[ 21.412071] tegra-i2c 7000c700.i2c: i2c transfer timed out addr: 0x50
[ 22.461920] dma dma0chan9: Dma length/memory address is not supported
[ 22.473777] serial-tegra 70006040.serial: Not able to get desc for Rx
[ 22.480959] serial-tegra 70006040.serial: Not able to start Rx DMA
[ 22.490036] serial-tegra 70006040.serial: Uart HW init failed, err = -5

it is the log
nanocom16_2020-12-19_15-36-52.log (552.9 KB)

The “ttyTHS2” driver is already DMA. No modification is required.

Your logs show a lot of i2c errors though. Is this a dev kit carrier board, or third party? I’m guessing third party, and that the device tree is wrong (leading to i2c failures prior to the UART ever showing up).

Then there are also a very large number of serious kernel errors. Basically the whole system is one big error, and I suspect that if you use a third party carrier board, then the firmware for that board is missing or incorrect. Can you say more about the carrier board, and whether or not there is any kind of firmware/device tree edit?

Also, mention if the monitor is purely HDMI, or not used, so on.

nanocom16_2020-12-22_09-18-21.log (28.8 KB)
The carrier board is developed by us,According to the schematic diagram on your website

The previous log is that I create root and nano users,upgrading the application, then I copy the rootfs,and directly replace original rootfs, then make a upgrade package . After finish update , HDMI can’t be turned on after the machine is flushed, but we don’t need a graphical interface,

The following log uses the original rootfs. We add an encryption chip to the device tree, so I2C is used and i2c0 is used

I short-circuit TX, Rx, and then use the serial port for communication, each send a certain number of bytes, such as sending 0xff, received 0x0;(baud rate is 500000 o115200 bps)
and If I just send and don’t accept the data, the log(serial-tegra 70006200.serial: RxData PIO to tty layer failed
) will be output soon
so I judge that DMA is not in effect and PIO is in effect

I don’t have enough knowledge to help with a custom carrier board, but I can tell you the large number of i2c error messages are unusual. This is quite possibly device tree related.

There are different methods for the device tree to be made available. Sometimes this is as a partition, and at other times the tree is named in the “/boot/extlinux/extlinux.conf” configuration file as the FDT key/value pair. There is a possibility that depending on your rootfs the device tree might not be coming from where you think it is.

There is a similar story for the initial ramdisk. If the state of hardware depends on that initrd, and the initrd is not what you expected, then behavior might be completely wrong due to starting in the wrong state when the rest of the rootfs takes over.

Normally the ttyS# UART designation does not use DMA. the ttyTHS# UARTs automatically use DMA. The “compatible” part of the serial@... UART designation of the device tree is what names which drivers are allowed. There are other parameters around this though, and it is possible that one of those other parameters needs to be changed for your carrier board…don’t know.

One thing I would suggest is to examine any part of your device tree related to the UART, and compare what you think it is to what actually occurs in “/proc/device-tree”. Make sure the tree you actually think is in place really is there. I would also consider comparing your “serial@...” entry to a default system and see if anything at all differs.

The I2C error has nothing to do with the serial communication data error. I2C error, i.e. error reporting in camera and HDMI,these two devices is not existed . Error reporting is normal;

Now the problem is that serial communication data error; serial port parameters using odd ; data error is more;When communicating, if the sending data is small, no error is found,Of course, we didn’t test for a long time,

sometime ,output log :ttyTHS ttyTHS2: 6 input overrun(s)

test1.txt (314.3 KB)

testcrcerror.txt (316.4 KB)

The attachment test1.txt is the hexadecimal data I sent, testcrcerror.txt It’s the data I received, using port ttyths2

the serial devices:

When I see unexpected i2c errors it makes me worry that the device tree might have other issues.

I noticed that the particular data happens to be the boot record of an older BIOS style partition or boot record. The “aa 55” would be the “magic bytes” of the partition scheme. Looks like this is from a PC using GRUB as the bootloader, and the bytes come from the start of an MBR or other partition record, but extend much further than the actual boot record. Was the data obtained via dd of a hard drive? If not dd, then by what method?

I put the two files through “kdiff3”. The first thing I noticed is that one is a Unix style end of line, the other is a Windows style end of line according to kdiff3. More on this below, “end of line” can probably be ignored as just a quirk of how kdiff3 is interpreting this.

How was the data saved? Did it go through any application (other than dd), or was it redirected to a file? Do all involved systems use the same character encodings? See “echo $LANG” on both systems. Many applications don’t care about encoding, but some do.

The overrun is probably important. Can you say more about the overruns? Any detail might be important. Was there an overrun associated with the two attached files test1.txt or testcrcerror.txt? Is there any sort of log you can provide which mentions the overrun? What speed was used for the transfer, and have you tried the same data at lower speeds (if lower speeds fail differently, or not at all, then the issue is probably different than if the same failure occurs no matter what speed is used). It is worth noting that the UART clock is not an exact match to what it should be once you surpass speed 115200, and above this two stop bits are generally required.

Included is a screenshot showing the first error, and possibly why the “Unix versus Windows End of Line” question might just be the diff tool misinterpreting text versus binary data:

There is a pattern to the failures. All failures are a loss of four bytes which are replaced with NULL bytes in the diff tool. I don’t see any other pattern, so more information on the overrun error would help.

"0xAA, 0x55, 0x81 "is the packet header, "0xff, 0xff "is the packet tail. The whole packet has more than 10000 bytes
nanocom16_2020-12-23_19-13-00.log (628.5 KB)
The test1.txt file is the binary data that I need to send when I package and generate it. In order to facilitate my analysis and comparison, I save the generated binary numbers in the text file. Because the test1.txt file is stored in the window, I save it in a row of 50 columns, and the ‘\ n’ removed by test1.txt is the complete data that I send,

testcrcerror.txt The file is the binary serial data that I receive on the nano board. It is also a line of 50 binary bits, it is the complete data by removing the ‘\r\n’ at the end of each line;

This error occurs when DMA reports error,

Now we need to first solve the problem of overflow
When an overflow error occurs, log refers to the attachment

I suppose the reason for using that in a packet header is the same as the reasons 0xAA and 0x55 were chosen for the old MBR “magic bytes”.

Any chance you can record the input and output data without any kind of newline? Just purely binary data? Assuming all of the data being recorded is on Linux, then it should be possible to just redirect the content to a file via the “>” operator. If binary data can be attached as a file, then it might be possible for someone to reproduce this on loopback. That would be by far the best way to debug this. You would however need to mention the UART speed being used with that particular data. Note that if you repeat the test with the same exact input, but with different UART speeds, and if the data still corrupts at the exact same locations, then debug would be different than if the data failure occurs at different locations when speed is changed. Knowing if this is a consistent error regardless of speed will be important.

FYI, the fact that a DMA error is being reported confirms the fact that DMA is being used (or attempted). DMA is failing, or at least being attempted…I don’t know if some component is actually in the wrong mode while the rest of it is in DMA mode, but it is possible.

FYI, this is the UART at physical address 0x70006200. You can find device tree content related to this. What do you see from:

cd /proc/device-tree/serial@70006200
cat compatible
# Hit the enter key to create a newline.
cat dma-names
# Hit the enter key to create a newline.

Many of the serial UARTs have both an NVIDIA driver and an older serial driver compatible. This is the reason some UARTs have both a “ttyS#” and “ttyTHS#” device available. I am thinking that if the non-DMA ttyS# driver is removed from the compatible list (the generic driver which is not NVIDIA), then you could likely guarantee no PIO mode would be used (except if there is a logic bug in the THS driver).

output log :ttyTHS ttyTHS2: 2 input overrun(s)
I think the first problem to be solved,Because when it input overrun, the data can’t be right

cd /proc/device-tree/serial@70006200
cat compatible

cat dma-names

nano@AI_View:/proc/device-tree/serial@70006200$ cat dma-names
nano@AI_View:/proc/device-tree/serial@70006200$ cat compatible

It shows under dma-names only tx, no rx. I am using a Jetson NX for my reference, but the dma-names seems to be a problem. Can I verify this is what you saw prior to any data being passed through for the error? If there is an error, then I suppose it could alter something, but if this is how it booted, then I am suspicious.

Can someone verify that the device tree dma-names should show both RX and TX on a Nano?

tegra210-porg-p3448-common.dtsi (21.9 KB)
this is the device tree,
how can I modify it?

the ttyTHS2 port,the addess should be serial@70006040? not serial@70006200

To start with, this will probably need someone from NVIDIA to look at the question. The output of “dma-names” could be causing a problem, or it might be that the name you found is just a different convention from the other Jetsons I’ve looked at…it might not even be an error. The lack of “rx” in “dma-names” does make me suspicious since “tx” is there. Don’t fix anything with the device tree until NVIDIA can reply.

For reference, a “.dtsi” file is not an actual device tree file. This is a file for creation of some part of a tree within the kernel code. Here are some descriptions which might help:

  • .dts: Device tree source file (dtc can compile this into a .dtb binary).
  • .dtb: Device tree binary file (the one actually used at runtime).
  • .dtsi: A “C” file within a kernel which is used to create a subset of the whole .dts source file. Used under kernel “make” target “dtbs”.

Technically a device tree is not part of a kernel. However, every feature within the kernel can accept arguments which might be passed as a device tree. If a driver or some component of the kernel needs an argument passed to it which is not generic, then this is quite possibly passed via device tree as the driver or feature loads, and prevents the need for every model of some hardware needing to be coded into the kernel.

“Not generic” is most easily described with examples. If a driver can be used for hardware designed by multiple vendors, and there is nothing custom among vendors, then this is generic. If a driver needs custom information for that same hardware, then rather than placing that information in the kernel code, the non-generic specific case would typically pass information via a device tree. Devices considered “hot plug” will self-report where they are, what address to use, so on. Devices which are hard wired to some physical address on a bus cannot self-report. The address to a device and knowledge of which driver to use would typically be added by the third party hardware vendor in the form of firmware (a device tree), but use the existing generic driver (once the driver knows how to find hardware, and that the driver belongs with that hardware, you can use a generic driver on custom hardware).

If you were to build a kernel, and start with a configuration which is an exact match to your running kernel, then every feature which might need special knowledge of where to find that hardware becomes an issue. Then “make dtbs” would build device trees which are used with the features you’ve enabled. Most of the time you won’t use this since the existing tree does the job perfectly as is (just because you’ve built a new kernel it does not mean some hardware which is hard wired to a specific address on a bus would change its address). Several trees are built for a given configuration when using “make dtbs”, and you would pick which one to install.

If you changed something in a kernel which you created using a custom configuration, and if that change involved changing non-generic physical hardware on a bus, then you’d build your kernel and also build dtbs. Each would be a separate install step, but the “.dtsi” file would not be your entire tree…this would be instructions for building a subset of the tree based on particular configurations.

Long story, but you should wait for NVIDIA to comment on the “dma-names” lacking “rx” and having only “tx”. This could be correct for your case, don’t know, but I am suspicious.

nano@AI_view:/proc/device-tree/serial@70006200$ cd /proc/device-tree/serial@70006040
nano@AI_view:/proc/device-tree/serial@70006040$ cat compatible
nano@AI_view:/proc/device-tree/serial@70006040$ cat dma-names

it is right ,the port ttyTHS2 address is serial@70006040
But some of the data received is wrong

So that says that you are using the correct driver with DMA enabled. At this point I am wondering, do you have text file (with no extra embedded newlines) which you can redirect to the UART and see the missing text?

As an example, suppose one of your sample failure cases is a file named “serial_data.txt”, is around 10kb, and that the tty to use is “/dev/ttyTHS2” (implies serial console is not on this port). If in loopback mode, then this should create a second file which is an exact duplicate of the first file (but we are looking to see if data goes missing…we want a way to reproduce the issue in some non-random fashion):

# Assumes the ttyTHS2 has TX and RX wired together.
# First set up read:
sudo cat /dev/ttyTHS2 | tee copy_data.txt
sudo cat serial_data.txt > /dev/ttyTHS2

In theory that should create file “copy_data.txt”, and it should be an exact match to “serial_data.txt”. It is possible you might need to set the port to different speeds to find out if it is a problem at all speeds, or just at other higher speeds.

for serial @ 70006200 ,can not start DMA,
,the port ttyTHS2 address is serial@70006200
the port ttyTHS1 address is serial@70006040

when i modfy the devices tree ;
serial@70006200 { /* UART-C : UART3 : M.2 Key E */
compatible = “nvidia,tegra114-hsuart”;
nvidia,adjust-baud-rates = <921600 921600 100>;
status = “okay”;
After finishing modify the devices tree,flash the image
then ,I can see following information
nano@nano-desktop:/media/uart$ cd /proc/device-tree/serial@70006200/
nano@nano-desktop:/proc/device-tree/serial@70006200$ cat dma-names
rxtxnano@nano-desktop:/proc/device-tree/serial@70006200$ cat compatible
nano@nano-desktop:/proc/device-tree/serial@70006200$ cd /media/uart
nano@nano-desktop:/media/uart$ sudo ./uart_read /dev/ttyTHS2 500000
[sudo] password for nano:
[ 4246.710046] dma dma0chan9: Dma length/memory address is not supported
[ 4246.719952] serial-tegra 70006200.serial: Not able to get desc for Rx
[ 4246.726563] serial-tegra 70006200.serial: Not able to start Rx DMA
[ 4246.732879] serial-tegra 70006200.serial: Uart HW init failed, err = -5
Open com success!!!
Input/output error [serial.cpp:70]

nano@nano-desktop:/media/uart$ sudo ./uart_read /dev/ttyTHS2 115200
[ 678.420039] dma dma0chan9: Dma length/memory address is not supported
[ 678.427048] serial-tegra 70006200.serial: Not able to get desc for Rx
[ 678.433633] serial-tegra 70006200.serial: Not able to start Rx DMA
[ 678.439985] serial-tegra 70006200.serial: Uart HW init failed, err = -5

How can I modify the DMA mode?