新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 嵌入式Linux下的USB設備驅動技術

        嵌入式Linux下的USB設備驅動技術

        作者: 時間:2010-05-19 來源:網絡 收藏


        該函數的形參對應的就是總線兩條鏈表里的設備和驅動。當總線上有新設備和驅動時,這個函數就會被調用。

        3 驅動程序的描述符

        一個設備可以有多個接口,一個接口可代表一個功能,因此,每個接口都對應著一個驅動。例如一個設備有兩種功能,一個鍵盤,上面還帶一個揚聲器,這就是兩個接口,就需要兩個驅動程序,一個是鍵盤驅動程序,一個是音頻流驅動程序。

        一個驅動程序是否支持一個設備,要通過讀取設備的描述符來判斷。那么,什么是的描述符呢?USB的描述符是一個帶有預定義格式的數據結構,里面保存有USB設備的各種屬性和相關信息,可以通過向設備請求獲得它們的描述符內容來深刻了解和感知一個USB設備。主要有四種USB描述符,分別為:接口描述符、端點描述符、設備描述符和配置描述符。

        協議規定:一個USB設備必須支持這四大描述符,還有些描述符不是必須包含的,有些特殊設備用來描述設備的不同特性,但這四大描述符是一個都不能少的。USB設備里有一個eeprom,可用來存儲設備本身信息,設備的描述符就存儲在這里。

        上述四個描述符分別放在了include/linux/usb.h文件中的struct usb_host_interface、structusb_host_endpoint、struct usb_device、struetusb_host_config里,而描述符結構體本身定義在include/linux/usb/ch9.h里.并分別用struct usb_interface_descriptor、struct usb_host_endpoint、structusb_device_descriptor和struct usb_config_descriptor來表示。描述符結構體的定義應完全按照USB協議對描述符的規定來定義。

        4 USB接口驅動

        4.1 接口結構

        平時編寫的USB驅動通常指的是寫USB接口的驅動,一個接口對應一個接口驅動程序,需要以一個struct usb_driver結構的對象為中心,并以設備的接口提供的功能為基礎,來進行USB驅動程序的編寫。struct usb_driver結構體一般定義在include/linux/usb.h文件里。具體如下:

        struct usb_driver{
        const char*name;
        int(*probe) (struct usb_interface*intf,const
        struct usb_device_jd*id);
        void(*disconnect) (struct usb_interface*intf);
        int(*ioctl) (struct usb_interface*intf,unsigned
        int code,void*buf);
        int (*suspend) (struct usb_interface*intf,
        pm_message_t message);
        int(*resume) (struct usb_interface*intf);
        void(*pre_reset) (struct usb_interface*intf);
        void(*post_reset)(struct usb_interface*intf);
        const struct usb_device_id*id_table;
        struct usb_dynids dynids;
        struct usbdrv_wrap drvwrap;
        unsigned int no_dynamic_id:1;
        unsigned int supports_autosuspend:1;
        };

        Name為驅動程序的名字,對應于/sys/bus/usb/drivers/下面的子目錄名稱。它只是彼此區別的一個代號,這里的名字在所有的USB驅動中必須是唯一的。probe用來看看這個USB驅動是否愿意接受某個接口的函數。Disconnect函數將在接口失去聯系或使用rmmod卸載驅動將它和接口強行分開時被調用。Ioctl函數則用在驅動通過usbfs和用戶空間進行交流時使用。Suspend、esume分別在設備被掛起和喚醒時使用。pre_reset、post_reset分別在設備將要復位(reset)和已經復位后使用。id_table的變量可用來判斷是否支持某個設備接口。Dynids是支持動態id的。實際上,即使驅動已經加載了,也可以添加新的id給它。drvwrap是給USB core區分和接口驅動用的。no_dynamic_id可以用來禁止動態id。supports_autosuspend可對autosuspend提供支持,如果設置為0,則不再允許綁定到這個驅動的接口autosuspend。

        接口驅動

        當insmod或modprobe驅動的時候,經過一個曲折的過程,就會調用相應USB驅動里的xxx_init函數,進而去調用usb_register (),以將相應的USB驅動提交給設備模型,添加到USB總線的驅動鏈表里。當rmmod驅動時,同樣,在經過一個曲折的過程之后,再調用相應驅動里的xxx_cleanup函數,進而調用usb_deregister ()將相應的USB驅動從USB總線的驅動鏈表里刪除。

        5 結束語

        本文介紹了下USB core的工作原理,同時介紹了驅動USB必須了解的四個描述符。此外,還介紹了下usb接口驅動的工作原理。本文介紹的方法能適應于下各種不同的USB程序的開發。

        本文引用地址:http://www.104case.com/article/151860.htm
        linux操作系統文章專題:linux操作系統詳解(linux不再難懂)

        上一頁 1 2 下一頁

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 壤塘县| 江川县| 卫辉市| 佛山市| 方正县| 望江县| 宁陕县| 清水河县| 攀枝花市| 铜陵市| 余庆县| 彩票| 通辽市| 衡阳县| 哈巴河县| 潞城市| 介休市| 汽车| 平舆县| 兴文县| 甘孜县| 鹤壁市| 兴化市| 化德县| 横山县| 南丰县| 黄浦区| 麻阳| 嘉鱼县| 峨山| 谷城县| 新竹县| 宁乡县| 彰化县| 进贤县| 武威市| 时尚| 伊金霍洛旗| 平利县| 徐水县| 闽侯县|