使用 PyUSB(不是 HIDAPI)读写 HID 设备

Read and Write HID device with PyUSB (not HIDAPI)

我想在 pysub 中实现 python hidapi 的读写调用。

使用 python hidapi 的示例代码如下所示:

import hid

hdev = hid.device()
h = hdev.open_path( path )

h.write( send_buffer )

res = h.read( 64 )    
receive_buffer = bytearray( res )

我遇到的主要问题是 python hidapi read() returns 一个整数列表(从接收到的缓冲区中的每个字节都有一个 python 整数硬件),我需要缓冲区作为字节并忠实于接收到的内容。(*)

第二个问题是打开、读取和写入是我唯一需要的东西,我需要让系统尽可能轻。因此我想避免额外的依赖。

(*) bytearray() 在这种情况下不是一个好的解决方案,原因超出了这个问题的范围。

这是一个似乎有效的最简单的代码示例。 HID 设备是一个 Teensy 板,它使用其 RAWHID.recv() 和 RAWHID.send() 与主机交换文本和二进制文件。

#!/usr/bin/python

import usb.core
import usb.util

dev = usb.core.find(idVendor=0x16C0, idProduct=0x0486)
    
try:
    dev.reset()
except Exception as e:
    print( 'reset', e)

if dev.is_kernel_driver_active(0):
    print( 'detaching kernel driver')
    dev.detach_kernel_driver(0)

endpoint_in = dev[0][(0,0)][0]
endpoint_out = dev[0][(0,0)][1]

# Send a command to the Teensy
endpoint_out.write( "version".encode() + bytes([0]) )

# Read the response, an array of byte, .tobytes() gives us a bytearray.
buffer = dev.read(endpoint_in.bEndpointAddress, 64, 1000).tobytes()

# Decode and print the zero terminated string response
n = buffer.index(0)
print( buffer[:n].decode() )

我已经完成了一些快速基准测试,看起来 arrays 上的工作肯定是朝着正确的方向前进,但是有一个稍微更好的转换选项。以下是在 64 字节数据缓冲区上运行 1000 万次迭代的结果。

使用

data_list = [30] * 64
data_array = array('B', data_list)

我在几秒钟内得到了以下 运行 次:

Technique Time (seconds, 10 million iterations)
bytearray(data_list) 12.7
bytearray(data_array) 3.0
data_array.tobytes() 2.0
struct.pack('%uB' % len(data_list), *data_list) 18.6
struct.pack('%uB' % len(data_array), *data_array) 22.5

似乎使用 array.tobytes 方法是最快的,其次是使用 array 作为参数调用 bytearray

显然,我在每次迭代中都重复使用了相同的缓冲区,可能还有其他不切实际的因素,所以 YMMV。这些应该是相对于彼此的指示性结果,即使不是绝对值。此外,这显然没有考虑 bytearraybytes.

的性能