1.1 Packets
USB總線上數據傳輸以包為基本單位,一個包含不同的域,但都要從同步域開始,然后跟蹤一個包標識符PID(Packet Identifier),最終以包結束符EOP(End of Packet)來結束這個包。
1.1.1 同步域
是以一串0開始的,作用是相當於uart的start信號。
1.1.2 包結束符EOP
對於全速、低速設備是一個大約為2個數據位寬的單端0(SE0)信號。SE0是指,D+和D-同時都保持為低電平。SE0用來表示一些特殊的含義,比如包結束、復位信號等。集線器就是通過將總線設置為SE0約為10ms實現設備復位。對於高速設備的EOP則是故意使用位填充錯誤來表示,如果CRC校驗正確說明位填充錯誤是EOP,否則是傳輸出錯。
1.1.3 包標識符PID
用來標識一個包的類型。共有8位,使用低4位,高4位取反用來校驗PID。定義如下:
1.1.4 令牌包
令牌包用來啟動一次USB傳輸,分別為:
- OUT,用來通知設備將要輸出一個數據包
- IN,通知設備返回一個數據包
- SETUP,只用在控制傳輸中,和OUT作用一樣,但是SETUP只能使用DATA0數據包,且只能發送到設備的控制端點,設備必須接收,而OUT令牌沒有這些限制。
- SOF,幀起始包在每幀(或微幀)開始時發送,所有USB全速和高速設備都可以收到SOF包。全速設備每ms產生一個幀,高速設備每125us產生一個微幀。主機會對當前幀進行編號,每ms內的8個微幀編號相同。
每個令牌包,最后都有一個CRC5的校驗,它只校驗PID之后的數據,不包括PID本身。
圖1.9.3 是OUT、IN、SETUP令牌包的結構。7位地址,按照A0、A1, ..., A6的順序傳輸,最多支持125個設備。
1.1.5 數據包
在USB1.1協議中只有兩種數據包:DATA0、DATA1包,在USB2.0又加入了DATA2和MDATA包,主要用在高速分裂事物和高速高帶寬同步傳輸中。
不同的種類的數據包是用來當握手包出錯時進行糾正,比如:當檢測到對方使用的數據包類型不對時,一般發生在握手包被損壞的情況下,當一端正確接收數據並返回確認信號時,確認信號卻受損。這時,另一端就無法得知剛剛發送的數據是否已成功,這時只好保持自己的數據包類型不變。如果對方下次用的數據包類型和自己的不一樣說明剛剛成功接收到數據報了,因為進行了數據包類型的切換;如果下次收到的數據包類型和自己一致說明上次數據包沒有發送成功,這是上一次的重試操作。
1.1.6 握手包
用來表示一個傳輸是否被對方確認,是最簡單的一種數據包:
握手包有:
- ACK,表示正確接收數據,並有足夠的空間容納數據。主機、設備均可使用,但NAK、STALL、NYET只有設備可以用。
- NAK,表示沒有數據需要返回,或者數據正確接收但是沒有足夠空間容納它們。主機會以后重試。
- STALL,表示設備無法執行這個請求,或者端點已經被掛起了,表示錯誤狀態。這時需要主機進行干預才能接觸該狀態。
- NYET,只在USB2.0的高速設備輸出事務中使用,表示設備本次成功接收,但沒有足夠空間接收下次數據。主機下次輸出數據會先用ping令牌試探設備是否有足夠空間接收數據。
當主機或者設備檢測到數據出錯時(如CRC、PID校驗錯誤,位填充錯誤等)將什么也不返回,這時等待接收握手包的一方就會收不到握手包從而等待超時。
1.1.7 特殊包
PRE,PING,SPLIT是令牌包,USB2.0協議新增,ERR是握手包。
- PRE,是通知集線器打開其低速端口的一種前導包。
- PING,和OUT令牌包有一樣的結構,但是PING令牌包不發送數據而是等待設備返回ACK或者NAK,也判斷是否能夠傳輸數據。
- SPLIT,是高速事務分裂令牌包,通知集線器將高速數據包轉換為全速或者低速數據包發送給其下面的端口。
- ERR,用來在分裂事務中表示錯誤。
1.1.8 如何處理數據包
一般USB接口芯片會自動完成如CRC校驗、位填充、PID識別、數據包切換、握手等協議的處理。
當正確接收到數據時,如有空間存儲,則會保存並返回ACK,同時置一個標志表示以正確接收到數據;如果沒有空間存儲,則自動返回NAK。
當收到輸入請求時,有數據發送就發送數據,並等待接收ACK。只有當收到ACK之后,才置位表示成功發送;如果無數據發送,則自動返回NAK。
1.2 USB事務:四種傳輸類型
1.2.1 批量傳輸
包括三個階段:令牌包階段、數據包階段、握手包階段。流程如下圖:
1.2.2 中斷傳輸
要求主機保證不超過某個時間間隔安排一次傳輸,通常用在數據量不大,但是對時間要求較嚴格的設備中,如鼠、鍵盤等。 中斷傳輸也可以用來不斷檢測某個狀態,當條件滿足后用來傳輸大量數據。
中斷傳輸和批量傳輸類型,沒有PING和NYET兩種包,使用中斷事務的流程圖如下:
1.2.3 等時傳輸
用在數據量大、實時性高的場合如:音頻和視頻設備等,不要求數據100%正確,要保證不能停頓。
1.2.4 控制傳輸
分為三個過程:建立過程、可選的數據過程、狀態過程。
- 建立過程使用一個建立事務,是一個輸出事務和批量傳輸的輸出事務不同:首先令牌使用SETUP,其次數據包只能用DATA0,最后握手包只能用ACK應答(除非錯了,不應答),不能用NAK或者STALL來應答,即設備必須接收建立事務的數據。
- 數據過程是可選的。在數據過程中,所有的數據事務必須是統一方向的,一旦數據傳輸方向發生改變說明進入了狀態過程。數據過程第一個數據包必須是DATA1包,然后依次切換。
- 狀態過程,傳輸方向與數據過程相反。
1.3 端點類型及傳輸類型的關系
一個具體的端點(Endpoint)只能工作在一種傳輸模式下,通常我們把工作在什么模式下的端點就叫做什么端點。例如:控制端點、批量端點等。
端點0,是每個USB設備都必須舉報的默認控制點,一上電就存在並且可以使用。其他端點是可選的,且只有在SetConfig之后才能使用。
每個端點描述符中都規定了端點所支持的最大數據包長。主機每次發送數據包,都不能超過端點的最大包長。
- 控制傳輸的端點,低速模式最大包長固定為8字節,高速模式最大包長固定64字節,而全速模式可在8、16、32、64字節中選擇。
- 等時傳輸的端點,全速模式最大包長上限為1023字節,高速模式下包長最大上限為1024字節,低速模式下不支持等時傳輸。
- 中斷傳輸的端點,低速模式最大包長固定為8字節,高速模式最大包長固定64字節,而全速模式可在8、16、32、64字節中選擇。
- 批量傳輸的端點,高速模式包長固定為512字節,全速模式最大包長可在8、16、32、64字節中選擇,低速模式不支持批量傳輸。
1.4 設備(device)、接口(Interfface)、端點(Endpoint)、管道(Pipe)等概念
層次概念
在USB設備的邏輯組織中,包含設備、配置、接口和端點4個層次,如下圖:
每個USB設備都提供了不同級別的配置,可以包含一個或多個配置,一般一個配置為多。不同配置決定了不同的使用功能,配置由多個接口組成。比如USB音響可以用作音響也可以做讀卡器使用,即具備不同的配置。
在USB協議中,接口由多個端點組成,代表一個基本的功能,是USB設備驅動程序控制的對象,一個功能賦值的USB設備可以有多個接口。比如USB音響可以包含一個音頻接口和一個對旋鈕和按鈕的接口。
端點是USB通信的最基本形式,每一個USB設備接口在主機看來是一個端點的集合。主機只能通過端點與設備進行通信,從而使用設備的功能。每個端點都有唯一的地址,是由設備地址和端點號給出的。每個端點都有一定的屬性,包括傳輸方式、總線訪問頻率、帶寬、端口號和數據包最大容量等。一個USB端點只能在一個方向上承載數據(這是因為主機發送地址時,最高位D7表示讀寫位,1為Input,0為Output由此造成了某一個端點不可能同時為輸入或是輸出端點,只能是其一),因此端點可以看作是一個單向的通道。端點0通常作為控制端點,用於設備的初始化,其他端點作為數據端點用於主機與設備通信。
管道通信
端點就是通信的發送點或者接收點,主機使用設備的過程本質上就是主機緩沖區與端點進行數據交互的過程。需要往主機發送數據需要將數據放置到相應的輸入端點,接收數據亦然。然而,這里涉及一個問題,就是數據怎么傳?
- Stream形式,這個好理解,就是主機和設備無需解碼,數據用戶自定義。
- Message形式,這個數據是要有一定的通信格式的,我們在端點設置時曾涉及到它的通信協議,就是要符合相應的通信協議,也是為了方便使用標准驅動。
1.5 USB 信號