蒲 進
嵌入式Linux USB OTG體系結構
蒲 進
通過引入基于嵌入式Linux的USB OTG子系統的體系結構,重點分析了支持Mass Storage Class的USB OTG協議棧結構,并據此提出了符合便攜式多媒體設備特點以及USB OTG規范的結構框架。
由于傳統的USB 系統是一個基于主機的主從(Host/ Device) 結構,作為外設端角色出現的嵌入式設備在通過USB 接口傳輸數據時就必須依賴PC進行通信。為了擺脫PC實現嵌入式系統間的USB 數據傳輸USBIF于2001 年發布了專門用于USB 外設間可移動互連的USB2.0協議的補充規范USB OTG(On-The-Go) 。USB OTG補充規范主要由HNP 協議和SRP協議組成,并定義了新的設備類型:即雙角色OTG 設備(Dual-Role Device) 。兩用OTG 設備允許設備以外設和主機兩種方式工作, 支持HNP 協議和SRP 協議。將嵌入式系統設計成雙角色OTG設備就可以和其他USB 接口設備直接相連,從而進行點對點的數據傳輸。USB OTG結合了對移動應用友好的新特性,包括低功耗、更小的USB接頭以及在相同的USB端口上增加了雙重角色的功能。OTG已經被越來越多的嵌入式設備采納。
為了迎合USB OTG成為更多嵌入式終端必備的標準接口這一趨勢,Linux也從2.6版本開始提供對USB OTG的支持。Linux下的USB OTG的系統結構可分為四層。
(1)Controller驅動層
Controller驅動層則是各種具體硬件的控制器的驅動程序,針對于OTG的結構一般包括host controller(UHC)驅動、device controller(UDC)驅動和OTG controller(UOC)驅動。為了保證上層USB通用驅動與具體的controller硬件無關,Controller驅動層必須根據Framework層導出的接口為其提供相應的實現。
(2)Framework層
Framework層則是對硬件的抽象層,它的目的就是通過定義一系列的數據結構、函數和宏定義來抽象所有和controller或device硬件相關的部分。其中主機端的USB Core為上層USB device driver和下層的UHC 驅動提供了標準接口,同樣,從機端的Gadget Framework為上層Gadget driver和下層UDC驅動也都分別提供了一組相應的標準接口。特別的是,OTG Framework服務對象不是上層的USB通用驅動而是UHC驅動和UDC驅動,和其下層的UOC驅動,簡單的說就是OTG Framework對上層的USB通用驅動來說是透明的。
(3)USB通用驅動層
USB通用驅動層則是對具體設備功能的實現。它們一般是硬件無關的,只是符合某種USB Class Spec的規定或者制造商自定義的設備類型即可。其中主機端的統稱為USB設備驅動(客戶驅動),從機端的稱為Gadget驅動。
(4)附加層
附加層則是包括諸如:文件系統、網絡、Block I/ O子系統等等。它們主要工作就是產生和消費通過下層USB OTG子系統傳輸的數據。
對于Mass Storage Class的支持是項目研發設備的既定目標之一。下面就以USB Mass Storage Class為例分析一下該情況下主機端和從機端的體系結構。
從機端的體系結構
通常情況下,從USB設備的角度來說某一時刻從機端只能是屬于某一個特定種類的設備,或者說是具有某種特定功能的設備。而這個功能的決定者就是從機端的設備功能驅動,在Linux里就是gadget驅動。所以gadget驅動的類型以及采用的機制將很大程度影響USB Gadget子系統和內核中其他驅動或子系統的交互方式。
在支持Mass Storage的從機端結構中,Gadget Mass Storage Device Driver是實現了從機端的Mass Storage Class的gadget driver,其目的就是讓使用該gadget driver的從機連接到主機上后顯示一個SCSI硬盤驅動器。實現該驅動的基本機制是File-backed,即用一個普通文件或者一個block設備來充當該驅動器的后臺存儲介質。另一個特點就是該驅動也允許后臺存儲介質的可插拔性,例如使用SD卡或MMC卡作為Block設備來從當后臺存儲介質。該驅動支持CB、CBI或者Bluk-only三種Mass Storage傳輸協議,以及RBC,ATAPI or SFF-8020i,QIC-157,UFI,SFF-8070i ,and transparent SCSI 等協議。

