【问题标题】:Weird (py)serial linux corruption奇怪的(py)串行linux损坏
【发布时间】:2016-11-30 21:46:40
【问题描述】:

我有一个基于 Atmel SAMA5D36 的 Linux SBC。我有另一个设备通过 /dev/ttyS2 通过 TTL 线 (115200 8N1) 连接到它。使用 pyserial,我与该设备进行了相当高带宽的查询/响应对话。

定期(至少每分钟一次),我看到从其他设备返回的日期非常可重复地损坏。如果它要回复一些文本,例如

"123456" (ascii character values)

它将删除一个字符并在以下字符后添加字符0:

"13\x00456"

希望这很清楚。它将删除 2,下一个字符如预期,字符 0 跟随,然后恢复正常。

我正在使用内核 4.1.10。通过一些调试语句,我很确定这不会发生在我的 python 循环中,因为 0 出现在 read() 缓冲区的随机位置。我还在传入线路上连接了一个示波器,并验证了线路没有携带这种损坏。

我正在寻找一个答案,可以让我找到正确的方向,弄清楚为什么会发生这种情况。 CPU 负载确实似乎会增加频率(例如,当我为连接的 BLE 适配器执行一堆 DBUS 流量时)。

【问题讨论】:

  • “相当高的带宽”是什么意思?你说你已经“验证了电线没有携带这种损坏”——如果这个错误每分钟只发生一次并且有大量数据流动,那么对于模拟示波器来说这实际上是相当困难的。一种可能性是您的 SBC uart 超出串行 Rx 可能是因为其他更高优先级的中断正在阻塞 uart 超过 80us-ish,这是 115200 波特的字符时间。或者如果 uart 有例如一个 16 字节的 rx fifo,并且中断被阻止超过 1 毫秒,尽管这听起来不太可能。
  • 明天我会在机器旁进行检测,以获得关于高带宽的更多数字答案。
  • 我使用可以对流进行串行解码的 PicoScope 验证了线路上没有损坏(正确的是它插入 Linux SBC 上的引脚)。通过让我的软件在我检测到意外的零时驱动一个 gpio 引脚,我可以触发其上的范围,然后逐个字符比较输入的内容,以及在 pyserial 端输出的内容。
  • 有什么方法可以计算出 rx fifos 有多大? Linux DTS 是否公开了这一点?还是我需要去数据表潜水才能弄清楚。是否有任何低级 linux 工具可以让我点击串行端口接收并帮助找出损坏进入的位置?
  • 有fifos:查看数据表。低级 linux 工具:抱歉,不知道。如果 uart 有 fifos,如果驱动程序没有启用它们,那将是令人惊讶的 - 但是值得检查它确实启用了。

标签: python linux serial-port pyserial


【解决方案1】:

这可能是溢出错误的结果。如果您查看 atmel_serial,您可以查看是否有任何错误。

cat /proc/tty/driver/atmel_serial

例如在 ttyS2 上,您可能会看到类似这样的内容(oe: 显示溢出错误):

2: uart:ATMEL_SERIAL mmio:0xF0020000 irq:31 tx:266758 rx:361385 oe:51 RTS|DTR|DSR|CD|RI

由于您是高速串行,您可以尝试在 USART 线路上实现 DMA。通过将以下内容添加到您的 usart 设置来调整内核中适当的 dts 文件:

atmel,use-dma-rx;
atmel,use-dma-tx;

对于我的内核,我必须禁用 SPI 和 I2C,以便有足够的 DMA 通道可用于 USART。

【讨论】:

  • 这让我明白了!谢谢!也升级到了更新的内核。
猜你喜欢
  • 2011-08-20
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 2013-04-14
  • 2020-02-26
  • 2012-11-17
相关资源
最近更新 更多