USB設備被識別流程【轉】


轉自:http://blog.csdn.net/myarrow/article/details/8286876

USB模塊包括usb core,host,hub,device驅動,其中hub會啟動一個內核線程名曰:khubd(hub_events一直在查詢(hub使用的是中斷傳輸), 當usb 設備連接在 hub 的某個端口上,hub檢測到有設備連接了進來,hub會去調用hub_port_status函數去獲取hub端口狀態,要是真有設備了,會調用hub_port_connect_change函數會調用usb_alloc_dev函數為設備分配一個struct usb_device 結構的對象並初始化,這個初始化將usb設備的狀態設置為 Attached,調用usb_set_device_state函數將設備的狀態設置成USB_STATE_POWERED上電狀態,然后復位設備,復位成功后,設備就會進入Default狀態(這個狀態可以接收hcd的回應了);

        然后設備又該進入 Address狀態,首先調用 hub_set_address設置address狀態需要發送usb_control_msg函數去設置,在usb_control_msg里面調用了usb_internal_control_msg函數,這個函數主要的功能就是創建一個控制 urb,並把它發送給 usb 設備,然后等待它完成,這個過程包括了(usb_alloc_urb、usb_fill_control_urb、usb_start_wait_urb)這三個函數調用,完了以后,調用usb_hcd_submit_urb將urb發送到HCD,HCD 每收到urb,就會將它添加到這個 urb指定的urb_list中,形成鏈表,現在進入了HCD模塊(略),處理完以后,會返回一個狀態,最后usb_api_blocking_completion會去處理這次urb的收尾工作,如果成功的話設備就是正式進入了address狀態;

       接下來設備要進入configer狀態,這個過程需要先獲取配置usb_get_device_descriptor->usb_get_descriptor先得到配置描述符中的wTotalLength字段,然后通過wTotalLength長度,獲取所以配置信息,然后將獲取的配置解析出來處理(此過程較為繁瑣),配置好以后調用usb_new_device說明發現了設備驅動;

        然后tell the world(announce_device)說明設備已經找到了,最后調用設備模型提供的接口device_add將設備添加到 usb 總線的設備列表里,然后 usb總線會遍歷驅動列表里的每個驅動,調用自己的 match(usb_device_match) 函數看它們和你的設備或接口是否匹配,匹配的話調用device_bind_driver函數,現在就將控制權交到設備驅動了。

   函數調用流程如下所示:

usb_hub_init(kthread_run(hub_thread, NULL, "khubd"))->
  hub_thread->
    hub_events->
       hub_port_connect_change->
         usb_new_device->
              usb_enumerate_device(udev); /* Read descriptors */
              announce_device(udev); /* Tell the world! */
              device_add
              usb_create_ep_devs


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM