[嵌入式专栏](系列一 、协议 - USB详解)

2023-12-28 16:55:10


【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485


1 . 前言

  • 1 . USB协议较为广泛,这里按以往风格描述物理层,协议层,应用层
  • 2 . 基于本人习惯简洁风格,此篇文章尽量把USB协议描述清晰
  • 3 . 接下来从物理层,协议层,应用层,从下往上深入浅出剖析

2 . USB外形类分

在这里插入图片描述

3 . 物理层

  1. USB2.0的结构简洁,VCC, D+, D-, GND通信.

  2. 主机的两个下拉电阻阻值为15K,从机的D+ D-上拉电阻为1.5K

  3. 通讯依靠D+,D-作为差分

  4. 对于低速,全速设备USB通信四种状态,逻辑0与逻辑1和JK状态不加以区分

    JKSE0SE1
    D +0101
    D -1001
  5. 对于高速设备,做了8b/10b编码,把逻辑0与逻辑1和JK状态区分开来
    { K, D[7], D[6], D[5], D[4], D[3], D[2], D[1], J, D[0] }

  6. 下图为USB2.0的结构 :
    在这里插入图片描述

4 . 协议层

  • USB协议层内容比较多,这里以 设备接入主机的整个过程 来描述

4.1 设备接入/拔出

  1. 当设备接入时,通过检测从机的上拉电阻接在了D- 或 D+来判断设备所属模式
    模式上拉电阻接入 (1.5K)速度
    低速D-1.5M
    全速D+12M
    高速D+480M
  2. 当设备拔出时,通过检测从机的D- 和 D+ 的上拉来判断设备拔出
    模式上拉电阻接入 (1.5K)
    拔出

4.2 首次通信

  1. 当主机识别到有设备接入后,主机会在总线上对 { “地址0” “端点0” } 发送信息,从机接入时,从 { “地址0” “端点0” } 处接收信息,这里的信息包含了主机分配给从机的 新地址,从机回复主机确认后,从机按 新地址 自居,从机找到家了,从此可以和主机愉快的生活了,主机就可以到 新地址 访问了,然后主机会向 新地址 请求完整的 设备描述符,配置描述符 来获取接口,如果接口存在多个,会继续遍历,当主机知晓设备的完整信息后,就完成了 枚举 的过程。

4.3 USB描述符

描述符前言 :

  • 在写描述符之前,这里将USB意义简述一下。
  • USB协议总是主机发起通信,如果从机的内容比较多,那么主机该如何与从机的某个局部信息进行交互呢?
  • 无论从机有多少信息,我们把它分而治之不就可以了吗,就像一省有N市,一市有N镇,一镇有N村,假如你想了解某个人的信息,那么通过省市镇村就可以找到对方进行交互,USB协议里也是一样,逐层解析。
  • 所以诞生了设备描述符,配置描述符,接口描述符,端点描述符,报告描述符,特殊描述符,字符串描述符,各描述符都有自己的数据结构,以下详述了各描述符意义。

在这里插入图片描述

4.3.1 设备描述符
  1. 设备的基本信息: 设备描述符包含了有关 USB 设备的基本信息,如设备类别、设备子类别、设备协议、最大包大小等。这些信息有助于主机系统正确识别和配置设备
  2. 供应商和产品标识: 设备描述符包含供应商标识(Vendor ID)和产品标识(Product ID),这两个标识唯一地标识了设备的制造商和产品。这对于主机系统正确识别和匹配设备驱动程序非常重要
  3. 设备版本信息: 设备描述符包含了设备的版本号,有助于主机系统确定设备的硬件或固件版本。
  4. 设备支持的 USB 规范版本: 设备描述符指明了设备支持的 USB 规范版本,这有助于主机系统适配与设备进行通信。
  5. 配置描述符的索引: 设备描述符中包含配置描述符的索引,主机系统可以通过这个索引获取设备的配置信息。

设备描述符总结

  • 设备描述符是设备插入 USB 总线时被主机系统主动请求的第一个描述符。
  • 主机系统通过读取设备描述符可以获取设备的基本特性,从而为设备进行正确的配置和管理。
  • 设备描述符是 USB 设备描述符的核心组成部分,提供了主机系统获取关于设备基本信息的入口,有助于主机正确识别、配置和与设备进行通信。

