本文主要介紹USB的基本概念和基礎(chǔ)知識
USB
USB 中文網(wǎng) 有很多資料, 很實用哦.
USB 是通用串行總線 (Universal Serial Bus) 的縮寫.
版本 | 理論最高速度 |
---|---|
USB 1.0 Low Speed | 1.5Mb/s 或 0.1875MB/s |
USB 1.0 Full Speed | 12Mb/s 或 1.5MB/s |
USB 1.1 (即 USB 1.0 Full Speed) | 12Mb/s 或 1.5MB/s |
USB 2.0 Full Speed(即USB 1.1) | 12Mb/s 或 1.5MB/s |
USB 2.0 High Speed | 480Mb/s 或 60MB/s |
USB 3.0 | 5Gb/s 或 600MB/s |
USB 3.1 Gen 1 (即USB 3.0) | 5Gb/s 或 600MB/s |
USB 3.1 Gen 2 | 10Gb/s 或 1250MB/s |
USB 3.2 Gen 1(即USB 3.1 Gen 1) | 5Gb/s 或 600MB/s |
USB 3.2 Gen 2(即USB 3.1 Gen 2) | 10Gb/s 或 1250MB/s |
USB 3.2 Gen 2×2(即USB 3.1 Gen 2雙通道,僅限Type-C接口) | 20Gb/s或2500MB/s |
USB 4 (僅限Type-C接口) | 40Gb/s 或 5000MB/s |
雷電1代 (Thunderbolt 1) | 10Gb/s 或 1250MB/s |
雷電2代(Thunderbolt 2) | 20Gb/s或2500MB/s |
雷電3代(Thunderbolt 3) | 40Gb/s 或 5000MB/s |
USB 拓?fù)浣Y(jié)構(gòu)
USB 是一種主從結(jié)構(gòu)的系統(tǒng), 主機(jī)叫做 Host, 從機(jī)叫做 Device (也叫做設(shè)備).
主機(jī)一般有一個或多個主控制器(host controller)
和 根集線器(root hub)
. 主控制器主要負(fù)責(zé)數(shù)據(jù)處理, 而根集線器則提供主機(jī)和設(shè)備之間的接口和通路.
有一類特殊的 USB 設(shè)備 – USB 集線器 (USB hub), 它可以在原有的 USB 口上擴(kuò)展出更多的 USB 口, 但是需要注意的是: 集線器只能擴(kuò)展出更多接口的USB口,而不能擴(kuò)展出更多的帶寬。帶寬是共享同一個USB主控制器的。 因此當(dāng)有多個不同的 USB 設(shè)備都需要較大的數(shù)據(jù)帶寬時, 可以考慮將它們分別連接到不同的主控制器的根集線器上以避免帶寬不足.
級連的 USB 集線器的層數(shù)也是有限制的, USB1.1 規(guī)定最多級連4層, USB 2.0 規(guī)定最多級連6層. 理論上, 一個 USB 主控制器最多可接 127 個設(shè)備, 因為協(xié)議規(guī)定每個 USB 設(shè)備具有一個 7bit 的地址 (取值范圍 0 ~ 127, 而 0 是保留給未是初始化設(shè)備使用的)
一個完整的 USB 數(shù)據(jù)傳輸過程如下:
先由 USB 主控制器發(fā)出命令和數(shù)據(jù), 通過集線器發(fā)給 USB 設(shè)備, 設(shè)備對接收到的數(shù)據(jù)進(jìn)行處理, 再通過集線器發(fā)送給主機(jī). 在標(biāo)準(zhǔn)的 PC 中, USB 主控制器是直接掛接在 PCI 總線上的.
在 Windows 中, 各個 USB 功能的驅(qū)動程序負(fù)責(zé)產(chǎn)生和管理 USB 功能設(shè)備 (FDO), 這就是我們最終看到的實際設(shè)備。
USB 電氣特性
標(biāo)準(zhǔn)的 USB 為 4 線: VBUS
、D+
、D-
以及 GND
.
USB 的主從模式的結(jié)構(gòu)也就意味著, 從機(jī)與從機(jī)、主機(jī)與主機(jī)之間不能直接互連和交換數(shù)據(jù). 由此出現(xiàn)了 USB OTG (On The Go), 即讓同一個設(shè)備, 在不同的場合下可以在主機(jī)和從機(jī)之間切換.
USB OTG 的接頭 (比如 USB MINI 頭) 比普通的 4 線 USB 多了一條 ID 標(biāo)識線, 用來表明它是主機(jī)還是設(shè)備.
USB 使用的是 NRZI 編碼方式, 一般芯片內(nèi)置, 具體過程略.
USB 協(xié)議規(guī)定 (USB 3.0之前) 設(shè)備未配置前, 可以從 VBUS 上最多獲取 100mA 的電流, 配置后最多獲取 500mA.
USB 各種接頭規(guī)格參考這篇文章
USB 插入檢測機(jī)制
USB 集線器每個端口的 D+ 和 D- 分別接 15kΩ 的下拉電阻, 而設(shè)備端在 D+ 或 D- 接 1.5kΩ 的上拉電阻. 當(dāng)設(shè)備插入時, 集線器端口的數(shù)據(jù)線由默認(rèn)的低電平轉(zhuǎn)為高電平, 集線器檢測到這個狀態(tài)后, 它就報告給上一層集線器最終傳遞給主機(jī), 從而識別設(shè)備插入.
對于低速設(shè)備, 上拉電阻接在 D-, 對于全速或高速, 上拉電阻接在 D+, 高速先被識別為全速, 再由集線器和設(shè)備相互確認(rèn)后切換到高速模式. 另外, 因為高速模式是電流傳輸模式, 這時要將 D+ 上的上拉電阻斷開.
一個實驗, 用 10k 電阻接在 USB 5V 和 D+ 或 D-, Windows 會提示發(fā)現(xiàn)新硬件, 但是無法識別設(shè)備. 這時因為 D+ 或 D- 被拉高, 集線器認(rèn)為有設(shè)備插入了, 它就報告給主機(jī), 但是主機(jī)請求獲取數(shù)據(jù)卻沒有響應(yīng), 就會得到一個無法識別的 USB 設(shè)備. 這時設(shè)備管理器里面顯示一個未知設(shè)備, 并且其
VID
和PID
都是 0.
VID
和PID
是設(shè)備在設(shè)備描述符中規(guī)定的, 在調(diào)試時如果發(fā)現(xiàn) VID 和 PID 都為 0, 那么很可能設(shè)備什么都沒返回.
一些 USB 芯片內(nèi)部已經(jīng)集成了一個 1.5kΩ 的上拉電阻, 并且還具有軟連接功能, 可通過軟件來實現(xiàn)上拉電阻的連接和斷開, 這樣就可以做到通過軟件斷開或重連 USB , 而 USB口 實際一直在插著供電.
USB 的描述符及其之間的關(guān)系
主機(jī)通過描述符來識別和處理設(shè)備, 描述符中記錄了設(shè)備類型, 廠商 ID 和產(chǎn)品 ID (通常依賴它們來加載對應(yīng)的驅(qū)動程序)、端點情況、版本號等.
USB 1.1 協(xié)議定義的標(biāo)準(zhǔn)描述符有:
- 設(shè)備描述符 (Device Descriptor)
- 配置描述符 (Configuration Descriptor)
- 接口描述符 (Interface Descriptor)
- 端點描述符 (End-point Descriptor)
- 字符串描述符 (String Descriptor)
USB 2.0 又新增了 2 個標(biāo)準(zhǔn)描述符:
- 設(shè)備限定符描述符 (Device Qualifier Descriptor)
- 其他速度配置描述符 (Other Speed Configuration Descriptor)
另外還有一些特殊的描述符, 例如類特殊描述符 (如 HID 描述符和音頻接口描述符), 廠商自定義的描述符等.
1. 描述符的內(nèi)容
一個USB設(shè)備只有一個設(shè)備描述符。設(shè)備描述符里決定了該設(shè)備有多少種配置,每種配置都有一個配置描述符;而在每個配置描述符中又定義了該配置里有多少個接口,每個接口都有一個接口描述符;在接口描述符里又定義了該接口有多少個端點,每個端點都有一個端點描述符;端點描述符定義了端點的大小、類型等。如果有類特殊描述符,它跟在相應(yīng)的接口描述符之后。
由此可以看出,USB的描述符之間的關(guān)系是一層一層的,最上一層是設(shè)備描述符,接下來是配置描述符,再下來是接口描述符,最下面是端點描述符。
下面是每種類型描述符的主要內(nèi)容:
- 設(shè)備描述符:USB協(xié)議版本號、設(shè)備類型、端點0的最大包大小、廠商ID(VID)和產(chǎn)品ID(PID)、設(shè)備版本號、廠商字符串索引、產(chǎn)品字符串索引、設(shè)備序列號索引、可能的配置數(shù)等。
- 配置描述符:配置所包含的接口數(shù)、配置的編號、供電方式、是否支持遠(yuǎn)程喚醒、電流需求量等。
- 接口描述符:接口的編號、接口的端點數(shù)、接口所使用的類、子類、協(xié)議等。
- 端點描述符:端點號及方向、端點的傳輸類型、最大包長度、查尋時間間隔等。
- 字符串描述符: 主要是提供共一些方便人們閱讀的信息,它不是必需的。
在主機(jī)獲取描述符時,首先獲取設(shè)備描述符,接著再獲取配置描述符,然后根據(jù)配置描述符中的配置集合的總長度,一次將配置描述符、接口描述符、類特殊描述符(如果有)、端點描述符一次讀回。
對于字符串描述符,是單獨獲取的。主機(jī)通過發(fā)送獲取字符串描述符的請求以及描述符的索引號、語言ID來獲取對應(yīng)的字符串描述符。
2. 描述符與設(shè)備的關(guān)系
每個接到集線器上的 USB 設(shè)備都分配有一個獨立的地址, USB 主機(jī)通過該地址來訪問設(shè)備 (類似于計算機(jī)網(wǎng)絡(luò)中的 IP 地址), 而在設(shè)備內(nèi)部有可能還會分出多個通信端點 (類似于計算機(jī)網(wǎng)絡(luò)中的端口), 每個端點都有自己的端點號. 要向設(shè)備發(fā)送或讀取數(shù)據(jù), 就需要像計算機(jī)網(wǎng)絡(luò)那樣, 同時給出設(shè)備地址和端點號.
與計算機(jī)網(wǎng)絡(luò)不同的是, USB設(shè)備種類眾多, 每種設(shè)備的端點數(shù)量和通信方式都不同, 為了更方便地管理這些零散的端點, USB 協(xié)議抽象出了配置和接口的概念. 它是這樣管理的:
設(shè)備和接口對端點的管理
一個設(shè)備可以有多個配置, 但是同一時刻只能有一個配置有效, 當(dāng)我們需要不同的功能時, 只要選擇不同的配置即可.
每個配置下可以有多個接口, 每個接口有一些端點, 它被定義為一種功能, 例如U盤、USB聲卡、USB串口等. 根據(jù)功能的不同接口下的端點數(shù)也不同. 并且多個接口可以同時有效, 這種情況一般被稱為復(fù)合設(shè)備, 例如一個 USB 設(shè)備同時具有聲卡和串口功能, 聲卡功能用來傳輸音頻, 而串口則用來對聲卡設(shè)備進(jìn)行控制.
總結(jié)如下:由端點構(gòu)成一個接口(或者反過來說,接口是端點的集合),由接口又構(gòu)成一個配置(反過來說,配置是接口的集合),再由配置構(gòu)成一個設(shè)備(設(shè)備是配置的集合)
USB 域,包,事務(wù)及傳輸
USB 是串行總線, 使用 LSB 方式傳輸。在USB系統(tǒng)中,主機(jī)處于主導(dǎo)地位,所以把從設(shè)備到主機(jī)的數(shù)據(jù)叫做輸入,從主機(jī)到設(shè)備的數(shù)據(jù)叫做輸出。
雖說包是 USB 傳輸?shù)幕締挝? 但為了方便解釋包的各個部分, USB 協(xié)議又定義了域的概念, 域是包的組成成分, 由域組成包, 多個包按照一定的順序排列組成一個事務(wù) (Transaction), 將不同的事務(wù)進(jìn)行組合成形成一次傳輸 (Transfer)。
0. 概覽
域通常來說有八個
SYNC | PID | ADDR | ENDP | FRAME | DATA | CRC | EOP |
---|
多個域組成包,USB 的包分為四大類
- token:令牌包
- data:數(shù)據(jù)包
- handshake:握手包
- special:特殊包
多個包組成不同的事務(wù),事務(wù)通常有三個
- setup 事務(wù)
- out 事務(wù)
- in 事務(wù)
多個事務(wù)組成傳輸,共有四類傳輸
- 批量傳輸:bulk transaction
- 控制傳輸:control transaction
- 中斷傳輸:interrupt transaction
- 等時傳輸:isochronous transaction
1. 域
USB 通常有八個域,即同步域 (SYNC)、包標(biāo)識 (PID)、地址域 (ADDR)、端點域 (ENDP)、幀號域 (FRAME)、數(shù)據(jù)域 (DATA),校驗域 (CRC),包結(jié)束 (EOP)
SYNC | PID | ADDR | ENDP | FRAME | DATA | CRC | EOP |
---|---|---|---|---|---|---|---|
8/32 bits | 8 bits | 7 bits | 4 bits | 11 bis | 0-1024 bytes | 5/16 bits | — |
注意,并不是每個 USB 包都包含上述的八個域,也就是說有些包只包含其中的?個域。但它們都有以下共同特點:
- 以同步域開始
- 緊跟著一個標(biāo)識域
- 最終以結(jié)束域
1) SYNC
同步域主要是通知對?數(shù)據(jù)傳輸開始,并提供同步時鐘。對于低速設(shè)備和全速設(shè)備,同步域使?的是 00000001(?進(jìn)制數(shù));對于?速設(shè)備使?的是 00000000 00000000 00000000 00000001。
2) PID
包標(biāo)識主要?于標(biāo)識包的類型,由 8 位組成:低 4 位是 PID 編碼,? 4 位是校驗字段,是對低 4 位取反得到,USB 中各種包是通過 PID 字段來區(qū)分
3) ADDR
由于接? USB 總線的設(shè)備可能有多個,因此需要引?地址域,以便于區(qū)分當(dāng)前通信的設(shè)備是哪個設(shè)備。地址域包含 7 個數(shù)據(jù)位,最多可以指定 128 個地址,地址 0 ?作缺省地址,不分配給 USB 設(shè)備。對于 USB 總線上的每個設(shè)備,地址唯?
4) ENDP:
端點域?于指定 USB 總線上某個設(shè)備的?個端點號,包含 4 個數(shù)據(jù)位;全速 / ?速設(shè)備最多可以含有 16 個端點,低速設(shè)備最多含有 3 個端點。所有 USB 設(shè)備都必須含有?個端點號為 0 的端點,?于主機(jī)與設(shè)備間交換基本信息。除端點 0 外,其余的端點都是具體 USB 設(shè)備所特有的。地址域和端點域組合,明確了主機(jī)與設(shè)備間通信的通道。
5) FRAME
幀號字段?于指出當(dāng)前幀的幀號,它僅在每幀 / 微幀開始的 SOF 令牌包中被發(fā)送,其數(shù)據(jù)位?度為 11 位,每傳輸?幀,主機(jī)就將其加 1。全速設(shè)備每毫米產(chǎn)生一個幀,高速設(shè)備每 125us 產(chǎn)生一個微幀,即每毫秒 8 個微幀
6) DATA
數(shù)據(jù)字段包含主機(jī)和 USB 設(shè)備間需要傳輸?shù)臄?shù)據(jù),以字節(jié)為單位,最??度為 1024,?實際?度取決于傳輸?shù)木唧w情況。
7) CRC
校驗域主要是為了校驗通信數(shù)據(jù)的正確性。USB 令牌包和數(shù)據(jù)包中都使?了 CRC。但是,CRC 是發(fā)送?在進(jìn)?位填充之前產(chǎn)?的,這樣要求接收?在去除位填充之后,再對 CRC 字段進(jìn)?譯碼。信息包中的 PID 字段本?含有校驗,所以 CRC 計算不包含有 PID 部分。令牌包的 CRC 采?的是 5 位 CRC,數(shù)據(jù)包中的數(shù)據(jù)字段使?的是 16 位 CRC
8) EOP
全速 / 低速設(shè)備的 EOP 是一個大約 2 個數(shù)據(jù)位寬度的單端 0(SE0) 信號,高速設(shè)備的 EOP 使用故意的位填充錯誤來表示一個包被分成不同的域
2. 包
域組成包
包 (Packet) 是 USB 系統(tǒng)中信息傳輸?shù)幕締卧?,所有傳輸?shù)臄?shù)據(jù)都是以包為基本單位的
USB 的包分為四大類 (其中 * 號是 USB2.0 后新增的):
PID 類型 | PID 名 | PID[3:0] | 說明 |
---|---|---|---|
令牌包 | OUT | 0001 | 通知設(shè)備將要輸出數(shù)據(jù) |
IN | 1001 | 通知設(shè)備將要輸入數(shù)據(jù) | |
SOF | 0101 | 通知設(shè)備這時一個幀起始包 | |
SETUP | 1101 | 通知設(shè)備將要開始一個控制傳輸 | |
數(shù)據(jù)包 | DATA0 | 0011 | 數(shù)據(jù)包(偶) |
DATA1 | 1011 | 數(shù)據(jù)包(奇) | |
DATA2 * | 0111 | ||
MDATA2 * | 1111 | ||
握手包 | ACK | 0010 | 確認(rèn) |
NACK | 1010 | 不確認(rèn) | |
STALL | 1110 | 掛起 | |
NYET * | 0110 | 未準(zhǔn)備好 | |
特殊包 | PRE | 1100 | 前導(dǎo) (這是一個令牌包) |
ERR * | 1100 | 錯誤 (這是一個握手包) | |
SPLIT * | 1000 | 分裂事務(wù) (這是一個令牌包) | |
PING * | 0100 | PING 測試 (這是一個令牌包) | |
– | 0000 | 保留, 未使用 |
1) 令牌包
令牌包用來啟動一次USB傳輸。因為USB是主從結(jié)構(gòu)的拓?fù)浣Y(jié)構(gòu),所以所有的數(shù)據(jù)傳輸都是由主機(jī)發(fā)起的,設(shè)備只能被動地接聽數(shù)據(jù)(唯一的例外是支持遠(yuǎn)程喚醒的設(shè)備能夠主動改變總線的狀態(tài)讓集線器感知到設(shè)備的喚醒信號,但是這個過程并不傳送數(shù)據(jù),只是改變一下總線的狀態(tài))。
這就需要主機(jī)發(fā)送一個令牌來通知哪個設(shè)備進(jìn)行響應(yīng),如何響應(yīng)。令牌包有4種,分別為輸出(OUT)、輸入(IN)、建立(SETUP)和幀起始(SOF Start Of Frame)。
SOF 令牌
SYNC | PID | FRAME | CRC5 | EOP |
---|---|---|---|---|
8/32 bits | 8 bits | 11 bis | 5 bis | — |
SOF 令牌包在每幀(或微幀)開始時發(fā)送,它以廣播的形式發(fā)送,所有USB全速設(shè)備和高速設(shè)備都可以接收到SOF包。
OUT 令牌 IN 令牌及 SETUP 令牌
SYNC | PID | ADDR | ENDP | CRC5 | EOP |
---|---|---|---|---|---|
8/32 bits | 8 bits | 7 bits | 4 bits | 5 bits | — |
SETUP 令牌包只用在控制傳輸中, 它和 OUT 令牌包一樣也是通知設(shè)備將要輸出一個數(shù)據(jù)包, 兩者的區(qū)別在于: SETUP 令牌包之后只使用 DATA0 數(shù)據(jù)包, 且只能發(fā)送到設(shè)備的控制端點, 并且設(shè)備必須要接收, 而 OUT 令牌包沒有這些限制
每個令牌包最后都有一個 CRC5 校驗, 它只校驗 PID 之后的數(shù)據(jù), 因為 PID 本身自帶校驗功能.
2) 數(shù)據(jù)包
數(shù)據(jù)包有 4 種: DATA0、DATA1、DATA2、MDATA
SYNC | PID | byte0 | byte1 | … | byte N | CRC16 | EOP |
---|---|---|---|---|---|---|---|
8/32 bits | 8 bits | 1 byte | 1 byte | 1 byte | 1 byte | 16 bits | — |
不同速度的數(shù)據(jù)負(fù)載
- low speed:8 bytes
- full speed:1023 bytes
- high speed:1024 bytes
之所以有不同類型的數(shù)據(jù)包,是用在當(dāng)握手包出錯時糾錯。下面以DATA0包和DATA1包的切換為例進(jìn)行具體的解釋。
主機(jī)和設(shè)備都會維護(hù)自己的一個數(shù)據(jù)包類型切換機(jī)制:當(dāng)數(shù)據(jù)包成功發(fā)送或者接收時,數(shù)據(jù)包類型切換。當(dāng)檢測到對方所使用的數(shù)據(jù)包類型不對時,USB系統(tǒng)認(rèn)為這發(fā)生了一個錯誤,并試圖從錯誤中恢復(fù)。
數(shù)據(jù)包類型不匹配主要發(fā)生在握手包被損壞的情形。當(dāng)一端已經(jīng)正確接收到數(shù)據(jù)并返回確認(rèn)信號時,確認(rèn)信號卻在傳輸過程中被損壞。這時另一端就無法知道剛剛發(fā)送的數(shù)據(jù)是否已經(jīng)成功,這時它只好保持自己的數(shù)據(jù)包的類型不變。
如果對方下一次使用的數(shù)據(jù)包類型跟自己的不一致,則說明它剛剛已經(jīng)成功接收到數(shù)據(jù)包了(因為它已經(jīng)做了數(shù)據(jù)包切換,只有正確接收才會如此):如果對方下一次使用的數(shù)據(jù)包類型跟自己的一致,則說明對方?jīng)]有切換數(shù)據(jù)包類型,也就是說,剛剛的數(shù)據(jù)包沒有發(fā)送成功,這是上一次的重試操作。
3) 握手包
握手包用來表示一個傳輸是否被對方確認(rèn)。
SYNC | PID | EOP |
---|---|---|
8/32 bits | 8 bits | — |
握手包有ACK、NAK、STALL 和 NYET
-
ACK 表示正確接收數(shù)據(jù),并且有足夠的空間來容納數(shù)據(jù)。主機(jī)和設(shè)備都可以用ACK來確認(rèn),NAK、STALL、NYET 只有設(shè)備能夠返回,主機(jī)不能使用這些握手包。
-
NAK 表示沒有數(shù)據(jù)需要返回,或者數(shù)據(jù)正確接收但是沒有足夠的空間來容納它們。當(dāng)主機(jī)收到NAK時,知道設(shè)備還未準(zhǔn)備好,主機(jī)會在以后合適的時機(jī)進(jìn)行重試傳輸。
-
STALL 表示設(shè)備無法執(zhí)行這個請求,或者端點已經(jīng)被掛起了,它表示一種錯誤的狀態(tài)。設(shè)備返回 STALL 后,需要主機(jī)進(jìn)行干預(yù)才能解除這種 STALL 狀態(tài)。
-
NYET 只在 USB2.0 的高速設(shè)備輸出事務(wù)中使用,它表示設(shè)備本次數(shù)據(jù)成功接收,但是沒有足夠的空間來接收下一次數(shù)據(jù)。主機(jī)在下一次輸出數(shù)據(jù)時,將先使用PING令牌包來試探設(shè)備是否有空間接收數(shù)據(jù),以避免不必要的帶寬浪費。
需要注意的是,返回 NAK 并不表示數(shù)據(jù)出錯,只是說明設(shè)備暫時沒有數(shù)據(jù)傳輸或者暫時沒有能力接收數(shù)據(jù)。當(dāng)USB主機(jī)或者設(shè)備檢測到數(shù)據(jù)出錯時(如CRC校驗錯、PID校驗錯、位填充錯等),將什么都不返回。這時等待接收握手包的一方就會收不到握手包從而等待超時。
4) special 特殊包
特殊包是一些在特殊場合使用的包。總共有4種:PRE、ERR、SPLIT和PING。其中PRE、SPLIT、PING是令牌包,ERR是握手包。
- PRE 令牌包是通知集線器打開其低速端口的一種前導(dǎo)包。PRE 只使用在全速模式中。平時,為了防止全速信號使低速設(shè)備誤動作,集線器是沒有將全速信號傳送給低速設(shè)備的。只有當(dāng)收到PRE令牌包時,才打開其低速端口。PRE令牌包與握手包的結(jié)構(gòu)一樣,只有同步域、PID和EOP。當(dāng)需要傳送低速事務(wù)時,主機(jī)首先發(fā)送一個PRE令牌包(以全速模式發(fā)送)。對于全速設(shè)備,將會忽略這個令牌包。集線器在收到這個令牌包后,打開其連接了低速設(shè)備的端口。接著,主機(jī)就會以低速模式給低速設(shè)備發(fā)送令牌包、數(shù)據(jù)包等。
- PING 令牌包與OUT令牌包具有一樣的結(jié)構(gòu),但是PING令牌包后并不發(fā)送數(shù)據(jù),而是等待設(shè)備返回ACK或者NAK,以判斷設(shè)備是否能夠傳送數(shù)據(jù)。在USB1.1中,是沒有PING令牌包的。只有在USB2.0高速環(huán)境中才會使用PING令牌包,它只被使用在批量傳輸和控制傳輸?shù)妮敵鍪聞?wù)中。直接使用OUT令牌包發(fā)送數(shù)據(jù)時,不管設(shè)備是否有空間接收數(shù)據(jù),都會在OUT令牌包之后跟著發(fā)送一個數(shù)據(jù)包,如果設(shè)備沒有空間接收數(shù)據(jù),就返回一個NAK。這樣的結(jié)果就是浪費了總線帶寬,白白傳送了數(shù)據(jù)。在高速設(shè)備中增加了這個PNG機(jī)制,主機(jī)先用PING令牌包試試設(shè)備是否有空間接收數(shù)據(jù),而不用事先把數(shù)據(jù)發(fā)送出去。在全速模式下,有時會遇到一個很有趣的現(xiàn)象,就是下位機(jī)程序慢了一點點處理完數(shù)據(jù),結(jié)果傳輸速度卻下降了很多。這就是前面所說的OUT過程直接發(fā)送數(shù)據(jù)導(dǎo)致的,也就是說,雖然程序只慢了一點,但是卻丟棄了整個數(shù)據(jù)包。
- SPLIT 令牌包是高速事務(wù)分裂令牌包,通知集線器將高速數(shù)據(jù)包轉(zhuǎn)化為全速或者低速數(shù)據(jù)包發(fā)送給其下面的端口。
- ERR 握手包是在分裂事務(wù)中表示錯誤使用。由于高速分裂事務(wù)過程比較復(fù)雜,主要屬于集線器的功能,在此就不詳述了,感興趣可以閱讀USB2.0協(xié)議相關(guān)部分。
如何處理數(shù)據(jù)包
一般來說, USB接口芯片會完成如CRC校驗、位填充、PID識別、數(shù)據(jù)包切換、握手等協(xié)議的處理。
當(dāng)USB接口芯片正確接收到數(shù)據(jù)時,如果有空間保存,則它將數(shù)據(jù)保存并返回ACK,同時,設(shè)置一個標(biāo)志表示已經(jīng)正確接收到數(shù)據(jù);如果沒有空間保存數(shù)據(jù),則自動會返回NAK。
收到輸入請求時,如果有數(shù)據(jù)需要發(fā)送,則發(fā)送數(shù)據(jù),并等待接收ACK。只有當(dāng)數(shù)據(jù)成功發(fā)送出去(即接收到應(yīng)答信號ACK)之后,它才設(shè)置標(biāo)志,表示數(shù)據(jù)已成功發(fā)送;如果無數(shù)據(jù)需要發(fā)送,則它自動返回NAK。
通常只需要根據(jù)芯片提供的一些標(biāo)志,準(zhǔn)備要發(fā)送的數(shù)據(jù)到端點,或者從端點讀取接收到的數(shù)據(jù)即可。所要發(fā)送和接收的數(shù)據(jù)是指數(shù)據(jù)包中的數(shù)據(jù),至于同步域、包標(biāo)識、地址、端點、CRC等是看不到的,在BUS Hound中抓到數(shù)據(jù)也是如此,僅是數(shù)據(jù)包,并且,BUS Hound中只能看到成功傳輸?shù)臄?shù)據(jù),即只有ACK確認(rèn)過的數(shù)據(jù)包。在USB接口芯片中,通過一些標(biāo)志可以知道是哪個端點接收或者成功發(fā)送了數(shù)據(jù)。另外,由于控制傳輸比較特殊,SETUP包也會有相應(yīng)的標(biāo)志供我們使用。
3. 事務(wù)
雖然USB定義了數(shù)據(jù)在總線上傳輸?shù)幕締挝皇前?,但是我們還不能隨意地使用包來傳輸數(shù)據(jù),必須按照一定的關(guān)系把這些不同的包組織成事務(wù)(transaction)才能傳輸數(shù)據(jù)。
事務(wù)通常由令牌包,數(shù)據(jù)包,握手包中的 2 個或者 3 個 包組成:
- 令牌包用來啟動一個事務(wù),總是由主機(jī)發(fā)送
- 數(shù)據(jù)包傳送數(shù)據(jù),可以從主機(jī)到設(shè)備,也可以從設(shè)備到主機(jī),方向由令牌包來決定
- 握?包的發(fā)送者通常為數(shù)據(jù)接收者,當(dāng)數(shù)據(jù)正確接收后,發(fā)送握?包,設(shè)備也可以使? NACK 表?數(shù)據(jù)未準(zhǔn)備好
注意,SOF 只是指??幀的開始,?有效數(shù)據(jù),并不是?次事務(wù);EOF 幀發(fā)送結(jié)束后的?種電平狀態(tài),也不是事務(wù)
例如下面是一些常見的事務(wù):
1) setup 事務(wù)
setup 事務(wù)處理并定義了 Host 與 Device 之間的特殊的數(shù)據(jù)傳輸,它僅適?于 USB 控制傳輸?shù)慕?階段。
正確的 setup 事務(wù)包括令牌、數(shù)據(jù)和握?三個階段, 例如下面是一個正常的 setup 事務(wù):
包類型 | ||||||
---|---|---|---|---|---|---|
1. 令牌包 (Host --> Device) | SYNC | SETUP | ADDR | ENDP | CRC5 | EOP |
2. 數(shù)據(jù)包 (Host --> Device) | SYNC | DATA0 | CRC16 | EOP | ||
3. 握手包 (Device --> Host) | SYNC | ACK | EOP |
setup 事務(wù)通常有三種狀態(tài),即:
- 正常 (握手包為 ACK)
- 設(shè)備忙 (握手包為 NAK)
- 設(shè)備出錯 (握手包為 STALL)
2) out 事務(wù)
out 事務(wù)是主機(jī)向 USB 設(shè)備的某個端點中發(fā)送數(shù)據(jù)的過程,正確的 out 事務(wù)包括令牌、數(shù)據(jù)和握?三個階段, 例如下面是一個正常的 out 事務(wù):
包類型 | ||||||
---|---|---|---|---|---|---|
1. 令牌包 (Host --> Device) | SYNC | OUT | ADDR | ENDP | CRC5 | EOP |
2. 數(shù)據(jù)包 (Host --> Device) | SYNC | DATA0/DATA1 | CRC16 | EOP | ||
3. 握手包 (Device --> Host) | SYNC | ACK | EOP |
同樣的, out 事務(wù)也有三種狀態(tài):
- 正常 (握手包為 ACK)
- 設(shè)備忙 (握手包為 NAK)
- 設(shè)備出錯 (握手包為 STALL)
3) in 事務(wù)
in 事務(wù)是主機(jī)從 USB 設(shè)備的某個端點中獲取數(shù)據(jù)的過程, 正確的輸?事務(wù)包括令牌包、數(shù)據(jù)包和握?包三個階段.
下面是?個 in 事務(wù)可能的三種狀態(tài)
- 正常的 in 事務(wù)
包類型 | ||||||
---|---|---|---|---|---|---|
1. 令牌包 (Host --> Device) | SYNC | IN | ADDR | ENDP | CRC5 | EOP |
2. 數(shù)據(jù)包 (Device --> Host) | SYNC | DATA0/DATA1 | CRC16 | EOP | ||
3. 握手包 (Host --> Device) | SYNC | ACK | EOP |
- 設(shè)備忙或?數(shù)據(jù)時
包類型 | ||||||
---|---|---|---|---|---|---|
1. 令牌包 (Host --> Device) | SYNC | IN | ADDR | ENDP | CRC5 | EOP |
2. 握手包 (Device --> Host) | SYNC | NACK | EOP |
- 設(shè)備出錯時
包類型 | ||||||
---|---|---|---|---|---|---|
1. 令牌包 (Host --> Device) | SYNC | IN | ADDR | ENDP | CRC5 | EOP |
2. 握手包 (Device --> Host) | SYNC | STALL | EOP |
4. 傳輸
事務(wù)構(gòu)成傳輸
1)批量傳輸 (Bulk Transactions)
批量傳輸中有三種事務(wù): IN 事務(wù)、OUT 事務(wù)、PING 事務(wù).
批量傳輸沒有規(guī)定數(shù)據(jù)包中數(shù)據(jù)的意義和結(jié)構(gòu),具體的數(shù)據(jù)結(jié)構(gòu)要由設(shè)備自己定義。批量傳輸通常用在數(shù)據(jù)量大、對數(shù)據(jù)的實時性要求不高的場合,例如USB打印機(jī)、掃描儀、大容量存儲設(shè)備等。批量傳輸?shù)牧鞒虉D如下:
ons.PNG)]
在圖中從上往下看, 最開始主機(jī)處于 IDLE 狀態(tài), 然后開始進(jìn)入三種傳輸狀態(tài)種的一個: IN、OUT、PING.
IN 事務(wù)
主機(jī)首先往USB總線上發(fā)出一個 IN 令牌包, 然后進(jìn)入數(shù)據(jù)接收狀態(tài), 等待設(shè)備返回數(shù)據(jù), 此時
- 若USB總線上沒有地址和端點匹配的設(shè)備或者雖然有匹配的設(shè)備, 但是設(shè)備檢測到包錯誤, 不做任何響應(yīng), 則主機(jī)將等待超時.
- 若有地址和端點匹配的設(shè)備,并且設(shè)備沒有檢測到錯誤,則該設(shè)備要做出響應(yīng):
- 如果設(shè)備有數(shù)據(jù)需要返回,那么它把一個數(shù)據(jù)包放到總線上(具體的數(shù)據(jù)包類型要看數(shù)據(jù)切換位)
- 如果設(shè)備沒有數(shù)據(jù)需要返回,則它直接使用NAK握手包來響應(yīng)主機(jī)。主機(jī)在收到NAK握手包后,知道設(shè)備暫時無數(shù)據(jù)返回,主機(jī)會在稍后的時間里重試該輸入事務(wù)
- 如果該端點處于掛起狀態(tài),設(shè)備會返回一個STALL握手包
然后在主機(jī)端:
- 如果主機(jī)接收到設(shè)備發(fā)送的數(shù)據(jù)包并解碼正確后,使用ACK握手包應(yīng)答設(shè)備。
- 如果主機(jī)檢測到錯誤,則不做任何響應(yīng),設(shè)備會檢測到超時。
USB協(xié)議規(guī)定,不允許主機(jī)使用NAK握手包來拒絕接收數(shù)據(jù)包(否則的話,設(shè)備會在下面想:U 真是 “SB” ?。〖热荒銢]空間接收數(shù)據(jù),你還請求我返回數(shù)據(jù)給你干啥!浪費表情)。
OUT 事務(wù)
[TODO]: OUT 令牌包發(fā)完會有一個 Error 分支, 而這個時候設(shè)備還沒有回復(fù), 主機(jī)是怎么檢測這個 Error 的呢?或則這個 Error 是什么意思呢? 難道是因為鏈路上能夠知道一個數(shù)據(jù)有沒有實際到達(dá)設(shè)備端.
也就是說每發(fā)送一個包都可能包含兩種的錯誤: 1. 是數(shù)據(jù)根本沒發(fā)送到設(shè)備端 (設(shè)備端不是一個正常 USB 設(shè)備或者設(shè)備已經(jīng)拔掉了) 2. 數(shù)據(jù)發(fā)送到設(shè)備端了, 但是設(shè)備沒有任何回復(fù).
主機(jī)先發(fā)送一個 OUT 令牌包, 說明有數(shù)據(jù)要輸出, 緊接著發(fā)送一個 DATA 包 (具體的數(shù)據(jù)包類型要看數(shù)據(jù)切換位), 然后進(jìn)入等待回復(fù)狀態(tài): 設(shè)備的回復(fù)有以下幾種種情況:
- 若設(shè)備解碼令牌包、數(shù)據(jù)包都準(zhǔn)確無誤,并且有足夠的緩沖區(qū)來保存數(shù)據(jù)就會發(fā)送 ACK 或 NYET 握手包來應(yīng)答主機(jī) (只有高速模式才有 NYET 握手包, 它表示本次數(shù)據(jù)接收成功, 但是沒有能力接收下一次傳輸).
- 若設(shè)備沒有足夠的緩沖區(qū)來保存數(shù)據(jù),那么他會返回一個 NAK 握手包, 主機(jī)會在稍后的時間重試該傳輸事務(wù).
- 若設(shè)備檢測到數(shù)據(jù)正確,但是端點處于掛起狀態(tài), 則返回一個 STALL 握手包。
- 若設(shè)備檢測到有錯誤 (例如校驗錯誤、位填充錯誤等) 則不做任何相應(yīng),讓主機(jī)等待超時
PING 事務(wù)
在 USB2.0 高速設(shè)備中增加了一個 PING 令牌包,用來探測設(shè)備是否有空間接收數(shù)據(jù),它不發(fā)出數(shù)據(jù),直接等待設(shè)備的握手包。因此PING事務(wù)只有令牌包和握手包。
- ACK 握手包表示有空間接收數(shù)據(jù)
- NAK 握手包表示無空間接收
- STALL 握手包表示端點掛起
2)中斷傳輸 (Interrupt Transaction)
中斷傳輸有 IN 事務(wù) 和 OUT 事務(wù)兩種.
中斷傳輸是一種保證查詢頻率的傳輸。中斷端點在端點描述符中要報告它的查詢間隔,主機(jī)會保證在小于這個時間間隔的范圍內(nèi)安排一次傳輸。
這里所說的中斷,跟我們硬件上的中斷是不一樣的。它不是由設(shè)備主動地發(fā)出一個中斷請求,而是由主機(jī)保證在不大于某個時間間隔內(nèi)安排一次傳輸。
中斷傳輸通常用在數(shù)據(jù)量不大,但是對時間要求較嚴(yán)格的設(shè)備中,例如人機(jī)接口設(shè)備(HID)中的鼠標(biāo)、鍵盤、軌跡球等。中斷傳輸也可以用來不斷地檢測某個狀態(tài),當(dāng)條件滿足后再使用批量傳輸來傳送大量的數(shù)據(jù)。
除了在對端點查詢的策略上不一樣之外,中斷傳輸和批量傳輸?shù)慕Y(jié)構(gòu)基本上是一樣的,只是中斷傳輸中沒有PING 和 NYET 兩種包。中斷傳輸?shù)牧鞒虉D如下:
3)等時傳輸 (Isochronous Transaction.PNG)
等時傳輸(同步傳輸)用在數(shù)據(jù)量大、對實時性要求高的場合。
例如音頻設(shè)備、視頻設(shè)備等,這些設(shè)備對數(shù)據(jù)延遲很敏感。對于音頻或者視頻設(shè)備來說,對數(shù)據(jù)的100%正確要求不高,少量數(shù)據(jù)的錯誤還是能夠容忍的,主要的是要保證不能停頓;
所以等時傳輸是不保證數(shù)據(jù)100%正確的。當(dāng)數(shù)據(jù)錯誤時,并不進(jìn)行重傳操作。因此等時傳輸也就沒有應(yīng)答包。數(shù)據(jù)是否正確,可以由數(shù)據(jù)包的CRC校驗來確認(rèn)。至于出錯的數(shù)據(jù)如何處理,由軟件來決定。
等時傳輸?shù)牧鞒虉D如下:
3)控制傳輸 (Isochronous Transaction.PNG)
控制傳輸與前面三種傳輸相比,要稍微復(fù)雜一些。
控制傳輸分為三個過程:
第一個是建立過程
建立過程使用一個 SETUP (建立) 事務(wù)。SETUP 事務(wù)是一個輸出數(shù)據(jù)的過程,與批量傳輸?shù)?OUT 事務(wù)相比,有幾處不一樣:
- 首先是令牌包不一樣,建立過程使用的是SETUP令牌包;
- 其次是數(shù)據(jù)包類型,SETUP只能使用DATA0包;
- 最后是握手包,設(shè)備只能使用ACK來應(yīng)答(若出錯則不應(yīng)答),而不能使用NAK或者STALL來應(yīng)答,即設(shè)備必須要接收 SETUP 事務(wù)的數(shù)據(jù)。
第二個是可選的數(shù)據(jù)過程
數(shù)據(jù)過程是可選的,即一個控制傳輸可能沒有數(shù)據(jù)過程。如果有,一個數(shù)據(jù)過程可以包含一筆或者多筆數(shù)據(jù)事務(wù)??刂苽鬏斔褂玫臄?shù)據(jù)事務(wù)與批量傳輸中的批量事務(wù)是一樣的。
要注意的是,在數(shù)據(jù)過程中,所有的數(shù)據(jù)事務(wù)必須是同一個傳輸方向的。也就是說:
在控制讀傳輸中,數(shù)據(jù)過程中的所有數(shù)據(jù)事務(wù)都必須是輸入的;
在控制寫傳輸中,數(shù)據(jù)過程中的所有數(shù)據(jù)事務(wù)都必須是輸出的。一旦數(shù)據(jù)傳輸方向發(fā)生改變,就會認(rèn)為進(jìn)入到了狀態(tài)過程。
數(shù)據(jù)過程的第一個數(shù)據(jù)包必須是 DATA1 (因為建立過程的數(shù)據(jù)包是 DATA0),然后每次正確傳輸一個數(shù)據(jù)包后就在DATA0和DATA1之間交替。
第三個是狀態(tài)過程
狀態(tài)過程也是一筆批量事務(wù),它的傳輸方向剛好跟前面的數(shù)據(jù)階段相反,即
- 若數(shù)據(jù)過程是輸出,則在狀態(tài)過程為一個批量輸入事務(wù);
- 若數(shù)據(jù)過程是輸入,則在狀態(tài)過程為一個批量輸出事務(wù);
- 若無數(shù)據(jù)過程, 則狀態(tài)為一個批量輸入事務(wù), 因為建立過程就是輸出
狀態(tài)過程只使用DATA1包。
控制傳輸之所以要弄得這么復(fù)雜,是因為它要保證數(shù)據(jù)傳輸過程的數(shù)據(jù)完整性。
設(shè)備枚舉過程中各種描述符的獲取以及設(shè)置地址、設(shè)置配置等,都是通過控制傳輸來實現(xiàn)的。
例如下面是幾種控制傳輸?shù)膶嵗?
控制類型 | 建立過程 | 數(shù)據(jù)過程 >> | >> | >> | >> | 狀態(tài)過程 |
---|---|---|---|---|---|---|
控制寫 | SETUP | OUT(1) | OUT(0) | … | OUT(0/1) | IN(1) |
DATA0 | DATA1 | DATA0 | DATA0/1 | DATA1 | ||
控制讀 | SETUP | IN(1) | IN(0) | … | IN(0/1) | OUT(1) |
DATA0 | DATA1 | DATA0 | DATA0/1 | DATA1 |
若沒有數(shù)據(jù)過程, 則直接進(jìn)入狀態(tài)過程:
控制類型 | 建立過程 | 狀態(tài)過程 |
---|---|---|
無數(shù)據(jù)控制寫 | SETUP | IN(1) |
DATA0 | DATA1 |
端點類型與傳輸類型、最大數(shù)據(jù)包長的關(guān)系
一個具體的端點,只能工作在一種傳輸模式下。通常,我們把工作在什么模式下的端點,就叫做什么端點。例如,控制端點、批量端點等。
端點0是每個USB設(shè)備都必須具備的默認(rèn)控制端點,它一上電就存在并且可點是可選的,需要根據(jù)具體的設(shè)備來決定。非0端點只有在Set Config之后才能使用。
每個端點描述符中都規(guī)定了端點所支持的最大數(shù)據(jù)包長。主機(jī)每次發(fā)送數(shù)據(jù)包,都不能超過端點的最大包長:
類型 \ 最大包長 \ 模式 | 低速模式 | 全速模式 | 高速模式 |
---|---|---|---|
控制端點 | 固定8字節(jié) | 可在8、16、32、64字節(jié)中選擇 | 固定64字節(jié) |
等時端點 | 不支持 | 上限1023字節(jié) | 上限1024字節(jié) |
中斷端點 | 上限8字節(jié) | 上限64字節(jié) | 上限1024字節(jié) |
批量端點 | 不支持 | 可在8、16、32、64字節(jié)中選擇 | 固定512字節(jié) |
USB 設(shè)備的枚舉過程
USB主機(jī)在檢測到USB設(shè)備插人后,就要對設(shè)備進(jìn)行枚舉了。枚舉就是主機(jī)從設(shè)備讀取各種描述符信息, 這樣主機(jī)就可以根據(jù)這些信息加載合適的驅(qū)動程序, 從而知道設(shè)備是什么樣的設(shè)備, 如何進(jìn)行通信等.
調(diào)試USB設(shè)備,很重要的一點就是USB的枚舉過程,只要枚舉成功了,剩下的工作就不多了。
枚舉過程使用的都是控制傳輸.
下面是枚舉過程地詳細(xì)介紹:
1. 獲取設(shè)備描述符
USB主機(jī)檢測到USB設(shè)備插入后,就會先對設(shè)備復(fù)位。USB設(shè)備在總線復(fù)位后其地址為0,這樣主機(jī)就可以通過地址0和那些剛剛插入的設(shè)備通信。
USB主機(jī)往地址為0的設(shè)備的端點0發(fā)送獲取設(shè)備描述符的標(biāo)準(zhǔn)請求(這是一個控制傳輸?shù)慕⑦^程)。
設(shè)備收到該請求后,會按照主機(jī)請求的參數(shù),將設(shè)備描述符返回給主機(jī) (數(shù)據(jù)過程)。
主機(jī)在成功獲取到一個數(shù)據(jù)包的設(shè)備描述符并且確認(rèn)沒有錯誤后,就會返回一個0長度的確認(rèn)數(shù)據(jù)包(狀態(tài)過程)給設(shè)備,從而進(jìn)入到接下來的設(shè)置地址階段。
該過程具體如下
過程 | 包類型 | 同步域 | PID | ||||
---|---|---|---|---|---|---|---|
建立過程 | 1. 令牌包 (H -> D) | SYNC | SETUP | ADDR (0) | ENDP (0) | CRC5 | EOP |
2. 數(shù)據(jù)包 (H -> D ) | SYNC | DATA0 | 8 bytes | CRC16 | EOP | ||
3. 握手包 (D -> H) | SYNC | ACK | EOP | ||||
數(shù)據(jù)過程 | 1. 令牌包 (H -> D) | SYNC | IN | ADDR (0) | ENDP (0) | CRC5 | EOP |
2. 數(shù)據(jù)包 (D -> H) | SYNC | DATA1 | 8 bytes (設(shè)備描述符) | CRC16 | EOP | ||
3. 握手包 (H -> D) | SYNC | ACK | EOP | ||||
狀態(tài)過程 | 1. 令牌包 (H -> D) | SYNC | OUT | ADDR (0) | ENDP (0) | CRC5 | EOP |
2. 數(shù)據(jù)包 (H -> D ) | SYNC | DATA1 | 8 bytes | CRC16 | EOP | ||
3. 握手包 (D -> H) | SYNC | ACK | EOP |
即:
控制類型 | 建立過程 | 數(shù)據(jù)過程 | 狀態(tài)過程 |
---|---|---|---|
控制讀 | SETUP | IN(1) | OUT(1) |
DATA0 | DATA1 | DATA1 |
這里需要注意的是,第一次主機(jī)只會讀取一個數(shù)據(jù)包的設(shè)備描述符。
標(biāo)準(zhǔn)的設(shè)備描述有18字節(jié),有些USB設(shè)備的端點0大小不足18字節(jié)(但至少具有8字節(jié)),在這種情況下,USB主機(jī)也是只發(fā)送一次數(shù)據(jù)輸輸入請求,多余的數(shù)據(jù)將不會再次請求。
因此,如果當(dāng)設(shè)備端點0大小不足18字節(jié)時,就需要注意到這個問題。也就是說在第一次獲取設(shè)備描述符時,只需要返回一次數(shù)據(jù)即可,不要再等主機(jī)繼續(xù)獲取剩余數(shù)據(jù)(如果還有),因為主機(jī)不會這么干的。
當(dāng)主機(jī)成功獲取到設(shè)備描述符的前8字節(jié)之后(USB協(xié)議規(guī)定端點0最大包長至少要有8字節(jié)),它就知道端點0的最大包長度了,因為端點0最大包長度剛好在設(shè)備描述符的第八字節(jié)處。
2. 設(shè)置地址
主機(jī)對設(shè)備又一次復(fù)位。這時就進(jìn)人到了設(shè)置地址階段。
USB主機(jī)往地址為0的設(shè)備的端點0發(fā)出一個設(shè)置地址的請求(控制傳輸?shù)慕⑦^程)。新的設(shè)備地址包含在建立過程的數(shù)據(jù)包中。具體的地址由USB主機(jī)負(fù)責(zé)管理,主機(jī)會分配一個唯一的地址給剛接入的設(shè)備。
USB設(shè)備在收到這個建立過程之后,就直接進(jìn)入到狀態(tài)過程,因為這個控制傳輸沒有數(shù)據(jù)過程。然后設(shè)備等待主機(jī)請求狀態(tài)返回(一個輸入令牌包),收到輸入令牌包后,設(shè)備就返回0長度的狀態(tài)數(shù)據(jù)包。如果主機(jī)確認(rèn)該狀態(tài)包已經(jīng)正確收到,就會發(fā)送應(yīng)答包ACK給設(shè)備,設(shè)備在收到這個ACK之后,就要啟用新的設(shè)備地址了。這樣設(shè)備就分配到了一個唯一的設(shè)備地址,以后主機(jī)就通過它來訪問該設(shè)備。
該過程具體如下
過程 | 包類型 | 同步域 | PID | ||||
---|---|---|---|---|---|---|---|
建立過程 | 1. 令牌包 (H -> D) | SYNC | SETUP | ADDR (0) | ENDP (0) | CRC5 | EOP |
2. 數(shù)據(jù)包 (H -> D ) | SYNC | DATA0 | 8 bytes (含設(shè)備地址) | CRC16 | EOP | ||
3. 握手包 (D -> H) | SYNC | ACK | EOP | ||||
狀態(tài)過程 | 1. 令牌包 (H -> D) | SYNC | IN | ADDR (0) | ENDP (0) | CRC5 | EOP |
2. 數(shù)據(jù)包 (D -> H ) | SYNC | DATA1 | 8 bytes (空包) | CRC16 | EOP | ||
3. 握手包 (H -> D) | SYNC | ACK | EOP |
即:
控制類型 | 建立過程 | 狀態(tài)過程 |
---|---|---|
無數(shù)據(jù)過程寫 | SETUP (含設(shè)備地址) | IN(1) |
DATA0 | DATA1 |
3. 主機(jī)再次獲取設(shè)備描述符
這次跟第一次有點不一樣,首先是主機(jī)不再使用地址0來訪問設(shè)備,而是新的設(shè)備地址;另外,這次需要獲取全部的18字節(jié)的設(shè)備描述符。如果你的端點0最大包長小于18字節(jié),那就會有多次請求數(shù)據(jù)輸入(即發(fā)送多個IN令牌包)。
4. 主機(jī)獲取配置描述符
配置描述符總共為9字節(jié)。主機(jī)在獲取到配置描述符后,根據(jù)配置描述符中所描述的配置集合總長度,獲取配置集合。獲取配置描述符和獲取配置描述符集合的請求是差不多的,只是指定的長度不一樣。
有些主機(jī)干脆不單獨獲取配置描述符,而是直接使用最大長度來獲取配置描述符集合,因為設(shè)備實際返回的數(shù)據(jù)可以少于指定的字節(jié)數(shù)。配置集合包括配置描述符、接口描述符、類特殊描述符(如果有)、端點描述符等。接口描述符、類特殊描述符、端點描述符是不能單獨獲取的,必須跟隨配置描述符以一個集合的方式一并返回。
獲取字符串描述符文章來源:http://www.zghlxwxcb.cn/news/detail-667157.html
如果有字符串描述符,還要獲取字符串描述符。另外,像HD設(shè)備還有報告描述符等,它們是單獨獲取的。我們可以使用BUS Hound(一個非常好的數(shù)據(jù)包監(jiān)聽軟件,后面會介紹)查看數(shù)據(jù)包或者通過串口返回信息來查看具體的請求,從而在程序中增加對它們的響應(yīng)代碼。主機(jī)請求什么,你的程序就要響應(yīng)什么。文章來源地址http://www.zghlxwxcb.cn/news/detail-667157.html
到了這里,關(guān)于USB的基本概念和基礎(chǔ)知識 01的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!