Linux上USB驱动开发

Linux驱动开发培训系列教程网址https://edu.csdn.net/course/detail/26814

本次课程分3个部分讲述USB驱动开发
第一部分:USB基本概念
第二部分:USB设备驱动框架
第三部分:实例分析(视频教程)

第一部分:USB基本概念

1,设备描述符:
设备描从整体述符描述了USB设备的通用信息,一个USB设备只有一个设备描述符。是在设备连接时,主机第一个读取的描述符。

typedef struct USB_DEVICE_DESCRIPTOR
{
BYTE bLength,
BYTE bDescriptorType,
WORD bcdUSB,
BYTE bDeviceClass,
BTYE bDeviceSubClass,
BYTE bDeviceProtol,
BYTE bMaxPacketSize0,
WORD idVenderI,
WORD idProduct,
WORD bcdDevice,
BYTE iManufacturer,
BYTE iProduct,
BYTE iSerialNumber,
BYTE iNumConfiguations
}USB_DEVICE_DESCRIPTOR;

1)、bLength
该字段表示整个设备描述符的字节数大小。而整个设备描述符占用了17个字节, 因此bLength的值是固定的, 就是18, 用十六进制表示就是0x12。

2)、bDescriptorType
设备描述符的类型。USB定义的设备描述符的类型编号为常数0x01,因此,该字段的值为固定值0x01。

3)、bcdUSB
该字段代表设备所遵循的USB协议的版本号。
USB1.1,其bcdUSB值为0x0110
USB2.0,其bcdUSB值为0x0200

4)、bDeviceClass
设备类型的代码。值从0x01~0xFE为USB定义的标准设备类,而值为0xFF时表示该设备类型代码是厂商自定义的类。如果设备类型不在设备描述符中定义的, 则该值为0(可以在接口描述符中定义设备类型)。比如人机接口设备 ( HID) 类。

5)、bDeviceSubClass
设备类中的子类类型。和bDeviceClass一样由USB规定和分配,当 上面一项为0时,本项也要设置为0。 代表该子类类型不在设备描述符中定义。 值为0xFF时, 也代表子类类型是由厂商所定义的。

6)、bDeviceProtocol
设备所遵循的协议,该值有USB协议规定,当值为0xFF时,表示该设备采用厂商自己为该类定义的协议。上面一项为0时,本项也要设置为0。

7)、bMaxPacketSize0
比较特殊的是, 默认控制管道的数据包的长度(也就是USB设备端点0的长度)是在设备描述符中定义的, 而不像其他端点一样是在端点描述符中定义的。
描述了端点0的最大包的大小, 低速设备的bMaxPacketSize0恒为8, 全速设备可以是一般为 8、16、32或64, 即0x08、0x10、0x20或0x40, 而高速设备则为64。

8)、idVendor
厂商编号。这个是需要跟USB组织申请的ID号,表示厂商代号。

9)、idProduct
该产品的编号。跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程序。

10)、bcdDevice
设备出厂编号。

11)、iMenufacturer
设备生产厂商的字符串的索引值。值为0则代表没有使用该字段。在获取字符串描述符时,使用该索引号来识别不同的字符串。

12)、iProduct
描述该产品的字符串的索引值。值为0时表示没有使用该字段。同上。

13)、iSerialNumber
设备的序列号的索引值。每个设备都有一个特定的序列号, 可供主机来识别不同的设备。同上。

14)、bNumConfigurations
该设备总共支持的配置描述符的数量。

2,配置描述符:
配置描述符用于描述一个USB设备的属性和能力等配置信息。通常一个USB设备只需要一个配置描述符就可以了。比如一个USB接口的鼠标,其功能仅仅是简单的双向数据中断传输, 并且是总线供电。因此按照这些要求来填写一个配置描述符即可。
不过多用途的USB设备可以支持多个配置,但在同一时间只能有一个配置起作用。 每一个配置都需要一个配置描述符。配置描述符中包含设备的电源使用以及支持的接口数目。每一个配置描述符包含一个或多个接口描述符。
配置描述符不会单独发送给USB主机,通常会以集合的形式发送给主机。集合通常包含:配置描述符,接口描述符,端点描述符,HID描述符。这几个描述符组成一个大数组。
typedef struct USB_CONFIGURATION_DESCRIPTOR
{
BYTE bLength,
BYTE bDescriptorType,
WORD wTotalLength,
BYTE bNumInterfaces,
BYTE bConfigurationValue,
BYTE iConfiguration,
BYTE bmAttributes,
BYTE MaxPower
}USB_CONFIGURATION_DESCRIPTOR;

