一、SUB概述USB協(xié)議有兩種:USB1.1和USB2.0。(現(xiàn)在有3.0了) USB2.0和USB1.1完全兼容。USB1.1支持的 數(shù)據(jù)傳輸率為12Mbps和1.5Mbps(用于慢 速外設(shè)),USB2.0支持的數(shù)據(jù)傳速率可達 480Mbps。在普通用戶看來,USB系統(tǒng)就是 外設(shè)通過一根USB電纜和PC機連接起來。 通常把外設(shè)稱為USB設(shè)備,把其所連接的 PC機稱為USB主機。將指向USB主機的數(shù)據(jù)傳輸方向稱為上行通信,把指向USB設(shè)備的 數(shù)據(jù)傳輸方向稱為下行通信。 USB網(wǎng)絡(luò)采用階梯式星形拓撲結(jié)構(gòu),如圖1。一個USB網(wǎng)絡(luò)中只能有一個主機。主機內(nèi)設(shè)置了一個根集線器,提供了主機上的初始附屬點。
圖1 USB主機和USB設(shè)備的連接 主機定時對集線器的狀態(tài)進行查詢。當一個新設(shè)備接入集線器時,主機會檢測到集線器狀態(tài)改變,主機發(fā)出一個命令使該端口有效并對其進行設(shè)置。位于這個端口上的設(shè)備進行響應(yīng),主機收到關(guān)于設(shè)備的信息,主機的操作系統(tǒng)確定對這個設(shè)備使用那種驅(qū)動程序,接著設(shè)備被分配一個唯一標識的地址,范圍從0~127,其中0為所有的設(shè)備在沒有分配惟一地址時使用的默認地址。主機向它發(fā)出內(nèi)部設(shè)置請求。當一個設(shè)備從總線上移走時,主機就從其可用資源列表中將這個設(shè)備刪除。 二、USB系統(tǒng)基本概念2.1、 USB主機USB的所有數(shù)據(jù)通信(不論是上行通信還是下行通信)都由USB主機啟動,所以USB主機在整個數(shù)據(jù)傳輸過程中占據(jù)著主導(dǎo)地位。在USB系統(tǒng)中只允許有一個主機。從開發(fā)人員的角度看,USB主機可分為三個不同的功能模塊:客戶軟件、USB系統(tǒng)軟件和USB總線接口。 (1) 客戶軟件 : 客戶軟件負責和USB設(shè)備的功能單元進行通信,以實現(xiàn)其特定功能。一般由開發(fā)人員自行開發(fā)??蛻糗浖荒苤苯釉L問USB設(shè)備,其與USB設(shè)備功能單元的通信必須經(jīng)過USB系統(tǒng)軟件和USB總線接口模塊才能實現(xiàn)??蛻糗浖话惆║SB設(shè)備驅(qū)動程序和界面應(yīng)用程序兩部分。 USB設(shè)備驅(qū)動程序負責和USB系統(tǒng)軟件進行通信。通常,它向USB總線驅(qū)動程序發(fā)出I/O請求包(IRP)以啟動一次USB數(shù)據(jù)傳輸。此外,根據(jù)數(shù)據(jù)傳輸?shù)姆较?,它還應(yīng)提供一個或空或滿的數(shù)據(jù)緩沖區(qū)以存儲這些數(shù)據(jù)。 (2) USB系統(tǒng)軟件: USB系統(tǒng)軟件負責和USB邏輯設(shè)備進行配置通信,并管理客戶軟件啟動的數(shù)據(jù)傳輸。USB邏輯設(shè)備是程序員與USB設(shè)備打交道的部分。USB系統(tǒng)軟件一般包括USB總線驅(qū)動程序和USB主控制器驅(qū)動程序這兩部分。這些軟件通常由操作系統(tǒng)提供,開發(fā)人員不必掌握。 (3) USB總線接口: USB總線接口包括主控制器和根集線器兩部分。根集線器為USB系統(tǒng)提供連接起點,用于給USB系統(tǒng)提供一個或多個連接點(端口)。主控制器負責完成主機和USB設(shè)備之間數(shù)據(jù)的實際傳輸,包括對傳輸?shù)臄?shù)據(jù)進行串行編解碼、差錯控制等。該部分與USB系統(tǒng)軟件的接口依賴于主控制器的硬件實現(xiàn),開發(fā)人員不必掌握。 2.2、USB設(shè)備一個USB設(shè)備由三個功能模塊組成:USB總線接口、USB邏輯設(shè)備和功能單元。這里的USB總線接口指的是USB設(shè)備中的串行接口引擎(SIE);USB邏輯設(shè)備被USB系統(tǒng)軟件看作是一個端點的集合;功能單元被客戶軟件看作是一個接口的集合。SIE、端點和接口都是USB設(shè)備的組成單元。為了更好地描述USB設(shè)備的特征,USB提出了設(shè)備架構(gòu)的概念。從這個角度來看,可以認為USB設(shè)備是由一些配置、接口和端點組成的,即一個USB設(shè)備可以含有一個或多個配置,在每個配置中可含有一個或多個接口,在每個接口中可含有若干個端點。其中,配置和接口是對USB設(shè)備功能的抽象,實際的數(shù)據(jù)傳輸由端點來完成。在使用USB設(shè)備前,必須指明其采用的配置和接口。這個步驟一般是在設(shè)備接入主機時設(shè)備進行自舉時完成的,我們在后面會進一步介紹。USB設(shè)備使用各種描述符來說明其設(shè)備架構(gòu),包括設(shè)備描述符、配置描述符、接口描述符、端點描述符以及字符串描述符,它們通常被保存在USB設(shè)備的固件程序中。 ①設(shè)備: 設(shè)備代表一個USB設(shè)備,它由一個或多個配置組成。設(shè)備描述符用于說明設(shè)備的總體信息,并指明其所含的配置的個數(shù)。一個USB設(shè)備只能有一個設(shè)備描述符。 ②配置: 一個USB設(shè)備可以包含一個或多個配置,如USB設(shè)備的低功耗模式和高功耗模式可分別對應(yīng)一個配置。在使用USB設(shè)備前,必須為其選擇一個合適的配置。配置描述符用于說明USB設(shè)備中各個配置的特性,如配置所含接口的個數(shù)等。USB設(shè)備的每一個配置都必須有一個配置描述符。 ③接口: 一個配置可以包含一個或多個接口,如對一個光驅(qū)來說,當用于文件傳輸時使用其大容量存儲接口;而當用于播放CD時,使用其音頻接口。接口是端點的集合,可以包含一個或多個可替換設(shè)置,用戶能夠在USB處于配置狀態(tài)時,改變當前接口所含的個數(shù)和特性。接口描述符用于說明USB設(shè)備中各個接口的特性,如接口所屬的設(shè)備類及其子類等。USB設(shè)備的每個接口都必須有一個接口描述符。 ④端點: 端點是USB設(shè)備中的實際物理單元,USB數(shù)據(jù)傳輸就是在主機和USB設(shè)備各個端點之間進行的。端點一般由USB接口芯片提供,例如Freescale的MC68HC908JB8。USB設(shè)備中的每一個端點都有唯一的端點號,每個端點所支持的數(shù)據(jù)傳輸方向一般而言也是確定的:或是輸入(IN)或是輸出(OUT),也有些芯片提供的端點的數(shù)據(jù)方向是可以配置的,例如MC68HC908JB8包含有兩個用于數(shù)據(jù)收發(fā)的端點:端點1和端點2。其中端點1只能用于數(shù)據(jù)發(fā)送,即支持輸入(IN),端點2既能用于數(shù)據(jù)發(fā)送也可用于數(shù)據(jù)接收,即支持輸入(IN)和輸出(OUT)操作。需要注意的是,在這里數(shù)據(jù)的傳輸方向是站在主機的立場上來看得。比如端點1只能發(fā)送數(shù)據(jù),在主機看來是端點1向主機輸入數(shù)據(jù),即IN操作;當端點2配置為接收數(shù)據(jù)時,主機向端點2輸出數(shù)據(jù),即OUT操作。這一點是初學(xué)者比較容易產(chǎn)生混淆的地方。 利用設(shè)備地址、端點號和傳輸方向就可以指定一個端點,并和它進行通信。0號端點比較特殊,它有數(shù)據(jù)輸入IN和數(shù)據(jù)輸出OUT兩個物理單元,且只能支持控制傳輸。 ⑤字符串 在USB設(shè)備中通常還含有字符串描述符,以說明一些專用信息,如制造商的名稱、設(shè)備的序列號等。它的內(nèi)容以UNICODE的形式給出,且可以被客戶軟件所讀取。對USB設(shè)備來說,字符串描述符是可選的。 ⑥管道 在USB系統(tǒng)結(jié)構(gòu)中,可以認為數(shù)據(jù)傳輸是在主機軟件(USB系統(tǒng)軟件或客戶軟件)和USB設(shè)備的各個端點之間直接進行的,它們之間的連接稱為管道。管道是在USB設(shè)備的配置過程中建立的。管道是對主機和USB設(shè)備間通信流的抽象,它表示主機的數(shù)據(jù)緩沖區(qū)和USB設(shè)備的端點之間存在著邏輯數(shù)據(jù)傳輸,而實際的數(shù)據(jù)傳輸是由USB總線接口層來完成的。 管道和USB設(shè)備中的端點一一對應(yīng)。一個USB設(shè)備含有多少個端點,其和主機進行通信時就可以使用多少條管道,且端點的類型決定了管道中數(shù)據(jù)的傳輸類型,如中斷端點對應(yīng)中斷管道,且該管道只能進行中斷傳輸。傳輸類型在后面會介紹。不論存在著多少條管道,在各個管道中進行的數(shù)據(jù)傳輸都是相互獨立的。 三、USB物理特性3.1、USB接口USB使用一根屏蔽的4線電纜與網(wǎng)絡(luò)上的設(shè)備進行互聯(lián)。數(shù)據(jù)傳輸通過一個差分雙絞線進行,這兩根線分別標為D+和D-,另外兩根線是Vcc和Ground,其中Vcc向USB設(shè)備供電。使用USB電源的設(shè)備稱為總線供電設(shè)備,而使用自己外部電源的設(shè)備叫做自供電設(shè)備。為了避免混淆,USB電纜中的線都用不同的顏色標記,如表1所示。(現(xiàn)在為了支持主機,設(shè)備的互換,增加了一條線,OTG,也就有了mini USB)
從一個設(shè)備連回到主機,稱為上行連接;從主機到設(shè)備的連接,稱為下行連接。為了防止回環(huán)情況的發(fā)生,上行和下行端口使用不同的連接器所以USB在電纜和設(shè)備的連接中分別采用了兩種類型的連接頭,即圖16-2所示的A型連接頭和B型連接頭。每個連接頭內(nèi)的電線號與圖16-2的引腳編號是一致的。A型連接頭,用于上行連接,即在主機或集線器上有一個A型插座,而在連接到主機或集線器的電纜的一端是A型插頭。在USB設(shè)備上有B型插座,而B型插頭在從主機或集線器接出的下行電纜的一端。采用這種連接方式,可以確保USB設(shè)備、主機/集線器和USB電纜始終以正確的方式連接,而不出現(xiàn)電纜接入方式出錯,或直接將兩個USB設(shè)備連接到一起的情況。 圖2 USB連接頭 3.2、USB信號(1) 差分信號技術(shù)特點 (2)USB通信的格式 圖3 在USB電纜上使用雙向不歸零編碼和差動信號的傳輸 USB的數(shù)據(jù)包使用反向不歸零編碼(NRZI)。圖3描述了在USB電纜段上傳輸信息的步驟。反向不歸零編碼由傳送信息的USB代理程序完成;然后,被編碼的數(shù)據(jù)通過差分驅(qū)動器送到USB電纜上;接著,接收器將輸入的差分信號進行放大,將其送給解碼器。使用該編碼和差動信號傳輸方式可以更好地保證數(shù)據(jù)的完整性并減少噪聲干擾。 圖4 反向不歸零編碼 使用反向不歸零編碼方式可以保證數(shù)據(jù)傳輸?shù)耐暾?,而且不要求傳輸過程中有獨立的時鐘信號。反向不歸零編碼不是一個新的編碼方式。它在許多方面都有應(yīng)用。圖4給出了一個數(shù)據(jù)流和編碼之后的結(jié)果。在反向不歸零編碼時,遇到“0”轉(zhuǎn)換,遇到“1”保持。反向不歸零碼必須保持與輸入數(shù)據(jù)的同步性,以確保數(shù)據(jù)采樣正確。反向不歸零碼數(shù)據(jù)流必須在一個數(shù)據(jù)窗口被采樣,無論前一個位時間是否發(fā)生過轉(zhuǎn)換。解碼器在每個位時間采樣數(shù)據(jù)以檢查是否有轉(zhuǎn)換。 圖5 在USB電纜上使用雙向不歸零編碼和差動信號的傳輸 若重復(fù)相同的“1”信號一直進入時,就會造成數(shù)據(jù)長時間無法轉(zhuǎn)換,逐漸的積累,而導(dǎo)致接收器最終丟失同步信號的狀況,使得讀取的時序會發(fā)生嚴重的錯誤。因此,在NRZI編碼之間,還需執(zhí)行所謂的位填充的工作。位填充要求數(shù)據(jù)流中如果有連續(xù)的六個“1”就要強行轉(zhuǎn)換。這樣接收器在反向不歸零碼數(shù)據(jù)流中最多每七個位就檢測到一次跳轉(zhuǎn)。這樣就保證了接收器與輸入數(shù)據(jù)流保持同步。反向不歸零碼的發(fā)送器要把“0”(填充位)插到數(shù)據(jù)流中。接收器必須被設(shè)計成能夠在連續(xù)的六個“1”之后識別一個自動跳轉(zhuǎn),并且立即扔掉這六個“1”之后的“0”位。 圖5的第一行是送到接收器的原始數(shù)據(jù)。注意數(shù)據(jù)流包括連續(xù)的八個“1”。第二行表示對原始數(shù)據(jù)進行了位填充,在原始的第六個和第七個“1”之間填入了一個“0”。第七個“1”延時一個位時間讓填充位插入。接收器知道連續(xù)六個“1”之后將是一個填充位,所以該位就要被忽略。注意,如果原始數(shù)據(jù)的第七個位是“0”,填充位也同樣插入,在填充過的數(shù)據(jù)流中就會有兩個連續(xù)的“0”。 3.3、檢測設(shè)備連接和速度在USB設(shè)備連接時,USB系統(tǒng)能自動檢測到這個連接,并識別出其采用的數(shù)據(jù)傳輸速率。USB采用在D+或D-線上增加上拉電阻的方法來識別低速和全速設(shè)備。USB支持三種類型的傳輸速率:1.5Mb/s的低速傳輸、12Mb/s的全速傳輸和480Mb/s的高速傳輸。如圖6所示。當主控制器或集線器的下行端口上沒有USB設(shè)備連接時,其D+和D-線上的下拉電阻使得這兩條數(shù)據(jù)線的電壓都是近地的(0V);當全速/低速設(shè)備連接以后,電流流過由集線器的下拉電阻和設(shè)備在D+/D-的上拉電阻構(gòu)成的分壓器。由于下拉電阻的阻值是15KΩ,上拉電阻的阻值是1.5KΩ,所以在D+/D-線上會出現(xiàn)大小為(Vcc*15/(15+1.5))的直流高電平電壓。當USB主機探測到D+/D-線的電壓已經(jīng)接近高電平,而其它的線保持接地時,它就知道全速/低速設(shè)備已經(jīng)連接了。保持接地時,它就知道全速/低速設(shè)備已經(jīng)連接了。 圖6:USB連接圖 四、USB通信協(xié)議4.1、 數(shù)據(jù)包包(Packet)是USB系統(tǒng)中信息傳輸?shù)幕締卧?,所有?shù)據(jù)都是經(jīng)過打包后在總線上傳輸?shù)摹SB包由五部分組成,即同步字段(SYNC)、包標識符字段(PID)、數(shù)據(jù)字段、循環(huán)冗余校驗字段(CRC)和包結(jié)尾字段(EOP),包的基本格式如下:
4.1.1、SYNC字段:由8位組成,作為每個數(shù)據(jù)封包的前導(dǎo),用來產(chǎn)生同步作用,使USB設(shè)備與總線的包傳輸率同步,它的數(shù)值固定為00000001。 4.1.2、PID字段:用來表示數(shù)據(jù)封包的類型。包標識符中的校驗字段是通過對類型字段的每個位求反碼產(chǎn)生的, PID字段如下圖所示:
4.1.3、數(shù)據(jù)字段: 是用來攜帶主機與設(shè)備之間要傳遞的信息,其內(nèi)容和長度根據(jù)包標識符、傳輸類型的不同而各不相同。在USB包中,數(shù)據(jù)字段可以包含設(shè)備地址、端點號、幀序列號以及數(shù)據(jù)等內(nèi)容。在總線傳輸中,總是首先傳輸字節(jié)的最低位,最后傳輸字節(jié)的最高位。 (1) 設(shè)備地址(ADDR)數(shù)據(jù)域:ADDR數(shù)據(jù)域由7位組成,可用來尋址多達127個外圍設(shè)備。 4.1.4、循環(huán)冗余碼CRC:字段由不同數(shù)目的位所組成。根據(jù)不同的信息包類型,CRC數(shù)據(jù)域由不同數(shù)目的位所組成。其中重要的數(shù)據(jù)信息包采用CRC16的數(shù)據(jù)域(16個位),而其余的信息包類型則采用CRC5的數(shù)據(jù)域(5個位)。其中的循環(huán)冗余碼校驗CRC,是一種錯誤檢測技術(shù)。由于數(shù)據(jù)在傳輸時,有時候會發(fā)生錯誤,因此CRC可根據(jù)數(shù)據(jù)算出一個校驗值,然后依此判斷數(shù)據(jù)的正確性 4.1.5、包結(jié)尾字段:即發(fā)送方在包的結(jié)尾發(fā)出包結(jié)尾信號。USB主機根據(jù)EOP判斷數(shù)據(jù)包的結(jié)束。 4.2、信息包格式4.2.1、令牌(token)包: 在USB系統(tǒng)中,只有主機才能發(fā)出令牌包。令牌包定義了數(shù)據(jù)傳輸?shù)念愋?,它是事?wù)處理的第一階段。令牌包中較為重要的是SETUP、IN和OUT這三個令牌包。它們用來在根集線器和設(shè)備端點之間建立數(shù)據(jù)傳輸。一個IN包用來建立一個從設(shè)備到根集線器的數(shù)據(jù)傳送,一個OUT包用來建立從根集線器到設(shè)備的數(shù)據(jù)傳輸。令牌包格式如下:
4.3、事務(wù)在USB上數(shù)據(jù)信息的一次接收或發(fā)送的處理過程稱為事務(wù)處理(Transaction)。事務(wù)處理的類型包括輸入(IN)事務(wù)處理、輸出(OUT)事務(wù)處理、設(shè)置(SETUP)事務(wù)處理和幀開始、幀結(jié)尾等類型。在輸出(OUT)事務(wù)處理和設(shè)置(SETUP)事務(wù)處理中,緊接著SETUP和OUT包后的是DATA包,DATA0和DATA1包是交替地發(fā)送的,在DATA包后面,設(shè)備將回應(yīng)一個握手信號,如果設(shè)備可以接收數(shù)據(jù),就回應(yīng)ACK包,如果設(shè)備忙,就回應(yīng)NAK包,如果設(shè)備出錯,則回應(yīng)STALL包;在IN事務(wù)中,IN包后面是設(shè)備發(fā)來的DATA包或NAK包或STALL包,若設(shè)備忙或出錯,就發(fā)NAK包或STALL包給主機,若設(shè)備數(shù)據(jù)準備好發(fā)送,則發(fā)DATA包,DATA0和DATA1包也是交替地發(fā)送的,緊接著DATA包后面是主機發(fā)給設(shè)備的握手包,ACK表示主機可以接收數(shù)據(jù),NAK包代表主機忙,STALL包代表主機出錯。 4.3.1、輸入(IN)事務(wù)處理輸入事務(wù)處理表示USB主機從總線上的某個USB設(shè)備接收一個數(shù)據(jù)包的過程。 ①正常的輸入事務(wù)處理
4.3.2、輸出(OUT)事務(wù)處理輸入事務(wù)處理表示USB主機從總線上的某個USB設(shè)備接收一個數(shù)據(jù)包的過程。 ①正常的輸入事務(wù)處理
②設(shè)備忙時的輸入事務(wù)處理
③設(shè)備出錯時的輸入事務(wù)處理
4.3.3、設(shè)置(SETUP)事務(wù)處理 輸入事務(wù)處理表示USB主機從總線上的某個USB設(shè)備接收一個數(shù)據(jù)包的過程。 ①正常的輸入事務(wù)處理
②設(shè)備忙時的輸入事務(wù)處理
③設(shè)備出錯時的輸入事務(wù)處理
4.4、USB的傳輸類型在USB的傳輸中,制定了4種傳輸類型:控制傳輸、中斷傳輸、批量傳輸以及等時傳輸??刂苽鬏旑愋头譃?~3個階段:設(shè)置階段、數(shù)據(jù)階段(無數(shù)據(jù)控制沒有此階段)以及狀態(tài)階段。根據(jù)數(shù)據(jù)階段的數(shù)據(jù)傳輸?shù)姆较颍刂苽鬏斢挚煞譃?種類型:控制讀?。ㄗx取USB描述符)、控制寫入(配置USB設(shè)備)以及無數(shù)據(jù)控制。 4.4.1、控制傳輸控制傳輸是USB傳輸中最重要的傳輸。它包含3種類型:控制讀取、控制寫入以及無數(shù)據(jù)控制。這3種控制傳輸類型又分為2~3個階段:設(shè)置階段、數(shù)據(jù)階段(無數(shù)據(jù)控制沒有此階段)以及狀態(tài)階段。 階段一:設(shè)置階段 主機從USB設(shè)備獲取配置信息,并設(shè)置設(shè)備的配置值。設(shè)置階段的數(shù)據(jù)交換包含了SETUP令牌封包、緊隨其后的DATA0數(shù)據(jù)封包以及ACK握手封包。它的作用是執(zhí)行一個設(shè)置(概念含糊)的數(shù)據(jù)交換,并定義此控制傳輸?shù)膬?nèi)容。 階段二:數(shù)據(jù)傳輸階段 數(shù)據(jù)傳輸階段用來傳輸主機與設(shè)備之間的數(shù)據(jù)??刂谱x取是將數(shù)據(jù)從設(shè)備讀到主機上,讀取的數(shù)據(jù)USB設(shè)備描述符。該過程如圖16-8所示。對每一個數(shù)據(jù)信息包而言,首先,主機會發(fā)送一個IN令牌信息包,表示要讀數(shù)據(jù)進來。然后,設(shè)備將數(shù)據(jù)通過DATA1數(shù)據(jù)信息包回傳給主機。最后,主機將以下列的方式加以響應(yīng):當數(shù)據(jù)已經(jīng)正確接收時,主機送出ACK令牌信息包;當主機正在忙碌時,發(fā)出NAK握手信息包;當發(fā)生了錯誤時,主機發(fā)出STALL握手信息包。 控制寫入則是將數(shù)據(jù)從主機傳到設(shè)備上,所傳的數(shù)據(jù)即為對USB設(shè)備的配置信息,該過程如圖16-9所示。對每一個數(shù)據(jù)信息包而言,主機將會送出一個OUT令牌信息包,表示數(shù)據(jù)要送出去。緊接著,主機將數(shù)據(jù)通過DATA0數(shù)據(jù)信息包傳遞至設(shè)備。最后,設(shè)備將以下列方式加以響應(yīng):當數(shù)據(jù)已經(jīng)正確接收時,設(shè)備送出ACK令牌信息包;當設(shè)備正在忙碌時,設(shè)備發(fā)出NAK握手信息包;當發(fā)生了錯誤時,設(shè)備發(fā)出STALL握手信息包。 圖7 控制讀取的IN數(shù)據(jù)交換的過程示意圖 圖 8 控制寫入的OUT數(shù)據(jù)交換的過程示意圖 階段三:狀態(tài)階段 狀態(tài)階段用來表示整個傳輸?shù)倪^程已完全結(jié)束。狀態(tài)階段傳輸?shù)姆较虮仨毰c數(shù)據(jù)階段的方向相反,即原來是IN令牌封包,這個階段應(yīng)為OUT令牌封包;反之,原來是OUT令牌封包,這個階段應(yīng)為IN令牌封包。對于控制讀取而言,主機會送出OUT令牌封包,其后再跟著0長度的DATA1封包。而此時,設(shè)備也會做出相對應(yīng)的動作,送ACK握手封包、NAK握手封包或STALL握手封包。相對地對于控制寫入傳輸,主機會送出IN令牌封包,然后設(shè)備送出表示完成狀態(tài)階段的0長度的DATA1封包,主機再做出相對應(yīng)的動作:送ACK握手封包、NAK握手封包或STALL握手封包。 4.4.2、實時傳輸實時傳輸適用于必須以固定速率抵達或在指定時刻抵達,可以容忍偶爾錯誤的數(shù)據(jù)上。實時傳輸一般用于麥克風(fēng)、喇叭等設(shè)備。實時傳輸只需令牌與數(shù)據(jù)兩個信息包階段,沒有握手包,故數(shù)據(jù)傳錯時不會重傳。 4.4.3、批量傳輸用于傳輸大量數(shù)據(jù),要求傳輸不能出錯,但對時間沒有要求,適用于打印機、存儲設(shè)備等。 4.4.4、中斷傳輸中斷傳輸方式總是用于對設(shè)備的查詢,以確定是否有數(shù)據(jù)需要傳輸。因此中斷傳輸?shù)姆较蚩偸菑腢SB設(shè)備到主機。 4.5、設(shè)備列舉4.5.1、描述符USB描述符就好像是USB外圍設(shè)備的“身份證”一樣,詳細地記錄著外圍設(shè)備相關(guān)的一切信息。為了描述不同的數(shù)據(jù),就需以不同類型的USB描述符來加以描述,它共有以下幾種類型:設(shè)備描述符、配置描述符、接口描述符和端點描述符,這幾個描述符是必須具有的,下面將結(jié)合實例詳細介紹;其他的描述符,例如,字符串描述符、數(shù)種不同的群組描述符以及報告描述符則可以根據(jù)不同的設(shè)備進行選擇。 (1)設(shè)備描述符 設(shè)備描述符具有 18 字節(jié)的長度,并且是主機向設(shè)備請求的第一個描述符。 以下列出設(shè)備描述符的范例、數(shù)值以及各個字段的意義(以C語言偽代碼表示): typedef struct _USB_DEVICE_DESCRIPTOR { BYTE bLength; //0x12, 表示該描述符的字節(jié)長度為18個字節(jié), BYTE bDescriptorType; //描述符類型,1代表設(shè)備 WORD bcdUSB; BYTE bDeviceClass; BYTE bDeviceSubClass; BYTE bDeviceProtocol; BYTE bMaxPacketSize0; WORD idVendor; WORD idProduct; WORD bcdDevice; BYTE iManufacturer; BYTE iProduct; BYTE iSerialNumber; BYTE bNumConfigurations;} USB_DEVICE_DESCRIPTOR; bLength是本結(jié)構(gòu)的數(shù)據(jù)長度,這樣可以方便以后兼容不同的版本協(xié)議。因為不同的結(jié)構(gòu)是不同的長度,這樣就可以區(qū)分不同的協(xié)議了。比如有一天想添加一個字段,那么它的長度就會改變,這時就可以根據(jù)不同的長度進行解釋不同的協(xié)議了。這次返回的結(jié)構(gòu)長度是0x12,也就是18個字節(jié),它的長度是從bLength長度開始,也就是說是完全整個結(jié)構(gòu)的長度。 bDescriptorType是描述符的類型。它的定義跟主控器發(fā)下來描述符的類型是一樣的,如下:
表3、描述符類型 由于返回的是設(shè)備描述符,所以就選擇了1,也就是包里顯示的第二個字節(jié)01。用這個類型來區(qū)分不同的描述符。 bcdUSB是USB發(fā)布的協(xié)議版本。也就是本設(shè)備能適用于那種協(xié)議,目前USB主要有兩個版本,一個是1.10,一個是2.10版本。在本設(shè)備里,采用了1.10的協(xié)議版本。由于這個字段是采用BCD編碼,所以1.10的表示為0x0110的格式,0x0210就表示USB2.10版本。 bDeviceClass是設(shè)備分類。當它的值是0時,表示所有接口在配置描述符里,并且所有接口是獨立的。當它的值是1到FEH時,表示不同的接口關(guān)聯(lián)的。當它的值是FFH時,它是廠商自己定義的。在這個設(shè)備里,是定義為0。 bDeviceSubClass是設(shè)備子分類碼。當前面的bDeviceClass值是0時,這里一定要設(shè)置為0。其它就跟據(jù)USB-IF組織定義的編碼。 bDeviceProtocol是設(shè)備使用的協(xié)議。如果使用USB-IF組織定義的協(xié)議,就需要設(shè)置這里的值。如果不使用,就直接設(shè)置為0。如果廠商自己定義的可以設(shè)置為FFH。 bMaxPacketSize0是端點0收發(fā)最大的包大小。僅允許設(shè)置8,16,32,64中的任何一個大小。 idVendor是廠商標識。由USB-IF分配的編碼。 idProduct是廠商定義的產(chǎn)品標識。由廠家和產(chǎn)品標識,就可以讓操作系統(tǒng)加載不同的驅(qū)動程序。 bcdDevice是用BCD表示的設(shè)備發(fā)布的版本號。 iManufacturer是廠商字符串的偏移值。這值主要說明了它在字符串描述符里的偏移位置。如果它設(shè)置為0,表示沒有廠商字符串。字符串描述符后面會講到。 iProduct是產(chǎn)品字符串的偏移值。這值主要說明了它在字符串描述符里的偏移位置。如果它設(shè)置為0,表示沒有產(chǎn)品字符串。字符串描述符后面會講到。 iSerialNumber是序列號字符串的偏移值。這值主要說明了它在字符串描述符里的偏移位置。如果它設(shè)置為0,表示沒有序列號字符串。所有字符串,都是采有UNICODE編碼。 bNumConfigurations是配置描述符的個數(shù)。在這里只使用了一個配置,所以設(shè)置為1。 2)配置描述符 配置描述符具有 9 字節(jié)的長度,針對設(shè)備給予配置的信息。以下列出配置 描述符的范例、數(shù)值以及各個字段的意義: typedef struct _USB_CONFIGURATION_DESCRIPTOR { BYTE bLength; //是配置的長度,也就是配置結(jié)構(gòu)的整個長度。在這里9個字節(jié)。 BYTE bDescriptorType; //是描述符的類型,這里配置描述符,所以設(shè)置為02。具體含義見表3 WORD wTotalLength; //是所有配置設(shè)置的結(jié)構(gòu)長度。包括配置描述符、接口描述符、HID或者其它描述符和端點描述符的長度。 BYTE bNumInterfaces; //該配置支持的接口數(shù)目(1字節(jié)) BYTE bConfigurationValue; //配置值,作為Set Configuration請求的配置值 BYTE iConfiguration; //是說明配置的字符的偏移值 BYTE bmAttributes; //是配置特性,D7位保留。D6位是說明是否自供電。D5位是否支持遠程喚醒。D4—D0是保留,設(shè)置為0。 BYTE MaxPower; //是使用的功率,它采用電流來表示。每2mA為單位,比如它的值是50時就表示是100mA的電流消耗。 //通過這樣說明,主控器就知道這個設(shè)備是什么樣的設(shè)備,有多少功能。} USB_CONFIGURATION_DESCRIPTOR; (3)接口描述符 接口描述符具有 9 字節(jié)的長度,用來描述每一個設(shè)備的接口特性。以下列 出接口描述符的范例、數(shù)值以及各個字段的意義:typedef struct _USB_INTERFACE_DESCRIPTOR { BYTE bLength; //表示該描述符的字節(jié)長度為9個字節(jié). BYTE bDescriptorType; //描述符類型,4代表接口。具體含義見表3 BYTE bInterfaceNumber; //接口數(shù)目以0為基值(表示一個接口)。 BYTE bAlternateSetting; //域,交互設(shè)置值為0(因為只有一個接口) BYTE bNumEndpoints; //端點數(shù)目設(shè)置為2 BYTE bInterfaceClass; //接口群組,$FF表示是供應(yīng)商說明書 BYTE bInterfaceSubClass; //接口次群組 BYTE bInterfaceProtocol; //接口協(xié)議,$FF表示該接口使用的 ;是供應(yīng)商說明的協(xié)議 BYTE iInterface; //接口的字符串描述符的索引,本實例沒有 }USB_INTERFACE_DESCRIPTOR; (4)端點描述符 端點描述符具有 7 字節(jié)長度,用來描述端點的屬性以及各個端點的位置。 該實例中有兩個端點,bEndpointAddress域的值不同,來區(qū)別IN/OUT端點 typedef struct _USB_ENDPOINT_DESCRIPTOR { BYTE bLength; //表示該描述符的字節(jié)長度為 7 個字節(jié) BYTE bDescriptorType; //描述符類型,5代表端點。具體含義見表3 BYTE bEndpointAddress; //端點地址([0x81=IN,0x02=OUT]) BYTE bmAttributes; //傳輸類型的屬性設(shè)置為中斷傳輸 ;(0=控制,1=等時,2=批量,3=中斷) WORD wMaxPacketSize; //域,最大信息包的大小設(shè)置為8個字節(jié) BYTE bInterval; //輪詢間隔,以ms為單位,在此設(shè)置為10m,0xA, }USB_ENDPOINT_DESCRIPTOR; (5) 字符串描述符ypedef struct _USB_STRING_DESCRIPTOR { BYTE bLength; //是所有數(shù)據(jù)的長度。具體長度根據(jù)bString的長度而定 BYTE bDescriptorType; //是描述類型,這里字符串描述符,所以它是3 WORD bString/*[]*/; //是可變的字符數(shù)組。不超過254個應(yīng)都可以的,并且它是使用UNICODE編碼的字符串。美國英語的標識,0x0409。中文的標識=0x0804。 //通過這個字符串描述符,主控器就知道字符串描述符是使用什么語言說明的了,這樣就可以支持全世界的語言標識。 } USB_STRING_DESCRIPTOR;4.5.2.USB請求主機要獲取相關(guān)信息,需要發(fā)送配置包,用C代碼定義如下: typedef struct _USB_SETUP_PACKET{ REQUEST_TYPE bmRequestType; BYTE bRequest; WORD_BYTE wValue; WORD_BYTE wIndex; WORD wLength;} USB_SETUP_PACKET; bmRequestType是包含有下面幾方面的內(nèi)容:D7 D6 D5 D4 D3 D2 D1 D0 在這一個字節(jié)里,又按位分為:D7位是表示后面?zhèn)魉蛿?shù)據(jù)的方向位。當D7等于0時,表示后面的數(shù)據(jù)是從主控器發(fā)送到USB設(shè)備。在PC里,就是從PC機發(fā)送到USB的設(shè)備。當D7等于1時,表示后面的數(shù)據(jù)是從USB設(shè)備發(fā)送到主控器。在PC里,就是從USB設(shè)備發(fā)送到USB設(shè)備。 D6-D5位是請求主分類型:0 是表示標準的請求。1 是表示類別的請求。2 是表示廠商的請求。3 是保留。 D4-D0位是表求接收這個包的接口。0 是表示USB設(shè)備接收。1 是表示接口接收。2 是表示端點接收。3 是表示其它接收,不知道的。4-31是保留。 bRequest是本描述符的請求類型,也就是后面發(fā)送的數(shù)據(jù)是什么樣的東西。由于USB里有很多配置信息,比如獲取設(shè)備描述符,又有設(shè)置USB地址等等,就是通過這個字節(jié)來區(qū)分的。
表4: 請求描述符的類型。 主控器想讀取USB設(shè)備的描述符,那么bRequest的值就應(yīng)該是0x06. wValue是根據(jù)不同的請求而設(shè)置不同的值。一般就是傳送參數(shù)給設(shè)備標明這是什么請求。在上面GET_DESCRIPTOR獲取設(shè)備描述符里,它的值是00 01。在GET_DESCRIPTOR里這個字段的低字節(jié)表示描述符的索引,高字節(jié)表示描述符的類型。高字節(jié)的類型如表3所示。wValue值在這里的高字節(jié)是01,那么它就是設(shè)備描述符了。低字節(jié)是00,那么它就是表示從偏移地址0開始讀取設(shè)備描述符。由于在配置描述符里有很多配置,所以低字節(jié)在那里就可以用來識別獲取同樣類型的描述符不同的配置。 wIndex是根據(jù)不同的請求而設(shè)置不同的值。一般用來說明端點號或者說明接口標識。在獲取描述符里,設(shè)置為0,或者是語言ID。在這個發(fā)送的描述符里,它是設(shè)置為00 00。 wLength是根據(jù)請求來決定下一階段發(fā)送數(shù)據(jù)的長度。前面請求第一個字節(jié)里,已經(jīng)說明下一階段數(shù)據(jù)傳送的方向,這里說明了傳送數(shù)據(jù)的長度。不管是發(fā)送數(shù)據(jù),還是接收數(shù)據(jù),都不要超過這個數(shù)據(jù)長度,否則主機會出問題,或者設(shè)備有問題。 面結(jié)合實例分別介紹幾個主要的設(shè)備請求。 (1) 清除特性(Clear Feature):
(2) 取得描述符(Get Descriptor)
(3) 設(shè)置地址(Set Address)
(4) 設(shè)置配置(Set Configuration)
4.5.3、設(shè)備列舉 設(shè)備列舉可以簡單地概括為這樣的一個過程:主機通過USB設(shè)備請求來取得設(shè)備描述符并對該設(shè)備進行配置。該過程可以簡化為如下5個步驟: |
|
來自: 出家人eqyi0h1n > 《usb》