【发布时间】:2019-08-21 13:01:56
【问题描述】:
我有一个 FPGA,它通过 FT2232H 在 USB 总线上传输数据,我观察到大约 10% 的数据必须丢弃,因为帧中的某些字节丢失了。以下是技术细节:
- FPGA 是 Artix 7。每 9 ms 准备好一批 4002 字节。这样算出 444,667 字节/秒的数据。
- 我的笔记本电脑在 Ubuntu 18.04LTS 上运行 python 3.7(来自 anaconda)
- FPGA/FT2232H 通过以下初始化行打开:
SYNCFF = 0x40
SIO_RTS_CTS_HS = (0x1 << 8)
self.device = pylibftdi.Device(mode='t', interface_select=pylibftdi.INTERFACE_A, encoding='latin1')
self.device.ftdi_fn.ftdi_set_bitmode(0xff, SYNCFF)
self.device.ftdi_fn.ftdi_read_data_set_chunksize(0x10000)
self.device.ftdi_fn.ftdi_write_data_set_chunksize(0x10000)
self.device.ftdi_fn.ftdi_setflowctrl(SIO_RTS_CTS_HS)
self.device.flush()
- 然后通过这个简单的行读取数据:
raw_usb_data = my_fpga.device.read(0x10000)
我观察到以下情况:
- 每批我总是得到
0x10000的数据,这正是我所期望的。 - 使用 device.read 一次读取 2**16 = 65,536 字节应该需要 147.4 毫秒,因为每 9 毫秒就准备好一批。但是对该线的计时给出了 143 毫秒的平均值,标准偏差为 6.6 毫秒。
我的第一个猜测是某处没有缓冲区/很小的缓冲区,并且由于操作系统(优先级问题?)或 python(垃圾收集?)在某个时间点做其他事情太久而丢失了一些信息。
如何减少读取设备时丢失的字节数?
【问题讨论】:
-
FPGA 是否发送二进制数据,但您告诉
Device处于文本模式? -
是的,好点。 FPGA 发送二进制数据,由 Device 以文本模式读取,然后转换为
bytes进行处理。我需要更新它,但我可以确认当设备设置为二进制模式时我遇到了同样的问题。很抱歉造成混乱! -
FT2232H 具有 4kB 内部缓冲器。你很有可能受到它们的限制。对于我的应用程序,我使用 pyserial 和一个子进程来收集数据并通过管道将它们发送到主进程以解决 GIL。管道本身在 Windows 下有一个约 8kb 的内部缓冲区,因此有时也必须对其进行调整。不确定 plibftdi 在内部做什么,以及切换到普通 VCP 是否适合您。
-
啊,“偏差”是正常的,因为我们正在谈论 USB。它的行为基本上就像一个“面向共享数据包的管道”,具有草率的时序保证。可以通过更改驱动程序的延迟设置(至少在 Windows 下)来减少延迟,但永远不会得到它。
-
啊!我不知道这一切。谢谢你提供的详情。你有链接到我可以用来开始与人打交道的示例代码吗?我从未使用过那个包,但如果我能绕过 GIL 并最终能够停止丢弃字节,那就太好了!