USB驱动之基础的概念和数据结构

liunx usb 驱动层次
linux系统中 可以从两个角度看usb 分别是是主机侧和设备侧视角
主机侧大致如下
……………………………………..
usb设备驱动
mass storage/CDC/HID
……………………………………..
USB核心
……………………………………..
USB主机控制器驱动OHCI/EHCI/UHCI
……………………………………..
USB主机控制器
……………………………………..
由此看见 最底层的是usb主机控制器硬件 在其上运行的的usb主机控制器驱动,在主机控制器上的usb核心层,再上层为usb设备驱动层
所以要实现的驱动有usb主机控制器驱动和usb设备驱动 前者控制插入启动的usb设备,后者控制usb设备如何与主机通信,linux内核中的usb核心负责usb驱动管理和协议处理的主要工作。主机控制器驱动和设备驱动之间的usb核心非常重要,其功能包括:通过定义一些数据结构,宏,功能函数,向上为设备驱动提供编程接口,向下为usb主机控制器提供编程家口,维护整个系统的usb设备信息,完成热拔插控制,总线数据传输控制等

设备侧大致如下
……………………………………..
Gadget Function驱动
mass storage
……………………………………..
Gadget Function API
……………………………………..
udc驱动
……………………………………..
USB设备控制器
……………………………………..
Linux 内核中 USB 设备侧驱动程序分为 3 个层次:UDC
驱动程序、Gadget FunctionAPI 和 Gadget Function驱动程序。UDC 驱动程序直接访问硬件,控制 USB设备和主机间的底层通信,向上层提供与硬件相关操作的回调函数。当前 Gadget Function API是 UDC 驱动程序回调函数的简单包装。 Gadget Function驱动程序具体控制 USB 设备功能的实现,使设备表现出“网络连接” 、 “打印机”或“USB Mass Storage”等特性,它使用Gadget FunctionAPI 控制 UDC 实现上述功能。Gadget FunctionAPI 把下层的 UDC 驱动程序和上层的Gadget Function驱动程序隔离开,使得在 Linux 系统中编写 USB 设备侧驱动程序时能够把功能的实现和底层通信分离。

设备、配置、接口、端点
在 USB 设备的逻辑组织中,包含设备、配置、接口和端点 4 个层次。每个 USB 设备都提供了不同级别的配置信息,可以包含一个或多个配置,不同的配置使设备表现出不同的功能组合(在探测/连接期间需从其中选定一个) ,配置由多个接口组成。在 USB 协议中,接口由多个端点组成,代表一个基本的功能,是 USB 设备驱动程序控制的对象。一个功能复杂的 USB 设备可以具有多个接口。每个配置中可以多个接口,而设备接口是端点的汇集(collection) 。例如 USB 扬声器可以包含一个音频接口以及对旋钮和按钮的接口。一个配置中的所有接口可以同时有效,并可被不同的驱动程序连接。每个接口可以有备用接口,以提供不同质量的服务参数。端点是 USB 通信的最基本形式,每一个 USB 设备接口在主机看来就是一个端点的集合。主机只能通过端点与设备进行通信,以使用设备的功能。在 USB 系统中每一个端点都有惟一的地址,这是由设备地址和端点号给出的。每个端点都有一定的属性,其中包括传输方式、总线访问频率、带宽、端点号和数据包的最大容量等。一个USB 端点只能在一个方向承载数据,或者从主机到设备(称为输出端点) ,或者从设备到主机(称为输入端点) ,因此端点可看作一个单向的管道。端点 0 通常为控制端点,用于设备初始化参数等。只要设备连接到 USB 上并且上电端点 0 就可以被访问。端点 1、2 等一般用作数据端点,存放主机与设备间往来的数据。

主要的数据结构
设备描述符:关于设备的通用信息,如供应商 ID、产品 ID 和修订 ID,支持
的设备类、子类和适用的协议以及默认端点的最大包大小等。在 Linux 内核
中,USB 设备用 usb_device 结构体来描述,USB 设备描述符定义为
usb_device_descriptor 结构体

struct usb_device_descriptor
2 {
3 _ _u8 bLength; //描述符长度
4 _ _u8 bDescriptorType; //描述符类型编号
5
6 _ _le16 bcdUSB; //USB 版本号
7 _ _u8 bDeviceClass; //USB 分配的设备类 code
8 _ _u8 bDeviceSubClass;// USB 分配的子类 code
9 _ _u8 bDeviceProtocol; //USB 分配的协议 code
10 _ _u8 bMaxPacketSize0; //endpoint0 最大包大小
11 _ _le16 idVendor; //厂商编号
12 _ _le16 idProduct; //产品编号
13 _ _le16 bcdDevice; //设备出厂编号
14 _ _u8 iManufacturer; //描述厂商字符串的索引
15 _ _u8 iProduct; //描述产品字符串的索引
16 _ _u8 iSerialNumber; //描述设备序列号字符串的索引
17 _ _u8 bNumConfigurations; //可能的配置数量
18 } _ _attribute_ _ ((packed));

