usb在江湖系列之一家族系统(2) 2010/12/18

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:黑体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimHei; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:CourierNewPSMT; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-alt:Arial; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:auto; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@黑体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:TimesNewRomanPSMT; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-alt:Arial; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:auto; mso-font-signature:3 0 0 0 1 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} h1 {mso-style-next:正文; margin-top:17.0pt; margin-right:0cm; margin-bottom:16.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:240%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:1; font-size:22.0pt; font-family:"Times New Roman"; mso-font-kerning:22.0pt;} h2 {mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:2; font-size:16.0pt; font-family:Arial; mso-fareast-font-family:黑体; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} --> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:黑体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimHei; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:CourierNewPSMT; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-alt:Arial; mso-font-charset:0; mso-generic-font-family:modern; mso-font-format:other; mso-font-pitch:auto; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@黑体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:TimesNewRomanPSMT; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-alt:Arial; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-format:other; mso-font-pitch:auto; mso-font-signature:3 0 0 0 1 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} h1 {mso-style-next:正文; margin-top:17.0pt; margin-right:0cm; margin-bottom:16.5pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:240%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:1; font-size:22.0pt; font-family:"Times New Roman"; mso-font-kerning:22.0pt;} h2 {mso-style-next:正文; margin-top:13.0pt; margin-right:0cm; margin-bottom:13.0pt; margin-left:0cm; text-align:justify; text-justify:inter-ideograph; line-height:173%; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:2; font-size:16.0pt; font-family:Arial; mso-fareast-font-family:黑体; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->

Life of USB device

       有一句话叫做事必躬亲,意思是每件事情都要亲自做。我觉得他也告诉我们另外一件思路:事情只有亲自参与了才能有切身体会。我们做嵌入式开发讲究的更是这个,整天抱着书看、不做试验、没有应用场景验证我们的思路,一是不好理解,二 是即使理解了慢慢也忘了。所以我的思路是学习知识时,要创造该知识的应用场景。应用才是王道,应用的场景推动着我们对知识的理解,所以我们从最熟悉的 U 盘开始,来引出 USB 中的几个关键术语。

       也许没有多少人了解 USB 的工作原理,但是大部分人却都使用着 U 盘。你知道 U 盘插入电脑的那一刻起一直到电脑上显示出盘符这短暂的瞬间都发生了什么?其他人可能不会去想,也没有必要想,但是你既然看到了这里,你就应该想一想。这是进入 USB 的开始。

       电脑对他做了什么?怎么知道他是 U 盘的?还知道他是那个厂家的?并且在插了 2 个或更多个 U 盘时,依然能够正确的向里边拷贝数据,怎么区分他们的?带着疑问,我们能走得更快。

       U 盘插入 hub 后,供电的瞬间就是设备 life 开始的时刻!佛祖曾经说过:万物皆有生命。

2.1 枚举

       USB 设备 (U ) 的一生有这么几个阶段:

Attach 态, Power 态, default 状态,寻址态,配置态、挂起态。

       首先将设备连接到 Hub 的端口上,这时就处于 Attach 态;端口然后给设备提供电源,这时处于 Power 态,这样才有了能量,总得吃了饭才能干活阿。供电态之后,设备还没有接受过 host 的任何指示,处于的状态为 Default 态,在 Default 状态下设备默认地址为 0 。目前它还没有得到主机的认可。这里强调一下,默认地址 0 是很重要的,是公共财产,谁也别想单独拥有,否则后果很严重。 Host 检测到 USB 设备的插入后,会重新给该设备分配一个地址,使设备进入寻址态;然后 host 会与设备通讯获取设备的信息, USB 设备告诉 host 自己都能干什么,然后 host 就选择设备的一种功能进行配置,从此 USB 设备就知道自己工作在哪种功能下了,找到了人生目标啊!从此步入了配置态,就开始正常的工作了,如果是 U 盘就开始传输文件了,当然正式工作还有很多东西要讲,我们先考虑枚举这段过程。当 host 没有什么任务、工作需要 USB 设备完成时,为了节能、低碳会将设备挂起,从此设备进入挂起状态。

       刚到一个班级时,老师会为每一个学生分配一个学号,来标识一个学生,这就类似于这里的设备地址。老师提问时如果叫到 9527 ,所有的人都会听到,然后判断是不是叫自己,如果不是不予理会;如果叫到的是自己,就需要起来回答问题。从 1.3 的逻辑拓扑结构来看, host 会将数据或者命令广播出去,所有的设备都要判断是否给予响应,决定其是否响应的就是地址, host 的呼叫的地址是不是自己。

2.2 枚举阶段的细节

       上面我们简单的说了一下 USB 设备枚举的过程,那么枚举的每个过程都发生了什么?怎么发生的呢? Attach 态和 Power 态没什么讲头,我们主要介绍的是 default 态,寻址态,配置态。

       default 态: USB 设备上电并正常工作后,就进入了 default 态,这个默认的意思是说地址处于默认状态,每一个 USB 设备都有一个默认地址,总得给 host 一个找到你的方式吧。此时 host 会通过默认地址 0 来和 USB 设备通讯。如果有两个设备都是地址 0 怎么办?我只能说不应该也不能出现这种情况,我们必须一个设备一个设备的供电、进入 default 态,如果有两个叫做 9527 的怎么办,乱套了?在 default 态时, host 并不知道这个 USB 设备是个什么主儿,所以 host 首先会发送一个命令来试探一下, USB 设备会对这个命令进行回应。专业术语叫做获取设备描述符。就这么一个简单的过程将引出多个 USB 的知识点。

       1  USB 的所有通讯都是 host 主动, USB 设备被动接受、响应,绝对不能主动请战。

       2  命令是什么样的? USB 中将命令叫做令牌。枚举过程中使用的令牌为 setup 令牌

       3  命令的参数是什么? setup 令牌的内容我们通常叫做 setup 包。他是 1 8 字节的数

据包,包含了各种信息:数据方向、长度、索引,主要的一项是要干什么。

什么是设备描述符?如果我问你:你叫什么名字,从哪来。我觉得应该可以答上来。一样的道理, USB 设备各式各样,他必须在设备内部有记录,自己是什么设备,都有什么资源等等,这就是设备描述符,关于设备描述符我们后面一看就知道了。

这个命令传给 USB 设备后, USB 设备采用的什么机制收到的数据。我先告诉你是端点。

注意:这里我一直称呼为 USB 设备,上面说过应该是 USB 接口的功能性设备,这个设备内部应该是一个 USB device 控制器, USB 通讯所涉及到的就是两个控制器: host device 之间的恩恩怨怨。

通过 default 我们就知道了,我们需要了解以下几点:令牌、 setup 包、描述符、端点

寻址态: 刚才 host 通过地址 0 与设备通讯,咱也不能一直这样过, USB 是博爱的,必

须做到人人有其居, host 会为其分配一个地址,从此 USB 设备就名正言顺的占着这个地址了。这个过程也是发送了一个 setup 命令。

配置态: USB 设备到底能干什么, host 还是不清楚的,所以会进一步获取信息,这

个过程会获取配置描述符和接口描述符,这两个描述里清晰的描述了该设备都能干什么。 Host 会根据自己的需要通知 USB 设备具体干什么。举个例子:你到一家公司面试时面试官会问你都能做什么:我能做 nandflash ,还能做 linux 驱动。如果面试通过,会通知你,你做 linux 驱动吧,这就是进行了配置。当然这里其实还复杂一些,我们先说的简单点,在这个过程中引出的知识点是:配置、接口

       USB 设备插入 hub 的瞬间就执行了这么一个复杂的过程,在每一个环节引出了我们需要进一步掌握的知识点,静下心来,脑子里捋一下这个过程都发生了什么?瞬间又多长,取决于你对上面的理解。

       通过 life of USB device 这一部分主要是为了对 USB 设备的工作过程首先有一个感性的认识,同时引出相关的基础知识点,我们依然需要带着梦想上路。

家族的血统

       USB 家族的成功,绝非偶然。正如一个人的成功一样,除了机会还需要自身条件的过硬,需要平时对自己个人能力的积累。下面就介绍 USB 协议中的几个知识点,正因为有了他们,才成就了 USB 这座大厦,他们是每一个 USB 设备所具有的,正如家族的印记一样刻在了每一个 USB 设备的骨子里。

3.1 端点

简单理解就是数据传输的终点, Endpoint 。每一个设备都会有若干个端点,来负责不同类型的传输, USB 数据传输有 4 种:控制传输、批量传输、中断传输和同步传输。就像一个公司有不同的部门,人事部、技术部、财务部各有各的职责。从某种角度来说,一个 USB 设备是若干端点的集合。当 host USB 设备通讯时,是直接和端点打交道的,端点是才是外交的门户。既然端点是用来传输数据,那么他就有方向,有能够接受的最大数据长度。所以记住 3 点: 1 端点有类型 ( 控制、批量、中断及同步 ) 2 端点有方向 (in out) 3 端点有大小 (MaxPacketSize) 。任何一个设备都有一个用于通讯的默认端点 0

每个端点的信息都将在端点描述符中一一找到。

3.2 管道 (pipe)

数据传输需要两个实体的参与,所以引入了管道的概念,管道必然涉及到两端。当面我们提到的 Endpoint 就是管道的一端,那另一端呢?另一端是什么并不确定,因为不同的控制器设计的方式是不一样的,如果是 host EHCI 作为数据的另一端的话,那么管道的另一端就只能认为是 host 控制器了。如果 host 端是 mentor otg host ,那么管道的另一端同样是一个端点。其实管道这个概念我们在实际设计中基本涉及不到,更多的是为了描述数据在两个实体间流动的场景,是一种抽象的东西。数据从这一端流淌到另一端,就像流水一样总得有个管道吧,你关心过水龙头,关心过水管么?

抽象的东西,需要在以后的工作中去慢慢领会。

3.3 描述符

简单的说, USB 的描述符是一个特定格式的数据结构,描述了 USB 设备的各种属性还有相关信息等,我们可以通过向设备发送 setup 命令请求获得描述符的内容来了解这个 USB 设备。主要有四种 USB 描述符:设备描述符、配置描述符、接口描述符和端点描述符,协议里规定一个 USB 设备是必须支持这四大描述符的,这四大描述符是一个都不能少的,设备工作所必须的,共性之外依然有各自的特性,如 hub 有自己的 hub 描述符,每一种特殊的设备都会有自己的描述符。设备大多有字符串描述符,不过即使没有也不会影响设备工作,字符串描述符并不是一无是处,他记录了厂家的信息,产品 id 等。

这些描述符放哪儿?当然是在 USB 设备里,等着 host 来取,描述符是 USB 设备提供给 host 了解自己的窗口。

好,抽象和具体必须结合才能产生不错的效果。我们对 4 个重要的描述符一一介绍一下。

 

a) 设备描述符

