python libusb多线程_一些有助于理解libusb1.0和ctypes的异步USB操作

好吧。我想出来了。传输.flags需要一个字节而不是整数。我真傻。现在我从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 "" % 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 "" % (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

libusb库中,异步传输通常通过回调函数和多线程处理来实现。以下是一个简化的Python示例,使用`threading`模块来演示如何在一个单独的线程中进行异步USB设备读写操作: ```python import libusb1 import threading # 初始化libusb context context = libusb1.USBContext() def async_transfer(device, endpoint, buffer_size): def transfer_callback(transferred_bytes, status, error_number): if status == libusb1.LIBUSB_TRANSFER_COMPLETED: print(f"Received {transferred_bytes} bytes") else: print(f"Transfer failed with error {error_number}") # 开始异步读取或写入 request_type = libusb1.LIBUSB_REQUEST_TYPE_DIR_IN if writing else libusb1.LIBUSB_REQUEST_TYPE_DIR_OUT request = libusb1.libusb_fill_transfer( .transfer_buffer, device.handle, endpoint, buffer_size, request_type, transfer_callback, None, ) # 开启传输 try: result = context.queue_transfer(request) if result > 0: print("Transfer started...") else: print("Failed to queue transfer.") except Exception as e: print(f"Error queuing transfer: {str(e)}") # 设备信息和端点 device_address = ... # 你的设备地址 endpoint = ... # 你想使用的端点(IN或OUT) buffer_size = ... # 每次请求的数据大小 # 创建读写标志 writing = True # 当True表示写操作,False表示读操作 # 分配内存缓冲区 transfer_buffer = (c_char * buffer_size).from_buffer(bytearray(buffer_size)) # 创建线程处理异步任务 async_thread = threading.Thread(target=async_transfer, args=(device_address, endpoint, buffer_size)) async_thread.start() # 等待线程完成,可根据需要添加其他线程同步逻辑 async_thread.join()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值