USB 批量传输在 Linux 下超时,而它在 Windows 下工作
usb bulk transfer timeout under Linux while it works under Windows
[编辑:我找到原因了,见下文]
问题:
我使用 Python(PyUSB 和 libusb-win32)为 Windows 中的设备创建了一个 "driver"。虽然此软件在 Windows 下的多台 PC 上无缝运行,但使用我的 Linux (Kubuntu 18.10) 测试笔记本电脑时,在第二次 512 字节批量传输后,一系列长度为 512 字节的批量写入每次都会超时。
有趣:我也尝试过使用 VirtualBox 进行同样的操作。事实证明,在同一台 Linux 主机上通过 VirtualBox 使用 Windows 来宾,仍然会出现相同的错误。所以不是因为
问题:
在Linux下可以发生什么在Windows下不会发生导致超时[Errno 110]?
更多信息,以防有帮助:
- 在 Windows 下,Wireshark 显示两次批量写入之间的时序差异,第一个为 6 毫秒,随后每个为 5 毫秒,而在 Linux 下,增量仅为大约 3 ms,这主要是由睡眠操作引起的(附上相关 Python 源代码)。将时间加倍没有任何作用。
- dmesg 显示类似 'bulk endpoint ## has invalid maxpacket 64' 的消息,其中 ## 是 0x01、0x08 和 0x81。
- 设备只有一种配置。
- 测试笔记本电脑只有 USB 3.0 接口,而 Windows PC 有 USB 3.0 和 2.0。我都测试了。
- Wireshark 显示设备在 Linux 下每次批量写入时都会用另一个(空)批量应答,而在 Windows 下则不会显示。据我了解,那是因为 USBPcap 无法捕获 Windows 下的握手。但我不确定,因为我不知道这种类型的回复是否真的会被归类为 "URB_BULK out".
- 我在 Linux 下尝试将 libusb0、libusb1 和 OpenUSB 作为后端,但没有成功。
- 有问题的批量传输是将 FPGA 固件传输到设备。
- 我能够在同一端点上仅使用几个字节的多 512 字节块批量操作之前与设备通信。然后导致超时的代码是此 for 循环的第二次迭代中的以下代码:
for chunk in chunks: # chunks: array of bytearrays with 512 bytes each
self.write(0x01,chunk)
time.sleep(0.003)
[编辑]原因 我发现这只发生在我使用 xhci 的测试笔记本电脑上,而不是第二台 Linux 使用 ehci 的测试机器上。所以这可能是由xhci引起的。我还没有解决方法,但这至少给出了一个解释。
事实证明,设备每个数据包请求的字节数较少,所需的字节数 (64) 可以在 dmesg
中找到,正如问题中已经写的那样。由于 xhci 不正式支持,Linux 决定忽略该请求。 Windows 似乎也随之而来,并按照请求的数据包大小拆分了较大的数据包。所以解决方案是在传输之前手动将数据拆分为64字节大小的数据包。
[编辑:我找到原因了,见下文]
问题:
我使用 Python(PyUSB 和 libusb-win32)为 Windows 中的设备创建了一个 "driver"。虽然此软件在 Windows 下的多台 PC 上无缝运行,但使用我的 Linux (Kubuntu 18.10) 测试笔记本电脑时,在第二次 512 字节批量传输后,一系列长度为 512 字节的批量写入每次都会超时。
有趣:我也尝试过使用 VirtualBox 进行同样的操作。事实证明,在同一台 Linux 主机上通过 VirtualBox 使用 Windows 来宾,仍然会出现相同的错误。所以不是因为
问题:
在Linux下可以发生什么在Windows下不会发生导致超时[Errno 110]?
更多信息,以防有帮助:
- 在 Windows 下,Wireshark 显示两次批量写入之间的时序差异,第一个为 6 毫秒,随后每个为 5 毫秒,而在 Linux 下,增量仅为大约 3 ms,这主要是由睡眠操作引起的(附上相关 Python 源代码)。将时间加倍没有任何作用。
- dmesg 显示类似 'bulk endpoint ## has invalid maxpacket 64' 的消息,其中 ## 是 0x01、0x08 和 0x81。
- 设备只有一种配置。
- 测试笔记本电脑只有 USB 3.0 接口,而 Windows PC 有 USB 3.0 和 2.0。我都测试了。
- Wireshark 显示设备在 Linux 下每次批量写入时都会用另一个(空)批量应答,而在 Windows 下则不会显示。据我了解,那是因为 USBPcap 无法捕获 Windows 下的握手。但我不确定,因为我不知道这种类型的回复是否真的会被归类为 "URB_BULK out".
- 我在 Linux 下尝试将 libusb0、libusb1 和 OpenUSB 作为后端,但没有成功。
- 有问题的批量传输是将 FPGA 固件传输到设备。
- 我能够在同一端点上仅使用几个字节的多 512 字节块批量操作之前与设备通信。然后导致超时的代码是此 for 循环的第二次迭代中的以下代码:
for chunk in chunks: # chunks: array of bytearrays with 512 bytes each
self.write(0x01,chunk)
time.sleep(0.003)
[编辑]原因 我发现这只发生在我使用 xhci 的测试笔记本电脑上,而不是第二台 Linux 使用 ehci 的测试机器上。所以这可能是由xhci引起的。我还没有解决方法,但这至少给出了一个解释。
事实证明,设备每个数据包请求的字节数较少,所需的字节数 (64) 可以在 dmesg
中找到,正如问题中已经写的那样。由于 xhci 不正式支持,Linux 决定忽略该请求。 Windows 似乎也随之而来,并按照请求的数据包大小拆分了较大的数据包。所以解决方案是在传输之前手动将数据拆分为64字节大小的数据包。