设备描述符给出了USB设备的一般信息,一个USB设备只能有一个设备描述符。所有的USB设备都有缺省控制通道。在设备描述符中指出了端点0的最大包长度、厂商信息和产品信息等。bNumberConfigurations是该设备支持的配置数。

 

 

Offset

Field

Size

Value

Description

bLength

1

描述符长度

此描述符的字节数

1

bDecriptorType

1

常量

设备描述符的标识

2

bcdUSB

2

BCD

USB 设备说明版本号( BCD 码)

4

bDeviceClass

1

设备类

类码

如果该值为 0 表示有 每个配置下每个接口指出它自己的类,并个接口各自独立工作。

如果值处于 1~FEH 之间,则设备在不同的接口上支持不同的类。并这些接口可能不能独立工作。此值指出了这些接口集体的类定义。

如果此域设为 FFH ,则此设备的类由厂商定义。

5

bDeviceSubClass

1

设备子类

子类码

这些码值的具体含义根据 bDeviceClass 域来看。

bDeviceClass 域为零,此域也须为零。

bDeviceClass 域为 FFH ,此域的所有值保留。

6

bDevicePortocol

1

协议

协议码

这些码的值视 bDeviceClass

bDeviceSubClass 的值而定。

如果设备支持设备基础上的类相关的协议,此码标志了设备类说明上的值。