11)、bLedgth
整个配置描述符的长度, 因此bLength是固定的, 值为9, 即0x09。

2)、bDescriptorType
USB给配置描述符分配的类型编号, 值为常数0x02。

3)、wTotalLength
此配置信息的总长(包括配置,接口,端点),即:将要返回的配置信息总长度。

4)、bNumInterfaces
该配置所支持的接口总数。

5)、bConfigurationValue
配置值。
一个USB设备可以有多个配置,配置值就是每个配置的标识。设置配置请求时,会发送配置值。如果发送的值和这里值一样,说明这个配值被激活(USB设备启用该配置)。
主机调用Get_Configuration读取某个配置。使用参数0,得到第一个配置描述符,使用参数1,得到第二个配置描述符。
主机调用Set_Configuration启用某个配置。把上一步取得的配置描述符中的bConfigurationValue值(不一定是从0开始),作为控制参数传递给USB设备,启动某个配置。

6)、iConfiguration
该字段指向描述该配置描述符的字符串。 如果该设备没有用字符串描述该配置, 那么此字段为0。

7)、bmAttributes
该字段1字节二进制数的每一位代表一个固定的含义:
D7:Reserve,固定为1;
D6:供电方式的选择, 值为1表示自供电, 值为0表示总线供电;
D5:远程唤醒功能的选择, 值为1表示支持远程唤醒, 值为0则不支持;
D4~D0:没有意义, 均把值固定为0。

8)、MaxPower
设备从总线上获取的电流总量。电流值为字段值的两倍,设备可以获取到的最大电流为500mA,所以字段值最大为0xFA;

说明:
如果主机发出标准命令Get_Descriptor要求获得设备的某个配置描述符时,该配置的所有信息都将发给主机,它包括:该标准配置符本身、该配置所包含的所有接口、端点描述符及设备类描述符和厂商描述符。

3,接口描述符:
接口描述符用于描述一个特定接口的属性。接口一般是由一系列端点所组成的集合体,用于实现某种特定的USB的数据传输功能。一般一个USB设备只需具有一个接口。比如,USB移动存储设备中就只有一个用于实现Mass Storage类的接口, 在该接口下使用了批量输入Bulk_IN和批量输出Bulk_OUT 2个非0端点用于传输文件。接口描述符还可以在配置后加以改变。前面已经提到, 标准的USB设备类型都是在设备描述符中定义的, 但是有些类是基于接口在接口描述符中定义的, 如HID设备。接口描述符对应一个逻辑设备。
typedef struct USB_INTERFACE_DESCRIPTOR
{
BYTE bLength,
BYTE bDescriptorType,
BYTE bInterfaceNumber,
BYTE bAlternateSetting,
BYTE bNumEndpoint,
BYTE bInterfaceClass,
BYTE bInterfaceSubClass,
BYTE bInterfaceProtocol,
BYTE iInterface
}USB_INTERFACE_DESCRIPTOR;

(1)、bLength
标准的接口描述符的长度是9个字节。

(2)、bDescriptorType
表示描述符的类型,接口描述符对应的值是4。

(3)、bInterfaceNumber
接口的编号。如果一个配置拥有N个接口, 那么这些接口都是互不相干的, 每一个接口都有惟一的编号, USB就是通过此字段来识别不同的接口。默认值为0。

(4)、bAlternateSetting
接口的备用编号,一般使用0。
上面讲的USB设备的配置与USB配置描述符是一一对应的, 即一个配置只能有一个配置描述符。USB允许一个接口有多个接口描述符, 而且这些描述符都可以通过命令来切换。此字段就是每一个这类描述符惟一的编号。USB可以通过调用这个字段来切换描述同一个接口的不同描述符。控制传输中可以通过Get_Interface和Set_Interface来获取、设置目前正在使用的描述一个确定接口的接口描述符的编号。

