前面的文章我們一起了解了USB的包結構以及令牌包,今天我們來說說USB的數據包和握手包。
顧名思義,數據包就是用來傳輸數據的,在USB1.1協議中,只有兩種數據包:DATA0包和DATA1包。在USB2.中又增加了DATA2和 MDATA包,主要用在高速分裂事務和高速高帶寬同步傳輸中。
數據包都具有同樣的結構:一個同步域,后面跟整數字節的數據,然后是CRC16校驗,最后是包結束符EOP,如圖1所示。
?
圖1
之所以有不同類型的數據包,是用在當握手包出錯時糾錯.下面以DATA0包和DATA1包的切換為例進行具體的解釋。
主機和設備都會維護自己的一個數據包類型切換機制:當數據包成功發送或者接收時,數據包類型切換。當檢測到對方所使用的數據包類型不對時,USB系統認為這發生了一個錯誤,并試圖從錯誤中恢復。數據包類型不匹配主要發生在握手包被損壞的情形。當一端已經正確接收到數據并返回確認信號時,確認信號卻在傳輸過程中被損壞。這時另一端就無法知道剛剛發送的數據是否已經成功,這時它只好保持自己的數據包的類型不變。如果對方下一次使用的數據包類型跟自己的不一致,則說明它剛剛已經成功接收到數據包了(因為它已經做了數據包切換,只有正確接收才會如此);如果對方下一次使用的數據包類型跟自己的一致,則說明對方沒有切換數據包類型,也就是說,剛剛的數據包沒有發送成功,這是上一次的重試操作。
握手包有ACK、NAK、 STALL和NYET。ACK表示正確接收數據,并且有足夠的空間來容納數據。主機和設備都可以用ACK來確認,而NAK、 STALL、NYET只有設備能夠返回,主機不能使用這些握手包。
?
圖2
●NAK表示沒有數據需要返回,或者數據正確接收但是沒有足夠的空間來容納它們。當主機收到NAK時,知道設備還未準備好,主機會在以后合適的時機進行重試傳輸。
● STALL表示設備無法執行這個請求,或者端點已經被掛起了,它表示一種錯誤的狀態。設備返回 STLSTALL后,需要主機進行干預才能解除這種狀態。
●NYET只在USB2.0的高速設備輸出事務中使用,它表示設備本次數據成功接收,但是沒有足夠的空間來接收下一次數據。主機在下一次輸出數據時,將先使用PING令牌包來試探設備是否有空間接收數據,以避免不必要的帶寬浪費。
需要注意的是,返回NAK并不表示數據出錯,只是說明設備暫時沒有數據傳輸或者暫時沒有能力接收數據。當USB主機或者設備檢測到數據出錯時(如CRC校驗錯、PID校驗錯、位填充錯等),將什么都不返回。這時等待接收握手包的一方就會收不到握手包從而等待超時。
以上就是數據包和握手包的內容,你明白了嗎?
往期回顧:
●USB令牌包
●存儲器保護單元
●快速應用張飛單片機之通用定時器
END