如果此域的值为零,则此设备不在设备基础上支持设备类相关的协议。然而,它可能在接口基础上支持设备类相关的协议。

如果此域的值为 FFH ,此设备使用厂商定义的协议。

7

bMaxPacketSize0

1

长度

端点 0 的最大包大小(仅 8,16,32,64 为合法值)

8

idVendor

1

ID

厂商标志(由 USB 标准付值)

10

idProduct

1

ID

产品标志(由厂商付值)

12

bcdDevice

2

BCD

设备发行号( BCD 码)

14

iManufacturer

1

索引

描述厂商信息的字串的索引

15

iProduct

1

索引

描述产品信息的字串的索引。

16

iSerialNumber

1

索引

描述设备序列号信息的字串的索引。

17

bNumConfigurations

1

数字

可能的设置数

 

 

 

 

b) 配置描述符

 

一个USB设备有一个或多个配置,每个配置做着不同的事情。每个配置有一个或多个接口。而每个接口又有1个或多个端点。在一个配置下,一个端点不能被几个接口使用,除非该端点被该接口的可选设置使用。在不同的配置中端点没有限制。对USB设备选完配置后,设备可支持对配置的有限调整,如果一个接口有备选设置,在配置好后可选择不同设置。

 

 

Offset

Field

Size

Value

Description

bLength

1

描述符长度

此描述符的字节数

1

bDecriptorType

1

常量

配置描述符的标识

2

WTotalLength

2

数目

此配置信息的总长(包括配置,接口,端点和设备类及厂商定义的描述表)

4

bNumInterfaces

1

