일부는 libusb-1.0 및 ctypes를 사용하여 Async USB 작업을 이해하는 데 도움이됩니다.

StackOverflow https://stackoverflow.com/questions/1052135

  •  20-08-2019
  •  | 
  •  

문제

괜찮은. 나는 그것을 알아. 송신. 플래그는 int 대신 바이트 여야했습니다. 바보 나. 이제 IOCTL, errno 16에서 오류 코드를 받고 있습니다. 이는 장치가 바쁘다는 것을 의미합니다. 얼마나 일하는 일입니다. 나는 Libusb 메일 링리스트에 물었다.

아래는 내가 지금까지 가지고있는 것입니다. 이것은 실제로 그다지 많은 코드가 아닙니다. 그것의 대부분은 libusb의 CTypes 구조입니다. 오류가 발생하는 실제 코드를 보려면 하단으로 스크롤하십시오.

from ctypes import *

VENDOR_ID = 0x04d8
PRODUCT_ID = 0xc002
_USBLCD_MAX_DATA_LEN = 24
LIBUSB_ENDPOINT_IN = 0x80
LIBUSB_ENDPOINT_OUT = 0x00

class EnumerationType(type(c_uint)):  
    def __new__(metacls, name, bases, dict):  
        if not "_members_" in dict:  
            _members_ = {}  
            for key,value in dict.items():  
                if not key.startswith("_"):  
                    _members_[key] = value  
            dict["_members_"] = _members_  
        cls = type(c_uint).__new__(metacls, name, bases, dict)  
        for key,value in cls._members_.items():  
            globals()[key] = value  
        return cls  

    def __contains__(self, value):
        return value in self._members_.values()

    def __repr__(self):
        return "<Enumeration %s>" % self.__name__

class Enumeration(c_uint):
    __metaclass__ = EnumerationType
    _members_ = {}
    def __init__(self, value):
        for k,v in self._members_.items():
            if v == value:
                self.name = k
                break
        else:
            raise ValueError("No enumeration member with value %r" % value)
        c_uint.__init__(self, value)


    @classmethod
    def from_param(cls, param):
        if isinstance(param, Enumeration):
            if param.__class__ != cls:
                raise ValueError("Cannot mix enumeration members")
            else:
                return param
        else:
            return cls(param)

    def __repr__(self):
        return "<member %s=%d of %r>" % (self.name, self.value, self.__class__)


class LIBUSB_TRANSFER_STATUS(Enumeration):
    _members_ = {'LIBUSB_TRANSFER_COMPLETED':0,
            'LIBUSB_TRANSFER_ERROR':1,
            'LIBUSB_TRANSFER_TIMED_OUT':2,
            'LIBUSB_TRANSFER_CANCELLED':3,
            'LIBUSB_TRANSFER_STALL':4,
            'LIBUSB_TRANSFER_NO_DEVICE':5,
            'LIBUSB_TRANSFER_OVERFLOW':6}

class LIBUSB_TRANSFER_FLAGS(Enumeration):
    _members_ = {'LIBUSB_TRANSFER_SHORT_NOT_OK':1<<0,
            'LIBUSB_TRANSFER_FREE_BUFFER':1<<1,
            'LIBUSB_TRANSFER_FREE_TRANSFER':1<<2}

class LIBUSB_TRANSFER_TYPE(Enumeration):
    _members_ = {'LIBUSB_TRANSFER_TYPE_CONTROL':0,
            'LIBUSB_TRANSFER_TYPE_ISOCHRONOUS':1,
            'LIBUSB_TRANSFER_TYPE_BULK':2,
            'LIBUSB_TRANSFER_TYPE_INTERRUPT':3}

class LIBUSB_CONTEXT(Structure):
    pass

class LIBUSB_DEVICE(Structure):
    pass

class LIBUSB_DEVICE_HANDLE(Structure):
    pass

class LIBUSB_CONTROL_SETUP(Structure):
    _fields_ = [("bmRequestType", c_int),
            ("bRequest", c_int),
            ("wValue", c_int),
            ("wIndex", c_int),
            ("wLength", c_int)]

class LIBUSB_ISO_PACKET_DESCRIPTOR(Structure):
    _fields_ = [("length", c_int),
            ("actual_length", c_int),
            ("status", LIBUSB_TRANSFER_STATUS)]

