基于A(yíng)T91RM9200的USB主機端Linux驅動(dòng)
1 AT91RM9200 USB主機端接口硬件構成
AT91RM9200處理器是Atmel公司一款比較流行的微型處理器,它具有ARM920T內核(帶有MMU),主時(shí)鐘頻率可達240 MHz,很適合嵌入式系統應用,它同時(shí)具有USB主機端和設備端,其中主機端處理開(kāi)HCI協(xié)議(OHCI)及USB v2.0全速與低速協(xié)議,還給ASB提供簡(jiǎn)單的讀/寫(xiě)協(xié)議,USB主機端口還集成1個(gè)根集線(xiàn)器,硬件結構如圖1所示。
2 Linux USB主機端驅動(dòng)
Linux在1999年就在其核心內嵌入了USB驅動(dòng)程序。理解Linux的USB主機端驅動(dòng)結構和原理,對在Linux系統上開(kāi)發(fā)USB設備端驅動(dòng)程序,以及進(jìn)一步理解USB協(xié)議有著(zhù)很重要的意義。下面基于內核版本2.6.19.2分析Linux USB的主機端驅動(dòng)。
![]() |
Linux USB主機端驅動(dòng)主要分為:主機控制器驅動(dòng)、USB核心驅動(dòng)和USB設備端驅動(dòng)3個(gè)部分,它們之間的層次關(guān)系如圖2所示。
在Linux內核中關(guān)于USB的代碼主要由2個(gè)部分構成:板級支持代碼和USB驅動(dòng)代碼。其中板極支持代碼主要分布在與處理器有關(guān)的目錄里,如:/arch/arm/mach-at91rm9200目錄。USB驅動(dòng)代碼主要集中在/drivers/usb目錄里,主要包括USB核心驅動(dòng),主機控制器驅動(dòng),從機端驅動(dòng),各類(lèi)設備端驅動(dòng)程序。其中在A(yíng)tmel的板極支持代碼/arch/arm/mach-at91rm9200/devices.c中包括USB主機端和從機端資源的數據結構at91_usbh_re-sources,at91_udc_resources,平臺設備數據結構at91rm9200_usbh_device,at91rm9200_udc_device,以及設備注冊函數at91_add_device_usbh(),at91_add_device_udc(),這2個(gè)函數在板極初始化函數中被調用,向內核添加USB主機設備和從機設備。USB驅動(dòng)的核心代碼是在/drivers/usb/core目錄里,主要的作用是管理設備端驅動(dòng)程序、控制協(xié)議命令集、管理數據傳輸、配置和管理USB設備、管理主機控制器。USB核心啟動(dòng)代碼在目錄/drivers/usb/core/usb.c中,具體的步驟如圖3所示。
![]() |
USB核心啟動(dòng)以后的結果是:注冊1條總線(xiàn)“usb”,1個(gè)文件系統“usbfs”,創(chuàng )建2個(gè)設備類(lèi)“usb_host”,“usb_device”,創(chuàng )建了許多的字符設備節點(diǎn),分別是主設備號為180,從設備號是0~255,主設備號為189,從設備號為0~64128,注冊3個(gè)驅動(dòng)程序:“usbfs”,“hub”,“usb”。創(chuàng )建一個(gè)內核線(xiàn)程“khubd”,PID=40,一旦有USB設備接入,這個(gè)內核線(xiàn)程就能捕捉到,并調用相應的驅動(dòng)探測函數。這些內容在系統啟動(dòng)以后根文件系統的/sys或/proc相關(guān)目錄下可以找到。Linux USB主機端驅動(dòng)涉及的主要數據結構有:
usb_driver:USB接口驅動(dòng)程序結構體;
usb_device_driver:USB設備驅動(dòng)程序結構體;
usb_bus:USB總線(xiàn)結構體;
usb_device:USB設備結構體;
urb:USB請求結構體。
在每個(gè)USB設備驅動(dòng)程序里都有1個(gè)設備表usb_device_id,用來(lái)保存此設備驅動(dòng)程序所支持的USB設備,如U盤(pán)驅動(dòng)程序的ID表名為usb_storage_ids,如果有些USB設備的驅動(dòng)Linux內核并不支持,就可以把這些USB設備的數據(包括設備供應商編號、產(chǎn)品編號、供應商名稱(chēng)、產(chǎn)品名稱(chēng)、USB協(xié)議、初始化函數、標記等,這些信息的獲取不依賴(lài)于特定的設備驅動(dòng)程序,設備接入后可以從根文件系統的目錄/proc中查看到)添加到相關(guān)設備驅動(dòng)程序的usb_device_ids中去,如U盤(pán)的驅動(dòng)程序設備表id_storage_ids在內核頭文件/drivers/usb/storage/unusual_devs.h中。每當有USB設備接入系統,USB內核的執行步驟如圖4所示:
![]() |
在device-add()函數中內核將該USB設備添加到USB總線(xiàn)上,并調用USB總線(xiàn)的匹配函數usb_device_match()尋找這個(gè)設備的驅動(dòng)程序,最終將該設備與匹配的驅動(dòng)程序綁定。
3 U盤(pán)設備驅動(dòng)示例
U盤(pán)是USB存儲器的通稱(chēng),在內核中被定義為USBMass Storage,除了默認配置以外,要在Linux中使用U盤(pán)還必須完成以下步驟:
(1)SCSl支持
U盤(pán)屬于海量存儲設備,Linux將它定義為SCSI塊設備,所以必須要配置這個(gè)選項。內核配置選項如下:
![]() |
(2)Windows文件系統支持
U盤(pán)可能大都是Windows下的文件格式,所以這里有必要選上對Windows下文件格式和語(yǔ)言的支持。內核配置選項如下:
![]() |
(3)USB驅動(dòng)支持
USB驅動(dòng)主要包括對USB主機端的支持、USB文件系統、OHCI協(xié)議、USB Mass Storage的支持。內核配置選項如下:
![]() |
(4)在/dev目錄下新建sda設備節點(diǎn)
為了能夠順利地訪(fǎng)問(wèn)USB設備,必須在/dev目錄下建立相應的設備節點(diǎn)。由于U盤(pán)被定義為塊設備,所以必須建立SCSI塊設備節點(diǎn),命令如下:
mknod-m 600 sda*b8*
這里的“*”根據不同的系統而不同。假如有很多的SCSI設備則需要建立許多的sda*設備節點(diǎn),至于U盤(pán)具體是哪一個(gè)設備節點(diǎn),則需要根據fdisk命令來(lái)查詢(xún)。
(5)安裝U盤(pán)
將U盤(pán)插入后,首先我們可以通過(guò)fdisk-1命令看到U盤(pán)的信息(包括該U盤(pán)是第幾個(gè)SCSI塊設備節點(diǎn),容量是多少等等),然后通過(guò)命令mount-t vfat/dev/sda*/mnt/usb(前提是已經(jīng)在/mnt目錄下建立了usb目錄,并且U盤(pán)的格式為Windows下的vfat)安裝U盤(pán)到指定的目錄下。這里的“*”由fdisk命令顯示的內容來(lái)定。
(6)運行結果
先將U盤(pán)插入主機端接口,再啟動(dòng)系統,就會(huì )打印出以下相關(guān)的信息:
![]() |
![]() |
根文件系統啟動(dòng)以后,可以通過(guò)cat命令顯示該U盤(pán)的相關(guān)信息,如:/cat/proc/bus/usb/devices。
4 結語(yǔ)
隨著(zhù)USB接口越來(lái)越廣泛的應用,USB-IF在2000年推出了USB 2.0規范。USB 2.0規范在兼容USB 1.X規范的基礎上支持480 Mb/s的高速數據傳輸。同時(shí)隨著(zhù)Linux內核的不斷擴充,內核將支持越來(lái)越多的USB設備和USB主機控制器,這對于USB的普及和應用有很重要的意義。
評論