1. 程式人生 > >Android裝置間USB傳輸(OTG)

Android裝置間USB傳輸(OTG)

    在電氣方面:USB在不同速度下(Low-speed、Full-speed、High-speed)輸入、輸出驅動電路的阻抗要求,線路的訊號傳輸延遲,裝置電壓敏感度,訊號衰減,訊號編解碼方式(NRZI),訊號有效範圍等電氣引數,USB標準都做了規範。

    在電源分配方面,由於連線到USB系統中的器件,連線線都會造成一定的壓降,USB標準要求給下行埠的最低電壓供給要帶到4.35V,對於外接電源的Hub、匯流排供電的Hub、外界電源的裝置、匯流排供電的裝置還有其他不同的的規範要求。另外,USB標準規定所有連線裝置都必須能夠進入休眠,預設狀態下休眠電流為500µ A,如果是支援喚醒或是high power埠,休眠電流為2.5mA。

    另外,USB標準規定,對於不同速度的裝置鑑別需要硬體上不同的連線(如圖2):低速裝置需要在D-接上拉電阻、全速裝置需要在D+接上拉電阻、而USB對於高速裝置規定需要有一個電流驅動器(通過電流驅動器灌到D+/D-上產生壓降)。當不同速率的裝置連線時,USB主設端正是通過D-/D+上的電壓變化來識別區分的。


圖2  USB不同速度裝置硬體連線

1.3  USB系統組成

    USB標準中將USB系統描述為三個部分:USB主設、USB從設、裝置間聯通。一個USB主設需要根據協議對資料的傳輸增加相應的協議資訊以及協議的解析(Protocol Engine);需要對傳輸的資料進行序列化及解序列化(SIE-Serial Interface Engine);需要對資料傳輸的差錯進行檢測、處理(ErrorHandling)等:


圖3 USB Host Controler架構

而軟體層上需要對USB主設進行控制,讀取資訊等工作(Host Controler Driver);同時需要有一部分軟體對連線到USB主設上的從裝置進行管理、控制(USB Device Driver);由於對特定從裝置的管理、控制的資料最終還是需要經過USB主設實際傳送,因此在HCD和UDD之間有一箇中間層(Host Core Driver)。

    USB從設也需要一個協議引擎來按照USB協議標準傳送、接收訊號;另外USB從設有許多可定址的FIFO緩衝區,USB主設具體上就是和這些FIFO進行資料互動。同樣,在軟體架構上,USB從設也有和USB從控制器互動的Device Controler Driver以及和從設上的具體裝置進行互動的USBGadget Driver,中間層則是Device Core Driver。


圖4 USB Device Controler架構

    在USB系統中除了以上介紹的USB主設和USB從設外,還有一個裝置可以對USB埠進行有效的擴充套件和管理—USBHub。USB Hub實際上在USB系統中是一個特殊的USB從裝置,它有著特定的裝置描述符以及相關元件來完成它在USB系統中的功能。


圖5 USB Hub框圖

USB Hub一般會有多個埠用來和其他USB從裝置進行連線(USBDownstream)以及一個和USB主裝置連線的埠(USB Upstream);USB Hub作為一個從裝置的身份也需要和USB主裝置進行資料互動(Hub Controler);而USB Hub作為連線USB主裝置和USB從裝置的中間裝置,需要對上行埠和下行埠的資料傳輸進行管理(Hub Repeater);另外,對於連線到Hub上的不同速度的裝置,需要一個元件(Transaction Translator)把一個速度的資料轉換到另一個速度進行傳輸。USBHub最重要的一個功能是將連線到Hub上的從裝置上報給USB主裝置,USB Hub中有一個特殊的Endpoint FIFO專門來儲存Hub埠上的狀態。

    USB系統就是由以上的裝置和傳輸協議以及其他規範來組成USB系統。主設端有Host裝置控制器,和Host裝置控制器直接連線的根Hub,向下再連線其他從裝置或其他Hub,組成一個級聯的系統。


圖6 USB系統拓撲圖

2  USB OTG

2.1  OTG概述

    USB OTG(On The Go)作為USB2.0的補充協議,於2001年由USB-IF提出。它提出的背景是移動消費類電子產品的迅猛增加,而之前USB協議的主從協議標準讓這些電子產品在離開PC電腦時的資料傳輸變得艱難,OTG技術正是為了解決這一問題的標準。


圖7  通過OTG技術實現裝置間端到端互聯

    OTG協議規定連線時預設情況作為Host的裝置為A裝置,A裝置負責為匯流排供電;預設作為Device的裝置為B裝置(USB OTG標準在完全相容USB2.0標準的基礎上,增加了一個ID pin;ID拉低為預設A裝置);而有些裝置由於集成了Host控制器和Device控制器,既可以作A裝置又可以做B裝置,稱為dura-role device。

2.2  OTG 相關協議

AttachDetection Protocol (ADT)

    ADT協議用來檢測裝置的連線和斷開(在沒有匯流排供電的情況下),原理為裝置連線或斷開後線路的阻抗發生變化,發起ADT探測的裝置用一電流源給Vbus升到一定電壓的時間會不同。

