本文轉(zhuǎn)自公眾號(hào)歡迎關(guān)注
基于DWC2的USB驅(qū)動(dòng)開發(fā)-USB包詳解 (qq.com)
一.前言
不管什么通訊協(xié)議,比如UART,SPI,USB等等,不管是并口還是串口,不管是同步還是異步,我們從抽象的角度去看,其本質(zhì)都是一樣的。都是先定義物理信號(hào),物理信號(hào)可能是差分,單端,電流驅(qū)動(dòng)電壓驅(qū)動(dòng)等等,不管是什么樣的物理信號(hào),我們從抽象角度看就是不同的物理狀態(tài)和數(shù)字1和0的對(duì)應(yīng), 這里的狀態(tài)不一定是電壓(雖然數(shù)字通訊大部分就是電壓),也可能是頻率,相位等等,這里的狀態(tài)也不一定是電平狀態(tài)也可能是跳變狀態(tài),只要是有不同狀態(tài)可以區(qū)分的都可以,甚至你可以自由發(fā)揮自我創(chuàng)造。這里的數(shù)字1和0即bit,至此我們就到了數(shù)字的世界,一切都是1和0的世界了,這個(gè)轉(zhuǎn)化是由PHY的收發(fā)器完成的。bit再按照一定規(guī)則組成幀或者包,然后在包的基礎(chǔ)上定義各層協(xié)議。任意的通信協(xié)議都不外呼上述的過(guò)程,USB也是如此。這樣一看USB也沒(méi)有那么可怕了,和我們用的UART等協(xié)議本質(zhì)是一樣的,只是物理層信號(hào)不一樣,協(xié)議不一樣而已。這一篇我們就來(lái)介紹協(xié)議層,底層相關(guān)的一些內(nèi)容,這一篇主要關(guān)注USB的包,不涉及物理層信號(hào),也不管位填充等等。
二.協(xié)議的一般約定
上面提到,協(xié)議都是建立在bit之上的,bit組成byte然后組成包或者幀。那么對(duì)于bit和byte在總線上的出現(xiàn)就有一個(gè)順序的約定,對(duì)于bit先發(fā)低位即 LSb ,對(duì)于byte先發(fā)低字節(jié)即 LSB 。對(duì)于協(xié)議中的多字節(jié)數(shù)據(jù)域都是 小端模式 ,即低字節(jié)在低地址,總線上先發(fā)送。
三.包組成
前面提到了包就是一系列的1,0序列組成,但是為了協(xié)議能解析,包需要分成一些特定的區(qū)域以代表不同的功能。比如一些常見的協(xié)議一般都有同步域,頭,負(fù)載,校驗(yàn)等部分。
USB也類似,下面就介紹USB包的組成部分,不同包類型可能由不同的部分扭組合而成。
3.1SYNC同步域
所有USB的數(shù)據(jù)包以一個(gè)SYNC同步區(qū)域開始,接收電路可以利用該區(qū)域進(jìn)行時(shí)鐘對(duì)齊。類似的CAN協(xié)議也有硬同步機(jī)制都差不多。所謂的硬對(duì)齊即通過(guò)一個(gè)特殊的狀態(tài)(區(qū)別于正常的數(shù)據(jù),比如一個(gè)長(zhǎng)串的1,長(zhǎng)串的0,任何可以區(qū)別于其他狀態(tài)的都可以)來(lái)表示開始,然后以該開始狀態(tài)后的一個(gè)時(shí)鐘邊沿作為對(duì)齊。
SYNC的最后兩位用于標(biāo)志SYNC的結(jié)束,承接PID的開始。
我們看到SYNC就是KJ對(duì),所以有,邊沿這樣接收端就可以根據(jù)這些邊沿進(jìn)行和北部時(shí)鐘同步,注意有意第一個(gè)KJ對(duì)有失真,所以不能用于同步。
SYNC是包的同步機(jī)制,不含協(xié)議層的有效信息,所以一般協(xié)議分析中就不會(huì)體現(xiàn)這部分了,只有硬件分析時(shí)才可能關(guān)注該部分,比如要示波器抓包則可以設(shè)置觸發(fā)條件來(lái)觸發(fā)到包頭觸發(fā)。
另外圖中SYNC開始,即從Idle到K也叫SOP,表示包的開始。
3.1.1全速/低速
8位:3個(gè)KJ對(duì)加兩個(gè)K,KJKJKJKK
如下所示
3.1.2高速
32位:15個(gè)KJ對(duì)加兩個(gè)K,KJKJKJKJ KJKJKJKJ KJKJKJKJ KJKJKJKK .
當(dāng)重復(fù)數(shù)據(jù)包時(shí),集線器允許從SYNC開始最多丟棄4位,但不能破壞SYNC字段的任何重復(fù)位。因此,在被5個(gè)集線器重復(fù)之后,SYNC字段可以短至12位。
但是注意對(duì)于接收方不一定要接收8位或者32位,對(duì)于高速接收到至少12位就算(KJKJKJKJKJKK)
3.2包ID區(qū)域
SYNC后面就是PID區(qū)域,可以看到和我們通常的協(xié)議都是一個(gè)套路,比如我們使用串口自定義應(yīng)用層協(xié)議,一般前面會(huì)用幾個(gè)特殊字節(jié)作為同步域用于標(biāo)志包的開頭,如果用AA,55這種還可以用于時(shí)鐘同步,波特率自適應(yīng)。然后定義一個(gè)TYPE字段表示該包的作用和類型,這樣看來(lái)USB也不過(guò)如此,這種套路我們?cè)缇陀眠^(guò)很多了。
USB的PID定義如下,用于表示包的類型,
低4位為包類型編碼,高四位為其取反用于校驗(yàn),接收方如果校驗(yàn)低4位不是高4位的取反則為PID錯(cuò)誤。對(duì)于編碼類型位定義或者PID校驗(yàn)錯(cuò)誤的包丟棄。
對(duì)于PID合法但是不符合預(yù)期的比如對(duì)IN端點(diǎn)收到了OUT令牌則不響應(yīng)。
PID的編碼如下,注意如下是按照高位在左,實(shí)際傳輸是低位先傳輸,注意觀察下表
可以看到PID分為了4組,通過(guò)PID<0:1> 區(qū)分。
比如,以下為一個(gè)控制傳輸?shù)膶?shí)例,和上表對(duì)應(yīng),高低4位相加都是0xF
SETUP是0x2D
DATA0 是0xC3
ACK是0xD2
IN是0x69
NAK是0x5A
3.3地址域
地址域包括功能地址域和端點(diǎn)域。地址域必須完全獨(dú)立匹配,不容許重名(別名),不符合的SETUP必須忽略,訪問(wèn)未初始化的端點(diǎn)的SETUP也要忽略。
一個(gè)設(shè)備對(duì)應(yīng)一個(gè)地址,地址有7位,所以可以尋址128個(gè)設(shè)備。
一個(gè)設(shè)備地址對(duì)應(yīng)一個(gè)功能,默認(rèn)設(shè)備地址是0,在枚舉階段,標(biāo)準(zhǔn)請(qǐng)求設(shè)置地址。
設(shè)備地址0即做枚舉使用,不能分配給其他使用。
IN,STEUP,OUT,PING,SPLIT都需要帶ADDR以表明是和哪個(gè)設(shè)備通訊。
ADDR后面是端點(diǎn)域,4位可以表示16個(gè)端點(diǎn)。所以可以到設(shè)備最多16個(gè)端點(diǎn)。
端點(diǎn)0用于控制傳輸是必須支持的,所以很多控制端點(diǎn)是默認(rèn)使能的,不需要手動(dòng)使能,
其他端點(diǎn)是功能相關(guān)。
SETUP,IN,OUT,PING都要帶端點(diǎn),表示和哪個(gè)端點(diǎn)通訊。
低速設(shè)備支持最多3個(gè)端點(diǎn),控制端點(diǎn)0+兩個(gè)端點(diǎn)(兩個(gè)控制端點(diǎn),控制端點(diǎn)+中斷端點(diǎn),或者兩個(gè)中斷端點(diǎn))。
注意控制端點(diǎn)不一定要是端點(diǎn)0,也可以是其他端點(diǎn),但是必須要有端點(diǎn)0的控制端點(diǎn)。
全速和高速設(shè)備支持最多16個(gè)IN和OUT端點(diǎn)。
3.4幀序號(hào)域
幀序號(hào)區(qū)域11位,由主機(jī)每1mS遞增1.
到達(dá)最大值0x7FFH時(shí)繞回,只有SOF包中有。
SOF包在低速全速時(shí)是1mS發(fā)一次,
高速則是125uS發(fā)一次,注意只有1mS才子等一次,即一個(gè)微幀內(nèi)不遞增,也就是8個(gè)SOF才遞增一次。
3.5數(shù)據(jù)域
數(shù)據(jù)域范圍從0到1024字節(jié),不同速度不同端點(diǎn)類型長(zhǎng)度不一樣,低字節(jié)先發(fā)
不同速度不同端點(diǎn)類型包長(zhǎng)如下表
控制 | 中斷 | 批量 | 同步 | |
---|---|---|---|---|
高速 | 64 | ≤1024 x 3 | 512 | ≤1024 x 3 |
全速 | 8, 16, 32, 64 | ≤64 | 8, 16, 32, 64 | ≤1023 |
低速 | 8 | ≤8 | 無(wú) | 無(wú) |
3.6校驗(yàn)域
校驗(yàn)區(qū)域采用CRC校驗(yàn),保護(hù)非PID區(qū)域,這里為什么不包括PID呢? 因?yàn)镻ID自帶校驗(yàn)了。
注意:CRC是在bit填充之前生成的,帶CRC的結(jié)果之后才是bit填充,接收是先bit填充恢復(fù),然后才是CRC計(jì)算。這個(gè)很好理解bit填充是硬件層對(duì)于信號(hào)編碼的處理,所以是最后一步,CRC是協(xié)議層的內(nèi)容肯行在前。
對(duì)于CRC錯(cuò)誤的丟棄該部分?jǐn)?shù)據(jù),一般就是整個(gè)包。
Token的CRC
對(duì)IN,SETUP和OUT包的ADDR ENDP部分
SOF包的時(shí)間戳部分
PING和SPLIT包的ADDR ENDP部分
進(jìn)行5位CRC校驗(yàn)。
G(X) = X5+ X **2 ** + 1
數(shù)據(jù)的CRC
數(shù)據(jù)包使用16位CRC,對(duì)數(shù)據(jù)域進(jìn)行校驗(yàn)
G(X) = X16+ X15+ X **2 ** + 1
四.各種包格式
4.1令牌包
PID可以是IN,OUT,SETUP,PING
只有主機(jī)才能發(fā)令牌包,為什么呢? 因?yàn)閁SB架構(gòu)是主從架構(gòu)的,只有主機(jī)發(fā)起通訊,即由令牌包開始,從機(jī)才能會(huì)響應(yīng),否則這么多設(shè)備一起啟動(dòng)發(fā)送就會(huì)亂套了。哪怕是設(shè)備要發(fā)送數(shù)據(jù)也是必須要主機(jī)發(fā)IN令牌包,從機(jī)才能響應(yīng)。
令牌和SOF包由數(shù)據(jù)之后三字節(jié)的EOP間隔。如果一個(gè)數(shù)據(jù)包解碼為非有效的令牌或SOF沒(méi)有有效的EOP終止,則它必須被視為無(wú)效包被忽略。
4.2SOF包
全速時(shí)1.00 ms ±0.0005 ms 發(fā)一次SOF包
高速則125 μs ±0.0625 μs 發(fā)一次
SOF包不需要響應(yīng)。
SOF包由主機(jī)或者HUB發(fā)送
注意高速的微幀內(nèi)幀序號(hào)是不遞增的,只有下一個(gè)ms才遞增,可以通過(guò)判斷幀號(hào)的遞增來(lái)同步到該微幀是1ms內(nèi)的第一個(gè)微幀,接下來(lái)的是剩余的7個(gè)。
4.3數(shù)據(jù)包
數(shù)據(jù)包有以下幾種
DATA0,DATA1,DATA2,MDATA
DATA1 DATA1 DATA0用于高帶寬ISO傳輸,即一個(gè)微幀傳3包則按照DATA2-DAT1-DATA0傳輸。
DATA1-DATA0用于傳輸翻轉(zhuǎn)差錯(cuò)控制
不同速度的不同傳輸類型包長(zhǎng)不一樣進(jìn)前面的說(shuō)明。
4.4握手包
握手包用于數(shù)據(jù)傳輸時(shí)報(bào)告狀態(tài), 反應(yīng)數(shù)據(jù)命令是否成功接收或接受,流控,halt等。
注意不是所有的包都需要握手,比如ISO數(shù)據(jù)是不需要握手的,因?yàn)槠渥⒅貙?shí)時(shí)性,不管可靠性,IN和OUT數(shù)據(jù)之后對(duì)方收沒(méi)收到不管,好比UDP和TCP的區(qū)別。
例如如下的ISO的IN,設(shè)備返回?cái)?shù)據(jù)后主機(jī)是不需要回ACK的
握手包格式如下,只有PID域:
握手包有如下幾種類型,具體什么情況回什么包,可以參考規(guī)格書的第8章的不同傳輸?shù)耐負(fù)鋱D,比如對(duì)于中斷傳輸?shù)腎N設(shè)備可能回NAK和STALL。
4.4.1ACK
ACK由數(shù)據(jù)的接收方回,表示數(shù)據(jù)被接收且沒(méi)有任何錯(cuò)誤。
4.4.2NAK
NAK用于流控,由設(shè)備回,注意主機(jī)不能回NAK。
表示數(shù)據(jù)沒(méi)有準(zhǔn)備好,或者不能接收數(shù)據(jù)。
4.4.3STALL
STALL由設(shè)備回,表示不能收發(fā)數(shù)據(jù),或者指定的請(qǐng)求不支持。
主機(jī)不能回STALL。
在端點(diǎn)相關(guān)的特征Halt之后,再請(qǐng)求端點(diǎn)相關(guān)的特征則回STALL。
還有就是控制傳輸時(shí)可能回STALL,具體參考規(guī)格書中各種傳輸?shù)耐負(fù)鋱D。
4.4.4NYET
只有高速有,
PING協(xié)議中對(duì)數(shù)據(jù)包回NYET表示本包接收,不能繼續(xù)接收下一包。
HUB在split傳輸時(shí)也可能回NYET表示split船速和未完成或者不能處理split傳輸。
4.4.5ERR
只有高速HUB使用
用于報(bào)告全速/低速總線上的錯(cuò)誤。
規(guī)格書8.4.6章節(jié)對(duì)響應(yīng)有一個(gè)總結(jié),
IN傳輸設(shè)備的響應(yīng)
IN傳輸主機(jī)的響應(yīng),可以看到主機(jī)不能NAK要不就是ACK要不就是不響應(yīng)。
OUT傳輸設(shè)備響應(yīng)
設(shè)備對(duì)SETUP的響應(yīng)
設(shè)備不能對(duì)SETUP和其數(shù)據(jù)做STALL和NAK響應(yīng),要么就是ACK要么就是不響應(yīng)。
4.5SPLIT相關(guān)令牌包
這部分內(nèi)容也比較多,后面單獨(dú)一篇講。
五.總結(jié)
熟悉USB包的格式,是后面查看協(xié)議分析儀,示波器抓波形分析等基礎(chǔ),所以需要了解。USB報(bào)的格式?jīng)]有什么特殊,和其他協(xié)議套路都是一樣的,要從抽象的結(jié)構(gòu)去理解。
審核編輯:湯梓紅
-
usb
+關(guān)注
關(guān)注
60文章
7936瀏覽量
264454 -
SPI
+關(guān)注
關(guān)注
17文章
1706瀏覽量
91499 -
編程
+關(guān)注
關(guān)注
88文章
3614瀏覽量
93685 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5032瀏覽量
97371 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68519 -
單板計(jì)算機(jī)
+關(guān)注
關(guān)注
0文章
74瀏覽量
15627 -
編譯
+關(guān)注
關(guān)注
0文章
657瀏覽量
32851 -
驅(qū)動(dòng)開發(fā)
+關(guān)注
關(guān)注
0文章
130瀏覽量
12072 -
DWC2
+關(guān)注
關(guān)注
0文章
35瀏覽量
125
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論