本文是我整理的一些 USB 的學習心得,希望能對大家有所幫助。
文章目錄
- 前言
- 🍍USB 協議層數據格式
- 🍇包格式
- 🍓 PID 域
- 🍓 令牌包
- 🍓 數據包
- 🍓 握手包
- 🍇傳輸類型
- 🍓 批量傳輸
- 🍓 中斷傳輸
- 🍓 實時傳輸
- 🍓 控制傳輸
- 🍍USB 描述符
- 總結
前言
這篇文章為大家介紹 USB協議層數據格式 以及 USB描述符 。
USB 模塊 全面解析(一)
🍍USB 協議層數據格式
在USB設備中,數據傳輸的基本單位是 “ 包 ”
。數據先傳輸最低位(LSB)。那 USB “包” 里面具體包含哪些內容(“域”)?
🍇包格式
至于SOP, SYNC, EOP 具體的電平狀態,在上篇文章中都已詳細介紹了 : USB 模塊 全面解析(一)
- SOP : “包” 的開始。
- SYNC : 用來同步時鐘。
- Packet Content : PID(包類型) + 地址/幀號/數據 + CRC(校驗)。
地址 :確定 包 要發給哪個 USB 設備。 - EOP : “包” 的結束。
下面主要介紹 包格式里 “Packet Content” 部分 的 PID。
🍓 PID 域
在 USB 協議中, PID 是用來標識 USB 數據包類型的關鍵字段。用于指示 數據包的類型 和 方向。
在 USB 包中,PID域 使用 8 位來表示,格式如下:
- 前 4 位 : 標識數據包的類型。
- 后 4 位:是前 4 位的取反,用于校驗 PID 類型的正確性。如果接收方發現 后 4 位不是 前 4 位的取反,就認為發生了錯誤。
“ 包 ” 可以分為 4 種類型:
① 令牌包(Token):指示數據傳輸的開始 和 方向。 (最低 2 位是 01 B)
② 數據包(Data):用于實際傳輸的數據部分。( 11 B)
③ 握手包(Handshake):確認數據包的接收狀態。( 10 B)
④ 特殊包(Special):用于特殊用途的包。( 00 B)
下面是根據 4 位的 PID 分為 16 種具體的 “包”類型:
🍓 令牌包
這里需要注意一點,有 4 種令牌包,其中 SOF 用于通知所有的設備,而 OUT, IN, SETUP 用來通知某個設備。下面是對于 OUT, IN, SETUP 令牌包的結構。
由于 令牌包 起通知作用,要通知某個具體的USB 設備,所以要知道 USB設備的地址(7位)
和 USB設備的端點號(4位)
。
所以一個完整的令牌包如下:
首先 發送 SOP 表示包的開始 -> SYNC 進行信號的同步 -> 根據 PID 的類型決定是 讀/寫數據 -> 11 位的幀號確定USB設備 -> CRC 校驗 -> EOP 表示包的結束。
🍓 數據包
Host 使用 OUT、IN、SETUP 來通知設備:我要傳輸數據了。數據通過"數據包"進行傳輸。數據包也有 4 種類型:DATA0、DATA1、DATA2、MDATA。我們只需了解 DATA0、DATA1。
為什么要 引入不同類型的數據包?
Host 和設備都會維護自己的數據包切換機制,當數據包成功發送或者接收時,數據包類型切換。當檢測到對方使用的數據包類型不對時,USB 系統認為發生了錯誤。
比如:
① Host 發送 DATA0 給設備,設備返回 ACK 表示成功接收,設備期待下一個數據是 DATA1
② 但是 Host 沒有接收到 ACK,Host 認為數據沒有發送成功,Host 繼續使用 DATA0 發送上一次的數據
③ 設備再次接收到 DATA0 數據包,它就知道:哦,這是重傳的數據包
一個完整的數據包如下:
🍓 握手包
握手包有 4 類:ACK、NAK、STALL、NYET。
- ACK : 數據接收方用來回復發送方,表示正確接收到了數據并且有足夠的空間保存數據。
- NACK : Host 發送數據給設備時,設備可以回應 NAK 表示"我還沒準備好,沒辦法接收數據";Host 想讀取設備的數據時,設備可以回復 NAK 表示"我沒有數據給你"。
- STALL : 表示發生了錯誤,比如設備無法執行這個請求(不支持該斷點等待)、斷點已經掛起。設備返回 STALL 后,需要主機進行干預才能接觸 STALL 狀態。
- NYET : 僅適用于高速設備。Host 可以發出 PING 包用來確認設備有數據,設備可以回應NYET 表示"還沒呢"。Hub 也可以回應 NYET 表示低速/全速傳輸還沒完結。
一個完整的握手包如下:
🍇傳輸類型
USB 設備支持 4 種不同的傳輸類型,每種不同的傳輸類型使用不同的場景和需求。
在介紹這 4 種傳輸類型之前,先來了解幾個概念:
- 事務:完整的數據傳輸,需要涉及多個包 令牌包、數據包、握手包。這個完整的數據傳輸過程,被稱為事務(Transaction)。
- 傳輸:由一個 或者多個事務組成,完成一次完整的通信。
有些事務需要握手包,有些事務不需要握手包,有些事務可以傳輸很大的數據,有些事務只能傳輸小量數據。
有四類事務:
① 批量事務:用來傳輸
大量的數據
,數據的正確性有保證,時效沒有保證。
② 中斷事務:用來傳輸周期性的、小量的數據,數據的正確性和時效
都有保證。
③ 實時事務:用來傳輸實時數據
,數據的正確性沒有保證,時效有保證。
④ 建立事務:跟批量事務類似,只不過令牌包是 SETUP
令牌包。
有四類傳輸(Transfer):
① 批量傳輸:就是使用
批量事務
實現數據傳輸,比如 U 盤。
② 中斷傳輸:就是使用中斷事務
實現數據傳輸,比如鼠標。
③ 實時傳輸:就是使用實時事務
實現數據傳輸,比如攝像頭。
④ 控制傳輸:由建立事務、批量事務
組成,所有的 USB 設備都必須支持控制傳輸,用于"識別/枚舉"。
-
過程 :
對于 批量,中斷,實時傳輸 都是由一個 事務組成,不再劃分為多個階段。
對于 控制傳輸 由多個 事務組成,這些事務分別處于 多個過程:建立過程,數據過程,狀態過程。 -
階段 :
事務由 包 組成,這些 包 處于 3 個階段:令牌階段,數據階段,握手階段。令牌階段(Token phase):由令牌包實現。 數據階段(Data phase):由數據包實現。握手階段(Handshake phase):由握手包實現。
① BIT 組成域(Field)
② 域組成包(Packet)
③ 包組成事務(Transaction)
④ 事務組成傳輸(Transfer)
🍓 批量傳輸
-
批量傳輸用批量事務來實現,用于傳輸大量的數據,數據的正確性有保證,時效沒有保證。
-
批量事務由 3 個階段(phase)組成:令牌階段、數據階段、握手階段。每個階段都是一個完整的包,含有 SOP、SYNC、PID、EOP。(下圖中各個矩形框就對應一個完整的包)
🍓 中斷傳輸
-
中斷傳輸用中斷事務來實現,用于傳輸小量的、周期性的數據。數據的正確性和時效都有保證。
-
中斷事務由 3 個階段(phase)組成:令牌階段、數據階段、握手階段。每個階段都是一個完整的包,含有 SOP、SYNC、PID、EOP。中斷事務的優先級比批量事務更高,它要求實時性,而批量事務不要求實時性。
中斷傳輸 要求實時性,由于 USB 協議中沒有 中斷的功能,所以,它使用"周期性的讀、寫"來實現及時性。具體過程如下:
① Host 每隔 n 毫秒發出一個 IN 令牌包
② 鼠標有數據的話,發出 DATA0 或 DATA1 數據包給 Host;鼠標沒有數據的話,發出 NAK
給Host。從下圖中可以看到沒有 NYET 延時等待
。
🍓 實時傳輸
- 實時傳輸用實時事務來實現,用于傳輸實時數據,對數據的正確性沒有要求。
- 實時事務由 2 個階段(phase)組成:令牌階段、數據階段。每個階段都是一個完整的包,含有 SOP、SYNC、PID、EOP。
實時事務不需要握手階段。
實時傳輸 不要求數據的準確性,沒有握手階段。(適用場景:視頻通話等)
🍓 控制傳輸
控制傳輸由多個事務組成,這些事務分別處于 3 個過程:建立過程(stage)、數據過程(stage)、狀態過程(stage)。
① 建立過程(stage),使用 SETUP 事務:Host 發出 SETUP 令牌包、DATA0 數據包、得到 ACK握手包。
② 數據過程(stage),使用批量事務:
a. 對于輸出:Host 發出OUT 令牌包,發出 DATA0、DATA1 數據包、得到 ACK 握手包
b. 對于輸入:Host 發出 IN 令牌包,讀到 DATA0、DATA1 數據包、發出 ACK 握手包
③ 狀態過程(stage),使用批量事務:
a. 對于輸出:Host 發出IN 令牌包,讀到 DATA1 數據包,發出 ACK 握手包
b. 對于輸入:Host 發出 OUT 令牌包,發出 DATA1 數據包,等待 ACK 握手包
上圖的 每一個方框,都是一個完整的事務,含有:Token Packet、Data Packet、Handshake Packet。
例如,對于一個 SETUP 事務,下面是它的組成包 :
在"setup 事務"中:
① SETUP 令牌包:用來通知設備,“要開始傳輸了”
② DATA0 數據包 ( 8 字節數據 ):它含有固定的格式,用來告訴設備"是讀還是寫"、“讀什么”、“寫什么”。
🍍USB 描述符
設備/配置/接口/端點 :
- 對于一個 USB設備,它可以有多種配置 (Configuration)。
- 一個配置下 可以有 多個接口 (Interface), 接口等同于 功能。 比如 USB 耳機有 2 個接口(功能):聲音收發,按鍵控制。
- 一個接口 可以有 多個設置(Setting),比如 默認設置下 它使用較低的帶寬,也可以選擇其他設置去使用更高的帶寬。
- 一個接口 由 一個/ 多個 端點(Endpoint)組成。端點0 屬于整個設備,是雙向的。
怎么描述 設備,配置,端點,接口?
使用描述符(Descriptors)。有設備描述符、配置描述符、接口描述符、端點描述符。所謂描述符,就是一些格式化的數據,用來描述信息。
一個 USB 設備:
① 只有一個設備描述符
:用來表示設備的 ID、它有多少個配置、它的端點 0 一次最大能傳
輸多少字節數據
② 可能有多個配置描述符
:用來表示它有多少個接口、供電方式、最大電流
③ 一個配置描述符下面,可能有多個接口描述符
:用來表示它是哪類接口、有幾個設置
(Setting)、有幾個端點
③ 一個接口描述符符下面,可能有多個端點描述符
:用來表示端點號、方向(IN/OUT)、類
型(批量/中斷/同步)
還有 一些字符串描述符(String descriptors),它用可讀的文字來描述設備,是可選的。
總結
下篇文章為大家介紹 工業控制中經常用到的 Modbus 通信協議。