gousb中出现Transfer Failed错误:如何调试libusb写入问题?
如何解包gousb中"Transfer Failed"的原始libusb错误?
解包原始libusb错误的方法
gousb会将libusb的底层错误包装为通用的"transfer failed"提示,但可以通过类型断言获取原始的libusb错误信息。gousb定义了*gousb.Error结构体,其中包含了libusb的错误码和原始描述。
修改你的错误处理代码如下:
n, err := device.Write(chunk) if err != nil { // 修正原代码变量错误:packetSize未定义,替换为chunkSize log.Printf("Error sending chunk at index %d: %v", i/chunkSize, err) // 断言错误为gousb.Error类型,提取原始信息 if usbErr, ok := err.(*gousb.Error); ok { log.Printf("libusb错误码: %d", usbErr.Code) log.Printf("原始错误描述: %s", usbErr.Desc) } }
usbErr.Code对应libusb的标准错误码(例如LIBUSB_ERROR_TIMEOUT、LIBUSB_ERROR_PIPE、LIBUSB_ERROR_NO_DEVICE等),usbErr.Desc是libusb返回的详细错误描述,能帮你定位具体问题。
额外排查方向
结合你的树莓派+Debian场景,还可以从以下方面排查传输失败问题:
- 检查数据包大小匹配:确认
chunkSize是否与端点的MaxPacketSize兼容。批量传输中,除最后一包外,其他包的大小建议设置为MaxPacketSize的整数倍,部分设备会严格要求这一点。 - 设置传输超时:尝试使用
WriteWithTimeout替代Write,手动指定更长的超时时间(例如5秒),避免因默认超时过短导致传输失败:n, err := device.WriteWithTimeout(chunk, 5*time.Second) - 设备权限问题:树莓派上访问USB设备可能需要特殊权限。创建udev规则文件
/etc/udev/rules.d/99-usb-device.rules,内容示例:
执行SUBSYSTEM=="usb", ATTRS{idVendor}=="你的设备厂商ID", ATTRS{idProduct}=="你的设备产品ID", MODE="0666"sudo udevadm control --reload-rules && sudo udevadm trigger后重新插拔设备,确保当前用户有读写权限。 - 端点状态恢复:如果设备端点进入halt状态,会导致传输失败。可以在错误处理中尝试重置端点:
if usbErr, ok := err.(*gousb.Error); ok && usbErr.Code == gousb.ErrorPipe { if resetErr := device.Reset(); resetErr != nil { log.Printf("重置端点失败: %v", resetErr) } else { log.Println("端点已重置,可尝试重新传输") } }
内容的提问来源于stack exchange,提问作者HappyGook
相关产品推荐
相关产品推荐

