每次在主機控制器和 USB 設備之間移動數據時,都會發生傳輸。 通常,USB 傳輸可大致分為控制傳輸和數據傳輸。 所有 USB 設備都必須支持控制傳輸,并且可以支持用于數據傳輸的端點。 每種類型的傳輸都與設備緩沖區USB 端點 的類型相關聯。 控制傳輸與默認端點相關聯,數據傳輸使用單向端點。 數據傳輸類型使用中斷、批量和常時等量端點。 USB 驅動程序堆棧為設備支持的每個端點創建名為 管道 的信道。 管道的一端是設備的端點。 管道的另一端始終是主控制器。
在向設備發送 I/O 請求之前,客戶端驅動程序必須從 USB 設備檢索有關配置、接口、端點、供應商和類特定描述符的信息。 此外,驅動程序還必須配置設備。 設備配置涉及諸如在每個接口中選擇配置和備用設置等任務。 每個備用設置都可以指定一個或多個可用于數據傳輸的 USB 端點。
客戶端驅動程序配置設備后,驅動程序可以訪問 USB 驅動程序堆棧為當前所選備用設置中的每個端點創建的管道句柄。 若要將數據傳輸到端點,客戶端驅動程序通過設置特定于請求類型的 URB 的格式來創建請求。
關于默認端點
所有 USB 設備必須支持至少一個名為“默認端點”的端點。 任何以默認端點為目標的傳輸都稱為“控制傳輸”。 控制傳輸的目的是使主機能夠獲取設備信息、配置設備或執行特定于設備的控制操作。
默認端點有以下特征:
- 默認端點的地址為 0;
- 默認端點是雙向的,也就是說,在一次傳輸過程中,主機可以向端點發送數據并從其接收數據;
- 默認端點在設備級別可用,不在設備的任何接口中定義;
- 一旦在主機和設備之間建立連接,默認端點就處于活動狀態。 甚至在選擇配置之前,它就已經處于活動狀態;
- 默認端點的數據包最大大小取決于設備的總線速度。 低速,8 字節;全速和高速,64 字節;超高速,512 字節;
控制傳輸
由于控制傳輸是高優先級傳輸,因此會由主機在總線上保留一定量的帶寬。 將為低速和全速設備保留 10% 的帶寬;為高速和超高速傳輸設備保留 20% 的帶寬。 現在,讓我們看看控制傳輸的布局。
控制傳輸分為三個事務:設置事務 、數據事務 、狀態事務 。 每個事務包含三類數據包:令牌數據包、數據數據包、握手數據包。
某些字段通用于所有數據包。 這些字段是:
- “同步”字段,指示數據包的開始;
- 數據包標識符 (PID),指示數據包的類型、事務的方向、事務是成功還是失敗(如果是握手數據包);
- EOP 字段,指示數據包的結束;
其他字段取決于數據包的類型。
令牌數據包
每個設置事務都以令牌數據包開頭。 下面是該數據包的結構。 主機始終發送令牌數據包。
PID 值指示令牌數據包的類型。 下面是可能的值:
- SETUP:指示控制傳輸中設置事務的開始;
- IN:指示主機在從設備請求數據;
- OUT:指示主機在將數據發送到設備;
- SOF:指示幀的開始。 此類型的令牌數據包包含一個 11 位的幀號。 主機發送 SOF 數據包。 發送此數據包的頻率取決于總線速度。 對于全速總線,主機每隔 1 毫秒發送一次數據包;對于高速總線,則每隔 125 微秒發送一次;
數據數據包
緊跟著令牌數據包的是包含有效負載的數據數據包。 每個數據數據包能夠包含的字節數取決于默認終結點的數據包最大大小。 數據數據包可以由主機或設備發送,具體取決于傳輸的方向。
握手數據包
緊跟著數據數據包的是握手數據包。 此數據包的 PID 指示是主機還是設備接收了數據包。 握手數據包可以由主機或設備發送,具體取決于傳輸的方向。
可以使用任何 USB 分析器(例如 Beagle、Ellisys、LeCroy USB 協議分析器)來查看事務和數據包的結構。 分析器設備顯示如何通過線路將數據發送到 USB 設備或從其接收數據。 在此示例中,讓我們檢查由 LeCroy USB 分析器捕獲的某些跟蹤。 此示例僅供參考, 不表示 Microsoft 的認可。
設置事務
始終由主機啟動控制傳輸。 為此,主機會發送設置事務。 此事務包含名為“設置令牌”的令牌數據包,后跟一個 8 字節的數據數據包。 以下屏幕截圖顯示了一個示例性的設置事務。
在前面的跟蹤中,主機通過發送設置令牌數據包 #434 來啟動 由H 指示控制傳輸。 請注意,PID 指定的 SETUP 表示一個設置令牌。 PID 后跟設備地址和終結點地址。 對于控制傳輸,該終結點地址始終為 0。
接下來,主機發送數據包#435。 PID 為 DATA0,該值用于數據包排序(在后面討論)。 PID 后跟 8 個字節,其中包含有關此請求的主要信息。 這 8 個字節指示請求的類型和緩沖區(設備將在其中寫入響應)的大小。
所有字節以相反順序接收。我們會看到以下字段和值:
因此,我們可以得出結論:在此控制(讀取)傳輸中,主機發送請求來檢索設備描述符,并指定 18 個字節作為保存該描述符所需的傳輸長度。 設備發送這 18 個字節的方式取決于默認終結點可以在一個事務中發送多少數據。 該信息包含在設備描述符中,由設備在數據事務中返回。
作為響應,設備發送握手數據包#436。 請注意,PID 值為 ACK(ACK 數據包)。 這表示設備確認了此事務。
數據事務
現在,讓我們看看設備在響應請求時返回的內容。 實際數據在數據事務中傳輸。
下面是數據事務的跟蹤。
在接收到 ACK 數據包后,主機會啟動數據事務。 為了啟動事務,它會發送一個令牌數據包 #450?,其方向為 IN ,稱為 IN token。
作為響應,設備發送 IN 令牌后面的數據包#451。 此數據數據包包含實際的設備描述符。 第一個字節指示設備描述符的長度,即 18 個字節 (0x12)。 此數據數據包中的最后一個字節指示默認終結點支持的數據包最大大小。 在此示例中,我們看到設備可以通過其默認終結點一次發送 8 個字節。
默認終結點的數據包最大大小取決于設備的速度。 高速設備的默認終結點為 64 個字節;低速設備為 8 個字節。
主機通過向設備發送 ACK 數據包 #452來確認數據事務。
讓我們計算返回的數據量。 在設置事務中數據包 #435的 wLength 字段中,主機請求了 18 個字節。 在數據事務中,我們看到從設備收到的只有設備描述符的前 8 個字節。 那么,主機如何接收存儲在剩余的 10 個字節中的信息? 設備分兩個事務這樣做:先是 8 個字節,然后是最后的 2 個字節。
主機知道了默認終結點的數據包最大大小以后,就會啟動新的數據事務,根據數據包大小請求下一部分。
下面是下一數據事務:
主機通過發送 IN 令牌 #463 并從設備請求接下來的 8 個字節來啟動上述數據事務。 設備使用數據包 #464 進行響應,其中包含設備描述符接下來的 8 個字節。
收到 8 個字節后,主機會向設備發送 ACK 數據包 #465。
接下來,主機在另一數據事務中請求最后的 2 個字節,如下所示:
因此,我們看到,為了將 18 個字節從設備傳輸到主機,主機會跟蹤傳輸的字節數并啟動三個數據事務 (8+8+2)。
請注意數據事務 19、23、26 中數據包的 PID。 PID 在 DATA0 和 DATA1 之間交替變換。 該順序稱為數據切換。 在有多個數據事務的情況下,數據切換用于驗證數據包順序。 此方法可確保數據數據包不重復或丟失。
將合并的數據數據包映射到設備描述符的結構,我們看到以下字段和值:
檢查這些值即可獲得設備的一些初步信息。 設備是低速 USB 麥克風。 默認終結點的數據包最大大小為 8 個字節。 設備支持一種配置。
狀態事務
最后,主機會啟動最后一個事務:狀態事務,從而完成控制傳輸。
主機使用 OUT 令牌數據包 (#481) 啟動事務。 此數據包的目的是驗證設備是否已發送所有請求的數據。 在此狀態事務中,不發送數據數據包。 設備使用 ACK 數據包進行響應。 如果發生錯誤,PID 可能為 NAK 或 STALL。