摘 要:隨著USB總線的普及,具有USB主機(jī)端和從機(jī)端控制器的微型處理器越來(lái)越多,AT91RM9200就是這種微型處理器之一。Linux既支持主機(jī)端驅(qū)動(dòng)又支持從機(jī)端驅(qū)動(dòng)。通過(guò)對(duì)Linux-2.6.19.2內(nèi)核USB主機(jī)端驅(qū)動(dòng)程序的分析和研究,以及結(jié)合U盤設(shè)備驅(qū)動(dòng)的實(shí)例,討論基于AT91RM9200的USB主機(jī)端Linux驅(qū)動(dòng),詳細(xì)地分析Linux內(nèi)核中USB主機(jī)端驅(qū)動(dòng)代碼的工作流程,對(duì)開發(fā)USB設(shè)備驅(qū)動(dòng)程序具有一定的指導(dǎo)意義。
關(guān)鍵詞:AT91RM9200;USB主機(jī)端;Linux;U盤驅(qū)動(dòng)
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)是一種新興的計(jì)算機(jī)外圍串行通信接口標(biāo)準(zhǔn),它克服傳統(tǒng)計(jì)算機(jī)串/并口的缺陷,具有熱插拔、即插即用、數(shù)據(jù)傳輸可靠、擴(kuò)展方便、低成本等優(yōu)點(diǎn),已成為當(dāng)前計(jì)算機(jī)必備的接口之一,同時(shí)也被廣泛地應(yīng)用與嵌入式系統(tǒng)設(shè)計(jì)中。本文著重介紹嵌入式Linux中的USB主機(jī)端驅(qū)動(dòng)。其硬件平臺(tái)是AT91RM9200處理器系統(tǒng),軟件平臺(tái)是Linux-2.6.19.2內(nèi)核。
1 AT91RM9200 USB主機(jī)端接口硬件構(gòu)成
AT91RM9200處理器是Atmel公司一款比較流行的微型處理器,它具有ARM920T內(nèi)核(帶有MMU),主時(shí)鐘頻率可達(dá)240 MHz,很適合嵌入式系統(tǒng)應(yīng)用,它同時(shí)具有USB主機(jī)端和設(shè)備端,其中主機(jī)端處理開HCI協(xié)議(OHCI)及USB v2.0全速與低速協(xié)議,還給ASB提供簡(jiǎn)單的讀/寫協(xié)議,USB主機(jī)端口還集成1個(gè)根集線器,硬件結(jié)構(gòu)如圖1所示。
2 Linux USB主機(jī)端驅(qū)動(dòng)
Linux在1999年就在其核心內(nèi)嵌入了USB驅(qū)動(dòng)程序。理解Linux的USB主機(jī)端驅(qū)動(dòng)結(jié)構(gòu)和原理,對(duì)在Linux系統(tǒng)上開發(fā)USB設(shè)備端驅(qū)動(dòng)程序,以及進(jìn)一步理解USB協(xié)議有著很重要的意義。下面基于內(nèi)核版本2.6.19.2分析Linux USB的主機(jī)端驅(qū)動(dòng)。
Linux USB主機(jī)端驅(qū)動(dòng)主要分為:主機(jī)控制器驅(qū)動(dòng)、USB核心驅(qū)動(dòng)和USB設(shè)備端驅(qū)動(dòng)3個(gè)部分,它們之間的層次關(guān)系如圖2所示[1]。
在Linux內(nèi)核中關(guān)于USB的代碼主要由2個(gè)部分構(gòu)成:板級(jí)支持代碼和USB驅(qū)動(dòng)代碼。其中板極支持代碼主要分布在與處理器有關(guān)的目錄里,如:/arch/arm/mach-at91rm9200[2]目錄。USB驅(qū)動(dòng)代碼主要集中在/drivers/usb[2]目錄里,主要包括USB核心驅(qū)動(dòng),主機(jī)控制器驅(qū)動(dòng),從機(jī)端驅(qū)動(dòng),各類設(shè)備端驅(qū)動(dòng)程序。其中在Atmel的板極支持代碼/arch/arm/mach-at91rm9200/devices.c[2]中包括USB主機(jī)端和從機(jī)端資源的數(shù)據(jù)結(jié)構(gòu)at91_usbh_resources,at91_udc_resources,平臺(tái)設(shè)備數(shù)據(jù)結(jié)構(gòu) at91rm9200_usbh_device,at91rm9200_udc_device,以及設(shè)備注冊(cè)函數(shù) at91_add_device_usbh(),at91_add_device_udc(),這2個(gè)函數(shù)在板極初始化函數(shù)中被調(diào)用,向內(nèi)核添加USB主機(jī)設(shè)備和從機(jī)設(shè)備。USB驅(qū)動(dòng)的核心代碼是在/drivers/usb/core[2]目錄里,主要的作用是管理設(shè)備端驅(qū)動(dòng)程序、控制協(xié)議命令集、管理數(shù)據(jù)傳輸、配置和管理USB設(shè)備、管理主機(jī)控制器[3]。USB核心啟動(dòng)代碼在目錄/drivers/usb/core/usb.c[2]中,具體的步驟如圖3所示。
USB核心啟動(dòng)以后的結(jié)果是:注冊(cè)1條總線“usb”,1個(gè)文件系統(tǒng)“usbfs”,創(chuàng)建2個(gè)設(shè)備類“usb_host”,“usb_device”,創(chuàng)建了許多的字符設(shè)備節(jié)點(diǎn),分別是主設(shè)備號(hào)為180,從設(shè)備號(hào)是0~255,主設(shè)備號(hào)為189,從設(shè)備號(hào)為0~64×128,注冊(cè)3個(gè)驅(qū)動(dòng)程序:“usbfs”,“hub”,“usb”。創(chuàng)建一個(gè)內(nèi)核線程“khubd”,PID=40,一旦有USB設(shè)備接入,這個(gè)內(nèi)核線程就能捕捉到,并調(diào)用相應(yīng)的驅(qū)動(dòng)探測(cè)函數(shù)。這些內(nèi)容在系統(tǒng)啟動(dòng)以后根文件系統(tǒng)的/sys或/proc相關(guān)目錄下可以找到。Linux USB主機(jī)端驅(qū)動(dòng)涉及的主要數(shù)據(jù)結(jié)構(gòu)有:
usb_driver:USB接口驅(qū)動(dòng)程序結(jié)構(gòu)體;
usb_device_driver:USB設(shè)備驅(qū)動(dòng)程序結(jié)構(gòu)體;
usb_bus:USB總線結(jié)構(gòu)體;
usb_device:USB設(shè)備結(jié)構(gòu)體;
urb:USB請(qǐng)求結(jié)構(gòu)體。
在每個(gè)USB設(shè)備驅(qū)動(dòng)程序里都有1個(gè)設(shè)備表 usb_device_id,用來(lái)保存此設(shè)備驅(qū)動(dòng)程序所支持的USB設(shè)備,如U盤驅(qū)動(dòng)程序的ID表名為usb_storage_ids,如果有些USB設(shè)備的驅(qū)動(dòng)Linux內(nèi)核并不支持,就可以把這些USB設(shè)備的數(shù)據(jù)(包括設(shè)備供應(yīng)商編號(hào)、產(chǎn)品編號(hào)、供應(yīng)商名稱、產(chǎn)品名稱、USB協(xié)議、初始化函數(shù)、標(biāo)記等,這些信息的獲取不依賴于特定的設(shè)備驅(qū)動(dòng)程序,設(shè)備接入后可以從根文件系統(tǒng)的目錄/proc中查看到)添加到相關(guān)設(shè)備驅(qū)動(dòng)程序的usb_device_ids中去,如U盤的驅(qū)動(dòng)程序設(shè)備表id_storage_ids在內(nèi)核頭文件/drivers/usb/storage/unusual_devs.h[2]中。每當(dāng)有USB設(shè)備接入系統(tǒng),USB內(nèi)核的執(zhí)行步驟如圖4所示:
在device-add(函數(shù)中內(nèi)核將該USB設(shè)備添加到USB總線上,并調(diào)用USB總線的匹配函數(shù)usb_device_match(尋找這個(gè)設(shè)備的驅(qū)動(dòng)程序,最終將該設(shè)備與匹配的驅(qū)動(dòng)程序綁定。
3 U盤設(shè)備驅(qū)動(dòng)示例
U盤是USB存儲(chǔ)器的通稱,在內(nèi)核中被定義為USB Mass Storage,除了默認(rèn)配置以外,要在Linux中使用U盤還必須完成以下步驟:
(1) SCSI支持
U盤屬于海量存儲(chǔ)設(shè)備,Linux將它定義為SCSI塊設(shè)備,所以必須要配置這個(gè)選項(xiàng)。內(nèi)核配置選項(xiàng)如下:
SCSI device support(
<*> SCSI device support
<*> SCSI disk support
(2)Windows文件系統(tǒng)支持
U盤可能大都是Windows下的文件格式,所以這里有必要選上對(duì)Windows下文件格式和語(yǔ)言的支持。內(nèi)核配置選項(xiàng)如下:
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驅(qū)動(dòng)支持
USB驅(qū)動(dòng)主要包括對(duì)USB主機(jī)端的支持、USB文件系統(tǒng)、OHCI協(xié)議、USB Mass Storage的支持。內(nèi)核配置選項(xiàng)如下:
USB support(
<*> Support for Host-side USB
[*] USB device filesystem
<*>OHCI HCD support
<*> USB Mass Storage support
(4) 在/dev目錄下新建sda設(shè)備節(jié)點(diǎn)
為了能夠順利地訪問(wèn)USB設(shè)備,必須在/dev目錄下建立相應(yīng)的設(shè)備節(jié)點(diǎn)。由于U盤被定義為塊設(shè)備,所以必須建立SCSI塊設(shè)備節(jié)點(diǎn),命令如下:
mknod–m600sda*b8 *
這里的“*”根據(jù)不同的系統(tǒng)而不同。假如有很多的SCSI設(shè)備則需要建立許多的sda*設(shè)備節(jié)點(diǎn),至于U盤具體是哪一個(gè)設(shè)備節(jié)點(diǎn),則需要根據(jù)fdisk命令來(lái)查詢。
(5)安裝U盤
將U盤插入后,首先我們可以通過(guò)fdisk –l 命令看到U盤的信息(包括該U盤是第幾個(gè)SCSI塊設(shè)備節(jié)點(diǎn),容量是多少等等),然后通過(guò)命令mount –t vfat /dev/sda* /mnt/usb (前提是已經(jīng)在/mnt目錄下建立了usb目錄,并且U盤的格式為Windows下的vfat安裝U盤到指定的目錄下。這里的“*”由fdisk命令顯示的內(nèi)容來(lái)定。
(6) 運(yùn)行結(jié)果
先將U盤插入主機(jī)端接口,再啟動(dòng)系統(tǒng),就會(huì)打印出以下相關(guān)的信息:
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
根文件系統(tǒng)啟動(dòng)以后,可以通過(guò)cat命令顯示該U盤的相關(guān)信息,如:/cat /proc/bus/usb/devices。
4 結(jié) 語(yǔ)
隨著USB接口越來(lái)越廣泛的應(yīng)用,USB-IF在2000年推出了USB 2.0規(guī)范。USB 2.0規(guī)范在兼容USB 1.X規(guī)范的基礎(chǔ)上支持480 Mb/s的高速數(shù)據(jù)傳輸。同時(shí)隨著Linux內(nèi)核的不斷擴(kuò)充,內(nèi)核將支持越來(lái)越多的USB設(shè)備和USB主機(jī)控制器,這對(duì)于USB的普及和應(yīng)用有很重要的意義。
參 考 文 獻(xiàn)
[1]Jonathan Corbet,Alessandro Rubini,Greg roah-Hartman.Linux設(shè)備驅(qū)動(dòng)[M].3版.魏永明,耿岳,鐘書毅,譯.北京:中國(guó)電力出版社,2006.
[2]Linux-2.6.19.2 kernel[EB/OL].http://www.kernel.org.
[3]肖踞雄,翁鐵成,宋中慶.USB技術(shù)及應(yīng)用設(shè)計(jì)[M].北京:清華大學(xué)出版社,2003.
[4]Daniel P.Bovet,Marco Cesati.深入理解Linux內(nèi)核[M].2版.陳莉君,馮銳,牛欣源,譯.北京:中國(guó)電力出版社,2004.
[5]李哲,王紹丹.AT91RM9200處理器同步串口SSC的特性分析與應(yīng)用[J].國(guó)外電子元器件,2007(7:57-60.