基于Linux的USB從設備驅動研究
0 引言
USB是英文Universal Serial Bus的縮寫,意為通用串行總線。USB是一種快速、雙向、同步、低成本、動態可連接的串行接口。USB現在已經廣泛應用到各種設備上,尤其是手持設備,幾乎都采用了USB接口。現在,USB即可用來與其他設備連接后高速地傳遞數據,又可用來充電,使手持設備可以發揮U盤、MODEM、無線網卡等作用。
事實上,USB只是主機和外圍設備之間的連接。如何來促使這種連接發揮作用,就需要驅動程序。驅動程序主要解決硬件“需要提供什么功能”以及“如何使用這些功能”。在linux系統中,USB設備可以作為主機使用,也可作為從設備使用。對應的USB驅動程序有兩種主要的類型:宿主系統上的驅動程序和設備上的驅動程序。從宿主的觀點來看(例如普通的左桌面計算機),宿主系統的USB驅動程序控制插入其中的USB設備,而USB設備的驅動程序則控制該設備如何作為一個USB設備和主機通信。
1 USB設備基礎
USB設備的構成包括配置接口和端點,以及USB驅動程序如何綁定到USB接口上。端點是USB通信最基本的形式,USB端點只能是往一個方向傳送數據,即從主機到設備(稱為輸出端點)或者從設備到主機(稱為輸入端點),故可以看作是單向管道。USB有四種不同的類型,分別對應不同的傳輸類型:控制、中斷、批量、等時。其次接口,USB端點被綁定即為接口。USB的一個接口只處理一種USB邏輯連接;一個USB設備可以有多個接口,不同的接口可以代表不同的功能,因此,功能不同的USB接口需要不同的驅動程序。另外就是配置,USB接口本身被綁定為配置。一個USB設備可以有多個配置,而且可以在配置之間切換以改變設備的狀態;一個時刻只能激活一個配置,怛一個配置通常具有一個或者更多的接口。
USB設備可由許多不同的邏輯單元組成,實際上,也就是這三種邏輯單元組合而成的。Linux內核中的USB代碼一般要用URB (usbrequst block)與USB設備通信。URB用struct urb結構體描述,它能以一種異步的方式往/從特定的USB端點發送/接收數據。USB設備驅動程序可能會為單個端點分配許多的URB,也可能對許多不同的端點重用單個URB,這取決于驅動的需要。當USB驅動程序只發送或接收一些簡單的USB數據時,可以使用兩個很簡單的接口函數:usb_bulk_msg、usb_control_msg。
2 USB設備驅動程序的結構
圖1所示是Linux環境下USB驅動的總體結構。從圖l中可以看到:在主機側層次結構中,實現USB驅動有兩類方式:USB主機控制器驅動和USB設備驅動;USB主機控制驅動主要控制插入其中的USB設備,主機控制器可以分為三類,分別對應于三種USB主控制器;USB設備驅動則用于控制USB設備如何與主機通信;USB核心負責USB驅動管理和協議處理的主要工作。
USB核心向上可為設備驅動提供編程接口,向下可為USB主機控制器驅動提供編程接口;它可以通過全局變量維護整個系統的USB設備信息,從而完成設備的熱插拔控制和總線數據傳輸控制等驅動。
另外,在從設備側,Linux內核中的USB設備側驅動程序可分為3個層次:USB設備控制器(UDC)驅動程序、Gadget API和Gadget驅動程序;UDC驅動程序可直接訪問硬件,控制USB設備和主機間的底層通信,并向上層提供和硬件相關的操作回調函數。不同的設備控制器硬件有不同的設備控制器驅動程序;Gadget驅動主要控制USB設備功能的實現,它使用Gadget API傳遞控制信息給UDC驅動程序,以便實現具體功能。
Gadget API是設備控制器的控制功能抽象接口,Gadget驅動程序可以試用Gadget API,它可以把下層的UDC驅動程序和上層Gadget驅動程序相隔離,以使得在linux系統中編寫USB設備側驅動程序時,能夠把功能的實現和底層通信相分離。
如果要在S3c24.10上實現大存儲類從設備,則需要運行file_storage.c和s3c2410_udc.c這兩個驅動程序。file_stoarge.c具體控制USB設備功能的實現,它使用Gadget API來控制s3c2410.c以實現其功能。s3c2410.c驅動程序可直接訪問硬件,以控制USB設備和主機間的底層通信,同時向上層提供和硬件相關操作的回調函數。
評論