文档章节

使用USB HID进行数据交互

coreyggj
 coreyggj
发布于 2017/06/27 13:59
字数 723
阅读 129
收藏 1
USB

最近看到一款与我们同类型的USB Audio  Chip的SPEC: CM108AH(http://www.hardwaresecrets.com/datasheets/CM108AH.pdf), 其中通过HID协议对芯片内部寄存器进行读写操作的feature觉得很有意思。 考虑到客户应用场景下通过USB进行寄存器调整的简便性,觉得增加这个功能还是很有必要。

由于之前已经使用USB HID来进行音量的控制,所以相对修改就小的多,基本上只需要进行描述符的改动即可。

HID接口描述符

  0x09,         /* bLength: Interface Descriptor size */
  0x04,         /* bDescriptorType: Interface descriptor type */
  0x03,         /* bInterfaceNumber: Number of Interface */
  0x00,         /* bAlternateSetting: Alternate setting */
  0x02,         /* bNumEndpoints */
  0x03,         /* bInterfaceClass: HID */
  0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
  0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
  0x00,         /* iInterface: Index of string descriptor */

端点描述符


  0x07,          /* bLength: Endpoint Descriptor size */
  0x05,          /* bDescriptorType: */
  0x81,          /* bEndpointAddress: Endpoint Address (IN) */
  0x03,          /* bmAttributes: Interrupt endpoint */
  0x08, 0x00,    /* wMaxPacketSize: 8 Bytes max */
  0x20,          /* bInterval: Polling Interval (32 ms) */

  0x07,          /* bLength: Endpoint Descriptor size */
  0x05,          /* bDescriptorType: */
  0x09,          /* bEndpointAddress: Endpoint Address (OUT) */
  0x03,          /* bmAttributes: Interrupt endpoint */
  0x08, 0x00,    /* wMaxPacketSize: 8 Bytes max */
  0x20,          /* bInterval: Polling Interval (32 ms) */
 

这里使用了2个端点,IN端点1作为媒体控制信息和私有数据的输入端点,OUT端点作为私有数据的输出端点。

由于IN端点1里面承载的2种不同用途的payload,就必须要用report id区分下。

HID 描述符

    0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)
    0x09, 0x01,                    // USAGE (Consumer Control)
    0xa1, 0x01,                    // COLLECTION (Application)
    
    0x85, 0x01,                    //   Report ID1
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x09, 0xe9,                    //   USAGE (Volume Up)
    0x09, 0xea,                    //   USAGE (Volume Down)
    0x09, 0xe2,                    //   USAGE (Mute)
    0x09, 0xCD,                    //   USAGE (Play/Pause)
    0x09, 0xb5,                    //   USAGE (Scan Next Track)
    0x09, 0xb6,                    //   USAGE (Scan Previous Track)
    0x09, 0xb3,                    //   USAGE (Fast Forward)
    0x09, 0xb7,                    //   USAGE (Stop)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)

    0x85, 0x02,                    //   Report ID2 Data Input(2 bytes)
    0x26, 0xFF, 0x00,
    0x09, 0x00,
    0x75, 0x08,
    0x95, 0x02,
    0x81, 0x02,
    
    0x85, 0x03,                    //   Report ID3 Data Output (2 bytes)
    0x26, 0xFF, 0x00,
    0x09, 0x00,
    0x75, 0x08,
    0x95, 0x02,
    0x91, 0x02,
    
    0xc0,                           // END_COLLECTION

注意在进行数据传输时,需要先发送report id,然后再加上playload。

按上面的描述信息,report ID1的payload是1个字节,所以传输数据格式应该为: 0x01,,0x**,其他对应的格式如下:

我是通过Linux下对/dev/hidrawX这个设备节点进行read、write操作来进行功能的验证。

USB分析仪抓包数据如下:

可以看到帧号45096是report1的输入数据,帧号45105是report3的输出数据。