4.3.2. 配置描述符
  1. 配置的基本信息: 配置描述符包含了有关设备配置的基本信息,如配置值、总长度、最大功率需求等。这些信息有助于主机系统了解设备的配置。
  2. 接口数量: 配置描述符指明了该配置下包含的接口的数量,主机系统可以通过这个信息了解设备提供了多少个功能或服务。
  3. 供电特性: 配置描述符包含了设备的供电特性,例如设备是否通过总线供电、是否支持远程唤醒等。
  4. 接口描述符的索引: 配置描述符中包含了接口描述符的索引,主机系统可以通过这个索引获取配置下每个接口的详细信息。
  5. 分配地址的标志: 配置描述符中的"bAttributes"字段指明了该配置是否是用于分配设备地址的配置,这对于 USB 设备的初始化阶段很重要。

配置描述符总结

  • 配置描述符提供了主机系统有关设备配置的基本信息。
  • 一个 USB 设备可以有一个或多个配置,每个配置可以包含一个或多个接口,每个接口可以包含一个或多个端点。
  • 主机系统通过读取配置描述符,能够了解设备的整体结构和提供的功能,从而为设备进行正确的配置和管理。
  • 配置描述符是 USB 设备描述符的关键组成部分,有助于主机系统正确识别、配置和与设备进行通信。

4.3.3. 接口描述符
  1. 接口的基本信息: 接口描述符包含了关于接口的基本信息,如接口号、接口类别、子类别、协议等。
  2. 端点数量: 接口描述符指明了该接口上包含的端点的数量。每个端点用于不同的数据传输目的,如控制传输、批量传输、中断传输或同步/异步传输等。
  3. 接口描述符的索引:接口描述符中包含了该接口的索引,主机系统可以通过这个索引获取接口的详细信息。
  4. 接口的特殊属性: 接口描述符中的一些字段提供了关于接口的特殊属性的信息,如是否支持 HID(Human Interface Device)等。
  5. 接口关联描述符: 在某些情况下,接口描述符可能包含关联其他接口的信息,用于表示多个接口之间的关系。

接口描述符总结

  • 接口描述符对于主机系统正确识别和配置设备的每个接口非常重要。
  • 主机系统通过读取接口描述符可以了解设备提供了多少个接口,每个接口的功能是什么,以及每个接口上有多少个端点。
  • 接口描述符是 USB 设备描述符的一部分,用于提供关于每个接口的基本信息,帮助主机系统正确识别、配置和与设备进行通信。

4.3.4. 端点描述符
  1. 端点地址(Endpoint Address): 描述端点的地址,包括方向(输入或输出)和端点号。
  2. 端点类型(Attributes): 描述端点的类型,如控制、同步、异步等。
  3. 最大包大小(Max Packet Size):表示每个 USB 事务中传输的最大数据包大小。
  4. 传输间隔(Interval): 对于同步和中断端点,表示两次传输之间的时间间隔。

端点描述符总结

  • 端点描述符提供了主机系统关于设备上每个端点的详细信息,主机系统根据这些信息来正确配置和管理数据传输。
  • 不同类型的端点有不同的用途,例如控制端点用于设备和主机之间的基本控制和配置,而同步和异步端点则用于数据传输等。
  • 每个 USB 接口可以包含多个端点,其中包括一个控制端点(Endpoint 0),用于设备和主机之间的基本通信。
  • 端点描述符通常跟随在接口描述符之后,为主机系统提供有关每个端点的配置信息。
  • 端点描述符是 USB 设备描述符的关键组成部分,提供了主机系统关于设备上每个端点的详细信息,有助于正确配置和管理数据传输。

4.3.5. 报告描述符
  1. 定义报告的结构: 接口描述符包含了关于接口的基本信息,如接口号、接口类别、子类别、协议等。
  2. 报告的用途: 接口描述符指明了该接口上包含的端点的数量。每个端点用于不同的数据传输目的,如控制传输、批量传输、中断传输或同步/异步传输等。
  3. 字段的含义:接口描述符中包含了该接口的索引,主机系统可以通过这个索引获取接口的详细信息。
  4. 数据的编码方式: 接口描述符中的一些字段提供了关于接口的特殊属性的信息,如是否支持 HID(Human Interface Device)等。
  5. 使用的协议: 在某些情况下,接口描述符可能包含关联其他接口的信息,用于表示多个接口之间的关系。