圖1 支持MSC的Linux USB Gadget Subsystem
圖1描述的就是基于File-backed機制的支持Mass Storage的Gadget子系統。其中Disk是一個掛載在本地文件系統上的塊設備。用戶空間中相應的設備文件節點/dev/hda1可以讓用戶或其他應有程序在用戶模式下對該塊設備進行讀取訪問。另一方面處于內核態的USB Gadget子系統也可以通過VFS對該塊設備進行操控以響應主機端發送過來的讀寫操作。但同一時刻對該塊設備只能有一種訪問方式進行,也即本地用戶模式下的應用和主機端只能互斥訪問該塊設備,以保證塊設備上的數據完畢性。
主機端的Mass Storage驅動設計原理是:當一個Mass Storage設備插入時,Mass Storage驅動會產生一個kernel線程去控制和處理該設備。該線程將注冊為一個虛擬的SCSI控制器,并且該線程會在設備插入/拔出時一直作為SCSI接點存在,這樣可以保證一個移去的設備再次插入時會被分配同樣的設備接點/dev。該控制線程從其上層的SCSI中間層接收命令,經過必要的完整性檢查后發送到協議處理函數,該處理函數負責在必要的情況下重寫命令到設備可以接受的形式。在協議處理函數處理完畢后,命令被遞交給傳輸處理函數,由該處理函數完成具體的命令傳輸、數據交換以及獲取設備狀態等任務。在命令被處理完畢后,scsi_done函數被調用來通知SCSI中間層該命令被成功處理,可以進行下一條命令的接收和處理工作。
主機端的基本處理流程:用戶從設備上讀寫數據首先通過VFS的通用系統調用到文件系統,然后由文件系統將通過通用硬盤結構得到塊設備信息以及讀寫操作傳遞到SCSI中間層進行SCSI協議的封裝。Mass Storage驅動從SCSI中間層獲得相應的SCSI命令,將命令封裝成USB Mass Storage Class對應的某種傳輸協議(CB,CBI,或者Bulk-Only),最后封裝成URB發送到USB Core,并由USB Core將該URB發送到主機控制驅動,最終通過USB接口傳給從機設備。
根據目標設備的情況需要對現有的Linux USB OTG架構做出一些改動。結合嵌入式目標設備的功能特點和USB規范提出的Linux USB OTG體系結構不僅設計了協議棧部分,同時還提出了OTG應用框架,該框架是對OTG協議規范在應用層面上的一種延伸,使得基于該體系結構開發的 USB OTG設備具備以下功能以兼容USB OTG規范:
具備受限的USB Host功能
Device模式下應支持Full Speed或者High Speed
Host模式下應支持Low Speed, Full Speed,High Speed
具備Target Peripheral List
支持SRP
支持HNP
在使用過程中提供用戶相關的信息。
此外,為了最終向用戶提供更友好的操作界面,該框架額外支持的功能和特性包括:
Host模式下支持hotplug,能主動提示用戶插入設備的基本信息以及設備的當前狀態
Device模式下支持用戶選擇和更換設備功能
可控的SRP
可控的HNP
更豐富的消息、狀態和提示。
易用性和兼容性是便攜式多媒體消費電子產品追求的重要目標。本文介紹的支持OTG的USB體系結構已經在炬力嵌入式Linux 系統中得到實現,使用該結構開發的多媒體播放器可以脫離PC的束縛,非常便利地交換數據,提高了用戶使用體驗,達到了預期的市場效果。

蒲 進
炬芯(珠海)科技有限公司
10.3969/j.issn.1001-8972.2015.16.021