USB裝置被識別流程
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
本文永久更新連結:http://embeddedlinux.org.cn/emb-linux/kernel-driver/201904/29-8652.html