新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > USB驅動程序框架搭建

        USB驅動程序框架搭建

        作者: 時間:2016-12-15 來源:網絡 收藏
        1.首先我們先從理論上淺談一下USB驅動的框架
        app:
        -------------------------------------------
        USB設備驅動程序 // 知道數據含義
        內核 --------------------------------------
        USB總線驅動程序 // 1. 識別, 2. 找到匹配的設備驅動, 3. 提供USB讀寫函數 (它不知道數據含義)
        -------------------------------------------
        USB主機控制器
        UHCI OHCI EHCI
        硬件 -----------
        USB設備
        UHCI: intel, 低速(1.5Mbps)/全速(12Mbps)
        OHCI: microsoft 低速/全速
        EHCI: 高速(480Mbps)
        也就是說最底層是usb設備,往上是USB總線控制器、USB總線驅動程序、USB驅動程序,最后是應用程序。其中USB總線控制器包括三種:UHCI OHCI EHCI
        2. USB總線驅動程序的作用
        1. 識別USB設備
        1.1 分配地址
        1.2 并告訴USB設備(set address)
        1.3 發出命令獲取描述符
        描述符的信息可以在includelinuxusbCh9.h看到
        2. 查找并安裝對應的設備驅動程序
        3. 提供USB讀寫函數
        3、我們開始正式構建linux usb框架了,小心了?。。?/div>
        首先我們需要從開發板獲得一些信息:
        把USB設備接到開發板上,看輸出信息:
        usb 1-1: new full speed USB device using s3c2410-ohci and address 2
        usb 1-1: configuration #1 chosen from 1 choice
        scsi0 : SCSI emulation for USB Mass Storage devices
        scsi 0:0:0:0: Direct-Access HTC Android Phone 0100 PQ: 0 ANSI: 2
        sd 0:0:0:0: [sda] Attached SCSI removable disk
        拔掉
        usb 1-1: USB disconnect, address 2
        再接上:
        usb 1-1: new full speed USB device using s3c2410-ohci and address 3
        usb 1-1: configuration #1 chosen from 1 choice
        scsi1 : SCSI emulation for USB Mass Storage devices
        scsi 1:0:0:0: Direct-Access HTC Android Phone 0100 PQ: 0 ANSI: 2
        sd 1:0:0:0: [sda] Attached SCSI removable disk
        接著我們就可以根據這些信息進行分析了:
        首先我們在內核的dirvers目錄下搜索:“USB device using
        grep "USB device using" * -nR
        結果搜到了下面這條信息:usb/core/hub.c:2186: "%s %s speed %sUSB device using %s and address %d",
        那么我們就從usb/core/hub.c這個文件開始分析:
        "%s %s speed %sUSB device using %s and address %d"這句話在hub_port_init 函數中被調用
        hub_port_init 在函數hub_port_connect_change中被調用
        hub_port_connect_change在函數hub_events中被調用
        hub_events在函數hub_thread中被調用
        hub_thread函數里有這么一句:
        wait_event_interruptible(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());
        說明進程會在khubd_wait這個等待隊列里休眠,那么誰把它喚醒呢?我們搜索一下
        在kick_khubd函數里有這么一句:wake_up(&khubd_wait);把進程喚醒了
        kick_khubd被函數hub_irq調用,根據注釋信息我們知道當連接發生變化或則出現措施就會發生中斷,從而進入這個函數。
        那么我們大致可以總結出了框架:
        hub_irq //發生接口狀態變化或出現錯誤時調用
        kick_khubd
        wake_up//喚醒進程
        hub_thread//進程在這個函數里休眠了,被wake up喚醒后會繼續執行
        hub_port_connect_change //我們重點來分析它
        udev = usb_alloc_dev(hdev, hdev->bus, port1);
        dev->dev.bus = &usb_bus_type;//指定設備總線是usb類型的
        choose_address(udev);//在0到128之間找到一個設備地址,至于為什么是128我們之前已經講過了
        hub_port_init
        hub_set_address//將上面找到的地址告訴usb設備
        usb_get_device_descriptor(udev, 8);//獲取設備描述符
        usb_get_device_descriptor(udev, USB_DT_DEVICE_SIZE);//再次獲取設備描述符,我們在 //usb協議分析里面有談到過的
        usb_new_device//把所有的描述符都讀出來并解析
        usb_get_configuration(udev);//獲取配置信息
        usb_cache_string(udev, udev->descriptor.iProduct);//讀取產品信息
        usb_cache_string(udev,udev->descriptor.iManufacturer);//讀取制造商信息
        usb_cache_string(udev, udev->descriptor.iSerialNumber);//讀取序列號信息
        __usb_get_extra_descriptor//獲得一些額外的信息
        device_add(&udev->dev);// 把device放入usb_bus_type的dev鏈表,
        // 從usb_bus_type的driver鏈表里取出usb_driver,
        // 把usb_interface和usb_driver的id_table比較
        // 如果能匹配,調用usb_driver的probe
        我們來總結一下上面的框架:首先接上usb設備時會發 生中斷,然后喚醒進程。接著先設置usb設備的地址,然后獲取設備描述符和配置描述符等各種描述符,這是為了尋找驅動程序。接著將usb設備加入到鏈表里,和驅動比較,如果匹配就調用probe函數。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 登封市| 宜兰市| 永修县| 温宿县| 西乡县| 谷城县| 吉安市| 阿坝| 屯昌县| 临西县| 凯里市| 南通市| 漠河县| 井冈山市| 天等县| 古浪县| 应用必备| 永丰县| 上虞市| 开平市| 汕尾市| 定陶县| 扶沟县| 临沭县| 吉安市| 慈溪市| 贡山| 田阳县| 当阳市| 秀山| 玉田县| 丹江口市| 泗洪县| 岳池县| 青铜峡市| 湖南省| 荔浦县| 察哈| 凤城市| 通城县| 遂溪县|