工具/软件:Linux
我使用的是基于 TI EVM 的 AM437x 定制板。
我已经使用 ti-processor-sdk-linux-am437x-evm-04.00.04中的 Linux 内核以及 Linux 主线复制中的更新版本(4.12.y、4.3.4.3.y、4.14.y)进行了测试。 都表现出以下行为。
我需要通过 UART (ttyS2)接收"高速"(1.5Mbs - 3Mbs)数据。 我使用默认的中断驱动接收器获得 RX 溢出、因此我在器件树中为该 UART 启用了 DMA。 串行端口已配置为传递原始数据、并且所有流控均已关闭。 我在逻辑分析仪上捕获了串行数据、传输的数据是正确的。
启用 DMA 后、传输包含额外的 NULL 字节。 也就是说、当我发送8192字节的有效载荷时、我有时会接收到更多的8192字节。 额外的字节始终为0x00、并且保留的数据是正确的。
为了进行测试、我生成了一个8k 文件、其中包含重复512次的以下字符串"0123456789ABCDEF"。 以下是源文件的 hexdump:
hexdump -C /root/8k 00000000 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 |0123456789ABCDEF| * 00002000
我使用以下命令发送和接收了数据:
CAT /dev/ttyS2 >/tmp/dump & Sleep 1;cat /root/8k >/dev/ttyS4;Sleep 10;kill -HUP %1;Sleep 2;wc /tmp/dump;hexdump -C /tmp/dump
休眠只是为了确保流程"就绪"。 以下是捕获额外的0x00时上述命令的输出示例:
0 1 8248 /tmp/dump
00000000 30 31 33 34 35 36 37 38 39 41 42 44 45 46 |0123456789ABCDEF|
*
000000c0 00 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 |.0123456789ABCDE|
000000d0 46 30 31 32 33 35 36 37 38 39 41 42 43 44 45 |F0123456789ABCDE|
*
00000140 46 00 00 00 00 30 31 32 33 34 35 36 37 38 39 41 | F....0123456789A|
00000150 42 43 45 46 30 31 33 34 35 36 38 39 41 | BCDEF0123456789A|
*
0000042 43 44 45 46 30 31 00 00 00 00 32 33 34 35 | BCDEF01..... 2345|
00000730 36 37 38 39 41 42 43 44 45 46 30 31 33 34 35 |6789ABCDEF012345|
*
00001380 36 37 38 39 41 42 43 44 45 46 00 00 00 00 00 00 00 |6789ABCDEF... |
00001390 00 30 31 33 34 35 36 37 38 39 41 42 43 44 45 |.0123456789ABCDE|
000013a0 46 30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 |F0123456789ABCDE|
*
000015d0 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | F. |
000015e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.......... |
000015f0 00 30 31 33 34 35 36 37 38 39 41 42 43 44 45 |.0123456789ABCDE|
00001600 46 30 31 33 34 35 36 37 38 39 41 42 43 44 45 |F0123456789ABCDE|
*
00001970 46 00 00 00 00 00 00 00 00 00 00 00 30 31 32 33 34 35 36 37 | F. 01234567|
00001980 38 39 41 42 43 44 45 46 30 31 32 33 34 35 36 37 |89ABCDEF01234567|
*
00002038
额外的56个字节是0x00。 其他8192个字节与源文件匹配。 如上所示、额外的0x00被插入多个位置的流中。
使用标准内核模块、Rx DMA 大小设置为48字节、具有48字节 FIFO 阈值和48字节 DMA 突发大小。 在一个 DMA 传输结束时、驱动程序直接从 UART FIFO 读取任何剩余的字节、然后启用另一个 DMA 传输。
使用自定义内核、我确定了额外的0x00发生在从 UART FIFO 到存储器的数据 DMA 期间、而不是直接读取期间。 此外、在第一个 DMA 传输中(在打开串行端口之后)没有出现额外的0x00。 我认为0x00是由从空 FIFO 读取 DMA 引起的。
我还使用1k 的较大 DMA 缓冲区大小进行了测试、具有各种 FIFO 阈值并匹配 DMA 突发大小。 在这些测试中、前1k 数据始终正常、在一个 DMA 传输结束和下一个传输开始之间从 FIFO 直接读取的字节始终良好。 在 DMA 传输期间、额外的0x00可能会出现在任何位置(例如、从252字节开始进入1k 缓冲区、阈值= 16突发= 16)。
似乎在 FIFO 有足够的数据之前触发了 DMA。 也许在随后的传输开始时 DMA 被错误地触发、并且需要几个传输来"捕捉"并取代 FIFO。
我没有发现任何与上述问题直接相关的勘误表、TRM 对 UART 的 Rx 触发器有些模糊。
这是杂散触发器吗? 是否有解决方法? 还有人注意到这个问题吗?