TA的每日心情 | 开心 2023-6-1 15:13 |
---|
签到天数: 1 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
USB的重要关键字:
- V' r) Z, }) t4 w9 C, I: D5 E1、端点:位于USB设备或主机上的一个数据缓冲区,用来存放和发送USB的各种数据,每一个端点都有惟一的确定地址,有不同的传输特性(如输入端点、输出端点、配置端点、批量传输端点)( ~% U( z6 b- I; l. K; W( _/ | Y
4 {) M9 c6 s* G9 K3 \0 k9 u- {8 p) G5 M4 f5 V' L
- B6 w- @; V8 h' Z2 t2、帧:时间概念,在USB中,一帧就是1MS,它是一个独立的单元,包含了一系列总线动作,USB将1帧分为好几份,每一份中是一个USB的传输动作。$ H3 ^6 H! n6 Q1 D+ @+ U; L9 l+ @, Q
; N. J* C1 x& W4 b- l' i5 a$ k( d# ~: }' A* n F! B% u. w$ c# R& _
3、上行、下行:设备到主机为上行,主机到设备为下行
$ |; j5 f6 n) i3 O% x5 ?+ n
- C# R7 H# }, ^" H' x
4 r% C' T4 z/ W+ a, {7 r下面以一问一答的形式开始学习吧。2 F, R9 P1 X- v* T
问题一:USB的传输线结构是如何的呢?3 d# V* i3 X. S: H. v' ~
. z; ]& `4 Z% g3 z答案一:一条USB的传输线分别由地线、电源线、D+、D-四条线构成,D+和D-是差分输入线,它使用的是3.3V的电压(注意哦,与CMOS的5V电平不同),而电源线和地线可向设备提供5V电压,最大电流为500MA(可以在编程中设置的,至于硬件的实现机制,就不要管它了)。- n0 a( B" m6 }' c* D( B, e5 O
' C2 ~. c5 W4 X' l+ \* A# K7 J$ A" \6 l- ?2 @; r
$ Z+ {7 G, e: A- Q- w1 Z9 g* G9 {5 \0 i; m9 z
问题二:数据是如何在USB传输线里面传送的8 r0 V& t3 L& w2 s
7 G) M, y: M c8 v( I答案二:数据在USB线里传送是由低位到高位发送的。 H5 S+ g$ {: C( j
6 o! ]0 B* a) G& u* l
' I* j9 H" U& S) S3 n( Y1 [ S+ M) m6 s, r- `. A. N: J8 A% H1 j3 w4 d/ s) s
问题三:USB的编码方案?4 X7 [% s7 H; _8 |/ c5 j9 o% |5 J) n3 J+ `7 z
答案三:USB采用不归零取反来传输数据,当传输线上的差分数据输入0时就取反,输入1时就保持原值,为了确保信号发送的准确性,当在USB总线上发送一个包时,传输设备就要进行位插入***作(即在数据流中每连续6个1后就插入一个0),从而强迫NRZI码发生变化。这个了解就行了,这些是由专门硬件处理的。7 h, w, x- O. E' w0 \
+ Q y! w! x3 q# \! n) B. A) R& x9 {/ ~2 z, N! j! ~' t
. U( o; _% V- x' M问题四:USB的数据格式是怎么样的呢?
0 ]0 A6 f0 b P# l) H1 ]$ S答案四:和其他的一样,USB数据是由二进制数字串构成的,首先数字串构成域(有七种),域再构成包,包再构成事务(IN、OUT、SETUP),事务最后构成传输(中断传输、并行传输、批量传输和控制传输)。下面简单介绍一下域、包、事务、传输,请注意他们之间的关系。# k. V- F* a' E0 l. q
2 u F( w9 z/ P) x4 F$ I
5 O( p) q. M b3 C6 Y$ {/ A" D3 v4 R* H) H: ~' @
(一)2 B4 [4 C+ k9 y* e4 N9 J! d* I6 G+ ~
域:是USB数据最小的单位,由若干位组成(至于是多少位由具体的域决定),域可分为七个类型:6 Y9 m8 w( w' e- @; E4 I$ Q6 A3 O9 @2 c7 K* C3 F( G* h
1、同步域(SYNC),八位,值固定为0000 0001,用于本地时钟与输入同步% e# i( A0 `3 ]) ^$ o
6 t* x; {/ _3 E! i( {: s% k# J d* _' I# r
8 G$ s8 d/ f4 W: o$ F2、标识域(PID),由四位标识符+四位标识符反码构成,表明包的类型和格式,这是一个很重要的部分,这里可以计算出,USB的标识码有16种,具体分类请看问题五。/ h0 s3 n( m8 |; O n
5 Y3 ?! Q' v: X8 T3 G) u) P- d ~4 E( ?& \' Y+ L7 i4 M- @
- m5 L; f% `4 ?3、地址域(ADDR):七位地址,代表了设备在主机上的地址,地址000 0000被命名为零地址,是任何一个设备第一次连接到主机时,在被主机配置、枚举前的默认地址,由此可以知道为什么一个USB主机只能接127个设备的原因。6 o8 V, M$ _. ]8 J+ r7 S6 P: I1 X
4 M9 S$ S) |* S N }6 G
; ~ a# h& {* n4、端点域(ENDP),四位,由此可知一个USB设备有的端点数量最大为16个。7 V, k4 y: T% _" v% q i P5 F( I
' t% Q& d1 H. i% f3 F) p$ G1 _2 W1 S% B# @; i% F; O& v. }
; q; a3 N, \0 K( Y4 {1 {
5、帧号域(FRAM),11位,每一个帧都有一个特定的帧号,帧号域最大容量0x800,对于同步传输有重要意义(同步传输为四种传输类型之一,请看下面)。
) k6 M3 m: I0 U3 H- @9 h" i. @$ u8 R- T$ e" t% {" @4 L- o! f: U. t: \+ U* A
, X) _, j( m9 E6 _3 l
6、数据域(DATA):长度为0~1023字节,在不同的传输类型中,数据域的长度各不相同,但必须为整数个字节的长度7 m9 g. h! ?- L
7 s+ Y3 E5 ^/ r* _& k6 h' h, J7 q% u
- b6 F5 y2 M1 |% _, U+ P4 k' `4 ^
1 M0 z& P, m1 p4 g# d) u+ W3 I7、校验域(CRC):对令牌包和数据包(对于包的分类请看下面)中非PID域进行校验的一种方法,CRC校验在通讯中应用很泛,是一种很好的校验方法,至于具体的校验方法这里就不多说,请查阅相关资料,只须注意CRC码的除法是模2运算,不同于10进制中的除法。
B5 A$ ]# w/ E- C2 ~: f$ a: K4 U: B o- K" l8 B
* U/ d# P( K: m& R7 x5 |3 Q+ l, `) a" g, T
(二)2 f4 _6 G: {1 U$ {1 @1 {5 B2 J, {" ^
包:由域构成的包有四种类型,分别是令牌包、数据包、握手包和特殊包,前面三种是重要的包,不同的包的域结构不同,介绍如下" Z+ p9 ^; F0 J1 p1 ?% R% d2 A
3 v/ c4 c4 ^4 |5 Z$ }6 c7 j. W. H) w
' M! ?; ?( l o7 h& x" g/ ?5 L5 n( ?0 D# {& \
3 M. j. y% o6 J2 v5 S( r1、令牌包:可分为输入包、输出包、设置包和帧起始包(注意这里的输入包是用于设置输入命令的,输出包是用来设置输出命令的,而不是放据数的)/ D2 U. t/ C/ \6 f# D! i. e/ d0 r5 B2 c; |- H& @8 J7 {
其中输入包、输出包和设置包的格式都是一样的:- A8 j6 J/ u/ c4 r C
: {, Z+ v1 p( p; s+ @" O8 {* ~2 VSYNC+PID+ADDR+ENDP+CRC5(五位的校验码) % i$ L9 t6 o3 K, M* C! z; d& c: G
4 V1 D. u" i3 c3 c0 T9 a$ O$ ^6 Z) Y(上面的缩写解释请看上面域的介绍,PID码的具体定义请看问题五)
6 D$ [0 {; y" X+ ^5 Z帧起始包的格式:
" ~. d" E, F. _5 g6 U0 O8 _% iSYNC+PID+11位FRAM+CRC5(五位的校验码)/ W% A# A" U8 \2 n
, d8 p" s0 k: `
1 F% o; b# Q D; H
7 f# E) ]! P+ R% C2、数据包:分为DATA0包和DATA1包,当USB发送数据的时候,当一次发送的数据长度大于相应端点的容量时,就需要把数据包分为好几个包,分批发送,DATA0包和DATA1包交替发送,即如果第一个数据包是DATA0,那第二个数据包就是DATA1。但也有例外情况,在同步传输中(四类传输类型中之一),所有的数据包都是为DATA0,格式如下:* q; F5 X; E% g; ~1 ^# B- z6 f! o! w; M8 u3 T! X7 F
SYNC+PID+0~1023字节+CRC16% u* P0 _0 a( K* u8 V
3 u, c' {3 \) I( o# m1 N8 E- K5 ?+ l& f' M: s4 g5 \
# d9 |" v, c5 ]! W2 \: q4 K7 K7 n$ L* Q
3、握手包:结构最为简单的包,格式如下0 Z# L9 ~- _ [: K' c. u+ X d0 A7 z, X. u3 i- }7 i
SYNC+PID- v8 _- u$ X2 j/ D* a/ N) J' ?" O9 W$ E+ H( x3 R) Z* ^
(注上面每种包都有不同类型的,USB1.1共定义了十种包,具体请见问题五)" j) K! D$ p- C: V; w
' [/ T. P4 X: Y2 g! Y6 R% Q `& a+ U% o2 t2 m' Y/ K$ ~' B, W: I9 P7 W
+ F! \; R9 m; x
(三)
* V9 L- L6 `7 z事务:分别有IN事务、OUT事务和SETUP事务三大事务,每一种事务都由令牌包、数据包、握手包三个阶段构成,这里用阶段的意思是因为这些包的发送是有一定的时间先后顺序的,事务的三个阶段如下:4 R) v0 w/ b7 L1 D6 ]
" b1 b; J t- O2 O) T
f; @2 U4 I! f) a1、令牌包阶段:启动一个输入、输出或设置的事务7 E' r- B! O; v! M- M0 O' R! r+ n
4 ~; R4 Y9 c# i4 b; z- z8 @( v9 e0 F1 J2 n9 t/ Q( W5 o, ]1 X _
6 q6 M- S' R; e7 S7 O
8 W7 g& R' k9 [) V2、数据包阶段:按输入、输出发送相应的数据
! q. u: V) s7 ?" y$ @7 {# U4 n, k( [! T
3 F, s5 i& H# V9 ?* b* H/ s& t; b( B2 X8 r+ C
5 z" W8 q* P9 F# ^! C3、握手包阶段:返回数据接收情况,在同步传输的IN和OUT事务中没有这个阶段,这是比较特殊的。6 O5 R- U3 [/ p1 q$ d# F3 A
/ F y7 ]) n% {# i1 k3 e( P5 ^
0 S; R, Y) y& m% w! y5 Y$ r! p) i5 G! G9 X0 k* [. t# r2 _! |9 ~. F3 p0 I/ V9 p
事务的三种类型如下(以下按三个阶段来说明一个事务):2 K$ }+ i' J: L5 S& I* w1 z' r+ O4 U' R3 ]4 l( ~
/ i3 L$ L1 K2 K$ v( d8 A. i# p+ b7 B8 w5 d
3 c( \. H: i! ~: x* h! [2 h) O
4 H3 J, s* {- @1、 IN事务:
7 o( D+ Y: V/ O+ I8 W, G% z7 F) ]+ J令牌包阶段——主机发送一个PID为IN的输入包给设备,通知设备要往主机发送数据;" x" ~. X, q# M. H& M4 L: J& w: B; V
1 w) G0 b# L0 \- X# }) _
( A, l; l$ l9 p: x' C' \; F+ d. E8 @: k H7 z/ n
数据包阶段——设备根据情况会作出三种反应(要注意:数据包阶段也不总是传送数据的,根据传输情况还会提前进入握手包阶段)3 [4 t1 d* y8 q. z: D- ~ L, u5 n/ _2 @- J) w9 a
) N$ R, ]5 Y% n. `4 [% v6 M1 l6 n. h5 Y; b! S2 i; s5 a1 E
+ z! ~3 w) ^; ^0 C0 V7 K! x
3 G2 Y, p( E4 b( y$ r# g, C. y# O' U' b1) 设备端点正常,设备往入主机里面发出数据包(DATA0与DATA1交替);
: T- |0 n3 V* V; z. q1 e1 k8 ~7 V- ` D O( {1 M( z4 U% @1 Q# S2 r& }& a
2 M! X* U$ ~+ k8 H) L3 ?9 n/ E) r2 `
2) 设备正在忙,无法往主机发出数据包就发送NAK无效包,IN事务提前结束,到了下一个IN事务才继续;! C9 ^5 z% `4 T( b. B: }1 D# x0 ?- M g& `$ J8 _7 V
2 W" {! L* c" ]* p" X8 S a- y& N
5 e3 P o4 e! u6 T W9 ]
3) 相应设备端点被禁止,发送错误包STALL包,事务也就提前结束了,总线进入空闲状态。( [5 M& }6 J* t2 B$ O& C
! l/ d7 |- |/ X. X2 y- M; O9 A
( O) A7 y1 b9 V1 ~7 t9 E7 [4 Y3 M% V5 J1 L! e- l' K
6 T2 Y( O1 Q; \' H, R& Q握手包阶段——主机正确接收到数据之后就会向设备发送ACK包。! i( x2 k% X4 {' N2 ]0 K, A( {; ?
& m' v% P3 y4 r5 j: R2 R+ r1 l! `3 N" y
2 N& o) h: m5 G/ }5 O# ?6 P) Z0 K
2、 OUT事务:: J4 p2 n$ j9 ]& u
令牌包阶段——主机发送一个PID为OUT的输出包给设备,通知设备要接收数据;" ^0 N/ u% j$ I+ m \, S$ o
, H7 w2 f0 x4 n! p1 v/ M- u4 m [6 Q5 L
8 f0 ~- j9 T# [; X) m9 Z( _数据包阶段——比较简单,就是主机会设备送数据,DATA0与DATA1交替 m- i) ?9 b3 g: o- B9 y
8 S$ V* f7 S" c1 b2 w2 T+ u& _# r* h5 R
1 X# _1 K! ^. e9 Y0 x8 L- n- e0 c6 _8 L% q. {
握手包阶段——设备根据情况会作出三种反应
) g% @% q" x" F7 c* k8 R) H [- t# N- A) a; m7 b; f' Y: g+ ~9 i5 I* r0 x; ?( v& B
2 z/ F9 m& F( x1 {1 s( H' k3 o# x4 w# ~( W
1) 设备端点接收正确,设备往入主机返回ACK,通知主机可以发送新的数据,如果数据
" j# t" g* i- c0 K$ t& h* u5 }% W
' R4 T, {3 `4 H/ p7 L2 v0 r1 H. _0 a$ y: g0 @! k- Z
# a, q) Z4 }( O8 _2) 发生了CRC校验错误,将不返回任何握手信息;5 Q5 J0 R# l) [* D# R
- g, L# A r) e. S1 p2 \" ~/ N, `1 |4 z3 g$ Z) M& p* _" v1 q- Z8 j9 K+ W
2) 设备正在忙,无法往主机发出数据包就发送NAK无效包,通知主机再次发送数据;* X- \% T0 p, V, l2 X8 X) V8 N& X. |0 ~; s5 x8 s
# A1 `5 U( W" Q% k: ]0 I' u3 x- m6 l% M4 y& J# p
% [6 T. g6 i3 B0 G- @2 ]
3) 相应设备端点被禁止,发送错误包STALL包,事务提前结束,总线直接进入空闲状态。. |+ Q. V, U! ]# m) J8 S
. }& g5 u v% _4 p) F
- C4 M7 t3 H( W5 y' m8 M
3、SETUT事务:
/ D, t/ I, Y5 ^! H' d @9 j7 k7 j( r: \* `! I/ J2 p- I- A
' L% W$ [3 k0 `* B# l
6 c/ g. g0 G/ ]; y. r% I令牌包阶段——主机发送一个PID为SETUP的输出包给设备,通知设备要接收数据;
0 n- F( @4 I: Z9 J, |& n* a+ V7 E0 a1 g* _3 e) J: M. b8 l% d0 @
% B% r5 h, m7 n* [ S V0 z; q
数据包阶段——比较简单,就是主机会设备送数据,注意,这里只有一个固定为8个字节的DATA0包,这8个字节的内容就是标准的USB设备请求命令(共有11条,具体请看问题七)9 G, i- ?/ d! ]8 Q
: A, ]! ^3 ^4 L5 S+ T/ o9 \1 t
' i- t3 H& _$ U }. l" w* g4 o, G# S' j6 S- J" z/ _
握手包阶段——设备接收到主机的命令信息后,返回ACK,此后总线进入空闲状态,并准备下一个传输(在SETUP事务后通常是一个IN或OUT事务构成的传输)$ X# Z8 e# d8 W3 I3 m; z' v6 Y
& k( Z; A- Y) W+ f4 U- n& v% V0 _5 a4 f f
0 j7 k. ?8 s& _1 |9 Y, }7 b9 Y: c1 j5 j
* _6 [' }- q' Z+ a/ f1 x2 v0 [(四)
( u% q8 Y; z+ z/ m# k p9 P传输:传输由OUT、IN、SETUP事务其中的事务构成,传输有四种类型,中断传输、批量传输、同步传输、控制传输,其中中断传输和批量转输的结构一样,同步传输有最简单的结构,而控制传输是最重要的也是最复杂的传输。 i1 ?7 ~: Z& E2 d- U
" [) Z0 d5 p4 n8 q7 d/ E1 }3 C. i' C! W+ S: N
' s4 ^. S, w* F' n2 C2 P% [1、中断传输:由OUT事务和IN事务构成,用于键盘、鼠标等HID设备的数据传输中
4 W P* Z4 i, H' X- ~8 e( w, X6 g m. v3 ^% u( A2 Q1 @3 g
6 Q# z- u3 t, A& ]; R# ^: O% E3 p6 z& v9 B9 ~) U9 ]0 l" \* [
2、批量传输:由OUT事务和IN事务构成,用于大容量数据传输,没有固定的传输速率,也不占用带宽,当总线忙时,USB会优先进行其他类型的数据传输,而暂时停止批量转输。
, u# u" Y9 @7 w/ f0 M7 P0 H+ U2 \$ U, {; @( f% P2 f5 [% D( W1 T
' p. ]! H; \$ p3、同步传输:由OUT事务和IN事务构成,有两个特殊地方,第一,在同步传输的IN和OUT事务中是没有返回包阶段的;第二,在数据包阶段所有的数据包都为DATA0$ y. q8 U$ b# M) W7 h0 E3 X4 k8 Q# \; e7 U. S
) P) X6 P2 d' V9 A
2 t2 k0 t. ~# ^+ V1 d" U0 F3 @) x7 E( H1 q: f, ~% m' k5 D: l3 ^
4、控制传输:最重要的也是最复杂的传输,控制传输由三个阶段构成(初始设置阶段、可选数据阶段、状态信息步骤),每一个阶段可以看成一个的传输,也就是说控制传输其实是由三个传输构成的,用来于USB设备初次加接到主机之后,主机通过控制传输来交换信息,设备地址和读取设备的描述符,使得主机识别设备,并安装相应的驱动程序,这是每一个USB开发者都要关心的问题。
, n0 l3 [2 B5 b- O( @
( |4 X R2 U, d& p
. e1 M! w/ k+ I1、初始设置步骤:就是一个由SET事务构成的传输/ a) K8 M, P- E" o2 r
; e# X g5 P+ A; D! P! ^0 c1 F
/ ?8 N% ~( y, z# g% ^3 W) l- y4 B' w; Q) f1 _* b/ O4 p3 ?+ \6 ^) r1 c
2、可选数据步骤:就是一个由IN或OUT事务构成的传输,这个步骤是可选的,要看初始设置步骤有没有要求读/写数据(由SET事务的数据包阶段发送的标准请求命令决定)
! J; K5 e/ s0 O! o! j0 ^
. J7 h% P1 R/ r8 J
* \4 }! f! @( O Z1 L5 A2 q3、 状态信息步骤:顾名思义,这个步骤就是要获取状态信息,由IN或OUT事务构成构成的传输,但是要注意这里的IN和OUT事务和之前的INT和OUT事务有两点不同:) ]; e2 m$ j. F: \
$ P" `9 O+ D2 t4 q# l- ^: v0 ?7 d3 ?+ G. k6 }' u1 ~1 w; `% d6 L
4 t3 Q8 M! B! c3 {& Q" T. x: \5 u$ |1) 传输方向相反,通常IN表示设备往主机送数据,OUT表示主机往设备送数据;在这里,IN表示主机往设备送数据,而OUT表示设备往主机送数据,这是为了和可选数据步骤相结合;8 p& ?9 |3 O$ `4 T% f
! ]( V: W6 j: `7 l% j6 Y( l# V* W
8 P- ]5 Z! [5 N9 w7 \% L: P% d% ?: w: V, B1 T0 c8 ^( Z% t4 g% A6 S5 n1 _( R' ], M% y
2) 在这个步骤里,数据包阶段的数据包都是0长度的,即SYNC+PID+CRC16; ^: N" u* o: S' o! Q! E$ v+ } e y) U6 B
, m/ V8 L. G. m& y2 e
4 _; ]% U, a& q. ]2 {8 E
" r$ W) D8 h" W3 S0 D& M1 ?; [除了以上两点有区别外,其他的一样,这里就不多说
# |5 X4 w* k# i# m( h, N0 |(思考:这些传输模式在实际***作中应如何通过什么方式去设置?)
: s! I2 J/ y' p ]& {# G' N+ z& _$ {( z3 A/ S$ i
: T# v+ H) R+ g2 M# h$ a6 G! X* f& Q问题五:标识码有哪些?0 {& n7 z j; o: k- b8 [
答案五:如同前面所说的标识码由四位数据组成,因此可以表示十六种标识码,在USB1.1规范里面,只用了十种标识码,USB2.0使用了十六种标识码,标识码的作用是用来说明包的属性的,标识码是和包联系在一起的,首先简单介绍一下数据包的类型,数据包分为令牌包、数据、握手包和特殊包四种(具体分类请看问题七),标识码分别有以下十六种:& r# k" Q. t: m3 ]3 D
' s( p6 o. O) Z6 W) l' n/ k, D: C5 U. k
1 u9 Z0 n f) {7 }! _令牌包 :8 x5 J/ J* k0 v2 V+ l6 B% l8 v9 ] s, p
0x01 输出(OUT)启动一个方向为主机到设备的传输,并包含了设备地址和标号3 g/ v+ z U! P E/ C5 ^- |
0x09 输入 (IN) 启动一个方向为设备到主机的传输,并包含了设备地址和标号
$ o- E1 B0 @6 D! ]" {0x05 帧起始(SOF)表示一个帧的开始,并且包含了相应的帧号) Z- S0 O" H& ?9 }% x+ `1 v: g- F8 H# i7 y
0x0d 设置(SETUP)启动一个控制传输,用于主机对设备的初始化
6 K0 p) A( N" f7 F, K$ A4 Z$ R' @2 k+ T$ N! P
' f1 m: F8 ^9 ]4 G: E% w: Q
% F9 L! D8 \$ P3 w; y0 d* U: ?数据包 :. e/ U) ^( q- H
1 s# w1 B& F3 N* |, S0x03 偶数据包(DATA0),
2 ]0 R% ~3 b# r( _* m) A0x0b 奇数据包(DATA1)
0 Y9 S0 r, @: x/ O' j- n7 y- p1 _& a" _
2 N5 M: i6 G! i2 E% B, e$ S
$ B9 _, ?: D8 N& V" e7 B握手包:: |1 U7 q5 e" J# d' d3 s" J! E$ C' i- n6 O% z
0x02 确认接收到无误的数据包(ACK)
3 l m8 n: _5 N* v0x0a 无效,接收(发送)端正在忙而无法接收(发送)信息
. E2 ~# ~. L* j) a C9 f0x0e 错误,端点被禁止或不支持控制管道请求- Q+ q3 a) g+ V
9 i) {: T$ ~4 r- F& y* {0 T6 K y特殊包 0x0C 前导,用于启动下行端口的低速设备的数据传输
, \ @, X! g0 s# C* P* e, O/ `* h- n& m/ I
问题六:USB主机是如何识别USB设备的?& z8 ~" C: Q# p, b" R: d
答案六:当USB设备插上主机时,主机就通过一系列的动作来对设备进行枚举配置(配置是属于枚举的一个态,态表示暂时的状态),这这些态如下:6 u3 I( `4 k5 I4 d3 J$ k. Y
, t& W2 S% Q. V0 ^ 0 o& o' W0 h" H+ f3 O9 e
+ E6 }# V: l* `% j; r1、接入态(Attached):设备接入主机后,主机通过检测信号线上的电平变化来发现设备的接入;1 \: k4 m) N% j- l$ L% L: h4 t# C
( I5 u1 s0 c' n2 t' z& n5 W
2、供电态(Powered):就是给设备供电,分为设备接入时的默认供电值,配置阶段后的供电值(按数据中要求的最大值,可通过编程设置)4 s# F" j" z. I( k l9 _- R: l6 G+ L+ F& K
6 `: N) f% ~% Q# n7 n; }. U1 a
/ {( ], {4 U9 N) v' |3、缺省态(Default):USB在被配置之前,通过缺省地址0与主机进行通信;
7 k: G) t+ p" l2 c; Y + w" h6 v1 p& }; |5 m! `( D( u. c7 P& O
4、地址态(Address):经过了配置,USB设备被复位后,就可以按主机分配给它的唯一地址来与主机通信,这种状态就是地址态;, k0 A2 }- B0 s7 y' v8 c; D5 y/ z3 U+ v1 }# U
+ ?1 M, P, f3 B% N$ \0 E- `0 g) B3 W% J# k7 ]. c' I
( u# ?7 l, m6 x5 B4 u# H8 C: ]5 p( `6 E5 A1 y _+ B
5、配置态(Configured):通过各种标准的USB请求命令来获取设备的各种信息,并对设备的某此信息进行改变或设置。+ |0 k1 Y) i: J4 ?3 e+ l5 f9 j/ r8 ?
: k3 ^6 W- ]3 r/ {" M7 t( r' R2 O1 Z; ~' s' K. }$ ]" q
- @: x8 G0 X) s, z' `- N) H. X' A8 v' V- ^+ @4 g+ d4 p ~8 B$ |& H8 Z: T, J @/ V0 Q3 [# s" E: q
6、挂起态(Suspended):总线供电设备在3ms内没有总线***作,即USB总线处于空闲状态的话,该设备就要自动进入挂起状态,在进入挂起状态后,总的电流功耗不超过280UA。
: R3 w% E* \% i2 ]3 }" D \ ~) D2 s& d" u% j% p4 |
0 u1 N" B3 E/ {" h- |* T
问题七:刚才在答案四提到的标准的USB设备请求命令究竟是什么?
& T- Y1 w0 C, a答案七:标准的USB设备请求命令是用在控制传输中的“初始设置步骤”里的数据包阶段(即DATA0,由八个字节构成),请看回问答四的内容。标准USB设备请求命令共有11个, 大小都是8个字节,具有相同的结构,由5个字段构成(字段是标准请求命令的数据部分),结构如下(括号中的数字表示字节数,首字母bm,b,w分别表示位图、字节,双字节):
4 z! ` A$ P9 m6 z( B1 _$ p* r6 E. p0 W
: n1 V$ u$ Y) Q
8 \7 {% c+ C0 I( RbmRequestType(1)+bRequest(1)+wvalue(2)+wIndex(2)+wLength(2)+ u' Q! L7 }7 G, s% R+ @2 b& K7 y' R* K u) k% {1 n
各字段的意义如下:9 Y9 \6 R3 w! N) i9 n
. m) K% O0 O) i' x( i Y& ^/ y
2 \ R1 h6 b) ?
( m6 k! Y0 [9 J1 F3 A! H: P; y1、bmRequestType:D7D6D5D4D3D2D1D0
& e4 \, X C! [; o7 `; {D7=0主机到设备, G# ]" F- C- i$ M5 X6 b: G7 ` k3 l; O7 P! y3 s
=1设备到主机;* a2 U' ]3 g. w% ~3 g* J0 b1 x+ J* |% H$ @3 |) e: u0 r) q9 m
D6D5=00标准请求命令- V: U, g3 ~6 Y5 I7 n; e
4 R, j" R$ g7 X, {3 v =01 类请求命令: |: Y: \* T/ O, ~% t6 c
. E9 e! M( X/ S. s9 C9 }4 ^/ i =10用户定义的命令 ! z: W) M6 H/ z1 |/ D/ N7 k* H7 }, T% Z7 F+ L
=11保留值! s/ u* @, K' m/ K
* E7 \8 u! Y7 r7 y- H$ T1 cD4D3D2D1D0=00000 接收者为设备0 {5 ^4 |# {1 J0 D6 H
* s8 ? G3 A$ x" | =00001 接收者为设备
0 k. H+ ]; g4 Y { =00010 接收者为端点2 g* E4 q( M: v( [2 e
) A, Y1 i) u/ B =00011 接收者为其他接收者
; E, {7 U) H1 j- L" | =其他 其他值保留
3 K' P v, }, B! l: @3 ~9 ?/ p0 d6 P% f1 l8 `6 i# c2 B% j
4 \9 V H8 q( f: s; Q- ^6 r, ^% z) x' v' T& ]: I- m# F0 ^, a" }6 J }$ Q& W
2、bRequest:请求命令代码,在标准的USB命令中,每一个命令都定义了编号,编号的值就为字段的值,编号与命令名称如下(要注意这里的命令代码要与其他字段结合使用,可以说命令代码是标准请求命令代码的核心,正是因为这些命令代码而决定了11个USB标准请求命令):8 R! j. I. F/ Y5 W3 t0 Q
0) 0 GET_STATUS:用来返回特定接收者的状态7 ~' h# W9 b J
1) 1 CLEAR_FEATURE:用来清除或禁止接收者的某些特性
! y; U% Z8 ?: y4 h0 t6 h+ Z! E5 e2) 3 SET_FEATURE:用来启用或激活命令接收者的某些特性" r0 `. d5 O) s2 B+ L
# V" ~+ f; E, `& v3) 5 SET_ADDRESS:用来给设备分配地址; {$ ]7 z/ e& R; L7 x3 u
9 ~6 L& p, a" Y: Q* \# P4) 6 GET_DEscriptOR:用于主机获取设备的特定描述符
* P" |4 R; A/ s5 z d, p" `2 f5) 7 SET_DEscriptOR:修改设备中有关的描述符,或者增加新的描述符6 h2 d+ J5 v. ]% }; Y
6) 8 GET_CONFIGURATION:用于主机获取设备当前设备的配置值(注同上面的不同) 3 S( Q2 m, \3 k
7) 9 SET_CONFIGURATION:用于主机指示设备采用的要求的配置6 ^' _/ R6 Z! O6 n) ^* N# a e3 ~. n) }" L, ^* V" d8 i+ o1 s
8) 10 GET_INTERFACE:用于获取当前某个接口描述符编号" r* c& @% @! ~0 F6 t
' h. m j [7 f& Z J& W' M7 F& j/ z9) 11 SET_INTERFACE:用于主机要求设备用某个描述符来描述接口3 A6 @: B7 {7 A! _6 u1 S3 ^
10) 12 SYNCH_FRAME:用于设备设置和报告一个端点的同步帧
# ^& `9 D, d# O1 ]( U以上的11个命令要说得明白真的有一匹布那么长,请各位去看书吧,这里就不多说了,控制传输是USB的重心,而这11个命令是控制传输的重心,所以这11个命令是重中之重,这个搞明白了,USB就算是入门了。, ~/ a. g9 H; O: J: ^; Z
3 L- u1 D V8 F; r$ [! U2 e0 k9 o6 B) g3 s: n; }2 ^! |
问题八:在标准的USB请求命令中,经常会看到Descriptor,这是什么来的呢?
* R# L( P0 M x% f! b3 `. \
8 \+ d+ S+ ^$ w# ?' S) [回答八:Descriptor即描述符,是一个完整的数据结构,可以通过C语言等编程实现,并存储在USB设备中,用于描述一个USB设备的所有属性,USB主机是通过一系列命令来要求设备发送这些信息的。它的作用就是通过如问答节中的命令***作来给主机传递信息,从而让主机知道设备具有什么功能、属于哪一类设备、要占用多少带宽、使用哪类传输方式及数据量的大小,只有主机确定了这些信息之后,设备才能真正开始工作,所以描述符也是十分重要的部分,要好好掌握。标准的描述符有5种,USB为这些描述符定义了编号:0 Y$ L" b$ d) D1 J6 ^' p
1——设备描述符/ ^% I$ T* M% z) l
2——配置描述符/ u% j+ g( Y9 k2 @8 U5 ?' h5 m
' J9 e" E5 O. B$ v) Z$ H2 @3——字符描述符3 z. u9 j# F1 p9 {5 W* _
& }. [1 u* t% `4——接口描述符2 v3 s1 ]7 G& z4 L% z
- `' E( i3 m; |8 ~0 O( a5——端点描述符% m" B$ S. L5 U/ Y) L1 y7 Z2 E) w4 Z- B* H; H
( \$ J3 a7 C4 d" y' b! L' Q! M$ ?1 P+ C Q# _
上面的描述符之间有一定的关系,一个设备只有一个设备描述符,而一个设备描述符可以包含多个配置描述符,而一个配置描述符可以包含多个接口描述符,一个接口使用了几个端点,就有几个端点描述符。这间描述符是用一定的字段构成的,分别如下说明:
3 K* F w, V: M& V" J% w
% r( z$ v9 y' O* Y" t2 n1 F1 ?7 I, Q' F$ N; w z; l( Z6 M. s W% G0 S% B1 p- T
1、设备描述符: {8 _ l# R$ `4 I# x
: g& y. G8 n2 V( `$ ]" |5 @& f- Rstruct _DEVICE_DEscriptOR_STRUCT/ {' r3 [, B# u2 |
{
6 g' M4 N( ~) DBYTE bLength; //设备描述符的字节数大小,为0x12" I1 `! y: _& A1 b" i
BYTE bDescriptorType; //描述符类型编号,为0x018 h2 Q7 j1 r5 G, N) G
) s( c3 _: ?- [: K8 ^ WORD bcdUSB; //USB版本号
6 D0 W8 ~4 a- r' L0 d BYTE bDeviceClass; //USB分配的设备类代码,0x01~0xfe为标准设备类,0xff为厂商自定义类型, p( P1 |) Y& Q. I& ]+ M" E( m- |' w$ T0 X% v
//0x00不是在设备描述符中定义的,如HID# X h6 F/ A' u
* a! p# k9 S+ k BYTE bDeviceSubClass; //usb分配的子类代码,同上,值由USB规定和分配的
1 C6 `7 K1 F4 L- M; C3 K% PBYTE bDeviceProtocl; //USB分配的设备协议代码,同上 S1 A5 J" x3 I1 t9 ?; @2 I8 i; ^; b* d' ^% c( M# I' J- k* O
BYTE bMaxPacketSize0; //端点0的最大包的大小
7 \ t9 p5 D( V WORD idVendor; //厂商编号/ Q/ u2 ^! D1 d5 ]; b1 }$ m) m( E* s+ H) b' Y" d' c# c
WORD idProduct; //产品编号
6 t1 T' d6 N9 h0 ]: O WORD bcdDevice; //设备出厂编号% y) w2 V7 k/ ]2 G9 E5 ]9 o! X& a3 k9 J; I# G7 t' n8 W9 L
BYTE iManufacturer; //描述厂商字符串的索引6 _$ @. v r; s4 a9 m9 C6 r
BYTE iProduct; //描述产品字符串的索引5 E# F* H% D9 Y; N) M! k5 F: w% s4 w w, G B
BYTE iSerialNumber; //描述设备序列号字符串的索引- Y- D' s( r) U- |, X8 T
5 I0 u) T+ H" [2 V# u BYTE bNumConfiguration; //可能的配置数量
, ]) ^* K! E) ~6 J ^}
, n" d2 n. V) N6 G
! M( P4 T+ L* E8 i4 L: L) P: {3 _5 V) M5 q4 P% H k- t. I
; B4 s" f9 I' G2、配置描述符; r" D( g5 v4 Q) O1 u1 j1 A: l; _1 L5 b; M9 V$ K2 l
struct _CONFIGURATION_DEscriptOR_STRUCT. p2 V$ T: G4 d: B1 s r
{. M9 N0 M, n$ G- E
4 [' d4 Q P! ?9 LBYTE bLength; //设备描述符的字节数大小,为0x127 f0 P% `5 x5 d# L% z! y# M2 [% `% c/ U" J
BYTE bDescriptorType; //描述符类型编号,为0x01, {" C6 Z4 _6 [" A$ H: j2 p3 w \4 X
WORD wTotalLength; //配置所返回的所有数量的大小9 X5 t( Z8 ?$ ~+ {9 i- u0 O
. v1 m. ]" m1 \' n: ^BYTE bNumInterface; //此配置所支持的接口数量! H+ b3 E0 ?8 Z6 ~# O, r& `: Z! m& w. n
BYTE bConfigurationVale; //Set_Configuration命令需要的参数值9 n7 m8 {! j1 b7 c* C6 O
BYTE iConfiguration; //描述该配置的字符串的索引值
6 P1 k- H0 z. \0 ]+ l6 b t$ K" J BYTE bmAttribute; //供电模式的选择. S0 H3 D+ q2 x# u7 `0 S* _2 H/ I( ]$ p+ L+ w. k
BYTE MaxPower; //设备从总线提取的最大电流8 u; r, a) f4 V4 E8 v4 p* L( Q- |1 V* J) Q$ V2 ?
}+ T. I+ X8 |2 @( i( f1 E
, i4 T8 Y- q( J- ]9 E& l S8 ?, {# B3 p& w8 Q/ S
8 c9 Q( R; b3 v+ Y) x. O3 V1 A% g% o p0 q2 t8 f" z" }
3、字符描述符
* k, s7 c9 R) I& x3 bstruct _STRING_DEscriptOR_STRUCT
/ z- k5 \' J6 v. R: H5 y{3 f0 R( J+ f, D. e* U$ h/ w- j4 ]6 F: [" e
BYTE bLength; //设备描述符的字节数大小,为0x12
# k2 P& o7 r4 J& F2 X& H- sBYTE bDescriptorType; //描述符类型编号,为0x01
$ _0 Y# ^. m: s" ?BYTE SomeDescriptor[36]; //UNICODE编码的字符串3 ?1 X/ c7 Z# v
}) l2 n F. H, s- T) G: W- A. |
8 R; Z. D' h! m+ B1 ]/ \1 L
9 O# q. t& r$ D3 M5 L. ~4、接口描述符5 B6 `% W! {% f' k, |
struct _INTERFACE_DEscriptOR_STRUCT* s' i. g6 E2 C" a, U
% a' z4 n9 E/ q; _{
) z9 V0 z2 z- B+ V0 ^% YBYTE bLength; //设备描述符的字节数大小,为0x128 a4 f1 q$ P& z: \
BYTE bDescriptorType; //描述符类型编号,为0x01% A+ c9 _' ?% Y" m' i- r* L, Z
; O& A) K5 U( p" r5 zBYTE bInterfaceNunber; //接口的编号! g$ {4 }8 ~: k! K j
: L( l' Y+ N( aBYTE bAlternateSetting;//备用的接口描述符编号
, Y9 Z/ y" Z0 e* P5 {. w+ kBYTE bNumEndpoints; //该接口使用端点数,不包括端点0) I( p- d1 S! S: ]& q- L. u- \6 n4 k, l. l6 ?) z
BYTE bInterfaceClass; //接口类型
7 l( J9 z0 u1 p! D0 iBYTE bInterfaceSubClass;//接口子类型6 L+ [- b: L( K4 C5 x( A3 x8 L- c
BYTE bInterfaceProtocol;//接口所遵循的协议
) n7 e! T/ ^6 R" V0 r; [BYTE iInterface; //描述该接口的字符串索引值+ N, Q8 P& p m; X
}) e/ l& F$ k+ k1 t4 ^
) V2 k& l* ]0 c, d9 b# m9 [: [
" D/ {) |. o; [% K" \- ^% Z: b
2 P6 B1 ?6 Z1 ]* L& P0 |1 ~5、端点描述符
$ ?$ X8 f% G9 ]+ d( b: C8 W! Astruct _ENDPOIN_DEscriptOR_STRUCT
5 v* ^9 @+ U. }0 I. F3 b{1 E3 f* W9 b& H! b( H% v9 }
BYTE bLength; //设备描述符的字节数大小,为0x12; k/ O2 ~0 b+ m8 K) n
. S5 l6 ~( \5 n9 V% eBYTE bDescriptorType; //描述符类型编号,为0x01" j2 l b0 \6 X* h0 m8 ~: _
BYTE bEndpointAddress; //端点地址及输入输出属性3 H# D+ N" q v/ b
BYTE bmAttribute; //端点的传输类型属性+ k) M/ g7 L) V# w
, H2 G9 h! {6 R4 q5 o+ }* ^WORD wMaxPacketSize; //端点收、发的最大包的大小4 Y1 l; i! y: q0 z5 |. k+ P2 s- y7 S! P0 Z1 g" o. ^
BYTE bInterval; //主机查询端点的时间间隔: X( \( A& O6 r; s" h; {
) ?( N q& f T4 ~ |
|