USB插入電腦的硬件檢測和枚舉流程


USB協議定義了設備的6種狀態,僅在枚舉過程種,設備就經歷了4個狀態的遷移:上電狀態(Powered),默認狀態(Default),地址狀態(Address)和配置狀態(Configured)(其他兩種是連接狀態和掛起狀態(Suspend))。

下面步驟是Windows系統下典型的枚舉過程,但是固件不能依此就認為所有的枚舉操作都是按照這樣一個流程行進。設備必須在任何時候都能正確處理所有的主機請求。

 

1.用戶把USB設備插入USB端口或給系統啟動時設備上電

    這里指的USB端口指的是主機下的根hub或主機下行端口上的hub端口。Hub給端口供電,連接着的設備處於上電狀態。

 

2.Hub監測它各個端口數據線上(D+/D-)的電壓

    在hub端,數據線D+和D-都有一個阻值在14.25k到24.8k的下拉電阻Rpd,而在設備端,D+(全速,高速)和D-(低速)上有一個1.5k的上拉電阻Rpu。當設備插入到hub端口時,有上拉電阻的一根數據線被拉高到幅值的90%的電壓(大致是3V)。hub檢測到它的一根數據線是高電平,就認為是有設備插入,並能根據是D+還是D-被拉高來判斷到底是什么設備(全速/低速)插入端口(全速、高速設備的區分在我將來的文章中描述)。如下圖。

                                        

USB全速/高速設備上電連接

(Full-speed Device Cable and Resistor Connections)

 

    檢測到設備后,hub繼續給設備供電,但並不急於與設備進行USB傳輸。

 

3. Host了解連接的設備

   每個hub利用它自己的中斷端點向主機報告它的各個端口的狀態(對於這個過程,設備是看不到的,也不必關心),報告的內容只是hub端口的設備連接/斷開的事件。如果有連接/斷開事件發生,那么host會發送一個 Get_Port_Status請求(request)以了解更多hub上的信息。Get_Port_Status等請求屬於所有hub都要求支持的hub類標准請求(standardhub-class requests)。

 

4.Hub檢測所插入的設備是高速還是低速設備

    hub通過檢測USB總線空閑(Idle)時差分線的高低電壓來判斷所連接設備的速度類型,當host發來Get_Port_Status請求時,hub就可以將此設備的速度類型信息回復給host。(USB 2.0規范要求速度檢測要先於復位(Reset)操作)。

 

5.hub復位設備

    當主機獲悉一個新的設備后,主機控制器就向hub發出一個Set_Port_Feature請求讓hub復位其管理的端口。hub通過驅動數據線到復位狀態(D+和D-全為低電平 ),並持續至少10ms。當然,hub不會把這樣的復位信號發送給其他已有設備連接的端口,所以其他連在該hub上的設備自然看不到復位信號,不受影響。

 

6.Host檢測所連接的全速設備是否是支持高速模式

    因為根據USB 2.0協議,高速(High Speed)設備在初始時是默認全速(Full Speed )狀態運行,所以對於一個支持USB 2.0的高速hub,當它發現它的端口連接的是一個全速設備時,會進行高速檢測,看看目前這個設備是否還支持高速傳輸,如果是,那就切到高速信號模式,否則就一直在全速狀態下工作。

    同樣的,從設備的角度來看,如果是一個高速設備,在剛連接bub或上電時只能用全速信號模式運行(根據USB 2.0協議,高速設備必須向下兼容USB 1.1的全速模式)。隨后hub會進行高速檢測,之后這個設備才會切換到告訴模式下工作。假如所連接的hub不支持USB 2.0,即不是高速hub,不能進行高速檢測,設備將一直以全速工作。

    高速設備檢測的過程在我另外一篇文章(USB2.0速度識別)中有詳細描述,這里不具體深入。

 

7. Hub建立設備和主機之間的信息通道

    主機不停得向hub發送 Get_Port_Status請求,以查詢設備是否復位成功。Hub返回的報告信息中有專門的一位用來標志設備的復位狀態。

    當hub撤銷了復位信號,設備就處於默認/空閑狀態(Default state),准備着主機發來的請求。設備和主機之間的通信通過控制傳輸,默認地址0,端點號0進行。在此時,設備能從總線上得到的最大電流是100mA。

 

8.主機發送Get_Descriptor請求獲取默認管道的最大包長度

    默認管道(Default Pipe)在設備一端來看就是端點0。主機此時發送的請求是默認地址0,端點0,雖然所有位分配地址的設備都是通過地址0來獲取主機發來的信息,但由於枚舉過程不是多個設備並行處理,而是一次枚舉一個設備的方式進行,所以不會發生多個設備同時響應主機發來的請求。

    設備描述符的第8字節代表設備端點0的最大包大小。對於Windows系統來說,Get_Descriptor請求中的wLength一項都會設為64,雖然說設備所返回的設備描述符(Device Descriptor)長度只有18字節,但系統也不在乎,此時,描述符的長度信息對它來說是最重要的,其他的瞄一眼就過了。Windows系統還有個怪癖,當完成第一次的控制傳輸后,也就是完成控制傳輸的狀態階段,系統會要求hub對設備進行再一次的復位操作(USB規范里面可沒這要求)。再次復位的目的是使設備進入一個確定的狀態。

 

9.主機給設備分配一個地址

    主機控制器通過Set_Address請求向設備分配一個唯一的地址。在完成這次傳輸之后,設備進入地址狀態(Address state),之后就啟用新地址繼續與主機通信。這個地址對於設備來說是終生制的,設備在,地址在;設備消失(被拔出,復位,系統重啟),地址被收回。同一個設備當再次被枚舉后得到的地址不一定是上次那個了。

 

10.主機獲取設備的信息

    主機發送 Get_Descriptor請求到新地址讀取設備描述符,這次主機發送Get_Descriptor請求可算是誠心,它會認真解析設備描述符的內容。設備描述符內信息包括端點0的最大包長度,設備所支持的配置(Configuration)個數,設備類型,VID(Vendor ID,由USB-IF分配), PID(Product ID,由廠商自己定制)等信息。Get_Descriptor請求(Device type)和設備描述符(已抹去VID,PID等信息)


免責聲明!

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



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