摘 要:隨著USB總線的普及,具有USB主機端和從機端控制器的微型處理器越來越多,AT91RM9200就是這種微型處理器之一。Linux既支持主機端驅動又支持從機端驅動。通過對Linux-2.6.19.2內核USB主機端驅動程序的分析和研究,以及結合U盤設備驅動的實例,討論基于AT91RM9200的USB主機端Linux驅動,詳細地分析Linux內核中USB主機端驅動代碼的工作流程,對開發USB設備驅動程序具有一定的指導意義。
關鍵詞:AT91RM9200;USB主機端;Linux;U盤驅動
USB Host Port of Driver for Linux Based on AT91RM9200
XIA Chuankai,WU Nailing
(School of Electronic Science Engineering,Sontheast University,Nanjing,210096,China
Abstract:As USB′s popularization,there are more and more micro-processors have USB host-side and device-side controller,such as AT91RM9200.Linux kernel supports USB host-side driver and device-side driver.Based on AT91RM9200,this article studies and analyzes USB host-side driver for Linux-2.6.19.2 kernel and takes USB disk device driver for Linux as an example.The innovating point of the article is that analyzing working flow of USB device driver code for Linux in detail,this is valuable to guiding the other device driver design.
eywords:AT91RM9200;USB host-side;Linux;USB disk driver
通用串行總線(USB)是一種新興的計算機外圍串行通信接口標準,它克服傳統計算機串/并口的缺陷,具有熱插拔、即插即用、數據傳輸可靠、擴展方便、低成本等優點,已成為當前計算機必備的接口之一,同時也被廣泛地應用與嵌入式系統設計中。本文著重介紹嵌入式Linux中的USB主機端驅動。其硬件平臺是AT91RM9200處理器系統,軟件平臺是Linux-2.6.19.2內核。
1 AT91RM9200 USB主機端接口硬件構成
AT91RM9200處理器是Atmel公司一款比較流行的微型處理器,它具有ARM920T內核(帶有MMU),主時鐘頻率可達240 MHz,很適合嵌入式系統應用,它同時具有USB主機端和設備端,其中主機端處理開HCI協議(OHCI)及USB v2.0全速與低速協議,還給ASB提供簡單的讀/寫協議,USB主機端口還集成1個根集線器,硬件結構如圖1所示。
2 Linux USB主機端驅動
Linux在1999年就在其核心內嵌入了USB驅動程序。理解Linux的USB主機端驅動結構和原理,對在Linux系統上開發USB設備端驅動程序,以及進一步理解USB協議有著很重要的意義。下面基于內核版本2.6.19.2分析Linux USB的主機端驅動。
Linux USB主機端驅動主要分為:主機控制器驅動、USB核心驅動和USB設備端驅動3個部分,它們之間的層次關系如圖2所示[1]。
在Linux內核中關于USB的代碼主要由2個部分構成:板級支持代碼和USB驅動代碼。其中板極支持代碼主要分布在與處理器有關的目錄里,如:/arch/arm/mach-at91rm9200[2]目錄。USB驅動代碼主要集中在/drivers/usb[2]目錄里,主要包括USB核心驅動,主機控制器驅動,從機端驅動,各類設備端驅動程序。其中在Atmel的板極支持代碼/arch/arm/mach-at91rm9200/devices.c[2]中包括USB主機端和從機端資源的數據結構at91_usbh_resources,at91_udc_resources,平臺設備數據結構 at91rm9200_usbh_device,at91rm9200_udc_device,以及設備注冊函數 at91_add_device_usbh(),at91_add_device_udc(),這2個函數在板極初始化函數中被調用,向內核添加USB主機設備和從機設備。USB驅動的核心代碼是在/drivers/usb/core[2]目錄里,主要的作用是管理設備端驅動程序、控制協議命令集、管理數據傳輸、配置和管理USB設備、管理主機控制器[3]。USB核心啟動代碼在目錄/drivers/usb/core/usb.c[2]中,具體的步驟如圖3所示。
USB核心啟動以后的結果是:注冊1條總線“usb”,1個文件系統“usbfs”,創建2個設備類“usb_host”,“usb_device”,創建了許多的字符設備節點,分別是主設備號為180,從設備號是0~255,主設備號為189,從設備號為0~64×128,注冊3個驅動程序:“usbfs”,“hub”,“usb”。創建一個內核線程“khubd”,PID=40,一旦有USB設備接入,這個內核線程就能捕捉到,并調用相應的驅動探測函數。這些內容在系統啟動以后根文件系統的/sys或/proc相關目錄下可以找到。Linux USB主機端驅動涉及的主要數據結構有:
usb_driver:USB接口驅動程序結構體;
usb_device_driver:USB設備驅動程序結構體;
usb_bus:USB總線結構體;
usb_device:USB設備結構體;
urb:USB請求結構體。
在每個USB設備驅動程序里都有1個設備表 usb_device_id,用來保存此設備驅動程序所支持的USB設備,如U盤驅動程序的ID表名為usb_storage_ids,如果有些USB設備的驅動Linux內核并不支持,就可以把這些USB設備的數據(包括設備供應商編號、產品編號、供應商名稱、產品名稱、USB協議、初始化函數、標記等,這些信息的獲取不依賴于特定的設備驅動程序,設備接入后可以從根文件系統的目錄/proc中查看到)添加到相關設備驅動程序的usb_device_ids中去,如U盤的驅動程序設備表id_storage_ids在內核頭文件/drivers/usb/storage/unusual_devs.h[2]中。每當有USB設備接入系統,USB內核的執行步驟如圖4所示:
在device-add(函數中內核將該USB設備添加到USB總線上,并調用USB總線的匹配函數usb_device_match(尋找這個設備的驅動程序,最終將該設備與匹配的驅動程序綁定。
3 U盤設備驅動示例
U盤是USB存儲器的通稱,在內核中被定義為USB Mass Storage,除了默認配置以外,要在Linux中使用U盤還必須完成以下步驟:
(1) SCSI支持
U盤屬于海量存儲設備,Linux將它定義為SCSI塊設備,所以必須要配置這個選項。內核配置選項如下:
SCSI device support(
<*> SCSI device support
<*> SCSI disk support
(2)Windows文件系統支持
U盤可能大都是Windows下的文件格式,所以這里有必要選上對Windows下文件格式和語言的支持。內核配置選項如下:
File systems (
DOS/FAT/NT filesystems(
<*> MSDOS fs support
<*> VFAT (windows 95 fs support
<*> NTFS file system support
Native Language Support(
<*> Base native language support
<*> Codepage 437 (Unite States,Canada
<*> NLS ISO 8859-1 (Latin 1;Western European Languages
(3) USB驅動支持
USB驅動主要包括對USB主機端的支持、USB文件系統、OHCI協議、USB Mass Storage的支持。內核配置選項如下:
USB support(
<*> Support for Host-side USB
[*] USB device filesystem
<*>OHCI HCD support
<*> USB Mass Storage support
(4) 在/dev目錄下新建sda設備節點
為了能夠順利地訪問USB設備,必須在/dev目錄下建立相應的設備節點。由于U盤被定義為塊設備,所以必須建立SCSI塊設備節點,命令如下:
mknod–m600sda*b8 *
這里的“*”根據不同的系統而不同。假如有很多的SCSI設備則需要建立許多的sda*設備節點,至于U盤具體是哪一個設備節點,則需要根據fdisk命令來查詢。
(5)安裝U盤
將U盤插入后,首先我們可以通過fdisk –l 命令看到U盤的信息(包括該U盤是第幾個SCSI塊設備節點,容量是多少等等),然后通過命令mount –t vfat /dev/sda* /mnt/usb (前提是已經在/mnt目錄下建立了usb目錄,并且U盤的格式為Windows下的vfat安裝U盤到指定的目錄下。這里的“*”由fdisk命令顯示的內容來定。
(6) 運行結果
先將U盤插入主機端接口,再啟動系統,就會打印出以下相關的信息:
SCSI subsystem initialized
usbcore:registered new interface driver usbfs
usbcore:registered new interface driver hub
usbcore:registered new device driver usb
at91_ohci at91_ohci:AT91 OHCI
at91_ohci at91_ohci:new USB bus registered,assigned bus number 1
at91_ohci at91_ohci:irq 23,io mem 0x00300000[LL]
usb usb1:Product:AT91 OHCI
usb usb1:Manufacturer:Linux 2.6.19.2 ohci_hcd
usb usb1:SerialNumber:at91
usb usb1:configuration #1 chosen from 1 choice
hub 1-0:1.0:USB hub found
hub 1-0:1.0:1 port detected
Initializing USB Mass Storage driver...
usb 1-1:new full speed USB device using at91_ohci and address 2
usb 1-1:configuration #1 chosen from 1 choice
usbcore:registered new interface driver
usb-storage
USB Mass Storage support registered
根文件系統啟動以后,可以通過cat命令顯示該U盤的相關信息,如:/cat /proc/bus/usb/devices。
4 結 語
隨著USB接口越來越廣泛的應用,USB-IF在2000年推出了USB 2.0規范。USB 2.0規范在兼容USB 1.X規范的基礎上支持480 Mb/s的高速數據傳輸。同時隨著Linux內核的不斷擴充,內核將支持越來越多的USB設備和USB主機控制器,這對于USB的普及和應用有很重要的意義。
參 考 文 獻
[1]Jonathan Corbet,Alessandro Rubini,Greg roah-Hartman.Linux設備驅動[M].3版.魏永明,耿岳,鐘書毅,譯.北京:中國電力出版社,2006.
[2]Linux-2.6.19.2 kernel[EB/OL].http://www.kernel.org.
[3]肖踞雄,翁鐵成,宋中慶.USB技術及應用設計[M].北京:清華大學出版社,2003.
[4]Daniel P.Bovet,Marco Cesati.深入理解Linux內核[M].2版.陳莉君,馮銳,牛欣源,譯.北京:中國電力出版社,2004.
[5]李哲,王紹丹.AT91RM9200處理器同步串口SSC的特性分析與應用[J].國外電子元器件,2007(7:57-60.