Linux基础入门--驱动开发--USB

1.基本概念

USB设备由3个功能模块组成:USB总线接口、USB逻辑设备和功能单元:
a.USB总线接口——指的是USB设备中的串行接口引擎(SIE);
b.USB逻辑设备——被USB系统软件看作是一个端点的集合;
c.功能单元——被看作是一个接口的集合。

为了更好地描述USB设备的特征,USB提出了设备架构的概念。从这个角度来看,可以认为USB设备是由一些配置、接口和端点组成,即一个USB设备可以含有一个或多个配置,在每个配置中可含有一个或多个接口,在每个接口中可含有若干个端点。其中,配置和接口是对USB设备功能的抽象,实际的数据传输由端点来完成。在使用USB设备前,必须指明其采用的配置和接口。这个步骤一般是在设备接入主机时设备进行枚举时完成的。这些单元之间的关系如下:
USB架构图
USB设备使用各种描述符来说明其设备架构,包括设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符,他们通常被保存在USB设备的固件程序中。

2.组成结构

2.1 设备描述符

设备代表一个USB设备,它由一个或多个配置组成。设备描述符用于说明设备的总体信息,并指明其所含的配置的个数。一个USB设备只能有一个设备描述符。

2.2 配置描述符

一个USB设备可以包含一个或多个配置,如USB设备的低功耗模式和高功耗模式可分别对应一个配置。在使用USB设备前,必须为其选择一个合适的配置。配置描述符用于说明USB设备中各个配置的特性,如配置所含接口的个数等。USB设备的每一个配置都必须有一个配置描述符。

2.3 接口描述符

一个配置可以包含一个或多个接口,例如对一个光驱来说,当用于文件传输时,使用其大容量存储接口;而当用于播放CD时,使用其音频接口。接口是端点的集合,可以包含一个或多个可替换设置,用户能够在USB处于配置状态时改变当前接口所含的个数和特性。接口描述符用于说明设备中各个接口的特性,如接口所属的设备类及其子类等。USB设备的每个接口都必须有一个接口描述符。

2.4 端点描述符

端点是USB设备中的实际物理单元,USB数据传输就是在主机和USB设备各个端点之间进行的。端点一般由USB接口芯片提供,USB设备中的每一个端点都有唯一的端点号,每个端点所支持的数据传输方向一般而言也是确定的:或是输入(IN),或是输出(OUT)。也有些芯片提供的端点的数据方向是可以配置的,包含有两个用于数据收发的端点:端点1和端点2。其中端点1只能用于数据发送,即支持输入(IN)操作;端点2既能用于数据发送,也可用于数据接收,即支持输入(IN)和输出(OUT)操作。
利用设备地址、端点号和传输方向就可以指定一个端点,并与它进行通信。端点的传输特性还决定了其与主机通信时所采用的传输类型,例如控制端点只能使用控制传输。根据端点的不同用途,可将端点分为两类:0号端点和非0号端点。
0号端点比较特殊,它有数据输入IN和数据输出OUT两个物理单元,且只能支持控制传输。所有的USB设备都必须含有一个0号端点,用作默认控制管道。USB系统软件就是使用该管道与USB逻辑设备进行配置通信的。0号端点在USB设备插上之后就可以使用,而非0号端点必须要在配置之后才可以使用。
根据具体应用的需要,USB设备还可以含有多个除0号端点以外的其他端点。对于低速设备,其附加的端点数最多为2个;对于全速/高速设备,其附加的端点数最多为15个。

2.5 字符串描述符

在USB设备中通常还含有字符串描述符,以说明一些专用信息,如制造商的名称、设备的序列号等。它的内容以UNICODE的形式给出,且可以被客户软件所读取。对USB设备来说,字符串描述符是可选的。

3.管道

在USB系统结构中,可以认为数据传输时在USB主机软件与USB设备的各个端点之间直接进行的,它们之间的连接称为管道。管道是在USB设备的配置过程中建立的。管道是对USB主机与USB设备间通信流的抽象,表示USB主机的数据缓冲区与USB设备的端点之间存在着逻辑数据传输,而实际的数据传输是由USB总线接口层来完成的。
管道与USB设备中的端点一一对应。一个USB设备含有多少个端点,其与USB主机进行通信时就可以使用多少条管道,且端点的类型决定了管道中数据的传输类型,例如中断端点对应中断管道,且该管道只能进行中断传输。不论存在着多少条管道,在各个管道中进行的数据传输都是相互独立的。

4.端点分类

