導(dǎo)言
上一節(jié)我們詳細討論了USB的比特級編解碼,本章將以此為基礎(chǔ),進一步介紹USB字段及包的格式。USB包的構(gòu)成是一個逐層的過程,信息首先以二進制串行數(shù)據(jù)的形式存在。這些串行數(shù)據(jù)按照特定規(guī)則被組織成字段(filed),字段(filed)是包(packet)的基本單元。多個字段(filed)按照一定的順序組成一個包(packed),進一步地,多個包(packed)可以組成一個事務(wù)(transaction),事務(wù)(transaction)是USB通信中更大粒度的數(shù)據(jù)傳輸單元。最終,多個事務(wù)(transaction)組成一個傳輸(transfer),代表了一個完整的數(shù)據(jù)傳輸過程。本文主要講解Packet,下一章將會探討USB事務(wù)(transaction)的傳輸過程。
1字段(filed)
?
所有包都有包開始(SOP)和結(jié)束(EOP)界定符。包(packet)與開始界定符(SOP)的分隔符是 SYNC 字段。輸入電路使用SYNC來將輸入數(shù)據(jù)與本地時鐘對齊,SYNC 字段中的最后兩位是一個標記,用于識別 SYNC 字段的結(jié)束,并通過推斷識別 PID 的開始。字段(filed)是包(packet)的基本單元,每種包(packet)都有對應(yīng)的字段。
包標識符字段(PID)
?
-
每個USB包的SYNC字段后緊跟一個PID
-
PID由一個四位包類型字段和一個四位校驗字段組成
-
PID指示包的類型,暗示了包的格式和應(yīng)用的錯誤檢測類型
-
四位校驗字段確保PID的可靠解碼,以確保正確解釋包
-
PID的四位校驗字段是通過對包類型字段進行補碼生成的
-
如果四個PID校驗位與它們各自的包識別符位不是補碼關(guān)系,則發(fā)生PID錯誤
-
主機和所有功能必須對所有接收到的PID字段進行完整解碼
-
如果接收到的PID的校驗字段失敗,或者解碼為非定義的值,則假定其已損壞
-
包接收器將忽略整個包,包括損壞的PID
-
如果功能收到了一個它不支持的事務(wù)類型或方向的有效PID,則該功能不得回應(yīng),例如,僅支持輸入的端點應(yīng)忽略輸出令牌
-
PID分為四個編碼組:令牌、數(shù)據(jù)、握手和特殊
-
傳輸?shù)那皟晌籔ID位(PID<0:1>)指示編碼組
地址字段
地址字段有兩部分組成:功能地址字段(ADDR)和端點字段(EP)。
如果包的地址字段與設(shè)備端點不匹配則必須忽略這個包。
「功能地址字段(ADDR Field)」
-
ADDR字段通過其地址指定功能,根據(jù)令牌PID的值,功能可能是包的源或目的。
-
ADDR<6:0>指定了128個地址
-
ADDR字段用于IN、SETUP和OUT令牌以及PING和SPLIT特殊令牌
-
每一個單獨的功能(function)都會有一個ADDR值,這意味著可能會有多個端點(Endpoint)共享一個ADDR
-
復(fù)位和上電時,ADDR默認為零,必須在枚舉過程中由主機進行分配
-
ADDR 0被保留作為默認地址,不能分配給其他用途
「端點字段(Endpoint Field)」
-
附加的4位端點字段(ENDP)允許在多端點(Endpoint)的功能(Function)中更靈活地進行尋址
-
除了端點地址0外,其他端點地址是根據(jù)功能(Function)的端點來定義的
-
端點字段定義了用于IN、SETUP和OUT令牌以及PING特殊令牌
-
所有功能必須支持端點地址為零的默認控制管道(Default Control Pipe)
-
低速設(shè)備每個功能最多支持3個端點:端點編號為零的控制管道以及另外兩個端點
額外的兩個端點可以作為:
1.兩個控制管道
2.一個控制管道和一個中斷端點
3.兩個中斷管道
-
全速和高速功能可以支持最多16個IN和OUT端點(16組端點)
幀號字段(Frame Number Field)
-
USB幀的概念是用于組織和標記數(shù)據(jù)傳輸?shù)臅r間間隔,幀號就是用來標識這些幀的序號,一個幀內(nèi)可以包含一個或多個包
-
在USB幀的包中,幀號字段位于幀的頭部。幀的頭部包含同步(SYNC)和定界符(SOP)以及其他必要的信息,幀號字段在這個頭部中用于指示當前幀的序號
-
USB 2.0規(guī)范中,幀號字段是11位長。這意味著,幀號的范圍在0到2047之間,當達到2047后會重新從0開始
-
每當USB總線上的一個新幀開始時,幀號字段會遞增
-
幀號字段的主要用途是為USB系統(tǒng)提供一個時間基準,確保設(shè)備和主機能夠按照同一時間軸進行數(shù)據(jù)傳輸。幀號也用于幫助處理時間敏感的USB應(yīng)用,如音頻和視頻傳輸
數(shù)據(jù)字段(Data?Field)
-
數(shù)據(jù)字段的范圍可以從 0 到 1024 字節(jié)
-
數(shù)據(jù)字段通常位于USB數(shù)據(jù)包的中間部分,緊隨在幀的同步和定界部分以及可能的地址、端點和其他控制信息之后。具體的數(shù)據(jù)字段位置和長度取決于USB傳輸?shù)念愋秃蛶Y(jié)構(gòu)
-
數(shù)據(jù)字段承載了需要在USB設(shè)備之間傳輸?shù)膶嶋H數(shù)據(jù)。這可以是應(yīng)用程序數(shù)據(jù)、控制命令、中斷數(shù)據(jù)等,取決于USB傳輸?shù)念愋?。例如,在批量傳輸中,?shù)據(jù)字段可能攜帶文件的內(nèi)容;在控制傳輸中,數(shù)據(jù)字段可能包含控制請求和應(yīng)答等
-
數(shù)據(jù)字段之后通常會包含錯誤檢測和結(jié)束標記。錯誤檢測用于驗證數(shù)據(jù)的完整性,而結(jié)束標記則指示數(shù)據(jù)字段的結(jié)束,幫助接收端正確解析傳輸
CRC字段(CRC?Field)
和以太網(wǎng)類似,USB包在末尾也會有校驗字段CRC,其CRC的校驗不包括PID字段,主要校驗PID之后的地址、幀號、數(shù)據(jù)等字段。USB包的CRC有兩種分別應(yīng)用于兩種不同的場合:
「令牌CRC(Token?CRC)」
-
G(X) = X5 + X2 + 1
-
令牌CRC字段用于校驗IN、SETUP和OUT令牌的ADDR和ENDP字段,或SOF令牌的時間戳字段。同時,PING和SPLIT特殊令牌也包括一個五位CRC字段
-
如果所有令牌位在接收端無錯誤地接收,CRC字段的5位余數(shù)將為01100B。這表示CRC校驗成功,沒有檢測到錯誤
「數(shù)據(jù)CRC(Data?CRC)」
-
G(X) = X16 + X15 + X2 + 1
-
數(shù)據(jù)CRC字段用于校驗帶有Data字段的數(shù)據(jù)包(Data Packet)
-
如果所有數(shù)據(jù)和CRC位都正確接收,則16位余數(shù)將為1000000000001101B
2包(Packet)
?
USB(Universal Serial Bus)的數(shù)據(jù)傳輸基本單位是數(shù)據(jù)包(Packet)。USB數(shù)據(jù)包根據(jù)不同的令牌類型和傳輸階段,有不同的格式和含義。常見的令牌類型包括IN、OUT、SETUP、SOF(Start of Frame)等。整個USB通信過程由一系列數(shù)據(jù)包組成,這些數(shù)據(jù)包通過同步和特定字段的解析,實現(xiàn)設(shè)備之間的可靠數(shù)據(jù)傳輸。
令牌包(Token Packets)
-
令牌包由PID(IN、OUT、SETUP類型)、ADDR和ENDP字段組成。PING特殊令牌包也包含相同的字段。令牌的PID指定了數(shù)據(jù)包類型和相關(guān)的地址、端點信息
-
令牌類型分為IN、OUT、SETUP和PING。IN令牌表示從設(shè)備到主機的數(shù)據(jù)傳輸,OUT和SETUP令牌表示從主機到設(shè)備的數(shù)據(jù)傳輸,PING令牌表示握手傳輸。令牌中的地址和端點字段用于唯一標識相關(guān)的設(shè)備端點
-
令牌包包含一個五位CRC校驗,用于覆蓋地址和端點字段。這有助于接收方驗證令牌包的完整性。不過,CRC不覆蓋PID,PID有自己的校驗字段。
-
令牌和SOF(Start of Frame)包在三個字節(jié)的數(shù)據(jù)字段后由EOP標志作為結(jié)束。如果一個包在三個字節(jié)后未以EOP結(jié)束,即使它解碼為有效的令牌或SOF,也必須被視為無效并被接收方忽略。
-
令牌包應(yīng)用
設(shè)備初始化:當USB設(shè)備插入計算機的端口時,主機會向設(shè)備發(fā)送OUT令牌包,指定設(shè)備的地址和初始化信息。設(shè)備收到令牌包后,可能會進行初始化過程。
數(shù)據(jù)讀?。喝绻鳈C需要從USB設(shè)備讀取數(shù)據(jù),它會發(fā)送IN令牌包,指定設(shè)備地址和相關(guān)的端點。設(shè)備在收到令牌后,將準備好的數(shù)據(jù)放入數(shù)據(jù)包中發(fā)送給主機。
數(shù)據(jù)寫入:當主機需要向USB設(shè)備寫入數(shù)據(jù)時,它會發(fā)送OUT令牌包,指定設(shè)備地址和相關(guān)的端點。設(shè)備在接收到令牌后,等待主機發(fā)送數(shù)據(jù)包,并進行數(shù)據(jù)的寫入操作。
設(shè)備控制:主機通過發(fā)送SETUP令牌包向USB設(shè)備發(fā)送控制信息,例如設(shè)備的配置、狀態(tài)查詢等。設(shè)備收到SETUP令牌后,執(zhí)行相應(yīng)的控制命令。
握手協(xié)議:使用PING令牌包進行握手協(xié)議。主機發(fā)送PING令牌,指定設(shè)備地址和端點,設(shè)備收到PING后,可以回復(fù)握手信號,表示是否準備好繼續(xù)通信
幀起始包(Start-of-Frame?Packets(SOF))
-
SOF包由主機定期發(fā)出,全速總線為每1.00毫秒±0.0005毫秒一次,高速總線為125微秒±0.0625微秒一次。它包含一個指示數(shù)據(jù)包類型的PID,后跟一個11位的幀編號字段。
-
SOF令牌是一個令牌-only事務(wù)(僅由令牌階段組成的事務(wù)),以精確定時的間隔分發(fā)SOF標記和相應(yīng)的幀編號,對應(yīng)于每個幀的開始。所有高速和全速功能(包括集線器)都接收SOF包。SOF令牌不會導(dǎo)致任何接收函數(shù)生成返回數(shù)據(jù)包,因此無法保證SOF包傳遞到任何給定的功能。
-
SOF令牌主要用于在總線上定期分發(fā)幀號,幫助USB設(shè)備同步其操作。SOF事務(wù)中的令牌僅包含PID(Packet Identifier)和幀編號字段,沒有數(shù)據(jù)傳輸或握手。
-
幀和微幀
全速(Full-Speed)幀時間:
??? USB定義了每1毫秒一個周期的全速幀時間
????通過每1ms發(fā)出一次的SOF令牌來指示全速幀的開始
高速(High-Speed)微幀:
??? USB還定義了高速微幀,其幀時間為125微秒
????與全速類似,SOF令牌用于指示每125μs一個周期的高速微幀的開始
SOF令牌生成:
??? SOF令牌由主機控制器或集線器事務(wù)轉(zhuǎn)換器(hub transaction translator)生成
????在全速鏈路上,每1毫秒生成一次SOF令牌
????在高速鏈路上,每過七個125μs周期后生成一次SOF令牌
高速設(shè)備對SOF的處理:
????高速設(shè)備在每1ms周期內(nèi)看到具有相同幀號的SOF令牌共八次(每125μs一次)
????高速設(shè)備可以通過檢測具有與之前的 SOF 不同的幀編號的 SOF 并將其視為第0個微幀來本地確定特定的微幀“編號”。接下來的 7 個具有相同幀號的 SOF 可被視為微幀 1 至 7。
-
SOF應(yīng)用:
幀同步:SOF令牌每隔一定的時間周期性地發(fā)出,用于同步所有連接到USB總線的設(shè)備。USB設(shè)備根據(jù)SOF令牌的到達來確定當前幀的開始。這對于協(xié)調(diào)和同步USB總線上的各個設(shè)備的操作至關(guān)重要。
時間基準:SOF令牌中包含一個幀編號字段,用于標識當前幀。USB設(shè)備可以利用幀編號來測量時間,實現(xiàn)時間同步或執(zhí)行與時間相關(guān)的操作。這對于需要準確時間基準的應(yīng)用非常重要。
輪詢設(shè)備:主機通過SOF令牌可以定期輪詢連接的USB設(shè)備。設(shè)備可以在SOF令牌的基礎(chǔ)上執(zhí)行特定的操作,例如響應(yīng)主機的查詢或報告設(shè)備的狀態(tài)。
管理USB總線帶寬:SOF令牌的周期性發(fā)送確保了USB總線的帶寬分配。USB設(shè)備可以根據(jù)SOF令牌的到達來進行數(shù)據(jù)傳輸或執(zhí)行其他操作,以確??偩€上的有效利用。
數(shù)據(jù)包(Data?Packets)
-
數(shù)據(jù)包由PID、包含零個或多個字節(jié)數(shù)據(jù)的數(shù)據(jù)字段以及CRC組成
-
有四種不同PID標識的數(shù)據(jù)包類型,分別是DATA0、DATA1、DATA2和MDATA
-
DATA0和DATA1兩種數(shù)據(jù)包PID用于支持數(shù)據(jù)切換同步(Data Toggle Synchronization)
-
所有四種數(shù)據(jù)PID在高帶寬高速等時鐘同步端點(USB 支持單獨的高速中斷或同步端點,這些端點需要高達 192 Mb/s 的數(shù)據(jù)速率)的數(shù)據(jù)PID排序中使用
?
-
三種數(shù)據(jù)PID(MDATA、DATA0、DATA1)用于分割事務(wù)(Split Transactions)
-
數(shù)據(jù)必須始終以整數(shù)字節(jié)數(shù)發(fā)送
-
數(shù)據(jù)CRC僅計算在數(shù)據(jù)包的數(shù)據(jù)字段上,不包括PID,而PID有自己的檢查字段
-
低速設(shè)備允許的最大數(shù)據(jù)負載大小為8字節(jié),全速設(shè)備允許的最大數(shù)據(jù)負載大小為1023字節(jié),高速設(shè)備允許的最大數(shù)據(jù)負載大小為1024字節(jié)
SPLIT包(分割事務(wù)包)
在 USB 中,分割事務(wù)(Split Transaction)是一種特殊的通信機制,允許高速 USB 主機與全速/低速 USB 設(shè)備進行通信。這個過程涉及兩個令牌:開始分割事務(wù)令牌(Start-Split Transaction Token)和完成分割事務(wù)令牌(Complete-Split Transaction Token)。這種機制使得高速主機能夠與全速或低速設(shè)備進行通信,同時維持 USB 總線的高速性能。分割事務(wù)的應(yīng)用場景通常涉及帶有分層結(jié)構(gòu)的 USB 架構(gòu),例如 USB hub 將高速總線轉(zhuǎn)換為全速或低速總線。
「開始分割事務(wù)令牌(Start-Split Transaction Token)」
Hub addr 字段:包含支持此全/低速事務(wù)的指定全/低速設(shè)備的集線器的 USB 設(shè)備地址(與功能地址字段涵義相同(ADD))
SC字段(開始/完成):設(shè)置為零的 SPLIT 特殊令牌包指示這是一個開始分割事務(wù)(SSPLIT)。
Port字段:包含此全速/低速事務(wù)指定的目標集線器的端口號。
S字段(速度):指定此中斷或控制事務(wù)的速度 ,?0 – 全速 ?1 – 低速
E字段(結(jié)束):對于全速等時 OUT 起始分割,S1(起始)和 E(結(jié)束)字段指定高速數(shù)據(jù)有效負載如何對應(yīng)全速數(shù)據(jù)包的數(shù)據(jù)
以下開始分割情況S字段必須設(shè)置為零:
批量(bulk)事務(wù) IN/OUT?
等時( isochronous )事務(wù) IN 開始分割
以下開始分割情況E字段必須設(shè)置為零:
批量(bulk)/控制(control)事務(wù) IN/OUT
中斷(interrupt)?IN/OUT?
等時( isochronous )事務(wù) IN?
?
ET(Endpoint Type)字段:指定全速/低速事務(wù)的端點類型
?
當高速主機需要與全速或低速設(shè)備進行通信時,它發(fā)送開始分割事務(wù)令牌
-
開始分割事務(wù)令牌的發(fā)送表明主機希望與設(shè)備進行通信。
-
主機等待一段時間,以便設(shè)備準備好接收通信。
-
如果設(shè)備可以接收,它返回 NYET(Not Yet)握手,表示尚未完成分割事務(wù)。
-
在收到 NYET 握手后,主機知道設(shè)備已準備好接收數(shù)據(jù)。
「完成分割事務(wù)令牌(Complete-Split Transaction Token)」
SC 字段:設(shè)置為 1 ,指示這是一個完全分割事務(wù) (CSPLIT)
U 字段(保留/未使用):必須置為零 (0B)
完全分割令牌包的其他字段與開始分割令牌包具有相同的定義
?
完成分割事務(wù)令牌用于結(jié)束分割事務(wù),確認數(shù)據(jù)已經(jīng)成功傳輸給全速/低速設(shè)備。
-
主機發(fā)送數(shù)據(jù)給設(shè)備,使用全速或低速速率。
-
完成分割事務(wù)令牌用于通知 hub 或主機,數(shù)據(jù)已經(jīng)傳輸完成。
-
如果數(shù)據(jù)傳輸成功,hub 或主機將返回 ACK 握手。
-
如果出現(xiàn)錯誤,可能返回 NAK 或 STALL 握手。
握手包(Handshake?Packets)
?
-
握手包僅由一個PID組成
-
握手包用于報告數(shù)據(jù)事務(wù)的狀態(tài),可以返回指示成功接收數(shù)據(jù)、命令接受或拒絕、流量控制和停止條件的值
-
僅支持流量控制的事務(wù)類型可以返回握手
-
握手始終在事務(wù)的握手階段返回,可以在數(shù)據(jù)階段返回握手而不是返回數(shù)據(jù)
-
握手包在一個字節(jié)的數(shù)據(jù)字段后由EOP定界如果一個數(shù)據(jù)包在解碼為握手包的情況下,在一個字節(jié)后沒有以EOP結(jié)束,它必須被視為無效并被接收器忽略
握手包有四種類型以及一種特殊的握手包:
「ACK(確認)」
-
ACK表示數(shù)據(jù)包在數(shù)據(jù)字段上沒有發(fā)生比特填充或CRC錯誤,且數(shù)據(jù)PID正確接收。
-
ACK可以在序列比特匹配且接收器可以接受數(shù)據(jù)時發(fā)出,也可以在序列比特不匹配且發(fā)送方和接收方必須重新同步時發(fā)出。
-
ACK僅適用于已傳輸數(shù)據(jù)且期望握手的事務(wù)。
-
HOST可以為IN事務(wù)返回ACK,而功能(Function)可以為OUT、SETUP或PING事務(wù)返回ACK。
場景:假設(shè)主機向 USB 設(shè)備的 OUT 端點發(fā)送數(shù)據(jù),設(shè)備成功接收并處理數(shù)據(jù)。
示例:數(shù)據(jù)傳輸結(jié)束后,設(shè)備可以返回 ACK 作為響應(yīng)。主機接收到 ACK 后,知道數(shù)據(jù)已被成功接收,可以繼續(xù)下一步的通信。
「NAK(否定)」
-
NAK表示功能(Function)無法從主機接受數(shù)據(jù)(OUT)或功能沒有要傳輸給主機的數(shù)據(jù)(IN)。
-
NAK只能由功能(Function)在IN事務(wù)的數(shù)據(jù)階段或OUT或PING事務(wù)的握手階段返回。
-
主機永遠不會發(fā)出NAK。
-
用于流量控制,表示功能暫時無法傳輸或接收數(shù)據(jù),但最終將能夠在無需主機干預(yù)的情況下執(zhí)行。
場景:假設(shè)一個 USB 設(shè)備在接收數(shù)據(jù)的過程中發(fā)現(xiàn)臨時無法處理,可能是因為其緩沖區(qū)已滿。
示例:在一個 OUT 事務(wù)中,當設(shè)備無法接受更多的數(shù)據(jù)時,它可以返回 NAK。主機收到 NAK 后,可能會嘗試重新發(fā)送數(shù)據(jù),直到設(shè)備準備好接收。
「STALL(停止)」
-
STALL由功能響應(yīng)IN令牌或OUT數(shù)據(jù)階段后,或響應(yīng)PING事務(wù)后返回。
-
STALL表示功能無法傳輸或接收數(shù)據(jù),或不支持控制管道請求。
-
在返回STALL后,除了默認端點之外的任何端點的功能狀態(tài)未定義。
-
STALL分為兩種情況:功能性STALL和協(xié)議性STALL。功能性STALL在端點的Halt功能被設(shè)置時發(fā)生,而協(xié)議性STALL是控制管道的特例。
場景:設(shè)備檢測到數(shù)據(jù)出現(xiàn)錯誤或設(shè)備無法接受主機的請求,需要中止當前的數(shù)據(jù)傳輸。
示例:在一個控制事務(wù)中,主機向設(shè)備發(fā)送了一個請求,但設(shè)備當前無法響應(yīng),可以返回 STALL。這可能是因為設(shè)備不支持該請求,或者由于某種原因?qū)е聼o法繼續(xù)。主機接收到 STALL 后,可能采取相應(yīng)的措施,例如中止或重新嘗試傳輸。
「NYET(Not yet)」
-
NYET是僅適用于高速的握手,在PING協(xié)議的一部分或在分割事務(wù)未完成或集線器無法處理分割事務(wù)時返回。
-
在PING協(xié)議中,當主機發(fā)出PING事務(wù)并等待高速設(shè)備的響應(yīng)時,設(shè)備可以返回NYET,NYET表示設(shè)備目前不能接受數(shù)據(jù),但可能會在未來的某個時候能夠。
-
在分割事務(wù)中,如果目標端點尚未準備好接收數(shù)據(jù),集線器可以返回NYET,表示當前不能接受數(shù)據(jù)。
-
NYET信號可以用于流量控制,告知主機在目標端點準備好之前,暫時不要發(fā)送更多的數(shù)據(jù)。
場景:假設(shè)一個高速 USB 設(shè)備正在執(zhí)行分割事務(wù),其中包含一個低速或全速的子事務(wù),而目標設(shè)備還沒有完成數(shù)據(jù)傳輸。
示例:分割事務(wù)的低速或全速子事務(wù)尚未完成時,集線器可以返回 NYET。主機可以根據(jù) NYET 信號來決定是否等待,以便在目標設(shè)備準備好接收數(shù)據(jù)時繼續(xù)傳輸。
「ERR(錯誤)」
-
ERR是僅適用于高速的握手,允許高速集線器報告在全速/低速總線上的錯誤。
-
僅由高速集線器作為分割事務(wù)協(xié)議的一部分返回。
場景:假設(shè)一個高速 USB 集線器在執(zhí)行分割事務(wù)時發(fā)生了錯誤,導(dǎo)致無法完成全速或低速事務(wù)。
示例:集線器可能返回 ERR,通知主機發(fā)生了錯誤。主機在接收 ERR 后,可能會采取適當?shù)拇胧?,如嘗試重新發(fā)送數(shù)據(jù)或采取其他糾正措施。
3往期回顧
?
?USB系列文章在合集 #USB2.0?
(1)深入理解USB2.0通信協(xié)議——框架概述
(2)深入理解USB2.0通信協(xié)議——數(shù)據(jù)流傳輸模型
(3)深入理解USB2.0通信協(xié)議——電氣及物理層規(guī)范
?
4寫在最后
?
創(chuàng)作不易,如果覺得這篇文章對您有用的話,記得點贊關(guān)注哦~
您的關(guān)注是我更新的動力
?
?
原文標題:深入理解USB2.0通信協(xié)議——解讀USB報文的神秘語言!
文章出處:【微信公眾號:Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
評論