使用PyUSB的usb.util.get_string()获取字符串描述符
我在获取USB设备的字符串描述时遇到了一些问题。我想要的是人类可读的制造商和产品名称。我正在使用libusb-1.0作为后端,并且能够通过提供的libusb测试程序获取制造商名称,所以我知道这个信息是存在的。
PyUSB的帮助文件说你可以通过以下方式访问usb_get_string_simple
(来自libusb后端):
get_string(dev, length, index, langid=None)
Retrieve a string descriptor from the device. dev is the Device object to which the request will be sent to. length is the length of string in number of characters. index is the string descriptor index and langid is the Language ID of the descriptor. If langid is omitted, the string descriptor of the first Language ID will be returned. The return value is the unicode string present in the descriptor.
import usb
#help(usb.core)
busses = usb.busses()
for bus in busses:
devices = bus.devices
for dev in devices:
_name = usb.util.get_string(dev.dev,256,0) #This is where I'm having trouble
print "device name=",_name
print "Device:", dev.filename
print " Device class:",dev.deviceClass
print " Device sub class:",dev.deviceSubClass
print " Device protocol:",dev.deviceProtocol
print " Max packet size:",dev.maxPacketSize
print " idVendor:",hex(dev.idVendor)
print " idProduct:",hex(dev.idProduct)
print " Device Version:",dev.deviceVersion
for config in dev.configurations:
print " Configuration:", config.value
print " Total length:", config.totalLength
print " selfPowered:", config.selfPowered
print " remoteWakeup:", config.remoteWakeup
print " maxPower:", config.maxPower
for intf in config.interfaces:
print " Interface:",intf[0].interfaceNumber
for alt in intf:
print " Alternate Setting:",alt.alternateSetting
print " Interface class:",alt.interfaceClass
print " Interface sub class:",alt.interfaceSubClass
print " Interface protocol:",alt.interfaceProtocol
for ep in alt.endpoints:
print " Endpoint:",hex(ep.address)
print " Type:",ep.type
print " Max packet size:",ep.maxPacketSize
print " Interval:",ep.interval
任何帮助都将不胜感激。
5 个回答
0
这段代码会从设备中获取字符串:
dev = usb.core.find(idVendor=0x077d, idProduct=0x0410) # fill in your own device, of course
if dev is None:
print 'Our device is not connected'
else:
if dev._manufacturer is None:
dev._manufacturer = usb.util.get_string(dev, dev.iManufacturer)
print str(dev._manufacturer)
if dev._product is None:
dev._product = usb.util.get_string(dev, dev.iProduct)
print str(dev._product)
6
把索引写死在代码里并不是个好主意。
我建议你可以用下面这种方式:
usb.util.get_string(dev, 256, dev.iSerialNumber)
usb.util.get_string(dev, 256, dev.iManufacturer)
你会发现,不同的设备索引是不同的。
这是 lsusb -v 命令的输出:
device 1: #index #string_descriptor
iManufacturer 3 Linux 3.8.13 musb-hcd
iProduct 2 MUSB HDRC host driver
iSerial 1 musb-hdrc.1.auto
device 2:
iManufacturer 2 E-boda
iProduct 3 SUNNY V35
iSerial 4 0123456789ABCDEF
6
(更新于2019年7月:请查看Teodor-Bogdan Barbieru的回答,里面清楚地解释了为什么你不应该硬编码索引!)
(第二次更新2019年7月:请查看gog的评论,里面有链接到USB规范的文档,里面有一个表格列出了所有设备描述符字段。)
你代码中的这一行:
usb.util.get_string(dev.dev,256,0)
确实是个问题。我不太确定USB规范具体说了什么,但在我目前的硬件项目中,我对索引的选择得到了以下结果:
- index=0(你的选择)返回一个单一的unicode字符
- index=1返回制造商的信息
- index=2返回设备描述
- index=3返回设备序列号
所以,试试这个:
usb.util.get_string(dev.dev, 256, 2)
祝你好运!