报告描述符总结

  • 报告描述符是在 HID 类别中定义的,典型的 HID 设备如键盘或鼠标通常会包含一个或多个报告描述符。
  • 主机系统通过读取报告描述符可以了解 HID 设备生成数据报告的结构,从而正确解析和处理来自 HID 设备的数据。
  • 报告描述符在 HID 设备中起到了定义设备数据报告结构的关键作用,它是 USB 设备描述符的一部分,用于描述 HID 设备生成的数据报告的格式和内容。

4.3.6. 特殊描述符
  1. String Descriptor(字符串描述符): USB 设备可以包含多个字符串描述符,用于提供设备的可读文本信息,如制造商名称、产品名称、序列号等。

  2. Interface Association Descriptor(接口关联描述符): 这是一种辅助描述符,用于关联多个接口。例如,一个设备可能同时提供音频输入和输出,这两个功能可能被关联在一起。

  3. Endpoint Companion Descriptor(端点伴随描述符): 在 USB 3.0 中引入,提供了关于端点的额外信息,如是否支持超速传输等。

  4. BOS (Binary Object Store) Descriptor(二进制对象存储描述符): 用于提供设备的固件升级和其他二进制对象的信息。

  5. Device Capability Descriptor(设备能力描述符): 提供了关于设备支持的一些特殊功能和能力的信息,如 USB PD(USB Power Delivery)的支持等。

特殊描述符总结

  • 一般HID,CDC设备会带有特殊描述符,补充描述
  • 这些描述符可能是标准描述符,也可能是设备特定的描述符。
  • 特殊描述符的存在使得设备能够提供额外的信息,或者支持一些规范中未明确定义的功能。
  • 需要查阅设备的技术文档或者 USB 设备的特定规范以了解特殊描述符的具体细节和用途,因为它们的内容和用途在不同类型的设备中可能有很大的差异。

4.3.7. 字符串描述符
  1. 语言标识符描述符(Language ID Descriptor): 这是一种特殊的字符串描述符,用于指示设备支持的语言。语言标识符描述符的索引为零,它的值是一个语言标识符列表,表示设备支持的语言。

  2. 字符串描述符: 每个字符串描述符包含了一个 UTF-16 编码的字符串,用于表示特定的信息,如制造商名称、产品名称、序列号等。字符串描述符的索引值是非零的,每个索引值对应一种特定的字符串。

字符串描述符总结

  • 字符串描述符的格式包括一个字节的长度信息,后面是一个或多个包含 UTF-16 编码的字符。
  • USB 规范规定字符串描述符的字符编码必须为 UTF-16LE(Little Endian)。
  • 例如,如果要获取设备的制造商名称,主机系统可以向设备发送请求,指定索引值为设备制造商名称的字符串描述符,设备会回复一个包含制造商名称的字符串描述符。
  • 字符串描述符提供了对设备信息的人类可读访问,有助于用户和操作系统正确识别和管理连接到系统的 USB 设备。
  • 字符串描述符是 USB 设备描述符中的一种类型,用于提供设备的人类可读的文本信息。

4.4 数据通信

USB协议里从机不会主动发起通信,因为主机很多事情做,总线却只有一个,所以当主机 “忙完”, 就会主动向从机发起通信,通信过程包含三种情况。

在这里插入图片描述

  1. 控制传输: 用于在主机和设备之间进行基本的命令和配置
  2. 批量传输: 用于需要高带宽但不要求低延迟的数据传输
  3. 中断传输: 用于传输具有周期性且对延迟敏感的小量数据
  4. 同步传输: 用于实时传输音频、视频等对数据完整性要求不高但对实时性要求较高的应用

主机一开始请求过程会发送令牌包(TOKEN),请求中声明有数据要传输则有数据过程(长度描述不为0),最后由从机发起状态过程,结束本次通信。
如果主机向从机获取数据,那么主机获取到数据后,状态过程由主机发起结束。

4.5 HID/CDC设备

  1. HID设备是人机交互设备,鼠标键盘这些为HID设备
  2. CDC设备是数据通信类,例如USB模拟串口这类

HID设备的数据在报告描述符内描述数据结构,然后就可以通过传输包来交互数据,报告描述符网上很多,若是不需要深入了解,可以直接用现成的。

5 . 应用层

const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
  {
    0x12,   /* bLength */
    USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */
    0x00,
    0x02,   /* bcdUSB = 2.00 */
    0x02,   /* bDeviceClass: CDC */
    0x00,   /* bDeviceSubClass */
    0x00,   /* bDeviceProtocol */
    0x40,   /* bMaxPacketSize0 */
    0x85,
    0x06,   /* idVendor = 0x0685 */
    0x40,
    0x57,   /* idProduct = 0x7540 */
    0x00,
    0x02,   /* bcdDevice = 2.00 */
    1,              /* Index of string descriptor describing manufacturer */
    2,              /* Index of string descriptor describing product */
    3,              /* Index of string descriptor describing the device's serial number */
    0x01    /* bNumConfigurations */
  };
