目录
1、usb.core.NoBackendError: No backend available
一、环境准备
1、已安装 Python 环境,python --version 确认;
2、已安装 Usb Module,pip install pywinusb,pip install pyusb;
二、遇到的问题:
1、usb.core.NoBackendError: No backend available
(1)pip install libusb1;
(2)复制 libusb-1.0.dll(Default Path:Python\Lib\site-packages\usb1)
to:
64-bit Windows: C:\Windows\System32\
32-bit Windows: C:\Windows\SysWOW64\
或者,将 libusb-1.0.dll(Default Path:Python\Lib\site-packages\usb1)的路径直接添加到系统环境变量中,如下图
2、Error: Operation not supported or unimplemented on this platform 或者 Error during SET/GET_REPORT exchange: [Errno 5] Input/Output Error
(1)下载 Zadig 工具,给USB设备安装或更新驱动,下载链接 https://zadig.akeo.ie/;
(2)点击Options,勾选 List All Devices,选择需要操作的设备,驱动选择 libusb-win32(WinUSB 或 libusbK),点击 Install Driver 即可,如下图所示:
注意:
1、如下图,案例中的 Usb Test Device,共有三个 Interface Num,测试时,需要用到哪个 Interface,就需要用 Zadig 安装下对应 Interface 的 Driver;
2、修改了 Device 设备的 Pid、Vid 等信息后,亦需要用 Zadig 重新安装下所用到的 Interface 的 Driver;
Why Do You Need Zadig?
Windows does not always allow user-space applications to directly access USB HID devices via libusb
or pyusb
. By default:
- HID devices (such as keyboards, mice, game controllers) use the Windows HID driver (
hid.dll
). - The default HID driver does not expose raw USB communication needed for control transfers (
ctrl_transfer
inpyusb
). - Zadig replaces the default HID driver with
WinUSB
,libusb-win32
, orlibusbK
, which allows user-space applications (like Python scripts) to communicate with the USB device directly.
三、代码实现
import usb.core
import usb.util
import logging
import time
logging.basicConfig(level=logging.INFO)
PID = 0x1234
VID = 0x5678
def send_and_receive():
# Locate the USB device.
dev = usb.core.find(idVendor=VID, idProduct=PID)
if dev is None:
logging.error("Device not found")
return
else:
print(f"Found device: {dev}")
try:
HID_REPORT_DESCRIPTOR_SIZE = 64 # Change this to the actual descriptor size
descriptor = dev.ctrl_transfer(0x81, 0x06, 0x2200, 0x0003, HID_REPORT_DESCRIPTOR_SIZE)
print("HID Report Descriptor:", list(descriptor))
# ---------------------------
# 1. Send SET_REPORT (Output Report)
# ---------------------------
# bmRequestType = 0x21 (Host-to-device, Class, Interface)
# bRequest = 0x09 (SET_REPORT)
# wValue = 0x200 (Output Report type, Report ID 0x00)
# wIndex = 0x00 (Interface number; adjust if necessary)
# Data = data_to_send (example: 64 bytes)
# Define the 4 bytes to send
data_to_send = bytearray([0xFF, 0xF7, 0xFF, 0xF7])
# data_to_send = bytearray([i % 256 for i in range(1, 65)]) # 64 bytes of data
logging.info("Sending SET_REPORT command...")
dev.ctrl_transfer(0x21, 0x09, 0x0200, 0x0002, data_to_send)
logging.info("SET_REPORT sent, Data: %s", list(data_to_send))
# # Optional delay to allow the device time to process the output report.
# time.sleep(0.1)
# # ---------------------------
# # 2. Send GET_REPORT (Input Report)
# # ---------------------------
# # bmRequestType = 0xA1 (Device-to-host, Class, Interface)
# # bRequest = 0x01 (GET_REPORT)
# # wValue = 0x100 (Input Report type, Report ID 0x00)
# # wIndex = 0x00 (Interface number; adjust if necessary)
# # Length = response_length (expected number of bytes)
response_length = 4 # Adjust this value based on your device's report size
logging.info("Sending GET_REPORT command...")
response = dev.ctrl_transfer(0xA1, 0x01, 0x100, 0x0002, response_length)
logging.info("Received GET_REPORT response: %s", list(response))
# # Optional delay to allow the device time to process the output report.
# time.sleep(1)
# data_to_send = bytearray([0xFF, 0xF7, 0x01, 0x02])
# # data_to_send = bytearray([i % 256 for i in range(1, 65)]) # 64 bytes of data
# logging.info("Sending SET_REPORT command...")
# dev.ctrl_transfer(0x21, 0x09, 0x0200, 0x02, data_to_send)
# logging.info("SET_REPORT sent, Data: %s", list(data_to_send))
# # Optional delay to allow the device time to process the output report.
# time.sleep(0.1)
except Exception as e:
logging.error("Error during SET/GET_REPORT exchange: %s", e)
if __name__ == '__main__':
send_and_receive()
1、hid 通讯的测试函数 ctrl_transfer
The ctrl_transfer
function in a USB library (like pyusb
) is used to send control transfer requests to a USB device. The function typically follows this format:
dev.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_length)
For control transfers, the setup packet is always 8 bytes long and consists of these fields:
Offset | Field Name | Size (Bytes) | Description |
---|---|---|---|
0 | bmRequestType | 1 | Specifies the request type (direction, type, and recipient). |
1 | bRequest | 1 | The specific request code. |
2-3 | wValue | 2 | A value that may be required for the request. |
4-5 | wIndex | 2 | Usually specifies the interface or endpoint. |
6-7 | wLength | 2 | Number of bytes to transfer in the data stage. |
四、测试
1、打开 PowerShell,进入对应的目录下;
2、执行程序,python test.py,结果如下;