安卓实现与USB_HID设备实现控制传输通信所需要具备的USB知识

5,526 阅读10分钟

人生要做的五件事情:1、恋爱,结婚,生子。2、尝试做一次自己喜欢的事情。3、回馈。4、有一个信仰。5、留下遗产。

目的

  写这篇文章的目的是记录最近在研究安卓与USB_HID设备通信时所学到的知识,发现虽然安卓里面已经封装好了方法给我们调用,但是有些参数我们不去了解一下USB那边的知识是不知道怎么获取的,怎么跟硬件工程师那边沟通,需要什么参数,这样自己不知道方法需要的实际参数是什么,硬件工程师那边又不知道自己想表达什么,所以,即使作为安卓工程师,了解一下USB的知识还是很有必要的,接下来我就来说明一下我在开发过程需要了解的USB知识,后面会有具体的实现文章,磨刀不误砍柴工,我们先去了解一下USB的一些基本知识,我也会在介绍这些知识的时候重点说明哪部分会用在安卓开发上。

目录

  接下来我会以以下目录进行讲述,如果目录中的内容读者已经知晓,可以跳过,选择性观看即可。
  一、认识USB
  二、USB描述符
    2.1 各描述符的作用
    2.2 USB的描述符及其之间的关系
  三、USB请求格式
  四、USB的传输方式
    4.1 控制传输(Control Transfer)
    4.2 批量传输(Bulk Transfer)
    4.3 中断传输(Interrupt Transfer)
    4.4 同步传输(Isochronous Transfer)
    4.5 四种传输方式对比
  五、什么是HID类设备
    5.1 HID类请求

一、认识USB

  USB是通用串行总线(Universal Serial Bus)的缩写,是一种连接PC与外部设备的一种串口总线标准。用于规范电脑与外部设备的连接和通讯,主要应用在PC领域,相关产品有鼠标、键盘、游戏手柄、摄影器材等等。

二、USB描述符

  可以理解为描述符就是一种”身份证”,USB HOST就是通过各种描述符来识别设备的。描述符的分类有设备描述符、配置描述符、接口描述符、端点描述符、字符串描述符。并且每种描述符都有自己独立的编号。如下图所示。
alt
  2.1 各描述符的作用
  ①设备描述符:定义标准的设备描述符结构。一个设备只有一个设备描述符。
alt
  这里面的PID和VID就是需要我们向硬件工程师那边了解的,VID每个公司都会有一个特定的,在安卓这边就需要这两样东西去找到我们要的设备。
  ②配置描述符:定义设备标准的配置信息,一个设备可以有多个配置描述符。
alt
  ③接口描述符:说明接口所提供的配置,一个配置所拥有的接口数量通过配置描述符的bNumInterfaces决定。
alt
  ④端点描述符:USB设备中的每个端点都有自己的端点描述符,由接口描述符中的bNumEndpoint决定其数量。
alt
  ⑤字符串描述符:字符串描述符是可选的。如果不支持字符串描述符,其设备,配置,接口描述符内的所有字符串描述符索引都必须为0。
alt
  2.2 USB的描述符及其之间的关系
  ①配置和接口是为了方便管理端点而抽象出来的概念
  ②同一个端点号可用在不同的配置中
  ③同一个端点号不能出现在同一个配置的不同接口中(端点0除外)
  ④设备是配置的集合,配置是接口的集合,接口是端点的集合。
alt

三、 USB请求格式

  这里面有些格式是我们开发过程中需要注意的,遇到我会特别说明。请求格式如下: alt
  参数说明:
  ① bmRequestType:请求特性
    D7-数据传输的方向。0:host->device,1:device->host;
    D6至D5-请求类型。0:标准请求,1:类请求,2:厂商自定义请求,3:保留;
    D4至D0-请求对象。0:设备,1:接口,2:端点。
  因此,如果是HID的设备类请求,只有10100001和00100001两种。注意,这里得记住这两个二进制数,进行通信的时候会用到,后面会讲解到。
  ② bRequest:定义请求类型
    USB设备的标准请求有以下几种:
    GET_DESCRIPTOR:在枚举过程中用得最多的一个请求,主机通过该请求来读取设备的各种描述符。
    SET_ADDRESS:主机用来请求设备使用指定地址。
    SET_CONFIGURATION:主机用来设置当前配置值。
    GET_CONFIGURATION:主机用来获取当前配置值。
    CLEAR_FEATURE:用来清除一个指定的特性(例如Device的Power由谁提供,是否支持wakeup)。
    SET_FEATURE:用来设置或使一个特性生效。
    GET_STATUS:返回所指接收者的状态。
  ③ mValue:这个参数占两个字节,高字节和低字节分别代表不同的含义。
    高字节说明描述符的类型:
    0x21:HID描述符
    0x22:报告描述符
    0x23:物理描述符
    低字节不为0时被用来选定物理描述符。
  这个在HID通信使用SET_REPORT和GET_REPORT请求时高字节表示报告类型:0x01—input(输入报告)、0x02—output(输出报告)、0x03—feature(特征报告)、Other—reserve。低字节代表Report ID(报告ID),对于报告ID,在安卓开发里面,我们要知道是在使用这两个请求进行控制传输时必须要知道的(如果使用特征报告的话),这个问硬件工程师那边就可以了。但是要注意的是这个位置的参数高位和低位是反过来的,比如在电脑上使用0x0203可以实现通信,但是在安卓这边不行,得反过来,改成0x0302。
  ④ wIndex:这个参数也占两个字节,根据不同的请求会有不同的意义。
  这个在后面讲解HID通信使用SET_REPORT和GET_REPORT请求时也会有重点讲解。但有一点要提的是这是接口号,当设备在电脑上传输的话,选的接口号设备中没有的话会一步一步向接口0去寻找,也就是说我在电脑上选择接口3进行数据传输,但是设备中没定义有接口3,然后就会自动去找接口2,接口2没有就找接口1,直到找到接口0进行传输,但是安卓中是不会自动去寻找的,这个一定要问清楚硬件那边,不然自己连问题出在哪都不知道。
  ⑤wLength:代表数据长度。

