USB驅(qū)動編程指南參考模板_第1頁
USB驅(qū)動編程指南參考模板_第2頁
USB驅(qū)動編程指南參考模板_第3頁
USB驅(qū)動編程指南參考模板_第4頁
USB驅(qū)動編程指南參考模板_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、USB驅(qū)動編寫指南1 概念:模塊和設(shè)備文件1.1模塊模塊是在內(nèi)核空間運(yùn)行的程序,實際上是一種目標(biāo)對象文件,沒有鏈接,不能獨(dú)立運(yùn)行,但是可以裝載到系統(tǒng)中作為內(nèi)核的一部分運(yùn)行,從而可以動態(tài)擴(kuò)充內(nèi)核的功能。模塊最主要的用處就是用來實現(xiàn)設(shè)備驅(qū)動程序。Linux下對于一個硬件的驅(qū)動,可以有兩種方式:直接加載到內(nèi)核代碼中,啟動內(nèi)核時就會驅(qū)動此硬件設(shè)備。另一種就是以模塊方式,編譯生成一個.ko文件(在2.4以下內(nèi)核中是用.o作模塊文件,我們以2.6的內(nèi)核為準(zhǔn),以下同)。當(dāng)應(yīng)用程序需要時再加載到內(nèi)核空間運(yùn)行。所以我們所說的一個硬件的驅(qū)動程序,通常指的就是一個驅(qū)動模塊。1.2設(shè)備文件設(shè)備文件對于一個設(shè)備,它可以

2、在/dev下面存在一個對應(yīng)的邏輯設(shè)備節(jié)點(diǎn),這個節(jié)點(diǎn)以文件的形式存在,但它不是普通意義上的文件,它是設(shè)備文件,更確切 的說,它是設(shè)備節(jié)點(diǎn)。這個節(jié)點(diǎn)是通過mknod命令建立的,其中指定了主設(shè)備號和次設(shè)備號。主設(shè)備號表明了某一類設(shè)備,一般對應(yīng)著確定的驅(qū)動程序;次設(shè)備號一般是區(qū)分不同屬性,例如不同的使用方法,不同的位置,不同的操作。這個設(shè)備號是從/proc/devices文件中獲得的,所以一般是先有驅(qū)動程序在內(nèi)核中,才有設(shè)備節(jié)點(diǎn)在目錄中。這個設(shè)備號(特指主設(shè)備號)的主要作用,就是聲明設(shè)備所使用的驅(qū)動程序。驅(qū)動程序和設(shè)備號是一一對應(yīng)的,當(dāng)你打開一個設(shè)備文件時,操作系統(tǒng)就已經(jīng)知道這個設(shè)備所對應(yīng)的驅(qū)動程序。

3、對于一個硬件,Linux是這樣來進(jìn)行驅(qū)動的:首先,我們必須提供一個.ko的驅(qū)動模塊文件。我們要使用這個驅(qū)動程序,首先要加載它,我們可以用insmod xxx.ko,這樣驅(qū)動就會根據(jù)自己的類型(字符設(shè)備類型或塊設(shè)備類型,例如鼠標(biāo)就是字符設(shè)備而硬盤就是塊設(shè)備)向系統(tǒng)注冊,注冊成功系統(tǒng)會反饋一個主設(shè)備號,這個主設(shè)備號就是系統(tǒng)對它的唯一標(biāo)識。驅(qū)動就是根據(jù)此主設(shè)備號來創(chuàng)建一個一般放置在/dev目錄下的設(shè)備文件。在我們要訪問此硬件時,就可以對設(shè)備文件通過open、read、write、close等命令進(jìn)行。而驅(qū)動就會接收到相應(yīng)的read、write操作而根據(jù)自己的模塊中的相應(yīng)函數(shù)進(jìn)行操作 了。2 USB驅(qū)

4、動程序如何應(yīng)用了解了上述理論后,我們就可以動手寫驅(qū)動程序,如果你基本功好,而且寫過linux下的硬件驅(qū)動,USB的硬件驅(qū)動和pci_driver很類似,那么寫 USB的驅(qū)動就比較簡單了,如果你只是大體了解了linux的硬件驅(qū)動,那也不要緊,因為在linux的內(nèi)核源碼中有一個框架程序可以拿來借用一下,這個框架程序在/usr/src/(你的內(nèi)核版本,以下同)/drivers/usb下,文件名為usb-skeleton.c。寫一個USB的驅(qū)動程序最基本的要做四件事:驅(qū)動程序要支持的設(shè)備、注冊USB驅(qū)動程序、探測和斷開、提交和控制urb(USB請求塊)(當(dāng)然也可以不用urb來傳輸數(shù)據(jù),下文我們會說到)