配置描述符:此配置中的接口数、支持的挂起和恢复能力以及功率要求。USB
配置在内核中使用 usb_host_config 结构体描述,USB 配置描述符定义为结构体
usb_config_descriptor

1 struct usb_config_descriptor
2 {
3 _ _u8 bLength; //描述符长度
4 _ _u8 bDescriptorType; //描述符类型编号
5
6 _ _le16 wTotalLength; //配置所返回的所有数据的大小
7 _ _u8 bNumInterfaces; // 配置所支持的接口数
8 _ _u8 bConfigurationValue; //Set_Configuration 命令需要的参数值
9 _ _u8 iConfiguration; //描述该配置的字符串的索引值
10 _ _u8 bmAttributes; //供电模式的选择
11 _ _u8 bMaxPower; //设备从总线提取的最大电流
12 } _ _attribute_ _ ((packed));

接口描述符: 接口类、子类和适用的协议, 接口备用配置的数目和端点数目。 USB
接口在内核中使用 usb_interface 结构体描述,USB 接口描述符定义为结构体
usb_interface_descriptor

1 struct usb_interface_descriptor
2 {
3 _ _u8 bLength; //描述符长度
4 _ _u8 bDescriptorType; //描述符类型
5
6 _ _u8 bInterfaceNumber; // 接口的编号
7 _ _u8 bAlternateSetting; //备用的接口描述符编号
8 _ _u8 bNumEndpoints; //该接口使用的端点数,不包括端点 0
9 _ _u8 bInterfaceClass; //接口类型
10 _ _u8 bInterfaceSubClass; //接口子类型
11 _ _u8 bInterfaceProtocol; //接口所遵循的协议
12 _ _u8 iInterface; //描述该接口的字符串索引值
13 } _ _attribute_ _ ((packed));

端点描述符:端点地址、方向和类型,支持的最大包大小,如果是中断
类型的端点则还包括轮询频率。在 Linux 内核中, USB 端点使用
usb_host_endpoint 结 构 体 来 描 述 , USB 端 点 描 述 符 定 义 为
usb_endpoint_descriptor 结构体

1 struct usb_endpoint_descriptor
2 {
3 _ _u8 bLength; //描述符长度
4 _ _u8 bDescriptorType; //描述符类型
5 _ _u8 bEndpointAddress; //端点地址:0~3 位是端点号,第 7 位是方向
(0-OUT,1-IN)
6 _ _u8 bmAttributes; //端点属性:bit[0:1] 的值为00 表示控制,为01 表示同步,为02
表示批量,为03表示中断
7 _ _le16 wMaxPacketSize; //// 本端点接收或发送的最大信息包的大小
8 _ _u8 bInterval; //轮询数据传送端点的时间间隔
9 //对于批量传送的端点以及控制传送的端点,此域忽略
10 //对于同步传送的端点,此域必须为 1
11 //对于中断传送的端点,此域值的范围为 1~255
12 _ _u8 bRefresh;
13 _ _u8 bSynchAddress;
14 } _ _attribute_ _ ((packed));

字符串描述符:在其他描述符中会为某些字段提供字符串索引,它们可
被用来检索描述性字符串,可以以多种语言形式提供。字符串描述符是
可 选 的 , 有 的 设 备 有 , 有 的 设 备 没 有 , 字 符 串 描 述 符 对 应 于
usb_string_descriptor 结构体

1 struct usb_string_descriptor
2 {
3 _ _u8 bLength; //描述符长度
4 _ _u8 bDescriptorType; //描述符类型
5
6 _ _le16 wData[1]; /* 以 UTF-16LE 编码 */
7 } _ _attribute_ _ ((packed));

例如,插入一个 SanDisk U 盘后,通过 lsusb
命令得到这个 U 盘相关的描述符,从中可以显示这个 U 盘包含了一个设备描述符、
一个配置描述符、一个接口描述符以及批量输入和批量输出两个端点描述符。呈现出
来 的 信 息 内 容 直 接 对 应 于 usb_device_descriptor 、 usb_config_descriptor 、
usb_interface_descriptor、usb_endpoint_descriptor、usb_string_descriptor 结构体,如下
所示:

Bus 001 Device 004: ID 0781:5151 SanDisk Corp.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 Interface
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0781 SanDisk Corp.
idProduct 0x5151
bcdDevice 0.10
iManufacturer 1 SanDisk Corporation
iProduct 2 Cruzer Micro
iSerial 3 20060877500A1BE1FDE1
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 32
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
MaxPower 200mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 8 Mass Storage
bInterfaceSubClass 6 SCSI
bInterfaceProtocol 80 Bulk (Zip)
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type none
wMaxPacketSize 512
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type none
wMaxPacketSize 512
bInterval 1
Language IDs: (length=4)
0409 English(US)

教材:linux设备驱动详解

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值