专栏文章目录传送门:返回专栏目录
Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】
目录
Linux 之USB子系统(一)
1. USB基础简介
1.1 USB的传输模式
1.2 USB 的设备描述符
1.3 USB 类的定义分类
2. USB 子系统框架
Linux 之USB子系统(一)
USB在嵌入式中使用还是非常广泛的一个接口,从本章开始将采用两个章节讲解USB子系统相关的内容,本章主要讲解一些关于USB的基础知识,USB子系统的相关架构等内容;
1. USB基础简介
USB(Universal Serial Bus(通用串行总线)) 支持设备的即插即用和热插拔功能,作为一种传输传输接口。在usb出现之前,采用的通信PC接口都非常的杂乱,扩展能力差,热插拔不支持,但是USB的出现解决了速度,扩展,易用性的特点,其主要作用:
-
多设备兼容性: USB允许多种设备(例如计算机、打印机、存储设备、摄像头等)通过同一种接口进行连接,实现了设备之间的通用性和互操作性。
-
快速数据传输: USB支持高速数据传输,使文件传输、设备同步等任务更加高效。
-
供电功能: USB接口可以为许多设备提供电力,消除了部分设备的需外部电源的需求,如充电设备和小型外设。
-
热插拔: USB支持热插拔功能,用户可以在不关机的情况下插拔设备,方便了设备的切换和连接。
-
统一连接标准: USB作为一个统一的连接标准,简化了设备之间的连接方式,减少了不同类型接口的混淆。
USB 的发展从1996年开始到今天已经过去20多年,版本已经发生了多次迭代,技术不断更新:
版本 | 描述 | 发布日期 |
---|---|---|
USB 1.0 | 最高传输速率为1.5Mbps,使用一对一的电缆连接设备。 | 1996年 |
USB 1.1 | 最高传输速率为12Mbps,支持双向传输,使用一对一的电缆连接设备。 | 1998年 |
USB 2.0 | 最高传输速率为480Mbps,支持高速数据传输,使用一对一或菊花链连接设备。 | 2000年 |
USB 3.0 | 最高传输速率为5Gbps,支持超高速数据传输,使用一对一、菊花链或集线器连接设备。 | 2008年 |
USB 3.1 | 最高传输速率为10Gbps,支持超高速数据传输,使用一对一、菊花链或集线器连接设备。 | 2013年 |
USB Type-C | 一种新型的USB接口类型,支持双面插入、更快的数据传输速度和更高的功率输出。 | 2014年 |
USB 3.2 | 最高传输速率为20Gbps,支持双通道传输,可向下兼容USB 3.1和USB 3.0。 | 2017年 |
USB 4.0 | 最高传输速率为40Gbps,支持单通道传输,可向下兼容USB 3.2和USB 2.0。 | 2019年 |
USB 体系一共分为两个角色:
USB 主模式(Host Mode):在主机模式下,设备被设置为USB总线的控制者和管理者。主机负责管理连接到它的各种USB从设备,控制数据传输以及进行配置和初始化。主机模式的设备称为“主机”或“主机控制器”,通常是计算机或其他拥有控制能力的设备。
USB 从模式(Device Mode):在主机模式下,设备被设置为USB总线的控制者和管理者。主机负责管理连接到它的各种USB从设备,控制数据传输以及进行配置和初始化。主机模式的设备称为“主机”或“主机控制器”,通常是计算机或其他拥有控制能力的设备。
这两种模式构成了USB通信的基础。在连接中,主机模式的设备通常为控制者,负责发起和管理通信,而从设备模式的设备则根据主机的请求响应和执行相应的操作。在最初开始USB只能作为固定的模式,没有办法切换,随着技术发展USB系统一些不足,OTG技术出现可以对USB主模式从模式进行切换。
1.1 USB的传输模式
USB的作用主要用于数据的传输以及控制,USB的传输方式一共分为四种:控制传输(Control Transfer)、中断传输(Interrupt Transfer)、批量传输(块传输)(Bulk Transfer)、实时传输(同步传输、等时传输)(Isochronous Transfer)
传输模式 | 特点 | 适用场景 |
---|---|---|
控制传输 (Control Transfer) | - 可靠、低速传输 - 用于配置和控制设备,发送命令和状态信息 | - 设备初始化和配置 - 设备插拔检测 - 设备控制命令发送 |
中断传输 (Interrupt Transfer) | - 低延迟、周期性传输 - 实时性较高,适用于快速响应设备 | - 鼠标、键盘、交互式设备 - 实时响应用户输入 |
批量传输 (Bulk Transfer) | - 高吞吐量传输 - 适用于大容量数据传输 - 不保证实时性 | - 大文件传输 - 外部硬盘驱动器 - 数据备份和恢复 |
实时传输 (Isochronous Transfer) | - 高实时性传输 - 固定传输速率 - 不保证数据完整性 | - 音频、视频流传输 - VoIP通信 - 实时传输要求较高的应用 |
对于这几种传输模式都有着不一样的特点,根据不同场景进行选择。
1.2 USB 的设备描述符
USB设备描述符(Device Descriptor)是USB通信中的重要元素之一,它包含了有关USB设备的基本信息,帮助主机(通常是计算机)识别和与设备进行通信。对于设备描述来说是一个包含多个字段的数据结构,通常由设备提供。
USB设备有一下几个主要组成,设备、配置、接口、端点。每个组成部分都有专有的描述符来描述信息。
USB Device (设备) | |--- Configuration 1 (配置1) | | | |--- Interface 1 (接口1) | | | | | |--- Endpoint 1 (端点1) | | | | | |--- Endpoint 2 (端点2) | | |--- Configuration 2 (配置2) | | | |--- Interface 2 (接口2) | | | |--- Endpoint 3 (端点3) | |--- ...
示意图显示了USB设备包含多个配置,每个配置包含一个或多个接口,每个接口可以包含多个端点。每个组件之间都有层次关系,主机通过解析描述符来了解设备的结构和功能,然后配置和控制通信。
这里提到的
设备描述符 :一个设备只能有一个设备描述符,里面有一个唯一的制造商ID(idVendor)和产品ID(idProduct),它们用于唯一标识设备。这些信息包含在设备描述符中。这个造商ID(idVendor)和产品ID(idProduct)是需要想USB协会申请,各个厂商都不一样。
vim ./include/uapi/linux/usb/ch9.h
struct usb_device_descriptor {
__u8 bLength; // 描述符的长度,通常为18字节
__u8 bDescriptorType; // 描述符类型,设备描述符的类型值为1
__le16 bcdUSB; // USB规范的版本号,例如0x0200表示USB 2.0
__u8 bDeviceClass; // 设备的类别,如存储设备、音频设备等
__u8 bDeviceSubClass; // 设备的子类别,进一步细化设备类别
__u8 bDeviceProtocol; // 设备的协议,定义设备与主机通信协议
__u8 bMaxPacketSize0; // 设备端点0(默认端点)的最大包大小
__le16 idVendor; // 设备的制造商ID,由USB-IF分配
__le16 idProduct; // 设备的产品ID,由设备制造商分配
__le16 bcdDevice; // 设备的固件版本号
__u8 iManufacturer; // 制造商名称的字符串描述符索引
__u8 iProduct; // 产品名称的字符串描述符索引
__u8 iSerialNumber; // 序列号的字符串描述符索引
__u8 bNumConfigurations; // 设备支持的配置数目
} __attribute__ ((packed));
配置描述符:一个设备描述符可以有多个配置描述符,配置描述符主要用于定义设备的不同功能或者工作模式,其中主要一些关键配置信息总功率消耗、接口数目等。
struct usb_config_descriptor {
__u8 bLength; // 描述符的长度,通常为9字节
__u8 bDescriptorType; // 描述符类型,配置描述符的类型值为2
__le16 wTotalLength; // 配置描述符及其相关描述符总长度,以小端序表示
__u8 bNumInterfaces; // 配置中包含的接口数目
__u8 bConfigurationValue; // 配置的值,用于唯一标识不同的配置
__u8 iConfiguration; // 配置字符串描述符的索引,通常指向描述配置的字符串
__u8 bmAttributes; // 配置的属性标志,包含了一些配置的特性信息
__u8 bMaxPower; // 配置所需的最大总电流消耗,以2毫安(mA)为单位
} __attribute__ ((packed));
接口描述符:一个配置描述符包含多个接口描述符,接口描述符包含了有关设备接口的信息,如接口类别、子类别、协议等。
端点描述符: 一个接口描述符包含多个端点描述符,端点描述符包含了有关设备端点(用于数据传输的通道)的信息,如端点地址、传输类型、最大包大小等。
struct usb_endpoint_descriptor {
__u8 bLength; // 描述符的长度,通常为7字节
__u8 bDescriptorType; // 描述符类型,端点描述符的类型值为5
__u8 bEndpointAddress; // 端点地址,指定端点的方向(IN或OUT)和端点号
__u8 bmAttributes; // 端点的属性,包括传输类型和同步类型
__le16 wMaxPacketSize; // 最大包大小,以字节为单位,表示端点支持的最大数据包大小
__u8 bInterval; // 端点的轮询间隔,通常用于中断传输
} __attribute__ ((packed));
字符串描述符:提供设备的可读字符串信息,例如制造商名称、产品名称、序列号等。这些字符串描述符通常用于设备的标识和用户友好的显示。当用户连接USB设备时,操作系统可以使用这些描述符来显示设备的相关信息,而不仅仅是设备的硬件ID。
struct usb_string_descriptor {
__u8 bLength; // 描述符的长度,以字节为单位
__u8 bDescriptorType; // 描述符类型,字符串描述符的类型值为3
__le16 wData[]; // 字符串数据,以UTF-16编码表示
} __attribute__ ((packed));
1.3 USB 类的定义分类
在USB通信中,类定义(Class Definitions)是一组规范和协议,用于定义USB设备的功能和行为。这些定义确定了USB设备如何与主机操作系统和应用程序进行通信。
通俗来讲就是这个USB设备到底是属于哪一种设备,比如这个是USB耳机设备,那么它就是属于音频类,比如USB鼠标,USB键盘,那么这些就属于HID类。那么这个类到底是在哪里去定义的,是怎么规定的。
这些USB类定义都是通过一个叫做USB Implementers Forum(USB-IF)制定的,这样去确保设备的互操作和兼容性。
USB 类别 | Base Class Descriptor Usage | 功能 | 典型设备示例 |
---|---|---|---|
Human Interface Device (HID) Class | 0x03 (Human Interface Device) | 键盘、鼠标、游戏控制器等人机界面设备 | 计算机键盘、鼠标、游戏手柄 |
Mass Storage Class | 0x08 (Mass Storage) | USB闪存驱动器、硬盘驱动器 | USB闪存驱动器、外部硬盘 |
Audio Class | 0x01 (Audio) | 音频输入和输出设备 | 耳机、麦克风、扬声器 |
Communication Device Class (CDC) | 0x02 (Communication Device) | 调制解调器、串口通信设备 | 调制解调器、串口适配器 |
Video Class | 0x0E (Video) | 摄像头、视频捕获设备 | USB摄像头、视频捕获设备 |
Still Image Class | 0x06 (Image) | 静态图像设备,如数码相机 | 数码相机、扫描仪 |
Printer Class | 0x07 (Printer) | 打印机设备 | 打印机、多功能打印机 |
Vendor-Specific Class | 0xFF (Vendor-Specific) | 制造商自定义的类别 | 制造商特定的USB设备 |
还有很多并没有展现出来,可以通过USB-IF官网查询。这里举一个具体的列子来说明这个是如何去定义一个USB类的。
// 一个简化的USB设备描述符
struct usb_device_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 bcdUSB;
__u8 bDeviceClass; // 这里设置设备的类别代码
// 其他字段...
} __attribute__ ((packed));
// USB设备描述符的实例
struct usb_device_descriptor my_device_descriptor = {
.bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200), // USB 2.0
.bDeviceClass = 0x03, // HID 设备类
// 其他字段的初始化...
};
代码中bDeviceClass
就是定义USB类,在设备描述符里面。
2. USB 子系统框架
在Linux USB子系统,包含设备,总线,驱动模型完成设备和驱动绑定。
从USB驱动模型框架如图看,主要对USB分为两种HOST和DEVICES;
HOST
-
USB Device Driver
: 这是主机操作系统中的驱动程序,负责与连接的USB设备进行通信。每种USB设备类型(如打印机、键盘、摄像头等)都需要相应的设备驱动程序来与主机通信。 -
USB Core
: USB核心是USB子系统的核心组件,它提供了USB设备的注册、管理和配置功能。它还处理USB设备的插拔事件,确保设备在连接和断开时得到适当的处理。 -
USB HCD
: USB HCD是与主机控制器硬件通信的驱动程序。它负责与主机控制器芯片(如USB控制器芯片)交互,管理USB总线上的数据传输和设备通信。监测外部设备插入,完成设备的枚举。
Device
Gadget Driver(Gadget驱动程序)
-
Gadget Driver是针对USB设备的驱动程序,它负责管理和控制设备的USB功能。这些驱动程序通常运行在设备上,与主机交互以提供特定的USB功能,例如存储、网络、音频等。Gadget Driver使用Gadget API与USB设备控制器驱动程序(Controller Driver)通信,以便配置USB设备并处理数据传输。
Gadget API(Gadget应用程序编程接口)
-
Gadget API是一组接口和函数,用于与Gadget Driver通信和控制USB设备功能。它提供了一种标准化的方式来配置和操作USB设备的功能。开发人员可以使用Gadget API编写应用程序或脚本,以控制和定制USB设备的行为。
USB Device Controller Driver(USB设备控制器驱动程序)
-
USB Device Controller Driver是USB设备控制器硬件的底层驱动程序,负责与USB设备的控制器硬件通信。它管理USB总线上的数据传输和设备控制。这个驱动程序通常运行在USB设备上,确保设备与主机之间的通信正常进行。