5、。2.1驅(qū)動程序支持的設(shè)備驅(qū)動程序支持的設(shè)備有一個結(jié)構(gòu)體struct usb_device_id,這個結(jié)構(gòu)體提供了一列不同類型的該驅(qū)動程序支持的USB設(shè)備,對于一個只控制一個特定的USB設(shè)備的驅(qū)動程序來說,struct usb_device_id表被定義為:/* 驅(qū)動程序支持的設(shè)備列表 */static struct usb_device_id skel_table = 1 / 11 USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) , /* 終止入口 */;MODULE_DEVICE_TABLE (usb, skel_table); 對于

6、PC驅(qū)動程序,MODULE_DEVICE_TABLE是必需的,而且usb必需為該宏的第一個值,而USB_SKEL_VENDOR_ID和 USB_SKEL_PRODUCT_ID就是這個特殊設(shè)備的制造商和產(chǎn)品的ID了,我們在程序中把定義的值改為我們這款USB的,如:/* 定義制造商和產(chǎn)品的ID號 */#define USB_SKEL_VENDOR_ID 0x1234#define USB_SKEL_PRODUCT_ID 0x2345 這兩個值可以通過命令lsusb,當(dāng)然你得先把USB設(shè)備先插到主機(jī)上了。或者查看廠商的USB設(shè)備的手冊也能得到,在我機(jī)器上運(yùn)行l(wèi)susb是這樣的結(jié)果:Bus 004 D

7、evice 001: ID 0000:0000Bus 003 Device 002: ID 1234:2345 Abc Corp.Bus 002 Device 001: ID 0000:0000Bus 001 Device 001: ID 0000:0000得到這兩個值后把它定義到程序里就可以了。2.2注冊USB驅(qū)動程序注冊USB驅(qū)動程序所有的USB驅(qū)動程序都必須創(chuàng)建的結(jié)構(gòu)體是struct usb_driver。這個結(jié)構(gòu)體必須由USB驅(qū)動程序來填寫,包括許多回調(diào)函數(shù)和變量,它們向USB核心代碼描述USB驅(qū)動程序。創(chuàng)建一個有效的struct usb_driver結(jié)構(gòu)體,只須要初始化五個字段就可以

8、了,在框架程序中是這樣的:static struct usb_driver skel_driver = .owner = THIS_MODULE,.name = skeleton,.probe = skel_probe,.disconnect = skel_disconnect,.id_table = skel_table,;struct module *owner :指向該驅(qū)動程序的模塊所有者的批針。USB核心使用它來正確地對該USB驅(qū)動程序進(jìn)行引用計數(shù),使它不會在不合適的時刻被卸載掉,這個變量應(yīng)該被設(shè)置為THIS_MODULE宏。const char *name:指向驅(qū)動程序名字的指針,在

9、內(nèi)核的所有USB驅(qū)動程序中它必須是唯一的,通常被設(shè)置為和驅(qū)動程序模塊名相同的名字。 int (*probe) (struct usb_interface *intf,const struct usb_device_id *id):這個是指向USB驅(qū)動程序中的探測函數(shù)的指針。當(dāng)USB核心認(rèn)為它有一個接口(usb_interface)可以由該驅(qū)動程序處理時,這個函數(shù)被調(diào)用。void (disconnect)(struct usb_interface *intf):指向USB驅(qū)動程序中的斷開函數(shù)的指針,當(dāng)一個USB接口(usb_interface)被從系統(tǒng)中移除或者驅(qū)動程序正在從USB核心中卸載時,

10、USB核心將調(diào)用這個函數(shù)。const struct usb_device_id *id_table:指向ID設(shè)備表的指針,這個表包含了一列該驅(qū)動程序可以支持的USB設(shè)備,如果沒有設(shè)置這個變量,USB驅(qū)動程序中的探測回調(diào)函數(shù)就不會被調(diào)用。在這個結(jié)構(gòu)體中還有其它的幾個回調(diào)函數(shù)不是很常用,這里就不一一說明了。以struct usb_driver 指針為參數(shù)的usb_register_driver函數(shù)調(diào)用把struct usb_driver注冊到USB核心。一般是在USB驅(qū)動程序的模塊初始化代碼中完成這個工作的:static int _init usb_skel_init(void)int resul