const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
  {
    /*Configuration Descriptor*/
    0x09,   /* bLength: Configuration Descriptor size */
    USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
    VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,       /* wTotalLength:no of returned bytes */
    0x00,
    0x02,   /* bNumInterfaces: 2 interface */
    0x01,   /* bConfigurationValue: Configuration value */
    0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
    0xC0,   /* bmAttributes: self powered */
    0x32,   /* MaxPower 0 mA */
    /*Interface Descriptor*/
    0x09,   /* bLength: Interface Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
    /* Interface descriptor type */
    0x00,   /* bInterfaceNumber: Number of Interface */
    0x00,   /* bAlternateSetting: Alternate setting */
    0x01,   /* bNumEndpoints: One endpoints used */
    0x02,   /* bInterfaceClass: Communication Interface Class */
    0x02,   /* bInterfaceSubClass: Abstract Control Model */
    0x01,   /* bInterfaceProtocol: Common AT commands */
    0x00,   /* iInterface: */
    /*Header Functional Descriptor*/
    0x05,   /* bLength: Endpoint Descriptor size */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x00,   /* bDescriptorSubtype: Header Func Desc */
    0x10,   /* bcdCDC: spec release number */
    0x01,
    /*Call Management Functional Descriptor*/
    0x05,   /* bFunctionLength */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x01,   /* bDescriptorSubtype: Call Management Func Desc */
    0x00,   /* bmCapabilities: D0+D1 */
    0x01,   /* bDataInterface: 1 */
    /*ACM Functional Descriptor*/
    0x04,   /* bFunctionLength */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
    0x02,   /* bmCapabilities */
    /*Union Functional Descriptor*/
    0x05,   /* bFunctionLength */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x06,   /* bDescriptorSubtype: Union func desc */
    0x00,   /* bMasterInterface: Communication class interface */
    0x01,   /* bSlaveInterface0: Data Class Interface */
    /*Endpoint 2 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
    0x82,   /* bEndpointAddress: (IN2) */
    0x03,   /* bmAttributes: Interrupt */
    VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */
    0x00,
    0xFF,   /* bInterval: */
    /*Data class interface descriptor*/
    0x09,   /* bLength: Endpoint Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
    0x01,   /* bInterfaceNumber: Number of Interface */
    0x00,   /* bAlternateSetting: Alternate setting */
    0x02,   /* bNumEndpoints: Two endpoints used */
    0x0A,   /* bInterfaceClass: CDC */
    0x00,   /* bInterfaceSubClass: */
    0x00,   /* bInterfaceProtocol: */
    0x00,   /* iInterface: */
    /*Endpoint 3 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
    0x03,   /* bEndpointAddress: (OUT3) */
    0x02,   /* bmAttributes: Bulk */
    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
    0x00,
    0x00,   /* bInterval: ignore for Bulk transfer */
    /*Endpoint 1 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
    0x81,   /* bEndpointAddress: (IN1) */
    0x02,   /* bmAttributes: Bulk */
    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
    0x00,
    0x00    /* bInterval */
  };

这里通过一个USB虚拟串口的CDC设备以代码形式展示,上面两个数组分别是设备描述符 和 配置描述符,其中设备描述符可以看到描述了关于USB协议2.0,属于CDC设备,VID,PID信息,配置描述符描述了接口描述符的数据结构,描述了端点描述符的结构,几个端点描述符分别用了中断传输,批量传输方式通信。

对于自带了USB外设的芯片,内部USB模块集成了串行接口控制器(SIE)、定时器、分组缓冲器接口、端点相关寄存器、控制寄存器和中断寄存器等部分组成,所以从机只需要把市面上USB的c文件h文件移植,移植后修改描述符,就可以对端点进行通信了。

6 . 小结

USB协议细节较多,后续持续补充内容。
个人风格秉承深入浅出,简洁风格描述,谢谢观看。

技术交流QQ群 : 745662457
群内专注 - 问题答疑,技术研究

图片资源本人在网上下载,若有侵权行为,请告知,本人会立刻删除

文章来源:https://blog.csdn.net/Engineer_LU/article/details/135198109
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。