数目

该配置所支持的接口个数

5

bCongfigurationValue

1

数目

SetConfiguration ()请求中用作参数来选定此配置。

6

iConfiguration

1

索引

描述此配置的字串描述表索引

7

bmAttributes

1

位图

配置特性:

D7 : 保留(设为一)

D6 : 自给电源

D5 : 远程唤醒

D4..0 :保留(设为一)

一个既用总线电源又有自给电源的设备会在 MaxPower 域指出需要从总线取的电量。并设置 D6 1 。运行时期的实际电源模式可由 GetStatus(DEVICE) 请求得到

8

MaxPower

1

mA

在此配置下的总线电源耗费量。以 2mA 为一个单位。

 

 

c) 接口描述符

接口描述符不能单独获取,只能在获取配置描述符时获得。如果一个配置支持不止一个接口,端节的描述符会跟在接口描述符后被返回,接口描述符跟在配置描述符的后面返回。接口描述不可直接用Set Description ( )和Get Descriptor ( )操作。

有时某个接口有可选设置,设备在进行了配置的情况下可以更改为接口的可选设置。SetInterface ( )与GetInterface ( )用来选择与返回选择了的接口设置。

如果一个设备的配置为一个接口,该接口有两个可选设置,当获取配置描述符时,返回配置描述符以后会紧跟着返回bInterfaceNumber与bAlternateSetting域皆为0的第一个设置的接口描述表及相关的端点描述符,然后是另一个设置接口描述符与端点描述符。第二个接口描述符的bInterfaceNumber域也应为0,但bAlternateSetting域应为1。因为是同一接口的不同设置,所以bInterfaceNumber是一样的。

每个接口代表着一种功能。你的手机是做 U 盘,还是做摄像头。这就是配置。当作为 U 盘时可能一个接口就够了。摄像头时可能需要几个接口,有音频还得有视频,而设置呢,比如音量可大可小,这应该就是设置吧。

接口描述符中的端点个数不包括端点 0

 

Offset

Field

Size

Value

Description

bLength

1

描述符长度

此描述符的字节数

1

bDecriptorType

1

常量

接口描述符的标识

2

bInterfaceNumber

1

数目

当前配置支持的接口数组索引,0开始。

3

bAlternateSetting

1

数目

可选设置的索引值

4

bNumEndpoints

1

数目

接口使用的端点数目。0代表只使用控制传输

5

bInterfaceClass

1

索引

类值零值为将来的标准保留。如果此域的值设为 FFH ,则此接口类由厂商说明。所有其它的值由 USB 说明保留

6

bInterfaceSubClass

1

子类

子类码

这些值的定义视 bInterfaceClass 域而

定。如果 bInterfaceClass 域的值为零则

此域的值必须为零。 bInterfaceClass

不为 FFH 则所有值由 USB 所保留

7

bInterfaceProtocol

1

协议

协议码: bInterfaceClass

bInterfaceSubClass 域的值而定 . 如果

一个接口支持设备类相关的请求此域的值指出了设备类说明中所定义的协议

8

iInterface

1

索引

描述此接口的字符串描述表的索引值

 

 

d) 端点描述符

       每个接口有若干个端点。端点描述符信息中包含端点号、方向、端点类型等。

 

Offset

Field

Size

Value

Description

bLength

1

描述符长度

此描述符的字节数

1

bDecriptorType

1

常量

端点描述符的标识

2

bEndpointAddress

1

端点

此描述表所描述的端点的地址。此地址的编码如下:

Bit 3..0 : 端点号 .Bit 6..4 : 保留 , 为零

Bit 7: 方向 , 如果控制端点则略。 (0 :出端点 1 :入端点 )

3

bmAttributes

1

位图

此域的值描述的是在 bConfigurationValue 域所指的配置下端点的特性。

Bit 1..0 : 传送类型 (00= 控制传送 01= 同步传送 10= 批传送 11= 中断传送 ) 所有其它的位都保留

4

wMaxPacketSize

2

数字

当前配置下此端点能够接收或发送的最大数据包的大小。对与同步传送此值用于为每幀的数据净负荷预留时间。而通道可能在实际运行时不需要预留的带宽。实际带宽可由设备通过一种非 USB 定义的机制汇报给主机 . 对于中断传送 , 批传送 , 控制传送 . 端点可能发送较小的数据包。并且在结束传送后既有可能间隙时间来重启,也有可能不需要这段时间

6

bInterval

1

数字

轮寻数据传送端点的时间间隙。此域的值对于批传送的端点及控制传送的端点忽略。对于同步传送的端点此域必需为 1 。对于中断传送的端点此域值的范围为 1 255

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值