11、t;/* 驅(qū)動程序注冊到USB子系統(tǒng)中*/result = usb_register(&skel_driver);if (result)err(usb_register failed. Error number %d, result);return result;當(dāng)USB驅(qū)動程序?qū)⒁恍遁d時,需要把struct usb_driver從內(nèi)核中注銷。通過調(diào)用usb_deregister_driver來完成這個工作,當(dāng)調(diào)用發(fā)生時,當(dāng)前綁定到該驅(qū)動程序上的任何USB接口都被斷開,斷開函數(shù)將被調(diào)用:static void _exit usb_skel_exit(void)/* 從子系統(tǒng)注銷驅(qū)動程序*/u

12、sb_deregister(&skel_driver);2.3探測和斷開探測和斷開當(dāng)一個設(shè)備被安裝而USB核心認(rèn)為該驅(qū)動程序應(yīng)該處理時,探測函數(shù)被調(diào)用,探測函數(shù)檢查傳遞給它的設(shè)備信息,確定驅(qū)動程序是否真的適合該設(shè)備。當(dāng)驅(qū)動程序因為某種原因不應(yīng)該控制設(shè)備時,斷開函數(shù)被調(diào)用,它可以做一些清理工作。探測回調(diào)函數(shù)中,USB驅(qū)動程序初始化任何可能用于控制USB設(shè)備的局部結(jié)構(gòu)體,它還把所需的任何設(shè)備相關(guān)信息保存到一個局部結(jié)構(gòu)體中,下面是探測函數(shù)的部分源碼,我們加以分析。/* 設(shè)置端點(diǎn)信息 */* 只使用第一個批量IN和批量OUT端點(diǎn) */iface_desc = interface-cur_altsett

13、ing;for (i = 0; i desc.bNumEndpoints; +i) endpoint = &iface_desc-endpoint.desc;if (!dev-bulk_in_endpointAddr &(endpoint-bEndpointAddress & USB_DIR_IN) &(endpoint-bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)= USB_ENDPOINT_XFER_BULK) /* 找到一個批量IN端點(diǎn) */buffer_size = endpoint-wMaxPacketSize;dev-bulk_in_size

14、 = buffer_size;dev-bulk_in_endpointAddr = endpoint-bEndpointAddress;dev-bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);if (!dev-bulk_in_buffer) err(Could not allocate bulk_in_buffer);goto error;if (!dev-bulk_out_endpointAddr &!(endpoint-bEndpointAddress & USB_DIR_IN) &(endpoint-bmAttributes & USB

15、_ENDPOINT_XFERTYPE_MASK)= USB_ENDPOINT_XFER_BULK) /* 找到一個批量OUT端點(diǎn) */dev-bulk_out_endpointAddr = endpoint-bEndpointAddress;if (!(dev-bulk_in_endpointAddr & dev-bulk_out_endpointAddr) err(Could not find both bulk-in and bulk-out endpoints);goto error;在探測函數(shù)里,這個循環(huán)首先訪問該接口中存在的每一個端點(diǎn),給該端點(diǎn)一個局部指針以便以后訪問:for (i

16、= 0; i desc.bNumEndpoints; +i) endpoint = &iface_desc-endpoint.desc;在一輪探測過后,我們就有了一個端點(diǎn),在還沒有發(fā)現(xiàn)批量IN類型的端點(diǎn)時,探測該端點(diǎn)方向是否為IN,這可以通過檢查USB_DIR_IN是否包含在 bEndpointAddress端點(diǎn)變量有確定,如果是的話,我們再探測該端點(diǎn)類型是否為批量,先用 USB_ENDPOINT_XFERTYPE_MASK位掩來取bmAttributes變量的值,然后探測它是否和 USB_ENDPOINT_XFER_BULK值匹配:if (!dev-bulk_out_endpointAddr

17、 &!(endpoint-bEndpointAddress & USB_DIR_IN) &(endpoint-bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)= USB_ENDPOINT_XFER_BULK)如果所有這些探測都通過了,驅(qū)動程序就知道它已經(jīng)發(fā)現(xiàn)了正確的端點(diǎn)類型,可以把該端點(diǎn)的相關(guān)信息保存到一個局部結(jié)構(gòu)體中以便稍后用它來和端點(diǎn)進(jìn)行通信:/* 找到一個批量IN類型的端點(diǎn) */buffer_size = endpoint-wMaxPacketSize;dev-bulk_in_size = buffer_size;dev-bulk_in_endpoin

18、tAddr = endpoint-bEndpointAddress;dev-bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);if (!dev-bulk_in_buffer) err(Could not allocate bulk_in_buffer);goto error;因為USB驅(qū)動程序要在設(shè)備的生命周期的稍后時間獲取和接口相關(guān)聯(lián)的局部數(shù)據(jù)結(jié)構(gòu)體,所以調(diào)用了usb_set_intfdata函數(shù),把它保存到struct usb_interface結(jié)構(gòu)體中以便后面的訪問/* 把數(shù)據(jù)指針保存到這個接口設(shè)備中*/usb_set_intfdata(

19、interface, dev);我們以后調(diào)用usb_set_intfdata函數(shù)來獲取數(shù)據(jù)。當(dāng)這一切都完成后,USB驅(qū)動程序必須在探測函數(shù)中調(diào)用usb_register_dev函數(shù)來把該設(shè)備注冊到USB核心里:/* 注冊設(shè)備到USB核心 */retval = usb_register_dev(interface, &skel_class);if (retval) /* 有些情況下是不允許注冊驅(qū)動程序的 */err(Not able to get a minor for this device.);usb_set_intfdata(interface, NULL);goto error;當(dāng)一個U

