USB 頻寬配置
本文提供有關仔細管理 USB 頻寬的指引。 每個 USB 用戶端驅動程式的責任是盡可能減少所使用的 USB 頻寬,並儘快將未使用的頻寬傳回給免費頻寬集區。
為什麼我的 USB 驅動程式遇到頻寬錯誤?
USB 總線上的頻寬競爭來自多個來源,包括硬體和軟體。 很難精確預測 USB 用戶端驅動程式可用的頻寬量。 USB 主機控制器需要一定數量的頻寬,以進行其作業。 所需的數量取決於控制器是否為高速。 其會因系統而異。 以高速運作的 USB 中樞有時必須轉譯高速上游埠與低速裝置之間的交易,而此轉譯程式會耗用頻寬。 但是,交易轉譯是否需要頻寬,取決於連線的裝置種類和裝置樹狀結構的拓撲。
帶寬資源的最嚴重壓力通常是來自可獨佔頻寬的 USB 用戶端驅動程式。 系統會以先到先服務的方式配置頻寬。 如果第一個 USB 驅動程式載入要求所有可用的頻寬,則稍後載入的 USB 驅動程式不允許其裝置的任何頻寬。 系統無法設定裝置,無法列舉它。 由於列舉失敗的原因並不明顯,因此用戶經驗不佳。
有時候,客戶端驅動程式會耗盡具有高速中斷傳輸的可用頻寬。 不過,到目前為止最常見的情況是,配置太多頻寬給異時傳輸的客戶端驅動程式,然後無法及時釋放頻寬。 系統會保留配置的頻寬,直到要求其關閉其端點的驅動程式 (,方法是開啟另一個端點) ,或移除配置頻寬的裝置。 系統不會為大量傳輸配置保證的頻寬,因此大量傳輸永遠不會造成列舉失敗的原因。 不過,大量傳輸裝置的效能取決於針對定期 (不定期和中斷) 傳輸的裝置配置多少頻寬。
USB 2.0 規格需要在預設介面設定上具有零頻寬端點的連續裝置。 這可確保在函式驅動程序開啟非預設介面之前,裝置不會保留任何頻寬,這有助於防止在裝置設定期間發生過多頻寬要求所造成的列舉失敗。 它不會防止客戶端驅動程式在設定裝置之後配置太多頻寬,因而防止其他裝置正常運作。
適當的頻寬管理的關鍵在於,系統中執行同步傳輸的每個USB裝置都必須針對包含連續端點的每個介面,提供多個替代 (Alt) 設定,而用戶端驅動程式必須使用這些Alt設定。 用戶端驅動程式應從要求具有最高頻寬的介面設定開始。 如果要求失敗,客戶端驅動程序應該要求具有較小和較小頻寬的介面設定,直到要求成功為止。
例如,假設網路攝影機裝置具有下列介面:
介面 0 (預設介面設定:預設設定中沒有具有非零非零頻寬的端點)
連續端點 1:封包大小上限 = 0 個字節
連續端點 2:封包大小上限 = 0 個字節
介面 0 Alt 設定 1
連續端點 1:封包大小上限 = 256 個字節
連續端點 2:封包大小上限 = 256 個字節
介面 0 Alt 設定 2
連續端點 1:封包大小上限 = 512 個字節
連續端點 2:封包大小上限 = 512 個字節
網路攝影機的驅動程式會將網路攝影機設定為在初始化時使用預設介面設定。 默認設定沒有連續的頻寬,因此在初始化期間使用預設設定可避免網路攝影機可能無法列舉的威脅,因為對連續頻寬的要求失敗。
當客戶端驅動程式準備好進行連續傳輸時,應該嘗試使用 Alt 設定 2,因為 Alt 設定 2 具有最大的封包大小。 如果要求失敗,驅動程式可以使用Alt設定1進行第二次嘗試。 由於Alt設定1需要較少的頻寬,因此即使第一個要求失敗,此要求仍可能會成功。 多個Alt設定可讓驅動程式先進行數次嘗試,再放棄。
網路攝影機閑置之後,可以再次選取預設設定,將配置的頻寬傳回給免費頻寬集區。
用戶可以藉由檢查 Windows 裝置管理員 中的控制器屬性,查看 USB 控制器所配置的頻寬。 選取控制器的屬性,然後查看 [進階] 索引標籤底下。此讀取不會指出已配置多少頻寬USB中樞以進行交易轉譯。
報告 USB 控制器頻寬使用量無法在 Windows XP 中正常運作的 裝置管理員 功能。
USB 傳輸和封包大小
本文說明各種 Windows 作業系統版本所允許的 USB 傳輸大小。
傳輸大小上限
傳輸大小上限會指定 USB 驅動程式堆疊中的硬式編碼限制。 傳輸大小低於這些限制可能會失敗,因為系統資源限制。 若要避免這些類型的失敗,並確保所有 Windows 版本的相容性,請避免針對 USB 傳輸使用大型傳輸大小。
注意
USBD_PIPE_INFORMATION 結構的 MaximumTransferSize 成員已過時。 USB 驅動程式堆疊會忽略複合和非複合裝置 的 MaximumTransferSize 中的值。
在 Windows 2000 中,USB 驅動程式堆疊會將 MaximumTransferSize 初始化為USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE。 用戶端驅動程式可以在設定裝置時設定較小的值。 針對複合裝置,每個函式的用戶端驅動程式只能針對非預設介面設定中的管道變更 MaximumTransferSize 。
USB 傳輸大小受限於下列限制:
傳輸管道 | Windows 8.1,Windows 8 | Windows 7、Windows Vista | Windows XP、Windows Server 2003 | Windows 2000 |
---|---|---|---|---|
控制 | 適用於 SuperSpeed 和高速的 64K (xHCI) 適用於完整和低速的 4K (xHCI、EHCI、UHCI、OHCI) 針對UHCI,預設端點上的4K;非預設控制管道上的 64K |
適用於高速 (EHCI) 的 64K 4K 適用於完整和低速 (EHCI、UHCI、OHCI) 針對UHCI,預設端點上的4K;非預設控制管道上的 64K (UHCI) |
適用於高速 (EHCI) 的 64K 4K 適用於完整和低速 (EHCI、UHCI、OHCI) 針對UHCI,預設端點上的4K;非預設控制管道上的 64K (UHCI) |
默認端點上的 4K;非預設控制管道上的 64K (OHCI) |
中斷 | 4MB for SuperSpeed、high、full 和 low speed (xHCI、EHCI、UHCI、OHCI) | 4MB 適用於高、完整和低速 (EHCI、UHCI、OHCI) | 無限制 | 未決定的 (OHCI) |
大量 | 適用於 SuperSpeed (xHCI) 的 32MB 適用於高速度與完整速度的 4MB (xHCI) 4MB (EHCI 和 UHCI) 256K 全速 (OHCI) |
適用於高速度與完整速度的 4MB (EHCI、UHCI) 256K (OHCI) |
3MB 適用於高速度與完整速度 (EHCI) 未決定 (UHCI) 256K (OHCI) |
未決定的 (OHCI) |
同步 | 1024 * wBytesPerInterval for SuperSpeed (xHCI) (請參閱 USB_SUPERSPEED_ENDPOINT_COMPANION_DESCRIPTOR) 1024 * HighPacketSize for high speed (xHCI, EHCI) 256 * MaximumPacketSize for full speed (xHCI, EHCI) 64K 用於完整速度 (UHCI、OHCI) |
1024 * HighPacketSize for high speed (EHCI) 256 * MaximumPacketSize for full-speed (EHCI) 64K 用於完整速度 (UHCI、OHCI) |
1024 * HighPacketSize for high-speed (EHCI) 256 * MaximumPacketSize for full speed (EHCI) 64K 用於完整速度 (UHCI、OHCI) |
64K 的全速 (OHCI) |
使用 MaximumTransferSize 限制傳輸大小不會直接影響裝置耗用多少頻寬。 用戶端驅動程序必須變更介面設定,或限制USBD_PIPE_INFORMATION MaximumPacketSize 成員中 設定的封包大小上限。
封包大小上限
封包大小上限是由端點描述元的 wMaxPacketSize 字段所定義。 用戶端驅動程式可以在對裝置的選取介面要求中規範 USB 封包大小。 變更此值並不會變更裝置上的 wMaxPacketSize 。
在要求的 URB 中,是管道 的USBD_PIPE_INFORMATION 結構。 在該結構中,
- 修改 USBD_PIPE_INFORMATION 結構的 MaximumPacketSize 成員。 將它設定為小於或等於目前介面設定之裝置韌體中定義的 wMaxPacketSize 值。
- 在 PipeFlags 成員 USBD_PIPE_INFORMATION 結構中設定USBD_PF_CHANGE_MAX_PACKET旗標。
如需選取介面設定的相關信息,請參閱 如何選取USB裝置的組態。
讀取傳輸緩衝區的封包大小限制上限
當客戶端驅動程式提出讀取要求時,傳輸緩衝區必須是封包大小上限的倍數。 即使驅動程式預期數據小於封包大小上限,仍必須要求整個封包。 當裝置傳送小於大小上限的封包 (短封包) 時,表示傳輸已完成。
在較舊的控制器上,用戶端驅動程式可以覆寫行為。 在數據傳輸 URB 的 TransferFlags 成員中,用戶端驅動程式必須設定USBD_SHORT_TRANSFER_OK旗標。 該旗標允許裝置傳送小於 wMaxPacketSize 的封包。
在 xHCI 主控制器上,USBD_SHORT_TRANSFER_OK針對大量和中斷端點忽略。 EHCI 控制器上的短封包傳輸不會產生錯誤狀況。
在 EHCI 主控制器上,大量和中斷端點會忽略USBD_SHORT_TRANSFER_OK。
在UHCI和 OHCI 主控制器上,如果未針對大量或中斷傳輸設定USBD_SHORT_TRANSFER_OK,則簡短封包傳輸會停止端點,並傳回錯誤碼以進行傳輸。
使用簡短封包分隔寫入傳輸
當寫入裝置時,USB 驅動程式堆疊驅動程式不會對封包大小施加相同的限制,而會在從裝置讀取時強制執行。 某些客戶端驅動程式必須經常傳輸少量的控制數據,以管理其裝置。 在這類情況下,將數據傳輸限制為統一大小的封包並不實用。 因此,驅動程式堆疊不會將任何特殊重要性指派給大小小於數據寫入期間端點大小上限的封包。 這可讓客戶端驅動程式將大型傳輸中斷至裝置的多個大小小於或等於最大值的 URL。
驅動程式必須以小於大小上限的封包結束傳輸,或以零長度封包分隔傳輸的結尾。 在驅動程式傳送小於 wMaxPacketSize 的封包之前,傳輸不會完成。 如果傳輸大小是最大上限的確切倍數,驅動程式必須傳送長度為零的分隔封包,才能明確終止傳輸
用戶端驅動程式負責根據 USB 規格的需求,以零長度封包分隔數據傳輸。 USB 驅動程式堆疊不會自動產生這些封包。
以小於 wMaxPacketSize 的封包分隔 USB 數據傳輸
符合規範的 USB 2.0 和 USB 1.1 驅動程式必須傳輸大小上限的封包, (wMaxPacketSize) ,然後使用小於大小上限的封包結束傳輸,或以零長度封包分隔傳輸的結尾。 在驅動程式傳送小於 wMaxPacketSize 的封包之前,傳輸不會完成。 如果傳輸大小是最大上限的確切倍數,驅動程式必須傳送長度為零的分隔封包,才能明確終止傳輸
裝置驅動程式負責根據 USB 規格的需求,以零長度封包分隔數據傳輸。 系統 USB 堆疊不會自動產生這些封包。