BTW:

  1. 大家可以观察下,HID采用USB中断传输类型,其本质也是轮询方式,如果过多使用的话也会很占用USB带宽(从超多的NAK就可以看出来)。
  2. 我本人是在vmware虚拟机里装ubuntu进行对hidrawX节点的操作,结果问题很多hidapi(http://www.signal11.us/oss/hidapi/)也用不起来。如果只能在虚拟机下测试,最好每次测试完后拔插下USB设备。
  3. 关于OUT端点9可以不用,这样的话HID默认采用端点0进行传输。

 

© 著作权归作者所有

上一篇: UAC1.0 vs UAC2.0
coreyggj
粉丝 1
博文 42
码字总数 19193
作品 0
无锡
程序员
私信 提问
USB与BT HID reports描述符实践与抓包分析

文章内容提示 这篇文章主要说明如何获取与查看USB和BLE HoGP HID设备报告描述符,如何根据获取的描述符读懂report。然后说明了可以使用hidrd-convert工具,来如何根据hex报告描述符转化得到C...

sy373466062
2017/10/13
0
0
《Linux内核修炼之道》精华分享与讨论(12)——设备模型(下)

推荐博文: Linux内核“问题门”——学习问题、经验集锦 推荐下载:《Linux内核修炼之道》精华版之方法论 设备模型拍得再玄幻,它也只是个模型,必须得落实在具体的子系统,否则就只能抱着个...

任桥伟
2010/04/12
0
0
ubuntu 16.04 重启主机后,无线网卡需插拔后才可以使用,求老鸟们协查

最近在台式机上安装了ubuntu 16.04,搭配了 USB插口的TP LINK TL-WN823N 无线网卡。 幸运的是可以正常上网了 不幸的是,只要reboot重启主机,无线网卡就需要重新插拔才可以用。 但是冷启动的...

DDFlycom
2017/09/18
274
4
手把手教你在pcduino上实现uspip--USB网络重定向

我们经常碰到一种情况,我们需要往pcduino上拷贝东西,新手都用U盘,高手一般都用samba这样的高级玩意儿。拷贝一次倒也无所谓,关键是有些情况下,我们需要多次测试,多次拷贝。pcduino的USB...

pc朵拉
2013/08/27
476
0
手把手教你在pcduino上实现uspip--USB网络重定向

我们经常碰到一种情况,我们需要往pcduino上拷贝东西,新手都用U盘,高手一般都用samba这样的高级玩意儿。拷贝一次倒也无所谓,关键是有些情况下,我们需要多次测试,多次拷贝。pcduino的USB...

pc朵拉
2013/08/16
2.5K
0

没有更多内容

加载失败,请刷新页面

加载更多

C 语言 二级指针的使用

#include <stdio.h>#include <stdlib.h>typedef struct node Node;struct node {int data;struct node* next;struct node* prev;};Node head;Node* insert(Node......

小张525
13分钟前
1
0
【大数据技术】——Hadoop(1)

什么是大数据 基本概念 《数据处理》 在互联网技术发展到现今阶段,大量日常、工作等事务产生的数据都已经信息化,人类产生的数据量相比以前有了爆炸式的增长,以前的传统的数据处理技术已经...

须臾之余
27分钟前
6
0
比特币从地址逆向计算私钥

区块链 区块链简介 说到比特币,就不得不提区块链。那什么是区块链呢? 区块链本质是一个数据集,只不过数据的组织采用了比较特殊的方式,就是把数据拆分为一块一块的小数据集。 为什么要进行...

trayvon
42分钟前
1
0
TypeScript……真香

写前端或者用 node 写命令行小工具一直采用的 es6 的语法,对于 TypeScript 则是秉持敬而远之的态度,毕竟团队中多推广一门语言所需要花费的精力都是让人望而却步的。所以对于 JavaScript 的...

郁也风
47分钟前
3
0
shell基本案例

1、自定义rm linux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来替换系统的rm命令,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做...

寰宇01
54分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部