20、SB設(shè)備被斷開時,和該設(shè)備相關(guān)聯(lián)的所有資源都應(yīng)該被盡可能的清理掉,在此時,如果已在在探測函數(shù)中調(diào)用了注冊函數(shù)來為該USB設(shè)備分配了一個次設(shè)備號話,必須調(diào)用usb_deregister_dev函數(shù)來把次設(shè)備號交還給USB核心。在斷開函數(shù)中,從接口獲取之前調(diào)用usb_set_intfdata設(shè)置的任何數(shù)據(jù)也是很重要的。然后設(shè)置struct usb_interface結(jié)構(gòu)體中的數(shù)據(jù)指針為NULL,以防任何不適當(dāng)?shù)膶υ摂?shù)據(jù)的錯誤訪問。在探測函數(shù)中會對每一個接口進(jìn)行一次探測,所以我們在寫USB驅(qū)動程序的時候,只要做好第一個端點(diǎn),其它的端點(diǎn)就會自動完成探測。在探測函數(shù)中我們要注意的是在內(nèi)核中用結(jié)構(gòu)體str

21、uct usb_host_endpoint來描述USB端點(diǎn),這個結(jié)構(gòu)體在另一個名為struct usb_endpoint_descriptor的結(jié)構(gòu)體中包含了真正的端點(diǎn)信息,struct usb_endpoint_descriptor結(jié)構(gòu)體包含了所有的USB特定的數(shù)據(jù),該結(jié)構(gòu)體中我們要關(guān)心的幾個字段是:bEndpointAddress:這個是特定的USB地址,可以結(jié)合USB_DIR_IN和USB_DIR_OUT來使用,以確定該端點(diǎn)的數(shù)據(jù)是傳向設(shè)備還是主機(jī)。bmAttributes:這個是端點(diǎn)的類型,這個值可以結(jié)合位掩碼USB_ENDPOINT_XFERTYPE_MASK來使用,以確定此端點(diǎn)的類

22、型是USB_ENDPOINT_XFER_ISOC(等時)、USB_ENDPOINT_XFER_BULK(批量)、 USB_ENDPOINT_XFER_INT的哪一種。wMaxPacketSize:這個是端點(diǎn)一次可以處理的最大字節(jié)數(shù),驅(qū)動程序可以發(fā)送數(shù)量大于此值的數(shù)據(jù)到端點(diǎn),在實際傳輸中,數(shù)據(jù)量如果大于此值會被分割。bInterval:這個值只有在端點(diǎn)類型是中斷類型時才起作用,它是端點(diǎn)中斷請求的間隔時間,以毫秒為單位。2.4提交和控制urb提交和控制urb當(dāng)驅(qū)動程序有數(shù)據(jù)要發(fā)送到USB設(shè)備時(大多數(shù)情況是在驅(qū)動程序的寫函數(shù)中),要分配一個urb來把數(shù)據(jù)傳輸給設(shè)備:/* 創(chuàng)建一個urb,并且給它分

23、配一個緩存*/urb = usb_alloc_urb(0, GFP_KERNEL);if (!urb) retval = -ENOMEM;goto error;當(dāng)urb被成功分配后,還要創(chuàng)建一個DMA緩沖區(qū)來以高效的方式發(fā)送數(shù)據(jù)到設(shè)備,傳遞給驅(qū)動程序的數(shù)據(jù)要復(fù)制到這塊緩沖中去:buf = usb_buffer_alloc(dev-udev, count, GFP_KERNEL, &urb-transfer_dma);if (!buf) retval = -ENOMEM;goto error;if (copy_from_user(buf, user_buffer, count) retval =

24、 -EFAULT;goto error;當(dāng)數(shù)據(jù)從用戶空間正確復(fù)制到局部緩沖區(qū)后,urb必須在可以被提交給USB核心之前被正確初始化:/* 初始化urb */usb_fill_bulk_urb(urb, dev-udev,usb_sndbulkpipe(dev-udev, dev-bulk_out_endpointAddr),buf, count, skel_write_bulk_callback, dev);urb-transfer_flags |= URB_NO_TRANSFER_DMA_MAP;然后urb就可以被提交給USB核心以傳輸?shù)皆O(shè)備了:/* 把數(shù)據(jù)從批量OUT端口發(fā)出 */retv

