Skip to content

ttyAMA0 (PL011) driver data corruption #4453

Open
@DodoB

Description

@DodoB

The Bug

Data received on ttyAMA0 (on the Raspberry Pi 4B GPIO header) exhibits data corruption on received data. The os is Raspbian with kernel verison 5.4.72-v7l+ (Linux raspberrypi 5.4.72-v7l+ #1356 SMP Thu Oct 22 13:57:51 BST 2020 armv7l GNU/Linux). I am seeing this at high data rates (3Mb/s) but I am sure it is not a hardware issue (see details below). The type of corruption is not related to changed values, due to fliped bits or such. It involves missing and added bytes.

To reproduce

Send data to the serial port. This may be done from an external device or simply by looping the port back to itself. Compare the received data against the original data. I have verified the signal quality with an oscilloscope and do not see any issues. The signal is very clean. I also use a USB serial adapter to simultaneously receive from the same line. The USB adapter (FTDI based) receives the data clean, while ttyAMA0 shows the problem. Note that the occurrence is unpredictable. Sometimes it shows up after only a few transmissions, sometimes it requires well over 100k transmissions before it shows.

The occurrence seems to be much higher with a high transmission frequency (every few ms) and data packets of varying sizes (random data). But this might simply be a time thing. Other activity on the machine also seems to have an influence, the more activity the more likely a data corruption occurs. It is my impression that a race condition in the driver may be involved.

In situations where transmissions are single byte or very short, this might look like the transmission was not received or the data byte was corrupted and might be mistaken by an observer for a hardware issue.

I am attaching C source code for an application that can run the test, including simultaneous reception from a second serial port. If started with -s on the command line it will automatically stop upon encountering the problem and produce a dump of the faulty data. To run the test, jumper the serial port on the GPIO adapter to loop it back to itself. To verify good data reception, connect a 3.3V logic level serial/USB adapter to the Raspberry Pi and list the path for that adapter (probably /dev/ttyUSB0) on the command line.

Expected behavior

Data is received exactly as sent.

Actual behavior

The received data may be corrupted in all sorts of ways. There may be more data than sent (quite rare), there may be less data than sent with changed bytes (quite frequent) there might be the same amount, but bytes have changed.

A pattern as the following is quite frequent.

  • T denotes the transmitted packet of data
  • P denotes the data receved on the primary channel (the une under test, i.e. ttyAMA0)
  • R denotes the reference channel (the serial/USB adapter)
    ^ indicates the location where the (first) error was detected.

T |44|AE|93|2E|F7|49|47|90|1C|48|DD|BE|06|40|82|48|85|43|BF|16|DD|27|79|53|9F|08|6D|F4|9D|03|74|61|30|87|0E|A6|CF|54|B5|6A|
P |44|AE|93|2E|F7|49|47|90|1C|48|DD|BE|06|40|82|48|85|43|BF|16|DD|27|79|53|9F|08|6D|F4|9D|03|74|61|87|00|0E|A6|CF|54|B5|6A|
R |44|AE|93|2E|F7|49|47|90|1C|48|DD|BE|06|40|82|48|85|43|BF|16|DD|27|79|53|9F|08|6D|F4|9D|03|74|61|30|87|0E|A6|CF|54|B5|6A|
^

Note that 30h is missing, 87h is correct, but shows in place of the missing 30h, followed by a 00h that does not exist in the original data. Then the data stream goes on without error. The reference data received from the USB adapter matches the transmitted packet. The missing byte and the next byte followed by 00h shows up a lot, also in connection with other types of corruption, such as fewer total bytes received.

Logs

The following logs show a few select scenarios.


Error showed after 119845 packet transmissions. In this case data was received from the tty driver in two fragments.

Transmission count = 119845
Error count = 1
Max skip count = 16
Error type = 5
Bytes transmitted = 45
Primary received = 44
Reference received = 45
Data:
T |91|D8|C6|4B|F2|8E|50|0A|19|B0|F2|5B|D0|C8|7C|50|B4|74|30|8F|03|39|83|6E|13|8E|97|FA|E8|4F|A4|F8|A6|E9|C3|99|F6|92|22|10|42|14|6A|92|5B|
P |91|D8|C6|4B|F2|8E|50|0A|19|B0|F2|5B|D0|C8|7C|50|B4|74|30|8F|03|39|83|6E|13|8E|97|FA|E8|4F|A4|F8|C3|00|99|F6|92|22|10|42|14|6A|92|5B|
R |91|D8|C6|4B|F2|8E|50|0A|19|B0|F2|5B|D0|C8|7C|50|B4|74|30|8F|03|39|83|6E|13|8E|97|FA|E8|4F|A4|F8|A6|E9|C3|99|F6|92|22|10|42|14|6A|92|5B|
^
Primary channel fragments
|91|D8|C6|4B|F2|8E|50|0A|19|B0|F2|5B|D0|C8|7C|50|B4|74|30|8F|03|39|83|6E|13|8E|97|FA|E8|4F|A4|F8|C3|00|99|
|F6|92|22|10|42|14|6A|92|5B|


Transmission count = 118443
Error count = 1
Max skip count = 16
Error type = 5
Bytes transmitted = 59
Primary received = 57
Reference received = 59
Data:
T |E8|8B|82|B6|24|D9|4E|2C|38|C3|B8|DE|C1|7C|57|43|0B|50|BF|2A|E5|2E|B9|BD|BE|15|1B|39|08|39|23|EF|43|A4|26|67|FD|F2|12|35|B5|C9|93|76|C4|E9|B8|CF|39|F6|F8|1F|25|31|5B|62|46|75|1A|
P |E8|8B|82|B6|24|D9|4E|2C|38|C3|B8|DE|C1|7C|57|43|0B|50|BF|2A|E5|2E|B9|BD|BE|15|1B|39|08|39|23|EF|43|A4|26|67|FD|F2|12|35|B5|C9|93|76|C4|E9|B8|CF|39|F6|F8|5B|00|62|46|75|1A|
R |E8|8B|82|B6|24|D9|4E|2C|38|C3|B8|DE|C1|7C|57|43|0B|50|BF|2A|E5|2E|B9|BD|BE|15|1B|39|08|39|23|EF|43|A4|26|67|FD|F2|12|35|B5|C9|93|76|C4|E9|B8|CF|39|F6|F8|1F|25|31|5B|62|46|75|1A|
^
Primary channel fragments
|E8|8B|82|B6|24|D9|4E|2C|38|C3|B8|DE|C1|7C|57|43|0B|50|BF|
|2A|E5|2E|B9|BD|BE|15|1B|39|08|39|23|EF|43|A4|26|67|FD|F2|12|35|B5|C9|93|76|C4|E9|B8|CF|39|F6|F8|5B|00|62|46|75|1A|


Transmission count = 1
Error count = 1
Max skip count = 0
Error type = 1
Bytes transmitted = 29
Primary received = 30
Reference received = 29
Data:
T |98|A3|56|54|BF|F2|FD|FA|7A|6C|53|15|14|EA|E3|2E|52|8F|20|57|09|58|28|A8|06|D5|D1|53|83|
P |98|00|A3|56|54|BF|F2|FD|FA|7A|6C|53|15|14|EA|E3|2E|52|8F|20|57|09|58|28|A8|06|D5|D1|53|83|
R |98|A3|56|54|BF|F2|FD|FA|7A|6C|53|15|14|EA|E3|2E|52|8F|20|57|09|58|28|A8|06|D5|D1|53|83|
^
UARTTest.c.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions