隨著計算機外圍硬件的擴展,,各種外圍設備使用不同的總線接口,,導致計算機外部各種總線繁多,管理困難,,USB總線可以解決這些問題,因此而誕生,。USB總線提供統(tǒng)一的外設的接口方式,,并且支持熱插拔,方便了廠商開發(fā)設備和用戶使用設備,。USB(通用串行總線)是由Microsft,,Compad,Inter和NEC等推出的外圍總線接口,,目前已發(fā)展到2.0標準最高支持480Mb/s的速率,,最多可以支持127個外設。
嵌入式Linux是一款源代碼完全免費的新興操作系統(tǒng),,用戶可以用戶可以通過網(wǎng)絡等其他途徑免費獲得,,并可以任意修改其源代碼,這是其他的操作系統(tǒng)做不到的,。正是由于這一點,,Linux得到了廣泛的應用。
1 Linux中USB設備驅(qū)動程序框架及數(shù)據(jù)結(jié)構(gòu)
1.1 USB的體系結(jié)構(gòu)
USB接口標準支持外部設備和主機之間進行數(shù)據(jù)傳送,。在USB結(jié)構(gòu)中主機頂設各種類型外設使用的總線寬度,。當外設和主機在運行時,USB總線允許使用,,設置,,添加和拆除外設。
在USB體系結(jié)構(gòu)中一個USB系統(tǒng)可以分成USB設備,、USB主機和USB互聯(lián)3個部分,。USB互聯(lián)是USB設備和USB主機之間進行連接通信的操作,主要包括:
1)總線拓撲結(jié)構(gòu):UsB主機和USB設備之間的連接方式,;
2)數(shù)據(jù)流模式:描述USB通信系統(tǒng)數(shù)據(jù)如何從產(chǎn)生方傳遞到使用方,;
3)USB調(diào)度:USB總線是一個共享連接,對可以使用的連按進行調(diào)度以支持同步數(shù)據(jù)傳輸,,并避免優(yōu)先級判斷的開銷,。
USB的物理連接是有層次的星型結(jié)構(gòu),如圖1所示,。
從圖中可以看出USB集線器在一個節(jié)點上連接多個設備,,每條線段都是點點連接,每個USB集線器在星形的中心,。從主機到設備或者USB集線器,,或USB集線器到設備都是點點連接,。
1.2 USB驅(qū)動程序的結(jié)構(gòu)
USN總線在技術層面上是非常簡單的,它是一個單主方式實現(xiàn)的,,主機輪詢各種不同的外圍設備,,USB另外一個重要的特性是它只擔當設備和主控制器之間通訊通道的角色,對所發(fā)送的數(shù)據(jù)沒有任何特殊的內(nèi)容和結(jié)構(gòu)上的要求,。
Linux支持兩種類型的USB驅(qū)動,,宿主系統(tǒng)上的驅(qū)動程序和設備上的驅(qū)動程序。宿主USB驅(qū)動程序控制插入其中的USB設備,,而USB設備的驅(qū)動程序控制設備如何作為一個USB設備和主機通訊,。這里主要討論設備驅(qū)動。
USB的基本通信的形式基本通過端點的東西,。USB端點只能往一個方向傳輸數(shù)據(jù),,從主機到設備或從設備到主機。USB端點分別具有不同的傳輸數(shù)據(jù)的方式,,他們有4種類型,,分別是:1)控制端點用來控制對USB設備不同部分的訪問。他們用于配置設備,,獲取設備信息,,獲取設備的狀態(tài)報告,發(fā)送命令到設備,。它是一種非周期性的可靠的傳輸,。2)中斷端點就是設備傳輸數(shù)據(jù)時以一個固定的速率來傳輸少量的數(shù)據(jù)。這些端點是鼠標和USB鍵盤所使用的主要傳輸方式,。它通常用于發(fā)送數(shù)據(jù)到USB設備以控制設備,,一般不用來傳輸大量數(shù)據(jù)。USB協(xié)議保證這些傳輸有足夠的保留帶寬來傳輸數(shù)據(jù),。3)等時端點同樣可以傳輸大批量的數(shù)據(jù),,但數(shù)據(jù)是否到達沒有保障,這些端點用于可以應付數(shù)據(jù)丟失的情況,,這類設備更注重于保持一定的恒定的數(shù)據(jù)流,,實時的數(shù)據(jù)收集都使用這類端點。4)批量端點傳輸大量的數(shù)據(jù),。這些端點通常比中斷端點大的多他們常用于需要確保沒有數(shù)據(jù)丟失的傳輸設備,。USB協(xié)議不保證這些傳輸始終可以在特定的時間內(nèi)完成。如果總線上的空間不足以發(fā)送整個批量包,。它將被分割為多個包進行傳輸,。
當一個USB設備連接到主機時,主機會給這個設備分配一個1~127之間的唯一的設備號同時讀取該設備的描述符,該設備描述符是描述設備信息及其屬性的數(shù)據(jù)結(jié)構(gòu),,USB以一種層次化的結(jié)構(gòu)定義設備的描述符,,設備描述符給出了USB設備的一般信息,包括對設備及所有設備配置起全程作用的信息,,一個USB設備只能有一個設備描述符,,配置描述符中的信息與設備特定的配置相關,一個USB設備可以有一個或多個配置描述符,,每一個配置描述符又由一個或多個接口描述符組成,,接口描述符的信息是與設備驅(qū)動程序的開發(fā)密切相關,可以一個接口對應一個設備驅(qū)動程序也可以多個接口對應一個設備驅(qū)動程序,,接口描述符由零個或多個端點描述符組成,端點描述符定義了在一個給定的設備里實現(xiàn)的實際寄存器,,這些描述符定義了每個寄存器的功能和特定的信息如端點要求的傳輸類型,、傳輸方向、帶寬要求,、查詢間隔等,。另外,還有一個可選的宇符串描述符,,它以UNCOND碼的格式給出了一些可讀的信息,,這些信息通常是有關設備生產(chǎn)廠商、設備名設備序列號等,,通過這些不同層次的描述符,,主機設備驅(qū)動程序就可以知道具體設備的相關信息,從而對設備進行相應控制,。
1.3 USB驅(qū)動程序框架
1.3.1 基本數(shù)據(jù)結(jié)構(gòu)
usb-skel設備使用自定義結(jié)構(gòu)usb_skel記錄設備驅(qū)動用到的所有描述符,,該結(jié)構(gòu)定義如下:
1.3.2 驅(qū)動程序初始化和注銷
同其他所有的Linux設備驅(qū)動程序一樣,usb-skel驅(qū)動使用module_init()宏初始化函數(shù),,使用module_exit()宏注銷函數(shù),。usb-skel驅(qū)動的初始化函數(shù)usb_skel_init()函數(shù),定義如下:
在USB驅(qū)動中調(diào)用usb_deregister()函數(shù)注銷usb-skel設備驅(qū)動,,函數(shù)定義如下:
1.3.3 初始化設備
從skel_driver結(jié)構(gòu)可以知道usb-skel設備的初始化函數(shù)是skel_probe()函數(shù),,設備初始化主要是探測設備類型,分配USB設備用到的urb資源,,注冊USB設備操作函數(shù)等,。
skel_class結(jié)構(gòu)變量記錄了usb-skel設備信息,定義如下:
name變量使用%d通配符表示一個整型變量,,當一個usb-skel類型的設備連接到USB總先后會2按照子設備編號自動設置設備名稱,。Fops設備操作函數(shù)結(jié)構(gòu)變量,定義如下:
1.3.4 設備注銷
skel_disconnect()函數(shù)在注銷設備時被調(diào)用,定義如下:
2 USB串口驅(qū)動
2. 1 驅(qū)動初始化函數(shù)
usb_serial_init()函數(shù)是一個典型的USB設備驅(qū)動初始化函數(shù),,定義如下:
函數(shù)首先調(diào)用alloc_tty_driver()函數(shù)分配一個串口驅(qū)動描述符,;然后設置串口驅(qū)動的屬性,包括驅(qū)動的主從設備號,、設備類型,、串口初始化參數(shù)等;串口驅(qū)動描述符設置完畢后,,調(diào)用usb_register()函數(shù)注冊USB串口設備,。
2. 2 驅(qū)動釋放函數(shù)
2.3 串口操作函數(shù)
USB串口設備驅(qū)動使用了一個tty_operations類型的結(jié)構(gòu),該結(jié)構(gòu)包含了串口的所有操作,,定義如下:
按上述的步驟和方法通過lnsmod命令成功實現(xiàn)了USB驅(qū)動程序的加載,,成功的通過USB串口進行了數(shù)據(jù)的讀寫。
3 結(jié)論
新出的Linux2.6內(nèi)核加入了對USB2.0的支持,,重新定義了usb_class_driver結(jié)構(gòu)體,。同時對探測函數(shù)probe和usb_submit_urb做了修改,包含了advanced linux sound Archiecture可以更安全的使用USB設備,。