2016-07-29 789 views
0

我试图与连接到我的Ubuntu 16系统(Python版本2.7.12)的设备接口。当我尝试写入设备时,出现写入超时(与读取设备类似)。根据我所用的很少的文档,HID接口在接口3中实现,除了标准端点(EP)0之外,该设备还支持EP4 IN(设备到主机)中断传输类型,而EP5 OUT(主机到设备)中断传输类型。它还指出USB Bulk基于请求 - 响应消息对,消息格式为64字节,第一个字节为'操作码'。对于“获取版本”命令,操作码是0x02,其余部分将被忽略。使用PyUSB从USB设备读取/写入时出现问题(超时)

我对Python和USB都很陌生,所以可能有这个错误,但我想写入'OUT'接口,然后从'IN'接口读取。我注意到,当我将设备插入Ubuntu系统时,我得到一个新设备/ dev/usb/hiddev0,但似乎无法写入,所以尝试连接到接口3并获取In/Out接口。 另外我加入了我认为是PYUSB_DEBUG的调用,但我没有看到任何更多的输出。

使用下面的代码我可以看到设备,并且我得到一个IN/OUT接口,但是写/读总是超时。我不知道我错过了什么。非常感谢您的任何帮助

import usb.core 
import usb.util 
from usb.core import * 
import sys 
import os 
import binascii 
import time 
import serial  
import itertools 


idV = 0x2abf 
idP = 0x0505 

# doesnt seem to write anything to log?! 
os.environ['PYUSB_DEBUG'] = 'debug' 
#os.environ['PYUSB_LOG_FILENAME'] = "pyusb.log" #never written 


print "finding idVendor = {}, idProduct= {}".format(idV, idP) 
device = usb.core.find(idVendor=idV, idProduct=idP) 

if device is None: 
    print ("Device not found") 
    exit() 


# free up the device from the kernal 
for cfg in device: 
    for intf in cfg: 
     if device.is_kernel_driver_active(intf.bInterfaceNumber): 
      try: 
       device.detach_kernel_driver(intf.bInterfaceNumber) 
      except usb.core.USBError as e: 
       sys.exit("Could not detach kernel driver from interface({0}): {1}".format(intf.bInterfaceNumber, str(e))) 

# try default conf 
print "setting configuration" 
device.set_configuration() 
print "config set" 

print "trying to claim device" 
try: 
    usb.util.claim_interface(device, 0) 
    print "claimed device" 
except usb.core.USBError as e: 
    print "Error occurred claiming " + str(e) 
    sys.exit("Error occurred on claiming") 
print "device claimed" 

# get enpoint instance 
cfg = device.get_active_configuration() 
print "***********" 
for intf in cfg: 
    print "intf= " + str(intf) 
print "***********" 

# from document: 
# The HID interface is implemented on Interface 3, in addition to standard endpoint (er)0, the device supports 
# EP4 IN (device to host) interrupt transfer type, and EP5 OUT (host to device) interrupt transfer type 
# Note: EP$ seems to come back as 0x84 while EP5 comes back as 0x05 
intf = cfg[(3, 0)] 

# get the BULK OUT descriptor 
epo = usb.util.find_descriptor(
    intf, 
    # match our first out endpoint 
    custom_match= \ 
     lambda e: \ 
      usb.util.endpoint_direction(e.bEndpointAddress) == \ 
      usb.util.ENDPOINT_OUT) 

assert epo is not None 

# get the BULK IN descriptor 
epi = usb.util.find_descriptor(
    intf, 
    # match our first out endpoint 
    custom_match= \ 
     lambda e: \ 
      usb.util.endpoint_direction(e.bEndpointAddress) == \ 
      usb.util.ENDPOINT_IN) 

assert epi is not None 

print "write the data" 
# commands are 64 bytes long, first byte is command code, 02 is 'get version', it doesn't need any of the other bytes set 
try: 
    # don't think I can use [0x00]*63 because it will be all pointers to same object?, call them out to be safe 
    test = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] 
    mybuff = b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 
    #device.write(epo,mybuff,1)   #timeout on write 
    #epo.write(mybuff)     #timeout on write 
    epo.write(mybuff.encode('utf-8')) #timeout on write 
except usb.core.USBError as e: 
    print "Write USBError: " + str(e) 
    sys.exit() 

print "done writing" 
print "try read?" 
try: 
    #info = device.read(0x84, 8) 
    info = epo.read(epi.bEndpointAddress,epi.wMaxPacketSize) 
except usb.core.USBError as e: 
    print "Read USBError: " + str(e) 
    sys.exit() 

print "read: " + str(info) 

输出:

finding idVendor = 10943, idProduct= 1285 
setting configuration 
config set 
trying to claim device 
claimed device 
device claimed 
*********** 
< skipping audio interfaces> 
intf=  INTERFACE 3: Human Interface Device ==================== 
    bLength   : 0x9 (9 bytes) 
    bDescriptorType : 0x4 Interface 
    bInterfaceNumber : 0x3 
    bAlternateSetting : 0x0 
    bNumEndpoints  : 0x2 
    bInterfaceClass : 0x3 Human Interface Device 
    bInterfaceSubClass : 0x0 
    bInterfaceProtocol : 0x0 
    iInterface   : 0x8 PlaylistControl 
     ENDPOINT 0x84: Interrupt IN ========================== 
     bLength   : 0x7 (7 bytes) 
     bDescriptorType : 0x5 Endpoint 
     bEndpointAddress : 0x84 IN 
     bmAttributes  : 0x3 Interrupt 
     wMaxPacketSize : 0x40 (64 bytes) 
     bInterval  : 0xa 
     ENDPOINT 0x5: Interrupt OUT ========================== 
     bLength   : 0x7 (7 bytes) 
     bDescriptorType : 0x5 Endpoint 
     bEndpointAddress : 0x5 OUT 
     bmAttributes  : 0x3 Interrupt 
     wMaxPacketSize : 0x40 (64 bytes) 
     bInterval  : 0xa 
*********** 
write the data 
Write USBError: [Errno 110] Operation timed out 
+0

'info = epo.read(epi.bEndpointAddress,epi.wMaxPacketSize)'你确定这不是'epi.read ...'吗? – Tagc

回答

1

我想你正在重用的设备在测试你的代码,当你多次执行它会出现你的问题。你应该使用

usb.util.dispose_resources(device) 

在你的代码结束。尝试使用

device.reset() 

device = usb.core.find(...) 

后,做什么都与设备之前,如果你怀疑前面的代码运行关闭不洁。

+0

非常感谢您的协助,我很抱歉没有更快找到这里,我放弃了一个答案,不知道为什么我错过了电子邮件。 – RichP

+0

我试图在程序结束后在device = usb.core.find(...)和usb.util.dispose_resources(device)之后添加device.reset()以释放内容,但仍无法获取任何地方。虽然我确实认为附加的线条可能很有意义。所以我很感激它! – RichP

+0

很抱歉,您的案件没有通过'reset()'解决。我发现它解决了我的问题,但另一方面,在数千次reset()之后,我的RaspberryPi引发了内核恐慌,所以没有我想象的那么完美。 – rishta

相关问题