USB通信的最基本形式是通过端点。一个USB端点只能向一个方向传输数据,从主机到设备(称为输出端点)或者从设备到主机(称为输入端点)。端点可被看作一个单向的管道。USB 端点有 4 种不同类型,分别具有不同的数据传送方式:

4.1 控制CONTROL

控制端点被用来控制对USB设备的不同部分访问。 通常用作配置设备、获取设备信息、发送命令到设备或获取设备状态报告。这些端点通常较小。每个 USB 设备都有一个控制端点称为"端点 0",被 USB 核心用来在插入时配置设备。USB协议保证总有足够的带宽留给控制端点传送数据到设备。

4.2 中断INTERRUPT

每当 USB 主机向设备请求数据时,中断端点以固定的速率传送小量的数据。此为USB 键盘和鼠标的主要的数据传送方法。它还用以传送数据到USB设备来控制设备。通常不用来传送大量数据。USB协议保证总有足够的带宽留给中断端点传送数据到设备。

4.3 批量BULK

批量端点用以传送大量数据。这些端点通常比中断端点大得多。它们普遍用于不能有任何数据丢失的情况。USB 协议不保证传输在特定时间范围内完成。如果总线上没有足够的空间来发送整个BULK包,它被分为多个包进行传输。这些端点普遍用于打印机、USB Mass Storage和USB网络设备上。

4.4 等时ISOCHRONOUS

等时端点也批量传送大量数据,但是这个数据不被保证能送达。这些端点用在可以处理数据丢失的设备中,并且更多依赖于保持持续的数据流,如音频和视频设备等等。

4.5 区别

控制和批量端点用于异步数据传送,而中断和等时端点是周期性的。这意味着这些端点被设置来在固定的时间连续传送数据,USB 核心为它们保留了相应的带宽。

5.总线

USB 主机控制器有 3 种规格:OHCI (Open Host Controller Interface),UHCI (Universal Host Controller Interface) 和 EHCI (Enhanced Host Controller Interface)。OHCI 驱动程序用来为非 PC 系统上以及带有 SiS 和 ALi 芯片组的 PC 主板上的 USB 芯片提供支持。 UHCI 驱动程序多用来为大多数其他 PC 主板(包括 Intel 和 Via)上的 USB 芯片提供支持。EHCI 由 USB 2.0 规范所提出,它兼容于 OHCI 和 UHCI。UHCI 的硬件线路比 OHCI 简单,所以成本较低,但需要较复杂的驱动程序,CPU 负荷稍重。

6.相关文件

文件 含义
/sys/kernel/debug/usb/devices 设备信息
/sys/bus/usb 树形结构
lsusb usb相关的设备信息
mount -t usbfs none /proc/bus/usb 挂载
/proc/bus/usb/devices 查看USB设备信息

6.1 设备信息

通过命令cat /sys/kernel/debug/usb/devices获取设备信息
设备信息至于信息的详细解析可以参照 Linux源代码中Documentation/usb/proc_usb_info.txt 文件。现摘录其中对该格式的详细解释:

T = 拓扑结构
B = 带宽(仅适用于USB主机控制器,它被虚拟化为根集线器)
D = 设备描述符信息
P = 产品ID信息
S = 字符串描述符
C = 配置描述符信息
I = 接口描述符信息
E = 端点描述符信息

说明:
  d = 十进制数
  x = 十六进制数
  s = 字符串

拓扑结构:
T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd
|       |       |      |       |      |       |       |         |__MaxChildren
|       |       |      |       |      |       |       |__Device Speed in Mbps
|       |       |      |       |      |       |__DeviceNumber
|       |       |      |       |      |__Count of devices at this level
|       |       |      |       |__Connector/Port on Parent for this device
|       |       |      |__Parent DeviceNumber
|       |       |__Level in topology for this bus
|       |__Bus number
|__Topology info tag

    Speed可能是:
        1.5     Mbit/s for low speed USB
        12      Mbit/s for full speed USB
        480     Mbit/s for high speed USB (added for USB 2.0);
                also used for Wireless USB, which has no fixed speed
        5000    Mbit/s for SuperSpeed USB (added for USB 3.0)
    Port号总是减去1显示。例如,插入Port 4的设备将显示“Port=03”。

带宽信息:
B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
|         |                      |         |__Number of isochronous requests
|         |                      |__Number of interrupt requests
|         |__Total Bandwidth allocated to this bus
|__Bandwidth info tag

    带宽分配是一帧(毫秒)占用多少的近似值。它只反映周期性传输,这是唯一保留带宽的传输。控制和批量传输使用所有其他带宽,
    包括不用于传输的保留带宽(例如用于短数据包)。
    百分比是指有多少“预留”带宽是由这些传输计划的。对于一个低或全速总线(松散地,“USB 1.1”),90%的总线带宽被保留。
    对于高速总线(松散地说,“usb2.0”)80%是保留的。