(5)、bNumEndpoints
该接口使用的端点总数(除端点0之外)。如果此值为0, 则意味着该接口只使用端点0。

(6)、bInterfaceClass
该接口所属的类别。这个类别编号由USB来分配。当值为0xFF时, 表示该接口是厂商所定义的接口类型。而值0保留。

(7)、bInterfaceSubClass
接口所属的类别中的子类类型。这个子类编号也由USB分配。同bInterfaceClass字段一样, 当其值为0xFF时代表该接口由厂商自己所定义。而值0保留。

(8)、bInterfaceProtocol
此接口类所遵循的类的协议。因而, 该字段的值跟bInterfaceClass和bInterfaceSubClass字段是相关的。其值从1~0xFE由USB分配, 代表不同标准的设备类的协议。 当值为0时, 表示该接口不遵循任何类协议; 而值为0xFF时, 表示该接口应用了厂商自定义的类协议。

(9)、iInterface
指向字符串描述符中相应的字符串内容, 用于描述该接口。 如果设备没有启用字符串描述符 , 则该值为0。

4,端点描述符:
端点描述符用于描述接口所使用的非0端点的属性, 包括输入/输出方向、端点编号、端点容量、数据传输方式。
USB设备中的每个端点都有自己的端点描述符,由接口描述符中的bNumEndpoint决定其数量。

typedef struct USB_ENDPOINT_DESCRIPTOR
{
BYTE bLength,
BYTE bDescriptorType,
BYTE bEndpointAddress,
BYTE bmAttributes,
WORD wMaxPacketSize,
BYTE bInterval
}USB_ENDPOINT_DESCRIPTOR;

(1)、bLength
这个端点描述符的长度。

(2)、bDescriptorType
USB为端点描述符分配的类型编号, 因此, 此字段的值固定, 即为0x05。

(3)、bEndpointAddress
D7 端点方向
0 OUT端点
1 IN端点
D6~D4 保留
D3~D0 端点编号

(4)、bmAttributes
D5~D4 用途
00 数据端点
01 反馈端点
10 隐式反馈数据端点
11 保留
D3~D2 同步类型
00 非同步
01 异步
10 自适应
11 同步
D1~D0 传输类型
00 控制传输
01 同步传输
10 块传输
11 中断传输
如果该端点不是同步端点,D5~D2保留且必须置0。

(5)、wMaxPacketSize
该端点最大包的大小。其中D10~D0位共11位为有效内容。在USB协议1 .1中D15~D11位保留, 值为0, 且最大包的大小范围为0~1023。

(6)、bIterval
主机轮询设备的周期。在USB协议1.1中, 对于中断端点, 该字段的值为1~255,时间单位ms,因此假设值为250, 则表示时间间隔为250ms; 对于同步端点, 该字段值固定为1 ; 而批量端点和控制端点则忽略该字段 ,值无效。

第二部分:USB设备驱动框架

一,和platform机制的对比
二,USB设备和驱动的配对机制

1,usb device driver
USB子系统初始化的时候就会注册驱动usb_generic_driver。它是USB系统中唯一的一个USB设备驱动,所有的USB设备都对应该驱动。
作用:
1)当主机上插入USB设备时,USB设备被探测并被注册到系统后(用device_add),
2)系统调用usb_bus_type.mach( )。只要是usb设备,都会跟usb_generic_driver匹配上。
3)调用usb_probe_device( ),从而调用usb_generic_driver的 probe( )函数。
4)probe( )函数为USB设备选择一个合适的配置,让设备进入configured状态。

2 ,usb driver

USB驱动(usb driver)就是USB设备的接口驱动程序,比如U盘驱动程序,鼠标驱动程序等等。

  • 从USB设备的配置中提取出接口,对接口调用device_add( ),向USB总线注册设备(此处指接口,逻辑设备)。
  • Linux启动时注册USB驱动,通过usb_register( )将USB驱动(接口驱动,或者叫逻辑设备驱动)提交给系统,添加到USB总线的驱动链表里。
  • 当驱动的id_table包含接口中的 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol三项时, 说明该驱动和该接口匹配,系统会调用驱动的probe函数。

在这里插入图片描述

在这里插入图片描述

第三部分:实例分析

