PyUSB modules
内容 | 描述 |
---|---|
core | USB主要模块 |
util | 实用功能模块 |
control | 标准控制请求模块 |
legacy | 0.x兼容性层 |
backend | 包含内置后端的子包 |
开始
pip install pyusb
查看USB的VID和PID
设备管理器->找到USB设备右键->属性->详细信息->硬件id
到目前为止设备的硬件id没有变动过。
测试程序:
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x067B, idProduct=0x2303)
if dev is None:
raise ValueError('Device not found')
print(dev)
可以查看USB信息的字段和对应的值。
官方测试代码
需要用zadig安装libusb-win32驱动
import usb.core
import usb.util
# find our device
dev = usb.core.find(idVendor=0x067B, idProduct=0x2303)
# was it found?
if dev is None:
raise ValueError('Device not found')
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)
assert ep is not None
# write the data
ep.write('test')
cfg是dev的设备信息。
intf是cfg中的子信息,包含接口和端点信息。
ep是ENDPOINT_OUT的端点信息。
assert判断为true正常执行,false抛出异常。
ep.write('test')
还可以用python dev.write(0x2,'text')
代替,0x2是out的bEndpointAddress的值,返回的是字符的个数
遍历所有设备
代码后面加上
import sys
for cfg in dev:
sys.stdout.write(str(cfg.bConfigurationValue) + '\n')
查询接口和端点信息
import usb.core
import usb.util
import sys
dev = usb.core.find(idVendor=0x067B, idProduct=0x2303)
for cfg in dev:
sys.stdout.write(str(cfg.bConfigurationValue) + '\n')
for intf in cfg:
sys.stdout.write('\t' + str(intf.bInterfaceNumber) + \
',' + str(intf.bAlternateSetting) + '\n')
for ep in intf:
sys.stdout.write('\t\t' + str(ep.bEndpointAddress) + \
'\n')
从运行结果可以看出遍历设备可以访问接口,遍历接口可以访问端点,有三个端点对应的ENDPOINT分别为129,2,131
也可以用下面的代码获得对应的描述符
# access the first configuration
cfg = dev[0]
# access the first interface
intf = cfg[(0,0)]
# third endpoint
ep = intf[2]
获得设备后的第一件事情是set_configuration(bConfigurationValue)设置bConfigurationValue,bConfigurationValue为空时表示默认设置。
四种传输方式
(1)同步传输方式(synchronous)
该方式占用预先制定好的带宽,并且有预定发送延时,用来连接需要连续传输数据,且对数据的正确性要求不高而对时间极为敏感的外部设备。在传送数据发生错误时,usb并不处理这些错误,而是续传新的数据。同步传输每次传输的最大有效负荷可为1024字节。
(2)中断传输方式(interrupt)
该方式用来传输由设备自发产生的数据,传输数据量很小,但这些数据需要及时处理,以达到实时效果。此方式主要用在键盘、鼠标及操纵杆等设备上。全速设备每次中断传输的最大有效负荷可为64个字节,而低速设备每次中断传输的最大有效负荷仅为8个字节。
(3)控制传输方式(control)
该方式用来处理主端口到usb从端口的数据传输,包括设备控制指令、设备各状态查询及确认命令。当usb设备收到这些数据和命令后,将依据先进先出的原则(队列)处理到达的数据。其传输的最大负荷与中断传输方式相同。是唯一一个结构化数据的传输
(4)批量传输方式(bulk)
该方式用来传输要求正确无误的数据。通常打印机、扫描仪和数字相机以这种方式与主机连接。在数据相对比较多和突发数据量较大时使用,在传输限制方面具有很宽的动态自由度。批量传输每次数据传输的最大有效负荷可为64个字节。
非控制传输方式
msg = 'test'
assert dev.write(0x2, msg, 100) == len(msg)
第一个参数是OUT的端点,第二个参数是发送的字节数,第三个参数是超时(可选项)。
ret = dev.read(0x81, len(msg), 100)
sret = ''.join([chr(x) for x in ret])
第一个参数是IN的端点,第二个参数是接收的字节数,chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
控制传输方式
msg = 'test'
assert dev.ctrl_transfer(0x40, CTRL_LOOPBACK_WRITE, 0, 0, msg) == len(msg)
ret = dev.ctrl_transfer(0xC0, CTRL_LOOPBACK_READ, 0, 0, len(msg))
sret = ''.join([chr(x) for x in ret])
第一个参数bmRequestType,第二个参数bmRequest可以是CTRL_LOOPBACK_WRITE写消息或者CTRL_LOOPBACK_READ读消息,第三个参数wValue,第四个参数wIndex,第五个参数可以是OUT输出的数据字节数,或者IN输入的数据字节数。
测试代码
import sys
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x1C4F, idProduct=0x0034)
dev.set_configuration()
ret = dev.read(0x81, 0x7, 10000)
print(ret)