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