以视频教程的形式进行讲解

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Linux USB驱动开发是指在Linux操作系统中开发USB设备驱动程序的过程。USB驱动程序是用来控制USB设备与计算机之间通信的软件,它负责管理USB设备的连接、数据传输和控制等功能。在Linux系统中,USB驱动程序是以内核模块的形式存在的,开发者需要了解Linux内核的结构和USB协议的相关知识,才能编写出高效、稳定的USB驱动程序。Linux USB驱动开发需要掌握C语言、Linux内核编程、USB协议等知识,同时需要使用一些开发工具和调试工具,如gcc编译器、make工具、GDB调试器等。 ### 回答2: Linux是一种开源的操作系统,广泛应用于服务器、嵌入式设备、超级计算机等领域。在Linux中,许多设备的驱动都是以模块的形式存在于系统中的。USB设备驱动也是Linux系统中非常重要的一类驱动之一。 Linux中的USB驱动开发主要包括以下几个方面: 1. USB架构 LinuxUSB架构分为两个部分:USB核心和USB驱动USB核心主要负责管理USB系统资源,并提供USB设备驱动与用户操作的桥梁,而USB驱动则是实际负责控制USB设备的代码。 2. USB驱动注册 USB设备驱动Linux中是以模块的形式存在的,因此需要通过驱动注册函数将驱动注册到系统中。驱动注册函数会指定驱动支持的USB设备ID等信息。当系统中有匹配的USB设备插入时,USB核心会调用驱动的probe函数,初始化并注册设备。 3. USB设备操作 USB设备驱动的主要任务是通过USB接口与设备进行通信。在Linux中,一般通过调用USB核心提供的函数,访问USB设备的寄存器等信息。设备的数据传输一般使用USB核心提供的异步通信机制。 4. USB设备的断开和移除 当USB设备被拔出时,USB核心会调用驱动的disconnect函数,释放资源。其次,驱动还需响应用户层的请求,卸载驱动相关的资源等。 综上所述,Linux中的USB驱动开发包括USB架构、驱动注册、设备操作、设备断开和移除等方面。熟练掌握这些技能对于嵌入式设备的开发和服务器维护等领域非常重要。 ### 回答3: Linux USB驱动开发主要是指在Linux操作系统上,通过编写USB 驱动程序,实现与USB设备的通信。相比较于其他操作系统,Linux天然具有对USB设备的支持。对于在Linux 2.4及以上版本中,USB集线器、鼠标、键盘等一些外设设备无需单独安装驱动就可以直接使用,这源于Linux内核中已经自带了许多USB驱动,而我们开发人员需要做的就是调用这些API接口,实现自己的业务逻辑即可。而对于一些需要特殊处理的USB设备(如自己开发或第三方成功能较为特殊的设备),我们需要在Linux内核中对其进行驱动开发。 在Linux USB驱动开发中,需要特别注意以下几点: 1.了解USB规范:了解USB规范才能更好地使用设备的功能。比如,我们需要知道USB设备的通信协议、数据格式等,才能正确地编写应用程序,并与USB设备成功通信。 2.学会如何注册USB设备驱动程序:注册USB设备驱动程序也是Linux USB驱动开发的重点。我们需要了解内核的函数和原理,才能正确地注册USB设备驱动程序。通过这个注册,我们可以将设备和驱动程序关联起来,并在内核层面进行相关操作。 3.掌握如何编写USB驱动程序的初始化函数和I/O操作函数:USB驱动程序的初始化函数是模块加载成功后第一次调用的函数。通过定义初始化函数,我们可以在设备驱动程序启动时完成一些需要准备的工作,比如设备寄存器的初始化配置等。I/O操作函数则是定义了USB设备在使用时的各种操作,如读取设备数据、控制设备状态等。 4.了解内核中USB的基本操作:如何进行USB请求、读写USB数据等操作是Linux USB驱动开发中必不可少的一部分。我们需要掌握USB集线器中的端口锁定、取出以及在数据缓冲区之间的数据交换等基本操作。 最后,Linux USB驱动开发需要技能深厚并有一定的底层技术基础,因此不太适合初学者。在实际应用中,我们还需要注意一些硬件和软件开发细节,以确保USB设备能正常运行,并防止一些潜在的错误发生。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gaoyanli1972

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值