嵌入式Linux下USB驅(qū)動程序的設計
一、引言
本文引用地址:http://2s4d.com/article/237803.htmUSB(Universal Serial Bus)即通用串行總線,是一種全新的雙向同步傳輸?shù)闹С譄岵灏蔚臄?shù)據(jù)傳輸總線,其目的是為了提供一種兼容不同速度的、可擴充的并且使用方便的外圍設備接口,同時也是為了解決計算機接口的太多的弊端而設計的。一個USB系統(tǒng)主要有三部分組成:USB互連、USB主機、USB設備三部分組成的,其結構如圖1所示。在編寫USB設備驅(qū)動程序設計時,可以分為三部分編寫:主機端設備驅(qū)動程序、主機控制器驅(qū)動程序設計和設備端驅(qū)動程序三部分,在本文中重點介紹主機端驅(qū)動程序的設計。
二、USB設備驅(qū)動程序的設計
USB設備驅(qū)動程序的設計包括主機端設備驅(qū)動程序設計、主機控制器驅(qū)動程序設計和設備端驅(qū)動程序設計三部分組成。主機端設備驅(qū)動程序就是通常說的設備驅(qū)動程序,它是主機環(huán)境中為用戶應用程序提供一個訪問USB外設的接口。Linux為這部分驅(qū)動程序提供編程接口,驅(qū)動程序設計者只要按照需求編寫驅(qū)動程序框架,通過調(diào)用操作系統(tǒng)提供的API接口函數(shù)可以完成對USB外設的特定訪問。
主機控制驅(qū)動主要是對USB主機控制器的驅(qū)動,在大多數(shù)PC環(huán)境下,主機控制器都是由操作系統(tǒng)提供。嵌入式設備一般都沒有USB主機控制器,只是工作在Slave模式下。如果要使USB具有主機功能,那么設備中需要選用一個帶主機控制器的USB接口控制芯片, 同時自己還要有實現(xiàn)該主機控制器的驅(qū)動程序。目前Linux內(nèi)核中只提供USB主機控制器的開放主機控制器和通用主機控制器接口兩種規(guī)格,而這兩種規(guī)格主要用在PC架構中。USB主機端驅(qū)動程序與主機控制器的結構如圖2所示。其中USB核是Linux的一個子模塊,集中定義了一組USB相關的數(shù)據(jù)結構、宏以及API函數(shù)。
USB設備驅(qū)動程序是常說的設備固件程序的一部分,提供設備信息與主機的通信接口。設備端USB驅(qū)動程序設計由以下幾部分處理程序組成。初始化例程:完成描述符指針、端點、配置改變等操作。數(shù)據(jù)傳輸例程:完成控制傳輸、批量傳輸、中斷傳輸及同步傳輸?shù)葌鬏敺绞较碌臄?shù)據(jù)收發(fā)工作。標準設備處理請求:處理標準設備請求。廠商請求處理:處理生產(chǎn)商指定請求。其他操作:處理主機發(fā)出的端口復位、配置改變等操作。
1.USB設備驅(qū)動程序框架
USB驅(qū)動程序首先要向Linux內(nèi)核注冊自己,并告訴系統(tǒng)它所支持的設備類型以及它所支持的操作。這些信息通過一個usb_driver結構來傳遞。usb_driver結構如下:
static struct usb_driver skel_driver = {
name: "skeleton";/*驅(qū)動程序的名稱*/
probe: skel_probe; /*設備列舉時被調(diào)用*/
disconnect: skel_disconnect; /*設備被卸載時被調(diào)用*/
fops: skel_fops; /*指向一個file_operation結構,內(nèi)核通過它來訪問驅(qū)動程序的文件操作函數(shù),與用戶程序的read、write等操作進行交互*/
minor USB_SKEL_MINOR_BASE; /*指向設備的次設備號,用于系統(tǒng)識別主設備號相同的設備(即一個驅(qū)動程序可以同時支持多個USB設備*/
id_table: skel_table; /*保存設備的廠商ID和產(chǎn)品ID,作為該設備的唯一標識,驅(qū)動程序向系統(tǒng)注冊后,當下次插入時,系統(tǒng)根據(jù)這個標識查找正確的驅(qū)動程序,實現(xiàn)設備的即插即用*/
};
static struct file_operation skel_fops={
{
owner:THIS_MODULE,
read:skel_read,
write:skel_write,
ioctl:skel_ioctl,
open:skel_open,
release:skel_release,
};
(1)注冊和注銷
USB驅(qū)動程序注冊,就是把在初始化函數(shù)中填好的use_driver結構作為參數(shù)傳遞給
use_register()函數(shù)即可,函數(shù)的調(diào)用方法為:
result=usb_register(skel_driver);
當要從系統(tǒng)卸載驅(qū)動程序時,也是將use_driver結構作為參數(shù)傳遞給usb_deregister 函數(shù)處理。 函數(shù)的調(diào)用格式為:
static void __exit usb_skel_exit(void)
{ /* deregister this driver with the USB subsystem */
usb_deregister(skel_driver);
}
module_exit(usb_skel_exit);
當USB設備插入時,為了使linux-hotplug(Linux中PCI、USB等設備熱插拔支持)系統(tǒng)自動裝載驅(qū)動程序,需要創(chuàng)建一個MODULE_DEVICE_TABLE。核心代碼如下(這個模塊僅支持某一特定設備):
/* table of devices that work with this driver */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID,
USB_SKEL_PRODUCT_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, skel_table);
USB_DEVICE宏利用廠商ID和產(chǎn)品ID提供了一個設備的唯一標識。當系統(tǒng)插入一個ID匹配的USB設備到USB總線時,驅(qū)動會在USB core中注冊,驅(qū)動程序中probe 函數(shù)也就會被調(diào)用。usb_device 結構指針、接口號和接口ID都會被傳遞到函數(shù)中。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)linux相關文章:linux教程
評論