四、 USB的四种传输方式

  传输方式有:控制传输(Control Transfer)、批量传输(Bulk Transfer)、中断传输(Interrupt Transfer)、同步传输(Isochronous Transfer)。我们先了解一下这四种传输分别是什么,最后再总结四种传输方式的对比。
  4.1 控制传输(Control Transfer)
  作用:USB系统软件用来主要进行查询配置和给USB设备发送通用的命令。
  特点:控制传输是双向传输,数据量通常较小;数据传送是无损性的。数据宽度:控制传输方式有8、16、32、64字节的数据。典型应用:在主计算机和USB外设之间的端点0(EP0)之间的传输。后面安卓使用的控制传输也是用到端点0。
  4.2 批量传输(Bulk Transfer)
  作用:在需要大量数据传输和接受数据上同时又没有带宽和间隔时间要求的情况下得以应用。
  特点:要求保证传输,适合传输非常慢和大量被延迟的传输,可以等所有其它类型的数据传输完成后再传输和接收数据。打印机和扫描仪就是属于这种传输类型的设备。
  4.3 中断传输(Interrupt Transfer)
  作用:主要用于定时查询设备是否有中断数据要传输。
  特点:设备的端点模式器的结构决定了它查询频率从1到255ms之间。这种传输方式是单向的,对于host来说只有输入模式。鼠标就是属于这种传输类型的设备,我拿来测试的硬件设备就是被定义成一个鼠标。
  4.4 同步传输(Isochronous Transfer)
  作用:用于时间严格并具有较强容错性的流数据传输,或者用于要求恒定的数据传输率的即时应用中。
  特点:保证传输的同步性,保证每秒都有固定的传输量。要注意的是同步传输允许有一定的误码率。典型应用是执行即时通话的网络电话。
  4.5 四种传输方式对比
alt

五、 什么是HID类设备

  HID类设备属于人机交互操作的设备,将设备枚举成HID设备可以不用开发驱动程序,用操作系统自带的HID类驱动程序即可完成通信。
  5.1HID类请求
  HID协议定义了6个HID类的特定请求:(注意,这是我们在开发USB_HID设备时要会的,要知道的)
  0x01:GET_REPORT-主机用控制传输从设备接收数据,所有HID设备都要支持这个请求。
  0x02:GET_IDLE-主机读取设备当前的空闲速率,设备可以不支持此请求。
  0x03:GET_PROTOCOL-仅仅适应于支持启动功能的HID设备(Boot Device)。
  0x09:SET_REPORT-设备用控制传输接收主机的数据,设备可以不支持此请求。
  0x0A:SET_IDLE-设置闲置状态,设备可不支持此请求。
  0x0B:SET_PROTOCOL-仅仅适应于支持启动功能的HID设备(Boot Device)。
  后面会讲解这六种请求类型的参数设置,并通过SET_REPORT和GET_REPORT实现与HID设备通信。
alt
  因为HID设备是我们本次要重点掌握的,下面分别讲解一下几个HID特定请求的参数。(注意这些参数是安卓中调用控制传输方法有关的参数,所以必须要了解)
  GET_REPORT:主机通过控制端点获取一个Report。
alt
  SET_REPORT:主机发送一个Report给设备,用以设置input,output或者feature。
alt
  GET_IDLE:主机读取设备当前的空闲速率,设备可以不支持此请求。
alt
  SET_IDLE:设置闲置状态,设备可不支持此请求。
alt
  GET_PROTOCOL:仅仅适应于支持启动功能的HID设备(Boot Device)。
alt
  SET_PROTOCOL:仅仅适应于支持启动功能的HID设备(Boot Device)。
alt

总结

  以上就是我在开发安卓与USB_HID设备通信时所学到及了解到的有关USB的知识,以此作为一个记录,下周我会将在安卓上如何实现的流程写成文章发布,如果以上有什么错的,欢迎指出,虚心修改O(∩_∩)O,如果对您有用,点个赞呗~