简体   繁体   English

Linux下的USB批量传输超时,而它在Windows下工作

[英]usb bulk transfer timeout under Linux while it works under Windows

[Edit: I found the reason, see below] [编辑:我找到了原因,见下文]

The problem:问题:

I created a "driver" for a device in Windows using Python (PyUSB and libusb-win32).我使用 Python(PyUSB 和 libusb-win32)为 Windows 中的设备创建了一个“驱动程序”。 While this software works seamlessly on multiple PCs under Windows, using my Linux (Kubuntu 18.10) test laptop, a sequence of bulk writes of length 512 bytes each times out after the second 512 byte bulk transfer.虽然该软件在 Windows 下的多台 PC 上无缝运行,但使用我的 Linux (Kubuntu 18.10) 测试笔记本电脑,在第二次 512 字节批量传输之后,每次长度为 512 字节的批量写入序列超时。

Interesting: I also tried the same using VirtualBox.有趣:我也尝试过使用 VirtualBox。 And it turns out using a Windows guest via VirtualBox on the same Linux host, the same error still occurs.事实证明,在同一台 Linux 主机上通过 VirtualBox 使用 Windows 来宾,仍然出现相同的错误。 So it is not because of所以这不是因为

The question:问题:

What can happen under Linux does not happen under Windows that causes a timeout [Errno 110]?在 Linux 下会发生什么在 Windows 下不会发生导致超时 [Errno 110]?

More information, in case it helps:更多信息,以防万一:

  • Under Windows, Wireshark shows timing differences between two of the bulk writes of 6 ms for the first one and 5 ms for every following, while under Linux the delta is only round about 3 ms, which are mostly resulting from a sleep operation (relevant Python source code is attached).在 Windows 下,Wireshark 显示两次批量写入之间的时间差异,第一次为 6 毫秒,随后为 5 毫秒,而在 Linux 下,增量仅为约 3 毫秒,这主要是由于睡眠操作(相关 Python附上源代码)。 Doubling that time does nothing.将时间加倍没有任何作用。
  • dmesg shows messages like 'bulk endpoint ## has invalid maxpacket 64', where ## is 0x01, 0x08 and 0x81. dmesg 显示诸如“bulk endpoint ## has invalid maxpacket 64”之类的消息,其中## 是 0x01、0x08 和 0x81。
  • The device only has one configuration.该设备只有一种配置。
  • The test laptop has only USB 3.0 connectors, where the Windows PCs have both USB 3.0 and 2.0.测试笔记本电脑只有 USB 3.0 连接器,而 Windows PC 有 USB 3.0 和 2.0。 I tested all.我都测试过了。
  • Wireshark shows the device answering with another (empty) bulk on every bulk write under Linux, while it does not show that under Windows.在 Linux 下,Wireshark 在每次批量写入时显示设备以另一个(空)批量应答,而在 Windows 下不显示。 As far as I understand, that is because USBPcap cannot capture handshakes under Windows.据我了解,那是因为 USBPcap 无法在 Windows 下捕获握手。 But I am not shure with that, because I do not know if this type of response would really be classified as "URB_BULK out".但我不同意,因为我不知道这种类型的响应是否真的会被归类为“URB_BULK out”。
  • I tried libusb0, libusb1 and OpenUSB as backends under Linux, without success.我在 Linux 下尝试了 libusb0、libusb1 和 OpenUSB 作为后端,但没有成功。
  • The bulk transfer in question is the transfer of FPGA firmware to the device.有问题的批量传输是将 FPGA 固件传输到设备。
  • I am able to communicate with the device before the multiple-512 byte-chunk bulk operation on the same endpoints using only a few bytes.我能够在仅使用几个字节的同一端点上进行多个 512 字节块批量操作之前与设备进行通信。 The code that then causes the timeout is the following one in the second iteration of this for loop:然后导致超时的代码是此 for 循环的第二次迭代中的以下代码:
for chunk in chunks: # chunks: array of bytearrays with 512 bytes each
    self.write(0x01,chunk)
    time.sleep(0.003)

[Edit] The reason I found out that this only occurs on my test laptop using xhci, not on a second Linux test machine using ehci. [编辑]我发现这仅发生在我使用 xhci 的测试笔记本电脑上,而不是使用 ehci 的第二台 Linux 测试机器上的原因。 So this might be caused by xhci.所以这可能是由 xhci 引起的。 I do not yet have a workaround, but this at least gives an explanation.我还没有解决方法,但这至少给出了一个解释。

It turns out that the device requested less bytes per packet, the desired amount of bytes (64) could be found in dmesg as already written in the question.事实证明,设备每个数据包请求的字节数较少,可以在dmesg找到所需的字节数(64),正如问题中已经写的那样。 Since xhci doesn't support that officially, Linux decided to ignore that request.由于 xhci 不正式支持,Linux 决定忽略该请求。 Windows seemingly went with it and split larger packets up in the requested packet size. Windows 似乎采用了它,并按照请求的数据包大小拆分了较大的数据包。 So the solution was to manually split the data to packets of 64 byte size before transferring it.因此,解决方案是在传输之前手动将数据拆分为 64 字节大小的数据包。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM