usb-hid学习

usb协议

  1. 设备中的endpoint端点 通信使用pipe管道

  2. 主机到从机out 反之in

  3. pipe数据通信方式主要是message stream

  4. 端点有四种类型 控制 中断 批量 等时 常用控制传输

  5. 逻辑设备 多端点设备 一个设备也可能有多个接口

  6. USB架构中, hub负责检测设备的连接和断开,利用其中断IN端点(Interrupt IN Endpoint)来向主机(Host)报告。在系统启动时,主机轮询它的根hub(Root Hub)的状态看是否有设备(包括子hub和子hub上的设备)连接。

  7. 描述符 区分从设备 设备描述符>配置描述符>接口描述符>端点描述符

  8. 设备描述符 :一个设备一个,设备类型、设备遵循的协议、厂商ID、产品id、序列号

:::
DEVICE DESCRIPTOR

bLength: 18

bDescriptorType: 0x01 (DEVICE)

bcdUSB: 0x0200

bDeviceClass: Vendor Specific (0xff)

bDeviceSubClass: 255

bDeviceProtocol: 255

bMaxPacketSize0: 64

idVendor: Marvell Semiconductor, Inc. (0x1286)

idProduct: Unknown (0x812a)

bcdDevice: 0x0000

iManufacturer: 3

iProduct: 2

iSerialNumber: 0

bNumConfigurations: 1

:::

  1. 配置描述符:一个设备同一时刻只能有一种配置生效

:::
CONFIGURATION DESCRIPTOR

bLength: 9

bDescriptorType: 0x02 (CONFIGURATION)

wTotalLength: 121

bNumInterfaces: 4

bConfigurationValue: 1

iConfiguration: 0

Configuration bmAttributes: 0xc0  SELF-POWERED  NO REMOTE-WAKEUP

    1... .... = Must be 1: Must be 1 for USB 1.1 and higher

    .1.. .... = Self-Powered: This device is SELF-POWERED

    ..0. .... = Remote Wakeup: This device does NOT support remote wakeup

bMaxPower: 250  (500mA)

:::

  1. **接口描述符:**复合设备多个接口

:::
INTERFACE DESCRIPTOR (2.0): class Vendor Specific

bLength: 9

bDescriptorType: 0x04 (INTERFACE)

bInterfaceNumber: 2

bAlternateSetting: 0

bNumEndpoints: 2

bInterfaceClass: Vendor Specific (0xff)

bInterfaceSubClass: 0x00

bInterfaceProtocol: 0x00

iInterface: 8

:::

  1. 端点描述符:USB通信的基本物理单位,一个endpiont只能承载一个方向的数据,control interrupt bulk iso

12.class 描述设备是哪种设备,class分为class subclass protol 用于系统加载对应的驱动文件

枚举

13.传输->事务->包

14.上电,检测速度,主机发请求获取包的最大长度,主机给设备分配地址,主机获取设备配置

传输过程

帧格式:传输信息,数据,设备应答

主机读取设备描述符代码:

joystick hid

oystick HID(Human Interface Device)是指使用 USB HID 协议通信的游戏手柄或者操纵杆设备。

  1. 报告描述器

定义了设备支持的各种报告类型和格式, 报告描述器通常以二进制格式表示,描述了设备的物理按钮、摇杆、轴等控件。

2.报告协议

Joystick HID 设备通常使用中断传输报告

Joystick HID 设备通常包含多个按钮、摇杆、方向键等控件,用于用户输入。这些控件的状态(按下或释放、摇动的方向和幅度等)会被编码为报告数据,并通过 USB HID 协议传输到计算机上。

custom hid

Custom HID(Custom Human Interface Device)是指自定义的 USB HID 设备,它们不属于标准的键盘、鼠标、游戏手柄等常见类型,而是根据特定的需求和应用场景而设计的设备。

t113固件烧写

纸飞机if 0 1 一个是主机发送,设备传回 一个是设备持续发送数据。使用的就是usb协议

qt动态链接hidapi库,可以使用定义好的api来读信息

win32:LIBS += -L$$_PRO_FILE_PWD_\

-lhidapi

常用api

  1. **hid_init()**:初始化 **hidapi** 库,用于在程序开始时调用。

  2. **hid_exit()**:关闭 **hidapi** 库,用于在程序结束时调用。

  3. **hid_open()**:打开指定路径的 HID 设备。

  4. **hid_open_path()**:通过设备路径打开 HID 设备。

  5. **hid_close()**:关闭已打开的 HID 设备。

  6. **hid_read()**:从 HID 设备中读取数据。

  7. **hid_write()**:向 HID 设备中写入数据。

  8. **hid_send_feature_report()**:发送 Feature 报告到 HID 设备。

  9. **hid_get_feature_report()**:从 HID 设备中获取 Feature 报告。

  10. **hid_get_manufacturer_string()**:获取设备的制造商字符串。

  11. **hid_get_product_string()**:获取设备的产品字符串。

  12. **hid_get_serial_number_string()**:获取设备的序列号字符串。

  13. **hid_error()**:获取最近一次发生的错误信息。

可以读取到固件连续发出的信息,24个字节

除去vid pid 接口数,interface number 有0 和1

hiddevinfo信息

:::
**vendor_id**:设备的制造商 ID。

**product_id**:设备的产品 ID。

**path**:设备的路径(在某些操作系统中,可以用来打开设备)。

**serial_number**:设备的序列号。

**release_number**:设备的发布版本号。

**manufacturer_string**:设备制造商的字符串描述。

**product_string**:设备产品的字符串描述。

**usage_page**:设备的使用页面(Usage Page)。

**usage**:设备的使用(Usage)。

**interface_number**:设备接口的编号。
:::

设备、接口信息

0接口

\?\HID#VID_2A62&PID_0088&MI_01#7&6bb4252&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

1接口

\?\HID#VID_2A62&PID_0088&MI_00#7&7899f96&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

**QByteArray** 是用于存储二进制数据的类,通常用于处理字节流数据

可以使用 **QIODevice** 子类(例如 **QTcpSocket****QUdpSocket** 等)的 **write****read** 方法来发送和接收数据。

HIDDEVICE

枚举参数

:::
enum

{

REPORT\_ID\_JOY = 1,

REPORT\_ID\_PARAM,//参数请求报告

REPORT\_ID\_CONFIG\_IN,//读取配置模式

REPORT\_ID\_CONFIG\_OUT,//应该是写入配置模式

REPORT\_ID\_FIRMWARE,

};
:::

方向:修改和32不同的字符名称、端口数量

线程安全:在多线程环境中,如果多个线程同时尝试修改共享的数据结构,比如清空列表 **m_hidDevicesList**,就可能导致竞态条件(Race Condition)的发生,进而造成不确定的行为,甚至是程序崩溃。这里是因为修改公共数据,所以两个线程进行数据处理时候加了锁。

:::
**processData()** 函数中的 **th** 线程和主线程都会访问和修改 **m_hidDevicesList** 列表。

#include

// 声明互斥锁

std::mutex m_mutex;

void someFunction() {

// 创建 lock\_guard 对象并传入互斥锁

std::lock\_guard<std::mutex> lock(m\_mutex);

// 在这个作用域中,m\_mutex 已经被锁定,可以安全地访问共享资源

// ...

// 在作用域结束时,lock\_guard 的析构函数会自动释放互斥锁

}
:::

同一个函数内如果存在两个进程,也属于不同的作用域,锁定义为成员变量,可以理解为两个作用域调用了同一个锁对象。

handle processdata function entry,create thread using movetothread()

:::
m_hidDeviceWorker->moveToThread(m_thread);

connect(m\_thread,&QThread::started,m\_hidDeviceWorker,&HidDevice::processData);

:::

**QString::fromWCharArray** 是 Qt 中用于将宽字符数组转换为 QString 对象的函数。它的作用是将以 null 结尾的宽字符数组(wchar_t[])转换为 QString 对象。

:::
QString QString::fromWCharArray(const wchar_t *unicode, int size = -1)
:::

代码分析,可以根据执行流程来进行 qDebug()<<“执行到这里”;

if (m_selectedDevice != oldSelectedDevice || (deviceCountChanged && m_selectedDevice >= 0))

这个是作者设置的判断条件,没有注释功能,之后再看,已进入了这个判断。

usb_hid设备收发

读配置

hid_write(m_paramsRead, config_request_buffer, 2);

res=hid_read_timeout(m_paramsRead, buffer, BUFFERSIZE,100);//返回数据的字节数

hid_set_nonblocking(handle,0)==0) 句柄 要打开的interface number 成功返回0,失败 -1

interface_num=0,设备并没有向外发数据,而是一个发啥读啥的过程。

设备会发送数据给主机,需要设置一个接收数据的循环。通过库函数从设备读取数据,并_根据报告描述符解析数据_

extern GlobalEnvironment gEnv; 这行代码,在当前文件中引用该变量,以便在当前文件中使用它而不需要重新定义。其他文件中已经定义了此结构体

NXP公司74HC165 移位寄存器 并行输入串行输出

image

pl

全局变量 extern 作用范围群全部程序

// 在头文件中定义全局变量

extern int global_var;

// 在源文件中定义全局变量

int global_var = 0;

当主机操作系统检测到新连接的USB设备时,会通过控制传输向USB设备发送请求获取设备描述符。USB设备在收到请求后,会将相应的设备描述符数据通过控制传输发送给主机操作系统。主机操作系统接收到设备描述符数据后,会解析数据并根据其中的信息来配置和识别USB设备。这部分在识别到设备之前就已经完成了。

// 将字符串转换为字节数组

QByteArray byteArray = str.toUtf8(); // 或者使用 toLatin1() 或 toLocal8Bit()

// 将字节数组转换为十六进制表示

QByteArray hexArray = byteArray.toHex();

// 输出十六进制表示

qDebug() << hexArray;

在写入数据时,应该构造一个比实际数据长1个字节的数组。然后将这个数组的第一个字节赋值为0,接着调用该函数,差一点就会出错乱码。

usb线接入电脑端口不同,也会导致读取到interface_number不同

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值