[嵌入式专栏](系列一 、协议 - USB详解)
文章目录
【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485
1 . 前言
- 1 . USB协议较为广泛,这里按以往风格描述物理层,协议层,应用层
- 2 . 基于本人习惯简洁风格,此篇文章尽量把USB协议描述清晰
- 3 . 接下来从物理层,协议层,应用层,从下往上深入浅出剖析
2 . USB外形类分
3 . 物理层
-
USB2.0的结构简洁,VCC, D+, D-, GND通信.
-
主机的两个下拉电阻阻值为15K,从机的D+ D-上拉电阻为1.5K
-
通讯依靠D+,D-作为差分
-
对于低速,全速设备USB通信四种状态,逻辑0与逻辑1和JK状态不加以区分
J K SE0 SE1 D + 0 1 0 1 D - 1 0 0 1 -
对于高速设备,做了8b/10b编码,把逻辑0与逻辑1和JK状态区分开来
{ K, D[7], D[6], D[5], D[4], D[3], D[2], D[1], J, D[0] }
-
下图为USB2.0的结构 :
4 . 协议层
- USB协议层内容比较多,这里以 设备接入主机的整个过程 来描述
4.1 设备接入/拔出
- 当设备接入时,通过检测从机的上拉电阻接在了D- 或 D+来判断设备所属模式
模式 上拉电阻接入 (1.5K) 速度 低速 D- 1.5M 全速 D+ 12M 高速 D+ 480M - 当设备拔出时,通过检测从机的D- 和 D+ 的上拉来判断设备拔出
模式 上拉电阻接入 (1.5K) 拔出 无
4.2 首次通信
- 当主机识别到有设备接入后,主机会在总线上对 { “地址0” “端点0” } 发送信息,从机接入时,从 { “地址0” “端点0” } 处接收信息,这里的信息包含了主机分配给从机的 新地址,从机回复主机确认后,从机按 新地址 自居,从机找到家了,从此可以和主机愉快的生活了,主机就可以到 新地址 访问了,然后主机会向 新地址 请求完整的 设备描述符,配置描述符 来获取接口,如果接口存在多个,会继续遍历,当主机知晓设备的完整信息后,就完成了 枚举 的过程。
4.3 USB描述符
描述符前言 :
- 在写描述符之前,这里将USB意义简述一下。
- USB协议总是主机发起通信,如果从机的内容比较多,那么主机该如何与从机的某个局部信息进行交互呢?
- 无论从机有多少信息,我们把它分而治之不就可以了吗,就像一省有N市,一市有N镇,一镇有N村,假如你想了解某个人的信息,那么通过省市镇村就可以找到对方进行交互,USB协议里也是一样,逐层解析。
- 所以诞生了设备描述符,配置描述符,接口描述符,端点描述符,报告描述符,特殊描述符,字符串描述符,各描述符都有自己的数据结构,以下详述了各描述符意义。
4.3.1 设备描述符
- 设备的基本信息: 设备描述符包含了有关 USB 设备的基本信息,如设备类别、设备子类别、设备协议、最大包大小等。这些信息有助于主机系统正确识别和配置设备
- 供应商和产品标识: 设备描述符包含供应商标识(Vendor ID)和产品标识(Product ID),这两个标识唯一地标识了设备的制造商和产品。这对于主机系统正确识别和匹配设备驱动程序非常重要
- 设备版本信息: 设备描述符包含了设备的版本号,有助于主机系统确定设备的硬件或固件版本。
- 设备支持的 USB 规范版本: 设备描述符指明了设备支持的 USB 规范版本,这有助于主机系统适配与设备进行通信。
- 配置描述符的索引: 设备描述符中包含配置描述符的索引,主机系统可以通过这个索引获取设备的配置信息。
设备描述符总结 :
- 设备描述符是设备插入 USB 总线时被主机系统主动请求的第一个描述符。
- 主机系统通过读取设备描述符可以获取设备的基本特性,从而为设备进行正确的配置和管理。
- 设备描述符是 USB 设备描述符的核心组成部分,提供了主机系统获取关于设备基本信息的入口,有助于主机正确识别、配置和与设备进行通信。
4.3.2. 配置描述符
- 配置的基本信息: 配置描述符包含了有关设备配置的基本信息,如配置值、总长度、最大功率需求等。这些信息有助于主机系统了解设备的配置。
- 接口数量: 配置描述符指明了该配置下包含的接口的数量,主机系统可以通过这个信息了解设备提供了多少个功能或服务。
- 供电特性: 配置描述符包含了设备的供电特性,例如设备是否通过总线供电、是否支持远程唤醒等。
- 接口描述符的索引: 配置描述符中包含了接口描述符的索引,主机系统可以通过这个索引获取配置下每个接口的详细信息。
- 分配地址的标志: 配置描述符中的"bAttributes"字段指明了该配置是否是用于分配设备地址的配置,这对于 USB 设备的初始化阶段很重要。
配置描述符总结 :
- 配置描述符提供了主机系统有关设备配置的基本信息。
- 一个 USB 设备可以有一个或多个配置,每个配置可以包含一个或多个接口,每个接口可以包含一个或多个端点。
- 主机系统通过读取配置描述符,能够了解设备的整体结构和提供的功能,从而为设备进行正确的配置和管理。
- 配置描述符是 USB 设备描述符的关键组成部分,有助于主机系统正确识别、配置和与设备进行通信。
4.3.3. 接口描述符
- 接口的基本信息: 接口描述符包含了关于接口的基本信息,如接口号、接口类别、子类别、协议等。
- 端点数量: 接口描述符指明了该接口上包含的端点的数量。每个端点用于不同的数据传输目的,如控制传输、批量传输、中断传输或同步/异步传输等。
- 接口描述符的索引:接口描述符中包含了该接口的索引,主机系统可以通过这个索引获取接口的详细信息。
- 接口的特殊属性: 接口描述符中的一些字段提供了关于接口的特殊属性的信息,如是否支持 HID(Human Interface Device)等。
- 接口关联描述符: 在某些情况下,接口描述符可能包含关联其他接口的信息,用于表示多个接口之间的关系。
接口描述符总结 :
- 接口描述符对于主机系统正确识别和配置设备的每个接口非常重要。
- 主机系统通过读取接口描述符可以了解设备提供了多少个接口,每个接口的功能是什么,以及每个接口上有多少个端点。
- 接口描述符是 USB 设备描述符的一部分,用于提供关于每个接口的基本信息,帮助主机系统正确识别、配置和与设备进行通信。
4.3.4. 端点描述符
- 端点地址(Endpoint Address): 描述端点的地址,包括方向(输入或输出)和端点号。
- 端点类型(Attributes): 描述端点的类型,如控制、同步、异步等。
- 最大包大小(Max Packet Size):表示每个 USB 事务中传输的最大数据包大小。
- 传输间隔(Interval): 对于同步和中断端点,表示两次传输之间的时间间隔。
端点描述符总结 :
- 端点描述符提供了主机系统关于设备上每个端点的详细信息,主机系统根据这些信息来正确配置和管理数据传输。
- 不同类型的端点有不同的用途,例如控制端点用于设备和主机之间的基本控制和配置,而同步和异步端点则用于数据传输等。
- 每个 USB 接口可以包含多个端点,其中包括一个控制端点(Endpoint 0),用于设备和主机之间的基本通信。
- 端点描述符通常跟随在接口描述符之后,为主机系统提供有关每个端点的配置信息。
- 端点描述符是 USB 设备描述符的关键组成部分,提供了主机系统关于设备上每个端点的详细信息,有助于正确配置和管理数据传输。
4.3.5. 报告描述符
- 定义报告的结构: 接口描述符包含了关于接口的基本信息,如接口号、接口类别、子类别、协议等。
- 报告的用途: 接口描述符指明了该接口上包含的端点的数量。每个端点用于不同的数据传输目的,如控制传输、批量传输、中断传输或同步/异步传输等。
- 字段的含义:接口描述符中包含了该接口的索引,主机系统可以通过这个索引获取接口的详细信息。
- 数据的编码方式: 接口描述符中的一些字段提供了关于接口的特殊属性的信息,如是否支持 HID(Human Interface Device)等。
- 使用的协议: 在某些情况下,接口描述符可能包含关联其他接口的信息,用于表示多个接口之间的关系。
报告描述符总结 :
- 报告描述符是在 HID 类别中定义的,典型的 HID 设备如键盘或鼠标通常会包含一个或多个报告描述符。
- 主机系统通过读取报告描述符可以了解 HID 设备生成数据报告的结构,从而正确解析和处理来自 HID 设备的数据。
- 报告描述符在 HID 设备中起到了定义设备数据报告结构的关键作用,它是 USB 设备描述符的一部分,用于描述 HID 设备生成的数据报告的格式和内容。
4.3.6. 特殊描述符
-
String Descriptor(字符串描述符): USB 设备可以包含多个字符串描述符,用于提供设备的可读文本信息,如制造商名称、产品名称、序列号等。
-
Interface Association Descriptor(接口关联描述符): 这是一种辅助描述符,用于关联多个接口。例如,一个设备可能同时提供音频输入和输出,这两个功能可能被关联在一起。
-
Endpoint Companion Descriptor(端点伴随描述符): 在 USB 3.0 中引入,提供了关于端点的额外信息,如是否支持超速传输等。
-
BOS (Binary Object Store) Descriptor(二进制对象存储描述符): 用于提供设备的固件升级和其他二进制对象的信息。
-
Device Capability Descriptor(设备能力描述符): 提供了关于设备支持的一些特殊功能和能力的信息,如 USB PD(USB Power Delivery)的支持等。
特殊描述符总结 :
- 一般HID,CDC设备会带有特殊描述符,补充描述
- 这些描述符可能是标准描述符,也可能是设备特定的描述符。
- 特殊描述符的存在使得设备能够提供额外的信息,或者支持一些规范中未明确定义的功能。
- 需要查阅设备的技术文档或者 USB 设备的特定规范以了解特殊描述符的具体细节和用途,因为它们的内容和用途在不同类型的设备中可能有很大的差异。
4.3.7. 字符串描述符
-
语言标识符描述符(Language ID Descriptor): 这是一种特殊的字符串描述符,用于指示设备支持的语言。语言标识符描述符的索引为零,它的值是一个语言标识符列表,表示设备支持的语言。
-
字符串描述符: 每个字符串描述符包含了一个 UTF-16 编码的字符串,用于表示特定的信息,如制造商名称、产品名称、序列号等。字符串描述符的索引值是非零的,每个索引值对应一种特定的字符串。
字符串描述符总结 :
- 字符串描述符的格式包括一个字节的长度信息,后面是一个或多个包含 UTF-16 编码的字符。
- USB 规范规定字符串描述符的字符编码必须为 UTF-16LE(Little Endian)。
- 例如,如果要获取设备的制造商名称,主机系统可以向设备发送请求,指定索引值为设备制造商名称的字符串描述符,设备会回复一个包含制造商名称的字符串描述符。
- 字符串描述符提供了对设备信息的人类可读访问,有助于用户和操作系统正确识别和管理连接到系统的 USB 设备。
- 字符串描述符是 USB 设备描述符中的一种类型,用于提供设备的人类可读的文本信息。
4.4 数据通信
USB协议里从机不会主动发起通信,因为主机很多事情做,总线却只有一个,所以当主机 “忙完”, 就会主动向从机发起通信,通信过程包含三种情况。
- 控制传输: 用于在主机和设备之间进行基本的命令和配置
- 批量传输: 用于需要高带宽但不要求低延迟的数据传输
- 中断传输: 用于传输具有周期性且对延迟敏感的小量数据
- 同步传输: 用于实时传输音频、视频等对数据完整性要求不高但对实时性要求较高的应用
主机一开始请求过程会发送令牌包(TOKEN),请求中声明有数据要传输则有数据过程(长度描述不为0),最后由从机发起状态过程,结束本次通信。
如果主机向从机获取数据,那么主机获取到数据后,状态过程由主机发起结束。
4.5 HID/CDC设备
- HID设备是人机交互设备,鼠标键盘这些为HID设备
- 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
群内专注 - 问题答疑,技术研究
图片资源本人在网上下载,若有侵权行为,请告知,本人会立刻删除
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!