2016-07-29 5 views
0

내 Ubuntu 16 시스템 (Python ver 2.7.12)에 연결된 장치와 인터페이스를 시도하고 있습니다. 장치에 쓰려고 할 때 장치에서 읽는 것과 비슷한 쓰기 시간 초과가 발생합니다.PyUSB를 사용하여 USB 장치에서 읽기/쓰기 문제가 발생했습니다 (시간 초과)

내가 가진 작은 문서에 따르면 HID 인터페이스는 EP4 IN (장치에서 호스트) 인터럽트 전송 유형과 EP5 OUT (호스트) 인터페이스를 지원하는 표준 엔드 포인트 (EP) 0 이외에 인터페이스 3에서 구현됩니다. to device) 인터럽트 전송 유형. 또한 USB Bulk는 첫 번째 바이트가 'op code'인 64 바이트 메시지 형식의 요청 - 응답 메시지 쌍을 기반으로합니다. 'get version'명령의 경우 op 코드는 0x02이고 나머지는 무시됩니다.

저는 파이썬과 USB에 익숙하지 않으므로 아마도이 잘못된 점을 가지고 있지만 'OUT'인터페이스에 쓰고 'IN'인터페이스에서 읽으려고합니다. 나는 장치를 우분투 시스템에 꽂을 때 새로운 장치 인/dev/usb/hiddev0을 얻을 수 있지만 인터페이스 3에 연결하여 입/출력 인터페이스를 잡으려고 시도 할 수 없었던 것으로 나타났습니다. 또한 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 = usb.core.find(...) 

후 장치와 함께 다른 작업을 수행하기 전에

device.reset() 

를 사용해보십시오.

+0

도움을 주셔서 감사합니다. 빨리 여기를 보지 못해 사과드립니다. 답변을 포기하고 이메일을 놓친 이유를 모르겠습니다. – RichP

+0

프로그램을 끝내고 device = usb.core.find (...) 및 usb.util.dispose_resources (장치) 바로 뒤에 device.reset()을 추가해 보았습니다. 그러나 아무데도 가지 못했습니다. 비록 내가 생각하기에 추가 라인이 아마도 많은 의미를 가졌을 것이라고 생각한다. 그래서 고맙습니다. – RichP

+0

불편을 끼쳐 드려 죄송합니다. 귀하의 사례가'reset()'에 의해 시정되지 않았습니다. 나는 그것을 내 문제를 해결하는 것으로 발견했다. 그러나 다른 한편으로는 수천 개의'reset()'후에 나의 RaspberryPi는 커널 패닉을 던지므로 생각만큼 완벽하지는 않다. – rishta

관련 문제