SessionRequest Protocol (SRP)

    SRP用來請求A裝置給Vbus進行供電。由於一般的移動電子裝置對功耗要求比較高,因此OTG標準允許A裝置平常關閉對匯流排的供電,而B裝置就可以使用SRP 請求A裝置開啟Vbus,建立一個有效的連線。

Host Negotiation Protocol (HNP)

    對於之前提到過的dual-roledevice,即可以做A裝置又可以做B裝置。預設情況下是根據USB OTG線的連線情況確定A裝置,而HNP可以讓dual-role device互聯時,在不調換USB OTG線的情況下,通過協商實現A裝置、B裝置的角色更換。

2.3  OTG軟體架構

    根據USB OTG的電氣和機械標準,USBOTG Controler需要支援一系列的OTG協議;而Controler Driver理所當然的就需要和這個Controler進行互動,讀取狀態、發起操作等;當完成了OTG的檢測連線、建立連線的工作後,最終需要去讓相應USB裝置的Host Controler或者Device Controler去進行資料傳輸,OTG Driver Core則負責這個工作。


圖8 OTG軟體架構

3  Android下USB驅動開發

    根據之前的介紹,進行USB傳輸的驅動開發在從裝置端需要進行Gadget Driver的開發;在裝置端需要進行Host Device Driver的開發。而之前介紹的相應Controler的驅動由於是直接和相關硬體控制器互動,一般由晶片廠商或者平臺端完成。由於USB裝置的普及應用,USB標準對一些通用的裝置:鍵盤、滑鼠、U盤等做了規範,即不同的裝置類(USBClass)。對於這些通用裝置,由於裝置端按照標準進行設計、韌體程式由廠商按照標準實現;主機端有對應的標準驅動程式,因此只要安裝相應驅動即可。對於自定義的裝置或是功能來說:

3.1  Host端驅動開發

    由於HostControler Driver做的工作以及Host Core Driver提供的完善介面,這裡的Host端驅動開發相對來說已經是比較簡單了。

    當裝置的連線探測、裝置資訊獲取等一系列操作完成後,會遍歷註冊到核心的Host Device Driver為連線到Host端的裝置尋找一個控制驅動,因此在編寫驅動時需要寫好自己的匹配規則;當編寫的驅動註冊到後,核心會建立一個字元裝置,使用者空間一般就通過這個字元裝置來讀寫USB裝置,因此驅動中實現讀寫等其他裝置操作介面是最重要的一部分內容。


圖9 Host端驅動開發步驟

對於USB裝置的讀寫,之前有提到過在從裝置端有多個EndPoint(可定址的FIFO),所以讀寫介面的實現就是對這些EndPoint進行操作。USB裝置中的端點除了0號端點是雙向的(用來初始獲取裝置資訊使用),其他端點都是單向的。讀/寫介面需要和IN/OUT端點互動,呼叫核心提供的介面從IN端點中讀或者向OUT端點中寫。


圖10 Host和端點進行資料傳輸

對於資料傳輸的方式,USB標準規範了四種傳輸方式:控制傳輸(Control Transfers)、中斷傳輸(InterruptTransfers)、同步傳輸(Isochronous Transfers)、塊傳輸(Bulk Transfers)。USB主機通過控制傳輸向USB裝置讀取資訊、配置;中斷傳輸具有固定速率、資料量少的資料傳輸;同步傳輸適合實時流傳輸,但是不保證資料正確性;塊傳輸適合大量資料傳輸,提供錯誤檢測和重傳機制。在實際程式中,選定不同的傳輸方式,只需要使用不同的核心介面即可,而具體的協議過程會由硬體控制器及其驅動來完成。

    對應於具體函式,可以參考核心中的usb-skeleton.c對應進行了解。對於主要的介面和基本的編寫過程下面提供一個簡單的草圖:


圖11 Host端驅動具體函式草圖


3.2   Device端驅動開發

    對於Android裝置來說,屬於USB複合裝置(裝置上有多個通過USB管理控制的功能)。為了方便使用者使用,Android將每種功能對應的gadgetdriver做了重新組織並和應用層互動:


圖12 Android下USBdevice端驅動組織

在這樣的架構下,USB gadget driver做的事情就是描述自己屬於何種型別的裝置,USB Host可以訪問的端點有哪些、端點的性質,讀取端點、填充端點的具體方式。

    USB從裝置利用描述符(Descriptor)來表明裝置的屬性,USB標準規定了各種不同的描述符,以及描述符的具體內容,USB主裝置通過獲得這些描述符的資訊來判斷連線裝置的型別、功能等一系列資訊。一般來說,USB gadget driver中需要關心的描述符有:裝置描述符、介面描述符、端點描述符、配置描述符,這裡面端點描述符描述EndPoint的方向、大小、地址等資訊;裝置描述符描述裝置的生產商資訊、裝置類、遵循協議等資訊;其他描述符可以認為是邏輯上的(一個介面對應一個功能,它對應著一個驅動)。


圖13 USB從裝置描述符及邏輯關係

    在Android對資料結構的組織和composite框架下,如果需要新加一個USBgadget driver只需要填充好Android提供的一個函式指標結構體,在一個bind_config介面中去把實現好的composite框架規定的介面加入composite框架中去,具體的端點操作可以在一些可選的介面中維護自己的讀寫介面(一般在init中註冊裝置)。詳細可參見f_adb.c檔案。


圖14 Android下新加功能需要關注