自定义 HID 设备的实现
来源:互联网 发布:js中的短路表达式 编辑:程序博客网 时间:2024/06/02 18:23
HID 设备,
|– 通过设备描述符来标识自己的设备信息,如设备ID、厂商名称、版本、配置数量等;
|– 通过配置描述符集合来标识自己的配置信息,包括
| |– 配置描述符(总述)、
| `– 接口描述符(接口类型,鼠标,键盘,自定义设备等)、
| |– 端点描述符(端点读写类型,支持的数据包属性等)和
| `– HID描述符(HID版本、下级描述符信息等)。
|– 通过字符串描述符来定义自己的一些字符串,如厂商名称等;
`– 通过报告描述符来标识数据流的格式,如数据用途(鼠标、键盘、自定义等)、长度、大小等。
网上的很多示例和介绍都使用c语言,但是,我遇到的源码,却是汇编编写的,所以我以我的项目为例,用汇编来介绍各个描述符结构,也算是个不一样的体验吧。
具体的描述介绍如下:
设备描述符
deviceDesc: ; Device descriptorDB deviceDescEnd - deviceDesc ; bLength 该描述符长度DB DESC_TYPE_DEVICE ; bDescriptorType 类型DW 0200H ; bcdUSB (USB 2.0) USB 版本DB 00H ; bDeviceClass (given by interface) 类代码DB 00H ; bDeviceSubClass 子类代码DB 00H ; bDeviceProtocol 设备协议DB EP0_PACKET_SIZE ; 端点0最大包长DW 0451H ; idVendor (Texas Instruments) 厂商ID (VID)#if (chip==2531)DW 16A9H ; idProduct (CC2531 HID) 产品ID (PID)#elif (chip==2511)DW 16A5H ; idProduct (CC2511 HID)#elseDW 16A7H ; idProduct (CC1111 HID)#endifDW 0100H ; bcdDevice (v1.0) 设备版本号DB 01H ; iManufacturer 描述厂商的字符串索引DB 02H ; iProduct 描述产品的字符串索引DB 00H ; iSerialNumber 产品序列号字符串的索引DB 01H ; bNumConfigurations 可能的配置数deviceDescEnd:
在里面,最重要的是VID和PID,它一般用来标识你的USB设备。VID需要向USB组织申请,PID则是公司内部自己定义。其实,我们还可以通过产品序列号来标识,但目前,我还没有添加这个功能,直接使用VID和PID识别的。
另外我们可以通过这份代码看到一些技巧,就是在填写描述符长度时,让编译器自己计算:deviceDescEnd – deviceDesc
配置描述符
configDesc: ; Configuration descriptorDB configDescEnd - configDesc ; bLength 该描述符长度DB DESC_TYPE_CONFIG ; bDescriptorType 类型DW config1LengthEnd - config1LengthStart ; wTotalLength 所有配置描述符的总长度; adding a custom interface, so this should be 3! - by tankery.DB 03H ; bNumInterfaces 端点数量DB 01H ; bConfigurationValue 该配置的值?不懂。。。。。。DB 00H ; iConfiguration 该配置的字符串索引值DB 80H ; bmAttributes 该配置属性DB 25 ; bMaxPower (max 2 * 25 = 50 mA) 设备所需电流大小。configDescEnd:
我目前的设备是鼠标、键盘、自定义3种接口。可以支持三种端点同时传输数据,非常high~~
接口描述符
interface2Desc: ; custom device interface descriptorDB interface2DescEnd - interface2Desc ; bLength 该描述符长度DB DESC_TYPE_INTERFACE ; bDescriptorType 类型; this should be increaced - by tankery.DB 02H ; bInterfaceNumber 该接口的编号DB 00H ; bAlternateSetting (none) 备用编号DB 01H ; bNumEndpoints 端点数DB 03H ; bInterfaceClass (HID) 接口使用的类(HID)DB 00H ; bInterfaceSubClass (custom) 接口使用的子类(00为自定义)DB 00H ; bInterfaceProcotol (custom) 接口使用的协议(00为自定义)DB 00H ; iInterface 该接口的字符串索引值interface2DescEnd:
我的这个项目中,有3 种接口,原始代码已经实现了鼠标和键盘的接口描述符。感兴趣的读者也可以在网上查阅。有现成的示例代码。
从本文开始的那个介绍看出,接口之下是包含端点的,因此,接口描述符中有一项的端点数,这个端点数标明的是除默认控制端点0之外的数据输入输出端点数量。目前我只实现了一个数据输入(USB中所有的输入、输出的对象都是主设备,在我这里,指的是PC)。
后期我会添加一个数据输出端点。
端点描述符
endpoint2Desc: ; Custom endpoint descriptor (EP3 IN); need endpoint 3 - by tankery.DB endpoint2DescEnd - endpoint2Desc ; bLength 该描述符长度DB DESC_TYPE_ENDPOINT ; bDescriptorType 类型DB 83H ; bEndpointAddress 端点地址(3)DB EP_ATTR_INT ; bmAttributes (INT) 端点类型(中断)DW 0008H ; wMaxPacketSize (8 bit) 最大数据包长度DB 0AH ; bInterval (10 full-speed frames = 10 ms)endpoint2DescEnd:
端点描述符中的bmAttributes 是个比较重要的字段,标明了该端点的类型,端点有控制(0)、等时(1)、批量(2)、中断(3)四种类型。HID只有控制端点和中断端点两种类型。
HID描述符
hid2Desc:; Custom HID descriptorDB hid2DescEnd - hid2Desc ; bLengthDB DESC_TYPE_HID ; bDescriptorTypeDW 0111H ; bcdHID (HID v1.11)DB 00H ; bCountryCode (not localized)DB 01H ; bNumDescriptorsDB DESC_TYPE_HIDREPORT ; bDescriptorTypeDW entity2DescEnd - entity2Desc ; wDescriptorLengthhid2DescEnd:
这个没啥要紧的,我也不清楚,不详述了。
报告描述符
报告描述符相当复杂,但也是HID设备的精髓。它标识了HID设备与主机通讯的报告格式以及数据用途,数据是存放在报告中的。
报告描述符的每个条目都有个条目前缀,是如下格式:
,-----------------------.|7 6 5 4 3 2 1 0 ||-----------------------|| bTag | bType | bSize |`-----------------------'
高 4 位bTag标识该条目的功能,具体的可以参看HID协议,第 2, 3 位为条目类型(0――主条目、1――全局条目、2――局部条目、3――保留),第 0, 1 位为条目大小,表示该前缀之后有多少个字节的内容。
比如 09H (00001001B) 表示这是一个局部条目,后跟一个字节。功能为用途页(0)。各种功能的定义可以参看HID协议或者其它示例,下面,我就以我写的自定义设备为例大致介绍一下报告描述符的设计:
entity2Desc: ; Custom HID device report descriptorDB 0005H, 0001H ; Usage Pg (Generic Desktop) 全局,功能为“用途页”。后跟的0001H表示这是通用桌面用途DB 0009H, 0000H ; Usage (0) ; custom usage 局部,功能为“用途页”。后跟0000H表示这是自定义用途。DB 00A1H, 0001H ; Collection: (Application) 主条目,功能为“开集合”,表示后面的条目都在集合 Application 下。 ;DB 0015H, 0000H ; Log Min (0) 全局,功能为“最小值”,表示数据的可以达到的逻辑最小值为0DB 0025H, 00FFH ; Log Max (255) 全局,“最大值”,表示最大为255 (一个字节)。DB 0019H, 0000H ; Usage Min (0) 局部,功能为“最小值”,表示局部用途,即上文定义的自定义用途最小值为0DB 0029H, 00FFH ; Usage Max (255) 局部。。。。 ; ; we will send the remote ID and selection ; need 2 byte (16 bit) data space.DB 0095H, 0002H ; Report Count (2) 全局,功能为“数据数量”,表示每个报告中数据的数据有2个DB 0075H, 0008H ; Report Size (8) 全局,功能为“数据大小”,表示每个数据大小为 8 个bit。DB 0081H, 0002H ; Input: (Data, Variable, Absolute) 主,功能为“输入”, ; 02H (00000010B) 表示以上的数据定义是变量,独立(非数组),绝对值(无符号)的。DB 00C0H ; End Collection 主条目,不跟内容,“关集合”。表示关闭上面打开的Application集合。entity2DescEnd:
通过这份报告描述符,我们就能知道,这个接口传输的数据是用于自定义用途的,而且是两个字节的数据。
当然,我这还是测试之用,到具体使用时,我会使用两个数据段,一个是 4 个字节的手持端ID数组,一个是1字节的手持端数据内容。
到时就会更复杂一些。
OK,剩下的工作就是编写这些描述符的发送函数了。我使用的是TI公司的代码,所以没有自己编写这些函数,就不误人子弟了。。
并且不同的芯片编写的代码也不一样。要看具体情况。有兴趣的读者就自己去体会吧~~
- 自定义 HID 设备的实现
- STM32 自定义HID USB设备的实现
- 自定义 HID 设备的实现――下位机
- Android实现HID鼠标的指针自定义
- s3c2416 自定义hid设备通信
- HID设备的开发
- HID 设备的开发
- Android基于wifi的无线HID设备实现
- android usb与自定义HID设备通讯
- LINUX 自定义USB Gadget HID 设备
- STM32 USB HID 自定义设备 bulk 传输
- 自定义USB-HID设备_笔记
- linux下自定义USB HID设备
- Android HID设备的连接
- STM32配置CH375B成HID Host模式读取自定义HID设备的数据 ——STM32端口初始化
- STM32配置CH375B成HID Host模式读取自定义HID设备的数据 ——STM32配置CH375B接口函数
- USB HID设备读写代码实现c++
- Windows主机端与自定义USB HID设备通信详解 - Windows - 阿Min的BLOG
- 在windows下安装python——详解(windows7)
- 有这样写JS的同学吗?感觉很不地道,放上来肯定会被喷的。里面还插入了php代码,但是我需要的功能都实现了!哇哈哈@
- 【C语言】程序执行时间测量
- C#自定义控件:扩展控件功能
- linux内核相关面试题
- 自定义 HID 设备的实现
- 08--java异常总结
- HttpURLConnection 的get跟post请求
- powerdesigner15.1 实体和别人不同(黄色圆角矩形),无association和inherit
- DOS批处理文件的当前目录问题
- 总算理解char *p="abc"与char p[]="abc"的不同
- layout的一些属性
- java学习笔记3——重载
- 程序员技术练级攻略【转自酷壳】