文/張凡忠 公安部第一研究所
摘要:USB設備已成為當前移動設備數(shù)據(jù)傳輸?shù)闹饕獋鬏斀涌?,即便在安防,移動存儲或擴展存儲時,也時常需要到,但USB技術如何?可怎樣設計和利用?請看本文就USB的體系結構、USB通信技術基礎、USB固件程序的開發(fā)方法等是如何論述的。
前言
不管是計算機還是連接的外圍設備,在新品開發(fā)時保持兼容性是必須考慮的。即使是革命性的新外圍設備,也必須使用到連接計算機的接口。當設計一個外圍設備的接口時,下列是該外圍設備應該具備的特性:
穩(wěn)定性:具備自動差錯與除錯的功能,使錯誤的發(fā)生率幾乎為零;
便宜:讓大部分的用戶都有能力購買;
省電:在便攜式計算機上節(jié)省電池的消耗;
有彈性:讓許多不同種類的外圍設備,都可以使用這個接口;
快速:此接口不可以成為傳輸?shù)钠款i;
容易使用:用戶容易安裝、設置與使用;
操作系統(tǒng)的支持:如果操作系統(tǒng)支持此接口,開發(fā)者就不必要自行開發(fā)底層的驅動程序來使用此接口。
USB就是一個為符合上述所有條件而開發(fā)的最新外圍設備接口。USB是一種通用串行總線。它是由COMPAQ、INTEL、MICROSOFT和NEC等公司共同開發(fā)的一種新型、快速、雙向、同步傳輸?shù)牟⒖梢詿岵灏蔚臄?shù)據(jù)傳輸總線接口。
規(guī)范的版本
USB規(guī)范的版本變動,如表1所示。
經(jīng)過多次版本的更新后,USB1.0發(fā)表于1996年1月。USB1.1則修訂了1.0版本的問題,并且新增一個新的傳輸類型(中斷傳輸)。USB2.0在2000年4月發(fā)表,新增了高速模式。對于支持USB1.1規(guī)范的設備最高傳輸率可達12Mb/s,而支持USB2.0規(guī)范的設備最高速率可達48012Mb/s。
USB系統(tǒng)結構
一個USB系統(tǒng)主要被定義為三個部分:
USB互連;
USB設備;
USB主機。
USB互連是指USB設備與主機之間進行連接和通信的操作,支持數(shù)據(jù)在USB主機與USB設備之間的流動。在任何USB系統(tǒng)中,只有一個主機。USB和主機系統(tǒng)的接口稱作主機控制器,主機控制器可由硬件、固件和軟件綜合實現(xiàn)。USB的主機通過主機控制器與USB設備進行交互。主機功能如下:
檢測USB設備的安裝和拆卸;
管理主機和USB設備之間的控制流;
收集狀態(tài)和動作信息;
提供能量給連接的USB設備。
USB設備包含一些設備描述符,它們指出了一個給定設備的屬性和特征。當設備被連接、編號后,該設備就擁有一個唯一的USB地址。設備就是通過該USB地址被操作的,每一個USB設備通過一個或多個通道與主機通訊。所有USB設備必須在零號端口上有一指定的通道,每個USB設備的USB控制通道將與之相連。通過此控制通道,所有的USB設備都列入一個共同的準入機制,以獲得控制操作的信息。
圖2展示了USB通信模型之間基本的信息流與互連關系。
USB通信基礎
傳輸基礎
USB通信可以分為兩類:配置通信、應用通信。在配置通信中,主機通知設備,然后使它準備好交換數(shù)據(jù)。大部分這類通信發(fā)生在上電或連接時主機檢測到外設的時候。應用通信出現(xiàn)在主機的應用程序與一個檢測到的外設交換數(shù)據(jù)的時候。這些是實現(xiàn)設備目的的通信。例如:對鍵盤來說,應用通信是發(fā)送按鍵數(shù)據(jù)給主機,告訴一個應用程序顯示一個特性或執(zhí)行其他動作。
配置通信
在檢測過程中,設備的固件對主機的一系列標準請求做出響應。設備必須識別出每一個請求,返回被請求的信息,并且采取其他一些請求指定的動作。在PC上,Windows執(zhí)行檢測工作,所以不涉及用戶編程的問題。然而,為了完成檢測工作,Windows必須有兩個可用的文件:一個識別這個設備的驅動程序的文件名和位置的INF文件和設備驅動程序本身。
應用通信
在主機已經(jīng)與設備交換了檢測信息并且設備驅動已經(jīng)被分配并載入后,應用程序段可以非常順利地進行。在主機上,應用程序可以使用標準Windows API功能來讀取和寫設備。在外設上,傳輸數(shù)據(jù)通常需要把要發(fā)送的數(shù)據(jù)放在USB控制器的傳輸緩存器中,當一個硬件中斷發(fā)出數(shù)據(jù)已經(jīng)到達的信號時從接收器中讀取接收到的數(shù)據(jù),并且在完成傳輸時確保外設準備好下一次傳輸??偩€上的每一次數(shù)據(jù)傳輸使用下列四種類型之一:控制、中斷、批量或同步。
傳輸類型
USB共有四種類型傳輸方式:分別為控制傳輸,中斷傳輸,批量傳輸和同步傳輸。
控制傳輸:用于主機對USB外設的配置,對USB設備的狀態(tài)查詢和控制命令的發(fā)送,也可用于用戶自定義的命令的發(fā)送。
中斷傳輸:用于小批量的、點式的、非連續(xù)性的數(shù)據(jù)傳輸?shù)膱龊?,它是低速設備可以傳輸數(shù)據(jù)的唯一方法。
批量傳輸:用于批量的,非實時的數(shù)據(jù)傳輸,即那些需要一次傳輸較多的數(shù)據(jù),但傳輸過程對時間要求不嚴格的傳輸類型。
同步傳輸:適用于那些要求數(shù)據(jù)連續(xù)的、實時的,以固定的數(shù)據(jù)率產(chǎn)生、傳送的場合。
傳輸(transfers)和事務(transactions)是經(jīng)常提到的兩個概念,分清這兩個概念是設計USB外設的關鍵。傳輸是指一次完整的發(fā)出請求到該請求被完整的處理結束的整個過程。事務是傳輸中的一個基本元素,或者叫一個傳輸?shù)膬?nèi)建模塊。每一次傳輸由一個或多個事務組成。事務又由包組成,而包還包含一個包識別器(PID),一個錯誤校驗位以及有時還有其他信息。參見圖3。
事務按照它們的目的和數(shù)據(jù)流方向可以分為三種類型:SETUP事務、IN事務、OUT事務。它們都是由一個令牌階段,一個數(shù)據(jù)階段和一個握手階段組成。對于SETUP事務來說,在令牌階段有主機發(fā)出SETUP令牌,然后主機又發(fā)出數(shù)據(jù)包,由該數(shù)據(jù)包指出本次請求的具體的內(nèi)容。在握手階段指出本次事務是否成功。各種事務的組成如圖4。
IN事務是從一個設備接收數(shù)據(jù),OUT事務是發(fā)送數(shù)據(jù)給其他一個設備。(IN和OUT事務的命名是從主機的角度出發(fā)的,在一個IN事務中,數(shù)據(jù)是從外設傳輸給主機的;在一個OUT事務中,數(shù)據(jù)是從主機傳輸?shù)酵庠O的。)在一個Setup事務中,數(shù)據(jù)也是從主機傳輸?shù)酵庠O的,但一個Setup事務是一個特殊情況,因為它啟動一個控制傳輸。任何事務都可以用IN或OUT事務,但只有控制傳輸可以使用Setup事務。
在應用程序可與一個設備通信之前,主機需知道設備支持哪些傳輸類型和終端。主機也須分配一個地址給設備,主機通過一個被稱為枚舉的信息交換來完成這些工作。
USB設備的枚舉過程
枚舉是使得主機的設備驅動程序能與這個設備通信的最基本的信息交換。該過程可以由以下動作來完成:
1、一個設備連到一個USB端口
或者系統(tǒng)上電時有一個設備已經(jīng)插入到一個端口中了。這個端口可以在主機的根基線器上或者在連接主機下游的基線器上。集線器正常給這個端口供電,這個設備正處于上電狀態(tài)。
2、集線器檢測到這個設備
集線器監(jiān)視著它的每一個端口的信號線的電壓。集線器端口的兩根信號線(D+和D-)的每一根都有一個15k 的下拉電阻,而一個設備在D+(為全速設備)和D-(為低速設備)都有一個1.5 k 的上拉電阻。當一個設備插入到一個端口中時,設備的上拉電阻使信號線為高,使得集線器可以檢測到一個設備連接上了。
3、主機知道了這個新設備
每個集線器使用它的中斷流程來報告發(fā)生在集線器上的事件。當主機知道了這個事件,它給集線器發(fā)送一個Get_Port_Status請求來了解更多的知識。返回的信息告訴主機該設備是什么時候連接的。
4、集線器重新設置這個設備
當主機知道有一個新設備時,主機控制器給集線器發(fā)送一個Set_Port_Feature請求,請求集線器來重新設置端口。集線器使得設備的USB數(shù)據(jù)線處于重啟狀態(tài)至少10ms。
5、集線器在設備和總線之間建立一個信號通路
主機通過發(fā)送一個Get_Port_Status請求來驗證設備是否激起重啟狀態(tài)。返回的數(shù)據(jù)的一位表示設備是否仍然處于重啟狀態(tài)。當集線器已經(jīng)釋放了重啟狀態(tài),設備就處于默認狀態(tài)了。設備的USB寄存器已經(jīng)處于它們的默認狀態(tài),設備已經(jīng)準備好通過終端0的默認流程來響應控制傳輸。設備現(xiàn)在可以能與主機通信,使用默認地址0h。在這一點上,設備可以從總線上抽取不超過100毫安的電流。
6、集線器檢測設備速度
或在重啟之前或在重啟之后,集線器通過檢查兩個信號線的電壓來檢測設備的速度。集線器通過測試那根信號線在空閑時有更高的電壓來檢測一個設備的速度。集線器發(fā)送信息給主機,以響應下一個Get_Port_Status請求。
7、主機發(fā)送一個Get_Descriptor請求來獲取默認流程的最大包的大小
主機發(fā)送請求給設備地址0、終端0。因為主機一次只列舉一個設備,只有一個設備將響應尋址設備地址0的通信。最大包的大小是這個描述符的第8位,因此主機只需要讀取頭8B。一個Windows主機請求64B,但在僅接收一個包后,它就開始了狀態(tài)階段。在完成狀態(tài)階段時,主機請求集線器來重啟這個設備。這里不需要重啟,因為設備應該可以用響應下一個設置階段的動作來處理任何時候的主機放棄一個控制傳輸情況。
8、主機分配一個地址
主機控制器通過發(fā)送一個Set_Address請求來分配一個單獨的地址給設備。設備讀取這個請求,返回一個確認,并且保存新的地址。這個設備現(xiàn)在處于一個地址狀態(tài)。從這現(xiàn)在開始的所有通信使用這個新地址。
9、主機知道了設備的能力
主機給新地址發(fā)送一個Get_Descriptor請求來讀取這個設備描述符,這次讀取整個部分。這個描述符是一個數(shù)據(jù)結構包括終端0的最大包的大小,設備支持的配置號,及關于這個設備的其他信息。主機把這些信息應用在其后的通信中。然后主機通過請求在設備描述符規(guī)定的一個或多個配置描述符來了解這個設備。一個Windows主機開始申請配置描述符的9B。含在這些B中的是這個配置描述符和它所有的從屬描述符的總長度。Windows然后再次請求配置描述符,這次使用得到的總長度,最多可達到FFhB。這導致設備發(fā)送跟隨在每個配置額的接口描述符后的配置描述符,在它后面是每個接口的終端描述符。若這些描述符總共超過了FFhB,則Windows在第三次請求時得到整套描述符。每個描述符以它的長度和類型開始,使主機能分解其后的數(shù)據(jù)。
10、主機分配和載入一個設備驅動
在主機已經(jīng)從它的描述符中知道了能夠知道的所有信息后,它開始在一個設備啟動中查找最合適的匹配來管理與設備間的通信。在選擇一個驅動時,Windows盡量去與從設備得到的、保存在系統(tǒng)INF文件中的信息中的銷售商和產(chǎn)品ID、發(fā)布號和類信息相匹配。在驅動程序被載入以后,它經(jīng)常請求設備來重新發(fā)送描述符或者發(fā)送應用于這個設備的類描述符。
11、主機的設備驅動選擇一個配置
在從描述符了解了設備后,設備驅動程序發(fā)送一個Set_Configuration命令來請求希望的配置號。設備讀取這個請求并且設置它的配置來匹配它。設備現(xiàn)在處于配置狀態(tài),并且設備的接口已經(jīng)被使能。
主機枚舉是通過給端點0發(fā)送包含標準USB請求的控制傳輸。所有的USB設備必須支持控制傳輸,標準USB請求和端點0。對一個成功的枚舉來說,設備必須對每一個請求響應,返回請求的信息以及采取其他請求的動作。USB設備的枚舉過程是在缺省的控制管道進行的,每一步都是在控制傳輸?shù)腟ETUP階段提出請求的。而具體的請求在SETUP事務的數(shù)據(jù)階段中,用戶可讀取并根據(jù)USB協(xié)議來分析該請求,然后根據(jù)分析的結果進入該控制傳輸?shù)臄?shù)據(jù)階段。在USB設備的枚舉過程中,主機要讀取USB設備的設備描述符、配置描述符、接口描述符和端點描述符。
固件設計
為了實現(xiàn)上述的枚舉過程在設備端需要固件程序的支持。下面以PDIUSBD12為例講述一下固件的設計方法。PDIUSBD12的固件設計成完全的中斷驅動,當PDIUSBD12檢測到有相應的事務發(fā)生時,就中斷CPU處理器調(diào)用中斷服務程序。
D12的固件程序可采用如圖5的積木式結構。
硬件抽象層:這是固件中的最低層代碼,它執(zhí)行對PDIUSBD12和硬件與I/O 相關的訪問。當與其它CPU 平臺接口時這部分代碼需要修改或增加。
PDIUSBD12命令接口:利用這些命令實現(xiàn)對D12的控制。
中斷服務程序:處理USB的各種事務。
標準請求:USB設備必須對這11種標準請求做出響應,這11種標準代碼可以查詢設備的能力和狀態(tài)以及選擇配置。當收到請求時,程序通過解析接收到的請求把要發(fā)送的數(shù)據(jù)存放到發(fā)送緩沖器中。設備不必執(zhí)行每一個請求;它只需要以一種可以理解的方式對請求做出響應。
廠商請求:一個供應商也可以與特定設備進行的傳輸控制而定義請求。
主程序:完成D12的初始化。
在USB通信過程中需要處理多種事務,有些事務的處理需要特別注意,設計者往往忽視,下面分別介紹。
D12初始化過程
D12的中斷寄存器清零
Set Address Enable
Set Endpoint Enable
Disconnect
延時1~2秒鐘
Connect
Setup Transaction處理流程
如圖6所示,對于Setup Transaction的處理需要注意,在讀取D12的FIFO數(shù)據(jù)前必須要選擇端點,為了使以后的Setup Packet數(shù)據(jù)包能夠被接收要用Acknowledge Setup命令使能Control In和Control Out端點。當D12接收到一個數(shù)據(jù)包時一個內(nèi)部端點緩存滿標志有效。后續(xù)的數(shù)據(jù)包將不能夠被接收,必須通過Clear Buffer命令來清出標志位。在讀取D12的數(shù)據(jù)后先要利用Acknowlege命令對主機進行回應,然后再清除D12的緩存。這兩個命令處理順序不能交換,因為在沒有回應主機前不能夠清除掉D12的緩存,這樣就不能接收新的數(shù)據(jù)。
Control In Transaction處理流程
如圖7所示,在Control In Transaction處理過程中注意,要發(fā)送的數(shù)據(jù)是端點0能傳送的最大數(shù)據(jù)報的整數(shù)倍時,在傳送完所有的數(shù)據(jù)后,必須向主機發(fā)送零長度數(shù)據(jù)報。
Get Descriptor命令處理流程
如圖8所示,在列舉過程中,被請求的描述符逐涉及設備的小的元素:首先是整個設備,然后是每個配置,接著是每個配置的接口,最后是每個接口的終端。對于字符串描述符是可選的。關于描述符是設計者可以配置的,可以根基設備的通信能力和要求來定義需要的描述符。
Set Address命令處理流程
如圖9所示,通過這個請求,主機指定以后與設備通信的地址。值字段是要設置的設備的新的地址。允許值為1到127。當上電或連接后集線器使能一個端口,端口使用默認地址0直到它 從主機接收到一個Set_Address請求。這個請求和大部分的其他請求不同,因為設備直到通過發(fā)送零長度數(shù)據(jù)包完成請求的狀態(tài)階段后才執(zhí)行這個請求。主機發(fā)送狀態(tài)階段標志包到默認地址,因為設備必須在改變地址之前發(fā)送這個包。完成這個請求后,所有通信都使用這個新地址。一個使用默認地址0的設備處于默認狀態(tài)。在完成Set_Address請求設置一個非0的新地址后,設備進入地址狀態(tài)。一個設備必須在接收到請求后的50毫秒內(nèi)發(fā)送交換包,并且它必須在完成狀態(tài)階段后的2毫秒內(nèi)完成請求。
另外要注意的是當USB設備接收主機發(fā)送的IN事務,如果設備沒有要發(fā)送到主機的數(shù)據(jù)時,這時設備進入掛起狀態(tài),為了避免這種情況出現(xiàn),當沒有數(shù)據(jù)要發(fā)送時可以發(fā)送零長度的數(shù)據(jù)報。
同時利用D12開發(fā)時有兩個突出的優(yōu)點:軟連接和GoodLink接口。所謂的軟連接就是把D12內(nèi)部集成的1.5K的上拉電阻連接到數(shù)據(jù)線D+上,通過此特性可以使設備CPU有充足的時間進行初始化,同時也避免頻繁的插拔USB數(shù)據(jù)線。GoodLink接口可以連接發(fā)光二極管,當設備枚舉成功后發(fā)光二極管常亮,當D12進行傳送數(shù)據(jù)時發(fā)光二極管閃爍。