25、al = usb_submit_urb(urb, GFP_KERNEL);if (retval) err(%s - failed submitting write urb, error %d, _FUNCTION_, retval);goto error;當(dāng)urb被成功傳輸?shù)経SB設(shè)備之后,urb回調(diào)函數(shù)將被USB核心調(diào)用,在我們的例子中,我們初始化urb,使它指向skel_write_bulk_callback函數(shù),以下就是該函數(shù):static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)struct

26、 usb_skel *dev;dev = (struct usb_skel *)urb-context;if (urb-status &!(urb-status = -ENOENT |urb-status = -ECONNRESET |urb-status = -ESHUTDOWN) dbg(%s - nonzero write bulk status received: %d,_FUNCTION_, urb-status);/* 釋放已分配的緩沖區(qū) */usb_buffer_free(urb-dev, urb-transfer_buffer_length,urb-transfer_buffe

27、r, urb-transfer_dma);有時候USB驅(qū)動程序只是要發(fā)送或者接收一些簡單的數(shù)據(jù),驅(qū)動程序也可以不用urb來進(jìn)行數(shù)據(jù)的傳輸,這是里涉及到兩個簡單的接口函數(shù):usb_bulk_msg和usb_control_msg ,在這個USB框架程序里讀操作就是這樣的一個應(yīng)用:/* 進(jìn)行阻塞的批量讀以從設(shè)備獲取數(shù)據(jù) */retval = usb_bulk_msg(dev-udev,usb_rcvbulkpipe(dev-udev, dev-bulk_in_endpointAddr),dev-bulk_in_buffer,min(dev-bulk_in_size, count),&count,

28、HZ*10);/*如果讀成功,復(fù)制到用戶空間 */if (!retval) if (copy_to_user(buffer, dev-bulk_in_buffer, count)retval = -EFAULT;elseretval = count;usb_bulk_msg接口函數(shù)的定義如下:int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout);其參數(shù)為:struct usb_device *usb_dev:指向批

29、量消息所發(fā)送的目標(biāo)USB設(shè)備指針。unsigned int pipe:批量消息所發(fā)送目標(biāo)USB設(shè)備的特定端點(diǎn),此值是調(diào)用usb_sndbulkpipe或者usb_rcvbulkpipe來創(chuàng)建的。void *data:如果是一個OUT端點(diǎn),它是指向即將發(fā)送到設(shè)備的數(shù)據(jù)的指針。如果是IN端點(diǎn),它是指向從設(shè)備讀取的數(shù)據(jù)應(yīng)該存放的位置的指針。 int len:data參數(shù)所指緩沖區(qū)的大小。int *actual_length:指向保存實際傳輸字節(jié)數(shù)的位置的指針,至于是傳輸?shù)皆O(shè)備還是從設(shè)備接收取決于端點(diǎn)的方向。int timeout:以Jiffies為單位的等待的超時時間,如果該值為0,該函數(shù)一直等待消

30、息的結(jié)束。 如果該接口函數(shù)調(diào)用成功,返回值為0,否則返回一個負(fù)的錯誤值。usb_control_msg接口函數(shù)定義如下:int usb_control_msg (struct usb_device *dev, unsigned int pipe, _u8 request, _u8requesttype, _u16 value, _u16 index, void *data, _u16 size, int timeout)除了允許驅(qū)動程序發(fā)送和接收USB控制消息之外,usb_control_msg函數(shù)的運(yùn)作和usb_bulk_msg函數(shù)類似,其參數(shù)和usb_bulk_msg的參數(shù)有幾個重要區(qū)別:

31、struct usb_device *dev:指向控制消息所發(fā)送的目標(biāo)USB設(shè)備的指針。unsigned int pipe:控制消息所發(fā)送的目標(biāo)USB設(shè)備的特定端點(diǎn),該值是調(diào)用usb_sndctrlpipe或usb_rcvctrlpipe來創(chuàng)建的。_u8 request:控制消息的USB請求值。_u8 requesttype:控制消息的USB請求類型值。_u16 value:控制消息的USB消息值。_u16 index:控制消息的USB消息索引值。void *data:如果是一個OUT端點(diǎn),它是指身即將發(fā)送到設(shè)備的數(shù)據(jù)的指針。如果是一個IN端點(diǎn),它是指向從設(shè)備讀取的數(shù)據(jù)應(yīng)該存放的位置的指針。_

32、u16 size:data參數(shù)所指緩沖區(qū)的大小。int timeout:以Jiffies為單位的應(yīng)該等待的超時時間,如果為0,該函數(shù)將一直等待消息結(jié)束。如果該接口函數(shù)調(diào)用成功,返回傳輸?shù)皆O(shè)備或者從設(shè)備讀取的字節(jié)數(shù);如果不成功它返回一個負(fù)的錯誤值。這兩個接口函數(shù)都不能在一個中斷上下文中或者持有自旋鎖的情況下調(diào)用,同樣,該函數(shù)也不能被任何其它函數(shù)取消,使用時要謹(jǐn)慎。我們要給未知的USB設(shè)備寫驅(qū)動程序,只需要把這個框架程序稍做修改就可以用了,前面我們已經(jīng)說過要修改制造商和產(chǎn)品的ID號,把0xfff0這兩個值改為未知USB的ID號。#define USB_SKEL_VENDOR_ID 0xfff0#d

33、efine USB_SKEL_PRODUCT_ID 0xfff0還有就是在探測函數(shù)中把需要探測的接口端點(diǎn)類型寫好,在這個框架程序中只探測了批量(USB_ENDPOINT_XFER_BULK)IN和OUT端點(diǎn), 可以在此處使用掩碼(USB_ENDPOINT_XFERTYPE_MASK)讓其探測其它的端點(diǎn)類型,驅(qū)動程序會對USB設(shè)備的每一個接口進(jìn)行一次探測,當(dāng)探測成功后,驅(qū)動程序就被綁定到這個接口上。再有就是urb的初始化問題,如果你只寫簡單的USB驅(qū)動,這塊不用多加考慮,框架程序里的東西已經(jīng)夠用了,這里我們簡單介紹三個初始化urb的輔助函數(shù):usb_fill_int_urb :它的函數(shù)原型是這樣

34、的:void usb_fill_int_urb (struct urb *urb, struct usb_device *dev, unsigned int pipe, void *transfer_buff, int buffer_length, usb_complete_t complete, void *context, int interval);這個函數(shù)用來正確的初始化即將被發(fā)送到USB設(shè)備的中斷端點(diǎn)的urb。usb_fill_bulk_urb :它的函數(shù)原型是這樣的:void usb_fill_bulk_urb (struct urb *urb, struct usb_device

35、 *dev, unsigned int pipe, void *transfer_buffer, int buffer_length, usb_complete_t complete)這個函數(shù)是用來正確的初始化批量urb端點(diǎn)的。usb_fill_control_urb :它的函數(shù)原型是這樣的:void usb_fill_control_urb(struct urb *urb,struct usb_device *dev,unsigned int pipe,unsigned char *setup_packet,void *transfer_buffer,int buffer_length,usb_complete_t complete,void *context);這個函數(shù)是用來正確初始化控制urb端點(diǎn)的。還有一個初始化等時urb的,它現(xiàn)在還沒有初始化函數(shù),所以它們在被提交到USB核心前,必須在驅(qū)動程序中手工地進(jìn)行初始化,可以參考內(nèi)核源代碼樹下的/usr/src/drivers/usb/media下的konicawc.c文件。3驅(qū)動模塊的編譯、配置和使用現(xiàn)在我們的驅(qū)動程序已經(jīng)大體寫好了,然后在linux下把它編譯成模塊就可以把驅(qū)動模塊插入到內(nèi)核中運(yùn)行了,編

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論