设备描述符信息:
D:  Ver=x.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd
|       |        |             |       |       |        |__NumberConfigurations
|       |        |             |       |       |__MaxPacketSize of Default Endpoint
|       |        |             |       |__DeviceProtocol
|       |        |             |__DeviceSubClass
|       |        |__DeviceClass
|       |__Device USB version
|__Device info tag #1

产品ID信息:
P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx
|          |           |        |__Product revision number
|          |           |__Product ID code
|          |__Vendor ID code
|__Device info tag #2

字符串描述符:
S:  Manufacturer=ssss
|                |__Manufacturer of this device as read from the device.
|__String info tag

S:  Product=ssss
|           |__Product description of this device as read from the device.
|__String info tag

S:  SerialNumber=ssss
|                |__Serial Number of this device as read from the device.
|__String info tag

配置描述符信息:
C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
| |      |       |      |       |__MaxPower in mA
| |      |       |      |__Attributes
| |      |       |__ConfiguratioNumber
| |      |__NumberOfInterfaces
| |__ "*" indicates the active configuration (others are " ")
|__Config info tag

    USB设备可能有多种配置,每一种都有不同的行为。例如,总线供电的配置可能比自供电的配置能力差得多。
    一次只能有一个设备配置处于活动状态;大多数设备只有一种配置。
    每个配置由一个或多个接口。每个接口服务一个不同的“功能”,这通常是绑定到一个不同的USB设备驱动程序。
    一个常见的例子是带有用于回放的音频接口的USB扬声器,以及用于软件音量控制的HID接口。

接口描述符信息:
I:* If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
| |     |      |       |      |             |       |         |__Driver name
| |     |      |       |      |             |       |          or "(none)"
| |     |      |       |      |             |       |__InterfaceProtocol
| |     |      |       |      |             |__InterfaceSubClass
| |     |      |       |      |__InterfaceClass
| |     |      |       |__NumberOfEndpoints
| |     |      |__AlternateSettingNumber
| |     |__InterfaceNumber
| |__ "*" indicates the active altsetting (others are " ")
|__Interface info tag

    给定接口可能有一个或多个“备用”设置。例如,默认设置可能只使用少量的周期带宽。
    为了使用总线带宽的重要部分,驱动程序必须选择一个非默认的alt配置。
    一个接口一次只能有一个设置是活动的,而且一次只能有一个驱动程序绑定到一个接口。大多数设备每个接口只有一个备用设置。

端点描述符信息:
E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddss
|      |         |             |        |__Interval (max) between transfers
|      |         |             |__EndpointMaxPacketSize
|      |         |__Attributes(EndpointType)
|      |__EndpointAddress(I=In,O=Out)
|__Endpoint info tag

    对于所有周期端点(中断或同步),时间间隔都是非零的。对于高速端点,传输间隔可以用微秒而不是毫秒来测量。
    对于高速周期端点,“MaxPacketSize”反映每微帧的数据传输大小。
    对于“高带宽”端点,每个端点可以反射2或3个数据包(每125 usec最多可反射3KBytes)。
    对于Linux-USB堆栈,周期性带宽保留使用urb提供的传输间隔和大小,可以小于端点描述符中的传输间隔和大小。

7.框架

USB驱动可以从两个角度去观察,一个是主机侧,一个是设备侧。Linux USB驱动的总体框架如下图所示:    
框架
从主机侧看usb驱动可分为四层:usb主机控制器硬件底层、usb主机控制器驱动、usb核心和usb设备驱动。在主机侧要实现的驱动主要分为两类:usb主机控制器驱动和usb设备驱动。主机控制器驱动负责控制插入其中的usb设备,usb设备驱动主要负责usb设备和主机的通信。usb核心向上为设备驱动提供编程接口,向下为usb控制器驱动提供编程接口,维护整个usb设备信息,完成设备热插拔控制,总线数据传输控制。可以看到这种设备驱动、核心层、主机控制器驱动这种三层结构的驱动框架,Linux内核中将主机控制器的驱动和外设端的驱动分离,通过一个核心层将某种总线的协议进行抽象,外设端的驱动调用核心层API间接过渡到主机驱动传输函数的调用。

温馨提示:
以上文章描述如有不清晰之处,欢迎在评论区评论,如有时间,会第一时间回复,谢谢!

猜你喜欢

转载自blog.csdn.net/qq_20677327/article/details/107445050