新闻  |   论坛  |   博客  |   在线研讨会
USB设备驱动开发-USB协议相关
luker | 2017-04-06 21:23:13    阅读:1053   发布文章

USB设备驱动开发-USB协议相关(一)

转载自:

http://blog.chinaunix.net/uid-14518381-id-3892699.html

一、USB设备模型

       USB设备模型从物理上分为两个部分:主机(host)控制端作为主机端,驱动的设备是USB Host Controller;外设端被称为设备端,驱动的设备是USB Device Controller。因此,USB设备驱动应该分为主机端驱动和设备端驱动两部分,只是由于USB协议的主从定位思想,从设备只需要响应主机控制器的请求,不能主动发起请求,通常所说的USB驱动都是指主机端的驱动程序。但近年来随着嵌入式设备的广泛使用,运行Linux系统嵌入式设备也需要通过USB协议与主机端通信,因此从设备端的Linux也需要进行USB设备驱动程序开发,为了避免和主机端的USB设备驱动开发混淆,就将运行Linux的从设备驱动开发成为USB gadget driver,进入与device driver区分开。

二、与驱动开发相关的USB协议规范

      1. USB设备被分为三层:

          usb host controller:最底层,也是总线接口层,负责传输和接收数据包;

          usb core:USB核心层,Linux系统已经根据USB协议规范实现的通用接口。作为中间层,主要完成总线与设备上端点的通信,端点是数据最终的生产者和消费者,一个设备可以有多个端点。因此,这一层其实就是总线和端点的路由。

         usb function:USB功能层,调用下层的接口实现不同的功能,如USB鼠标、USB键盘、USB话筒。通常的USB驱动开发指的都是这层的工作。

    2. USB设备的状态和状态机转换

clip_image001

clip_image002

        Attached:USB设备接入或拔出,USB协议规范只定义了USB设备接入时的状态;

        Powered:USB设备的供电分为两种,从USB总线取电的称为总线供电,USB设备从外部取电的称为自供电。即时是自供电设备在插入前已经接通电源仍不能认为其处于Powered状态,只有插入Attached加电后才处于Powered状态;

支持两种供电模式的设备可以通过配置描述符来向主机报告它当前的供电模式。

       Default:当设备处于Powered状态后,仍不能相应任何总线通信,只有设备手段总线的reset请求后,设备才能通过默认地址进行通信。设备被成功reset后,可以相应配置描述符请求并返回相应的信息;

       Addess:在设备被reset后,每个USB设备将被分配一个独一无二的地址,USB设备在其挂起期间仍拥有这个地址。不论USB被分配了独一无二的地址或使用的默认地址,都能通过默认的通道(pipe,即每个设备的0号端点)进行通信;

      Configured:在设备的功能被正常使用前,设备必须被配置。从设备端来讲,配置就是正常处理一个带有非0参数的SetConfiguration()请求。包括将每个端点的数据包默认类型设为DATA0;

       Suspended:电源管理相关,在没有总线传输的一段时间后,USB设备将自动进入suspend状态。在suspend状态,USB设备自身维护它分配的地址和配置。当有一个总线激活信号后,设备从suspend状态返回。USB设备也可以支持远程唤醒(Remote Wakeup)来唤醒处于suspend状态的主机控制器,但需支持host可以使能或关闭这个功能。

  3. 总线枚举

当一个USB设备接入或拔出时,主机需要通过总线枚举功能来管理设备的状态。当设备接入时,将采取下面的措施:

      1.  当设备接入后,接入的HUB通过一个状态改变通道通知主机这个事件,这时USB设备处于Powered状态并且其连接的端口是disabled的;

      2.  主机询问HUB这次事件的类型等信息;

      3.  当主机了解这是个插入事件后,将enable设备接入的端口并等待100ms,让设备的供电稳定,然后向这个端口发出reset命令;

      4.  HUB执行这次reset操作,USB设备将处于default状态,同时可以从Vbus获取不超过100ma的电源。当前设备的寄存器和状态都被reset了,并且可以通过默认地址进行响应;

      5.  主机将给USB设备分配一个独一无二的地址,设备将进入address状态;

      6.   在USB设备获取独一无二的地址之间,通过默认地址的默认控制通道仍然可以访问,host获取设备描述符来决定默认控制通道的最大数据载荷;

      7.   主机将从设备获取全部配置信息,从0到n-1的配置描述符,即设备所拥有的所有配置描述符;这将花费几毫秒;

      8.    通过获取的配置信息来决定设备将被如何使用,主机将分配各设备一个配置值,这时设备处于configured状态同时所有的端点也就具有这个配置下的特性,USB设备也将获取在其所指定的配置中的电流值。设备处于可用状态了;

USB设备驱动开发-USB协议相关(二)

一、USB设备通用操作

      1. 热插拔

在热插拔中,USB HUB扮演着很重要的角色,HUB向主机报告端口的状态改变,主机才能对相应的动作采取相应的操作;

      2. 地址分派

当USB设备插入后,主机会对USB设备分配一个独一无二的地址,同时resetUSB设备并对HUB的相应端口使能;

      3. 配置(Configuration):

