基础层次详解
通用串行总线(USB)主要用于连接主机和外部设备(协调主机和设备之间的通讯),USB 设备不能主动向主机发送数据。USB 总线采用拓扑(树形),主机侧和设备侧的 USB 控制器(Host 和 UDC),每个总线只要一个主机控制器。
主机侧的 USB 节点为根节点,所有子节点都连接在根节点集线器(Root hub)上,根节点有 USB 主机控制器(USB Host Controller)控制。
USB 只要设备包括:设备、配置、接口及端点四个层次,具体视图如下:
基础知识
- USB 采用树形拓扑结构,主机侧和设备侧的 USB 控制器(Host 和 UDC),每个总线只要一个主机控制器。
- 在主机侧层次结构中,要实现的 USB 驱动包括两种:USB 主机控制器驱动(控制插入其中的 USB 设备)和 USB 设备驱动(控制 USB 设备如何跟主机通讯)
- Linux 内核中的 USB 核心负责 USB 驱动管理和协议处理操作。主机控制器驱动和设备驱动之间的 USB 核心非常重要,向上为设备驱动提供 API 编程接口,向下为 USB 主机控制器驱动提供 API 编程接口。
USB 主机控制器接口如下:- OHCI:微软主导的低速
USB1.0(1.5Mbps)
和全速USB1.1(12Mbps)
; - EHCI:Intel 主导的低速
USB1.0(1.5Mbps)
和全速USB1.1(12Mbps)
; - UHCI:高速
USB2.0(480Mbps)
; - xHCI:
USB3.0(5.0Gbps)
。
- OHCI:微软主导的低速
- USB 的四种传输类型:
- 中断传输(USB 键盘)
- 实时传输(USB 摄像头)
- 批量传输(U 盘)
- 控制传输
- 一个 USB 端点只能在一个方向上承载数据,从主机到设备(输出端点)或者从设备到主机(输入端点),端点为单向管道;设备通常会有一个或多个配置;配置通常会有一个或多个接口;接口通常会有一个或多个设备;几口有 0 个或多个端口。
USB 驱动常用的数据结构
-
USB 设备驱动结构体类型:
struct usb_driver
,Linux 内核具体核心成员如下:
-
支持不同类型 USB 设备列表,Linux 内核具体核心成员如下:
-
通过
struct usb_endpoint_descriptor
结构体描述端点,源码如下:
-
通过
struct usb_host_endpoint
来表示主机侧的端点,具体源码如下:
-
Linux 内核用
struct usb_interface_descriptor
结构来来表示接口,具体源码如下:
描述主机侧的接口结构体类型,源码如下:
-
Linux 内核中的 USB 配置结构体类型为:
struct usb_config_descriptor
,源码如下:
主机侧的配置结构体类型为:usb_host_config
源码如下:
-
Linux 内核中,USB 的设备结构体类型为
struct usb_device_dscriptor
源码如下:
-
USB 是一种总线,而连接到总线上 USB 设备可以是块设备、字符设备、输入设备等。
usb_driver
结构体类型源码如下:
-
Linux 内核使用
struct usb_device
结构体类型标识一个 USB 设备。当 USB 控制器检测到 USB 硬件设备连接过来,则分配一个usb_device
结构体,接着注册到总线设备列表中,然后进行匹配对应的驱动就可以了。
-
USB 设备主机控制器驱动对应的结构体
usb_hcd
类型分析,具体如下:
通过struct usb_create_hcd
函数创建主控制器,使用注册/注销主机控制器对应 API 操作如下:
-
USB 请求 URB(SUB Request Block)分为两个部分:私有(SUB 核心层和主机控制器),公有(被 USB 设备支持程序所使用)。具体源码如下:
URB 结构体分配和初始化成功之后,就可以使用usb_submit_urb()
请求异步提交到 USB 核心层。返回 0 成功,否则失败。