class LIBUSB_TRANSFER(Structure):
    pass

LIBUSB_TRANSFER_CB_FN = CFUNCTYPE(c_void_p, POINTER(LIBUSB_TRANSFER))

LIBUSB_TRANSFER._fields_ = [("dev_handle", POINTER(LIBUSB_DEVICE_HANDLE)),
            ("flags", c_ubyte),
            ("endpoint", c_ubyte),
            ("type", c_ubyte),
            ("timeout", c_uint),
            ("status", LIBUSB_TRANSFER_STATUS),
            ("length", c_int),
            ("actual_length", c_int),
            ("callback", LIBUSB_TRANSFER_CB_FN),
            ("user_data", c_void_p),
            ("buffer", POINTER(c_ubyte)),
            ("num_iso_packets", c_int),
            ("iso_packet_desc", POINTER(LIBUSB_ISO_PACKET_DESCRIPTOR))]


class TIMEVAL(Structure):
    _fields_ = [('tv_sec', c_long), ('tv_usec', c_long)]

lib = cdll.LoadLibrary("libusb-1.0.so")
lib.libusb_open_device_with_vid_pid.restype = POINTER(LIBUSB_DEVICE_HANDLE)
lib.libusb_alloc_transfer.restype = POINTER(LIBUSB_TRANSFER)

def libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, buffer, length, callback, user_data, timeout):
    transfer[0].dev_handle = dev_handle
    transfer[0].endpoint = chr(endpoint)
    transfer[0].type = chr(LIBUSB_TRANSFER_TYPE_INTERRUPT)
    transfer[0].timeout = timeout
    transfer[0].buffer = buffer
    transfer[0].length = length
    transfer[0].user_data = user_data
    transfer[0].callback = LIBUSB_TRANSFER_CB_FN(callback)

def cb_transfer(transfer):
    print "Transfer status %d" % transfer.status

if __name__ == "__main__":
    context = POINTER(LIBUSB_CONTEXT)()
    lib.libusb_init(None)
    transfer = lib.libusb_alloc_transfer(0)
    handle = lib.libusb_open_device_with_vid_pid(None, VENDOR_ID, PRODUCT_ID)
    size = _USBLCD_MAX_DATA_LEN
    buffer = c_char_p(size)
    libusb_fill_interrupt_transfer(transfer, handle, LIBUSB_ENDPOINT_IN + 1, buffer, size, cb_transfer, None, 0)

    r = lib.libusb_submit_transfer(transfer) # This is returning -2, should be => 0.
    if r < 0:
        print "libusb_submit_transfer failed", r

    while r >= 0:
        print "Poll before"
        tv = TIMEVAL(1, 0)
        r = lib.libusb_handle_events_timeout(None, byref(tv))
        print "Poll after", r
도움이 되었습니까?

해결책 2

한 번 뿌리로 실행하면 바쁜 깃발을 수정했습니다.

다른 팁

  • 반환 값을 확인하기 위해 확인 했습니까? libusb_alloc_transfer 그리고 libusb_open_device_with_vid_pid 유효합니까?
  • 라이브러리 기능을 적절한 상태로 주석을 달아 보셨습니까? Argtypes?
  • 당신은 곤경에 빠질 수 있습니다 transfer[0].callback = LIBUSB_TRANSFER_CB_FN(callback)- 당신은 어떤 언급도 보관하지 않습니다 CFunctionType 객체가 돌아 왔습니다 LIBUSB_TRANSFER_CB_FN(), 그리고 그 객체가 방출되어 덮어 쓰기가 될 수 있습니다.

다음 단계는 디버깅 기호가있는 Libusb 버전을 설치하고 GDB를 부팅하고 중단 점을 설정하는 것입니다. libusb_submit_transfer(), 통과가 있는지 확인하십시오 libusb_transfer 제정신이며 반환 할 오류가 발생하는 것을 확인하십시오.

초기 이전 선언은 어디에 있습니까? 나는 Python에 익숙하지 않지만 어떤 데이터 유형이어야하는지 정의하지 않고 구조물의 필드에 값을 할당해도 괜찮습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top