在USB设备的功能可用之前必须被配置,主机首先获取设备的配置信息了解设备的功能进而进行配置。主机将设置设备的配置(configuration),并且可能对接口(Interface)选择可变的设置(setting).

在一个配置中,设备可能支持多个接口,一个接口就是相关的一些端点(Endpoint) ,通过这些端点提供一个功能。因此,一个接口就向主机提供一个功能,在一个配置中,一个USB设备可以向主机提供多个不同的功能。接口中端点的特性和端点与主机通信的协议可以通过设备类(device class)或厂商自定义的标记来标示。

接口可以有一些设置来重定义接口关联的端点的编号和特性,但这需要设备支持GetInterface()请求来报告接口的当前设置,并通过SetInterface()请求来为接口选则可变的设置。

接口配置符(Interface Descriptor)数据结构包含表示接口号和可变设置的域,其中接口号是从0至n-1(n表示当前配置所支持的接口数),可变设置也是编号从0至n-1编号,当设备初始化配置中接口的默认设置是0号设置。

为了支持通用性驱动程序,设备描述符和接口描述符中都包含Class、SubClass和Protocol域,来标示USB设备提供的功能和利用这些功能主机和设备的通信协议。

4. 数据传输

USB设备和主机之间有四种数据传输方式(控制、中断、批量和等时),端口号可以在不同的接口设置中使用不同的传输方式。但一旦这种接口设置选定,在这种接口设置期间相应的端口就只能使用这种设置中指定的数据传输方式。

5. 请求响应

在USB设备处理请求时,为了保证处理的及时性,设置了一个时间上限5秒。在5秒内任何请求都必须被处理完成,但这不是强制性的规定。一个设备标准的请求包括三个阶段:发出请求,传输数据,返回状态。

在设备标准请求中,若没有数据阶段,则设备必须在50ms内完成请求处理并返回状态,这个限制适用于设备、接口和端点。

若需要在数据阶段传输数据给主机,则设备必须在接收到请求50ms内发出第一个数据包,并在500ms内传输完其他数据包,然后在最后一个数据传输完50ms内返回状态,完成状态阶段。也就是说,主机获取数据的请求必须在600ms内完成。

若主机需要发送数据到设备,则是5秒的限制。设备需要在5秒内完成数据的接收和状态阶段。

二、USB设备请求(USB Device Request)

所有的USB设备请求都是通过设备的默认控制通道(0号控制端点)完成的,使用控制传输协议。这些请求和请求的参数通过Setup包发送,每个Setup包都是8个字节。

         Setup包的格式:

clip_image003

bmRequestType:请求类型相关信息,一个字节

其中的Direction表示第二阶段数据传输的方向,若wLength字段为0,表示没有数据传输,则这个位可以忽略。

Type位(两位)表示请求的类型,USB设备规范定义了一些所有设备必须支持的标准设备请求,用Standard。或者这类设备定义了一些请求,用class表示,或这个厂商自定义的请求,用vendor。

Recipient位(5位)表示请求的对象,请求对象可以是设备、设备上的接口或指定的端点。若操作的对象是接口或端点,则wIndex域来表示接口号或端点号。

bRequest:是具体的请求,一个字节

具体的请求操作,标准设备请求将在后表列出

wValue:根据请求的不同有不同的含义,两个字节

与具体的请求相关,将在后表列出

wIndex:根据请求的不同有不同的含义,一般表示索引或便宜量,两个字节

当请求操作对象是设备时,可用于传递给设备的参数;

当请求操作对象是接口或端点时,用于表示操作的接口号或端点号

clip_image004

Direction位设为0,表示OUT端点,设为1表示IN端点。在控制通道中,应当将其设置为0。

clip_image005

wLength:若请求有数据传输,则表示传输数据的长度

表示在第二阶段数据传输的长度,bmRequestType字段中指示了数据传输的方向。若wlength表示为0,则没有数据传输阶段。

在一个获取数据的请求中,设备不能返回多于wLength的数据,但可以返回少于wLength的数据。而在输出数据的请求猪,wLength总是发出数据的准确长度,若发出的数据长度超过wLength,则设备的行为是不可知。

设备标准请求指令和Setup包中相关字段对应的值

clip_image006

clip_image007

USB设备驱动开发-USB协议相关(三)

一、USB设备标准请求

USB设备标准请求是为所有USB设备定义的操作,即使设备还没有被分配地址或还没有被配置都必须相应设备标准请求。

标准特性选择子

clip_image008

特性选择子用于对特性使能或设置特性,若一个不支持或非法的请求发送给USB设备,设备将在数据或状态传输阶段返回STALL作为响应。若设备的默认控制通道由于错误不能通信,则设备将被reset来清除错误状态并重启默认控制通道。

1. Clear Feature

clip_image009

wValue中的特性选择子必须和操作对象匹配,即设备特性对应设备,接口特性对应接口,端点特性对应端点。

若对应的特性不存在或不能被清除,或者操作的接口或端点不存在,将返回一个请求错误状态。

在Default状态:设备接收到这个请求后的操作是未定义的;

在Address状态:对设备操作是有效的,但对接口和端点的操作将返回请求错误;

