1. 程式人生 > >USB學習系列之四——USB包結構

USB學習系列之四——USB包結構

1.USB的資料傳輸以包為單位,一個包被分成不同的域。USB傳輸時使用的是LSB在前,MSB在後的方式。

2.不同的包所包含的域是不同的,但是都有共同的特點是:以同步域開始,緊跟著一個包識別符號PID,最終以包結束符EOP結束這個包。

3.同步域:高速USB序列介面引擎資料傳輸要開始了,同時也提供同步時鐘。對於低速裝置和全速裝置,同步域使用的是0000 0001(二進位制數);對於高速裝置使用的是00000000 00000000 00000000 00000001。

注意:這個是對傳送端的要求,接收端解碼時,0的個數可以少於這個數目。

4.包結束符:包結束符一共有8位,其中USB協議使用的只有4位(PID0~PID3),另外4位(PID4~PID7)是前四位的取反,用來校驗PID。USB協議規定了四類包,分別是:令牌包(PID1~PID0為01)、資料包(PID1~PID0為11)、握手包(PID1~PID0為10)和特殊包(PID1~PID0為00)。以下為USB2.0協議的包,帶*的為USB1.1協議沒有的:

5.令牌包:令牌包用來啟動一次USB傳輸。主機發送一個令牌來通知哪個裝置進行響應,如何響應。

輸入令牌包:用來通知裝置將要輸出一個數據包。

輸出令牌包:用來通知裝置返回一個數據包。

建立令牌包:只用在控制傳輸中,通知裝置輸出一個數據包,建立令牌包後只使用DATA0資料包,且只能傳送到裝置的控制端點,並且裝置必須要接收,而輸出令牌包沒有這些限制。

幀起始包:在每幀開始時傳送,以廣播的形式傳送。USB全速裝置沒毫秒產生一個幀,高速裝置每125微秒產生一個幀。USB主機會對當前的幀號進行計數,在每次幀開始時通過SOF包傳送幀號(或者微幀開始時,每毫秒有八個微幀,這8個微幀的幀號是一樣的)。SOF中的幀號是11位。
注意:在4個令牌包中,只有SOF令牌包之後不能跟資料傳輸,其他的都有資料傳輸。每個令牌包之後都有一個CRC5的校驗,它只校驗PID之後的資料,不包括PID本身,因為PID本身的後4位已經有取反的校驗機制了。

由於SOF令牌包之後不跟隨資料傳遞,所以SOF令牌包和其他三種包的結構不同,具體如下圖所示:

SOF令牌包結構圖

IN、OUT、SETUP令牌包結構圖

6.資料包

USB1.1中只有DATA0和DATA1兩種資料包。

USB2.0中增加了DATA2和MDATA兩種資料包,這兩種資料包主要用在高速分裂事物和高速高頻寬同步傳輸中。

資料包的統一結構:同步域 + 8位包標誌PID + 整數字節資料 + CRC16校驗 + EOP。

之所以有不同型別的資料包,是用在握手包出錯時糾錯。具體解釋如下:

主機和裝置都會維護自己的一個數據包型別切換機制:當資料包成功傳送或者接收時,資料包型別切換。當檢測到對方所使用的資料包型別不對時,USB系統認為這發生了一個錯誤,並試圖從錯誤中恢復。資料包型別不匹配主要發生在握手包被損壞的時候。當一端已經正確接收到資料並且返回確認訊號後,確認訊號在傳輸過程中被損壞。這時另一端就無法知道剛才傳送的資料是否已經發送成功,這時只好繼續保持自己的資料包型別不變。如果對方下一次使用的資料包型別跟自己的不一致,則說明它剛剛已經成功接收到資料包;如果對方下一次使用的資料包跟自己的一致,則說明對方沒有切換資料包型別,也就是剛剛的資料包沒有傳送成功,這是上一次的重試操作。

7.握手包

握手包用來表示一個傳輸是否被對方確認。

握手包的結構:同步域 + 包識別符號PID + EOP。

握手包有ACK、NAK、STALL和NYET。

ACK:表示正確接收資料,並且有足夠的空間來容納資料。主機和裝置都可以用ACK來確認,而NAK、STALL和NYET只有裝置能夠返回,主機不能使用這些握手包。

NAK:表示沒有資料需要返回,或者資料正確接收但是沒有足夠的空間來容納。當主機接收到NAK時,知道裝置還沒有準備好,主機會在以後合適的實際進行重試傳輸。

STALL:表示裝置無法執行這個請求,或者端點已經被掛起,它表示一種錯誤的狀態,裝置返回STALL之後,需要主機進行干預才能解除這種STALL狀態。

NYET:只有在USB2.0高速裝置輸出事物中使用,它表示裝置本次資料成功接收,但是沒有足夠的空間來接收下一次資料。主機在下一次輸出資料時,將先使用PING命令牌包來探測裝置是否有足夠的空間接收資料,一面不必要的頻寬浪費。

注意:NAK並不表示資料出錯,當USB主機或者裝置檢測到資料出錯時,將什麼都不返回,這時等待接收握手包的一方就會收不到握手包從而等待超時。

8.特殊包

特殊包是在一些特殊場合使用的包。總共有四種:PRE、ERR、SPLIT和PING。其中PRE、SPLIT、PING是令牌包,ERR是握手包。ERR、SPLIT、PING三個是在USB2.0協議中增加的。

(1)PRE:通知集線器開啟其低速埠的一種前導包,PRE只能使用在全速模式中。一般情況下集線器不會將全速訊號傳送給低速裝置,只有當接收到PRE令牌包之後,才打開其低速埠。

PRE令牌包結構:同步域 + PID + EOP。

當需要傳送低速事務時,主機首先發送一個PRE令牌包(以全速模式傳送)。對於全速裝置,將會忽略這個令牌包。集線器在接收到這個令牌包之後,開啟其連線了低速裝置的埠,接著主機就會以低速模式給低速裝置傳送令牌包和資料包等。

(2)PING:令牌包結構同OUT令牌包。但是PING令牌包後不傳送資料,而是等待裝置返回ACK或者NAK,以判斷裝置是否能夠傳送資料。在USB2.0中的高速環境中才會使用PING令牌包,且只被使用在批量傳輸和控制傳輸事務中。

(3)SPLIT:高速事務分裂令牌包,通知集線器將高速資料包轉化為全速或者低速資料包傳送給其下面的埠。

(4)ERR:在分裂事務中表示錯誤使用。高速分裂事務的過程比較複雜,而且主要是由集線器完成,所以不詳細說明。

9.資料包的處理

    一般的USB介面晶片都會完成如CRC校驗、位填充、PID識別、資料包切換、握手等協議的處理。當USB介面晶片正確接收到資料時,入股偶有空間儲存,則它將資料儲存並返回ACK,同時,設定一個標誌表示已經正確接收到資料;如果沒有空間儲存資料,則會自動返回NAK。

    收到輸入請求時,如果有資料需要傳送,則傳送資料,並等待接收ACK。只有當資料成功傳送出去之後,才設定標誌位,表示資料已經成功傳送;如果沒有資料需要傳送,則它自動返回NAK。

    通常只需要根據晶片提供的一些標誌,準備需要傳送的資料到端點,或者從端點讀取接收到的資料即可。所要傳送和接收的資料指的是資料包中的資料,至於同步域、包標識、地址、端點、CRC等是看不到的,在BUS Hound中抓到資料也是如此,僅是資料包;並且在BUS Hound中只能看到成功傳輸的資料,即只有ACK確認過的資料包。由於控制傳輸比較特殊,SETUP包也會有相應的標誌供我們使用。