在Configured状态:所有的请求都是有效的。

其中TEST_MODE特性不能被ClearFeature请求清除。

2. Set Feature

clip_image010

设置或使能特性

3. Get Configuration

clip_image011

返回当前的设备配置值(一个字节),在配置状态下,返回非0的bConfigurationValue值。若设备没有配置则返回0。

4. Set Configuration

clip_image012

设置设备的配置

在wValue的低字节是配置值,若配置值为0,则设备将仍处于Address状态。

5. Set Descriptor

clip_image013

clip_image014

用于更新已有的描述符或新增描述符。

6. Get Descriptor

clip_image015

其中wValue的高字节表示描述符的类型,如下表所示;低字节表示描述符的索引。一个设备可以实现多个配置描述符和字符串描述符,因此只有这两种描述符才会用到索引值。

7. Get Interface

clip_image016

这个请求返回接口目前选择的可选设置(Alernate Setting)。

8. Set Interface

clip_image017

设置接口

9. Get Status

clip_image018

返回操作对象的状态。

clip_image019

clip_image020

clip_image021

10. Set Address

clip_image022

设置设备的地址

只允许对设备描述符、配置描述符和字符串描述符进行操作。

11. Synch Frame

clip_image023

在等时传输方式中,用于设置并返回端点的同步帧。

二、描述符

USB设备使用描述符来报告属性,一个描述符即预先定义好的数据结构。每个描述符的第一个字节表示描述符的长度,第二个字节表示描述符的类型。

在描述符中可能包含有对字符串描述符的引用来描述这个描述符,若设备不支持字符串描述符,则其他描述符中字符串描述符引用域必须存储,但需要设置为0来描述没有可用字符串描述符。

1. 设备描述符

设备描述符用于描述一个设备的通用信息,一个USB设备只具有一个设备描述符。高速设备的设备描述符有一个版本号bcdUSB,0200H来表示USB 2.0

clip_image024

clip_image025

struct usb_device_descriptor {

__u8 bLength;

__u8 bDescriptorType;

__le16 bcdUSB;

__u8 bDeviceClass;

__u8 bDeviceSubClass;

__u8 bDeviceProtocol;

__u8 bMaxPacketSize0;

__le16 idVendor;

__le16 idProduct;

__le16 bcdDevice;

__u8 iManufacturer;

__u8 iProduct;

__u8 iSerialNumber;

__u8 bNumConfigurations;

} __attribute__ ((packed));

2. Device_Qualifier

clip_image026

对于高速设备,若在其他速度下需要更改一些配置,这需要定义这个描述符。

3. 配置描述符

配置描述符描述一个设备配置的信息,其中的bConfigurationValue值作为传输传递给SetConfiguration()请求,使设备采用这个配置。

一个USB设备有一个或多个配置描述符,一个配置描述符拥有一个或多个接口,一个接口拥有0个或多个端点。在同一个配置中,一个端点不能在不同的接口之间共用,但可以在同一个接口的不同设置共有。但在不同的配置中,端点可以在接口之间共用。

一旦配置选定,则设备一般仅少有的可变设置,即接口拥有可选设置则才可能更改设置。

clip_image027

clip_image028

4. 接口描述符

接口描述符描述一个配置中的接口。一个配置提供一个或多个接口。当一个配置支持一个或多个接口时,接口描述将作为配置描述符的一部分返回,端点描述符将紧跟着接口描述符返回。接口描述符不能通过GetDescriptor()或SetDescriptor访问。

一个接口包含可变设置来允许在设备配置后允许端点或一些特性做一定的改变。接口默认的设置都为0,SetInterface()请求用于选择一个设置或返回默认的设置。GetInterface()请求返回选择的设置。

如果一个设备配置支持单个接口并此接口有两个可选设置,配置描述表返回以后会紧跟着返回bInterfaceNumber与bAlternateSetting域皆为0的第一个设置的接口描述表及相关的结点描述表,而随之后是另一个设置接口描述表与结点描述表第二个接口描述表的bInterfaceNumber域也应为0但bAlternate Setting域应为1 。

如果一个接口仅使用节点0则接口描述表以后就不再返回节点描述表并且此接口表示的是一个请求接口它使用连在节点0上的缺省通道在这种情况下bNumberEndpoints域应被设置成0 ,一个接口描述表的节点个数不把结点0计在内。

clip_image029

clip_image030

5. 端点描述符

接口的端点拥有自己的描述符,描述符包含主机分配每个端点带宽的信息。每个端点描述符是作为配置信息的一部分在GetDescriptor请求中返回的。端点描述符不能直接通过GetDescriptor()或SetDescriptor()请求访问,这点与接口描述符一致。端点0没有端点描述符。

clip_image031

clip_image032

clip_image033

6. 字符串描述符

字符串描述符是可选的,但若设备不支持字符串描述符,则设备中配置描述符、接口描述符中对字符串描述符的引用值必须设置为0。字符串描述符使用UNICODE编码方式。USB设备可能需要支持多种语言,字符串描述符中16位的LANGID来表示支持的语言。

clip_image034 

clip_image035

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客