USB總線專題(四)——枚舉過程

前言:

爲了方便查看博客,特意申請了一個公衆號,附上二維碼,有興趣的朋友可以關注,和我一起討論學習,一起享受技術,一起成長。

在這裏插入圖片描述


1. 定義

枚舉就是從設備讀取一些信息,知道設備是什麼樣的設備,如何進行通信,這樣主機就可以根據這些信息來加載合適的驅動程序。枚舉過程包括設備地址的分配,從設備讀取設備描述符,分配加載驅動程序,選擇規定的設備功耗要求和接口配置信息。

USB 架構中, hub 負責檢測設備的連接和斷開,利用其中斷 IN 端點 (Interrupt IN Endpoint) 來向主機(Host)報告。在系統啓動時,主機輪詢它的根 hub(Root Hub)的狀態看是否有設備(包括子hub和子hub上的設備)連接。 只要檢測到有新設備連接上來,主機就會發送一系列的請求 (Resqusts) 給設備所掛載到的 hub,再由 hub 建立起一條連接主機(Host)和設備(Device)之間的通信通道。然後主機以控制傳輸 (Control Transfer) 的方式,通過端點0 (Endpoint 0) 對設備發送各種請求,設備收到主機發來的請求後回覆相應的信息,進行枚舉(Enumerate)操作。所有的 USB 設備必須支持標準請求(Standard Requests),控制傳輸方式(Control Transfer)和端點0(Endpoint 0)。

2. 設備狀態

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

在這裏插入圖片描述

2.1 連接(Attached)

設備可以連接到 USB 或者從 USB 上拔出。設備接入主機後,主機通過檢測信號線上的電平變化來發現設備的接入。

2.2上 電(Powered)

USB 設備的電源可來自外部電源,也可從 USB 接口的集線器而來。電源來自外部電源的 USB 設備被稱作自給電源式的 (self-powered)。儘管自給電源式的 USB 設備可能在連接上 USB 接口以前可能已經帶電,但它們直到連線上 USB 接口後才能被看作是加電狀態 (Powered state),這時候 VBUS 已經對設備產生作用了。

一個設備可能有既支持自給電源的,同時也支持總線電源式的配置。有一些支持其中的一種,而另一些設備配置可能只有在自給電源下才能被使用。設備對電源支持的能力是通過配置描述表 (configuration descriptor) 來反映的。當前的電源供給形式被作爲設備狀態的一部分被反映出來。設備可在任何時候改變它們的供電來源,比如說:從自給式向總線式改變,如果一個配置同時支持兩種模式,那此狀態的最大電源需求就是指設備在兩種模式下從 VBUS 上獲取電能的最大值。設備必須以此最大電源作爲參照,而究竟處於何狀態是不考慮的。如果有一配置僅支持一種電源模式,那麼電源模式的改變會使得設備失去當前配置與地址,返回加電狀態。如果一個設備是自給電源式,並且當前配置需要大於 100mA 電流,那麼如果此設備轉到了總線電源式,它必須返回地址狀態 (Address state)。自給電源式集線器使用 VBUS 來爲集線控制器 (Hub controller) 提供電源,因而可以仍然保持配置狀態 (Configured state),儘管自給電源停止提供電源。

2.3 默認狀態(Default)

設備上電後,它不響應任何總線處理,直到總線接收到復位信號爲止。接收到復位信號後,用默認的地址可以對設備尋址。

當用復位過程完成後,USB 設備在正確的速度下操作(即低速/全速/高速)。低速和全速的數據選擇由設備的終端電阻決定,能進行高速操作的設備決定它是否在復位的過程的一部分執行高速操作。

能進行高速操作的設備在全速的電氣環境中操作時,必須能以全速成功復位,設備成功復位後,設備必須成功響應設備和配置描述符請求,並且返回適當的信息。當在全速下工作時,設備可能或者不能支持預定義的功能。

2.4 地址(Address)

所有的 USB 設備在加電覆位以後都使用缺省地址,每一設備在連接或復位後由主機分配一個唯一的地址。當 USB 設備處於掛起狀態時,它保持這個地址不變。 USB 設備只對缺省通道 (Pipe) 請求發生響應,而不管設備是否已經被分配地址或在使用缺省地址。

主控制器分配從設備設備的設備地址。範圍爲 0 – 127。包格式 ”00 05 XX XX 00 00 00 00”,其中 XX XX 爲 2 字節設備地址,地址範圍 0 – 128。

在這裏插入圖片描述

2.5 配置狀態( Configured )

在 USB 設備正常工作以前,設備必須被正確配置。從設備的角度來看,配置包括一個將非零值寫入設備配置寄存器的操作。配置一個設備或改變一個可變的設備設置,將會使得與這個相關接口的終端結點的所有的狀態與配置值被設成缺省值。這包括將正在使用 (date toggle) 的端點 (end point) 的 (Date toggle) 被設置成DATA0。

2.6 掛起狀態(Suspended)

爲節省電源,USB 設備在探測不到總線傳輸時自動進入中止狀態。當中止時,USB 設備保持本身的內部狀態,包括它的地址及配置。

所有的設備在一段特定的時間內探測不到總線活動時必須進入中止態。不管設備是被分配了非缺省的地址或者是被配置了,已經連接的設備必須在任何加電的時刻隨時準備中止。總線活動的中止可能是因爲主機本身進入了中止狀態。另外,USB 設備必須在所連接的集線器端口失效時進入中止態。這就是所指的選擇性中止 (Selective suspend)。

USB 設備在總線活動來到時結束中止態。USB 設備也可以遠程喚醒的電流信號來請求主機退出中止態或選擇性中止態。具體設備具有的遠程喚醒的能力是可選的,也就是說,如果一個設備有遠程喚醒的能力,此設備必須能讓主機控制此能力的有效與否,當設備復位時,遠程喚醒能力必須被禁止。

3. 枚舉步驟

整體步驟如下圖: 通過 USB 協議分析儀抓取。

在這裏插入圖片描述

3.1 USB 設備插入端口或給系統啓動時設備上電

指的 USB 端口指的是主機下的根 hub 或主機下行端口上的 Hub 端口。Hub 給端口供電,連接着的設備處於上電狀態。此時,USB 設備處於加電狀態,它所連接的端口是無效的。

在這裏插入圖片描述

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

在 hub 端,數據線 D+ 和 D- 都有一個阻值在 14.25K 到 24.8K 的下拉電阻 Rpd(一般設置爲 15K ),而在設備端,D+(全速,高速)和 D-(低速)上有一個 1.5K 的上拉電阻 Rpu。當設備插入到 hub 端口時,有上拉電阻的一根數據線被拉高到幅值的 90%的電壓(大約 3V)。hub 檢測到它的一根數據線是高電平,就認爲是有設備插入,並能根據是 D+ 還是 D- 被拉高來判斷到底是什麼設備(全速/低速)插入端口(高速設備先識別書全速,然後再進一步協商確定爲高速)。當 USB 設備上電後,一直監測 USB 設備接口電平變化 HUB 檢測到有電壓變化,將利用自己的中斷端點將信息反饋給主控制器有設備連接。

3.3 Host 瞭解連接的設備

每個 hub 利用它的中斷端點向主機報告它的各個端口的狀態(對於這個過程,設備是看不到的,也不關心),報告的內容只是 hub 端口的設備連接或斷開的事件。如果有連接或斷開事件發生,那麼 Host 會發送一個 Get_Port_Status 請求 (request) 給 hub 以瞭解此次狀態改變的確切含義。Get_Port_Status 等請求屬於所有 hub 都要求支持的 hub 類標準請求。

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

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

在這裏插入圖片描述

3.5 hub復位設備

Host 一旦得知新設備已連上以後,它至少等待 100ms 以使得插入操作的完成以及設備電源穩定工作。然後主機控制器就向 hub 發出一個 Set_Port_Feature 請求讓 hub 復位其管理的端口 (剛纔設備插上的端口)。hub 通過驅動數據線到復位狀態( D+ 和 D- 全爲低電平 ),並持續至少 10ms。當然,hub 不會把這樣的復位信號發送給其他已有設備連接的端口,故其他連在該 hub上的設備自然看不到復位信號,不受影響。

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

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

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

在這裏插入圖片描述

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

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

當 hub 撤銷了復位信號,設備就處於默認或空閒狀態,準備接收主機發來的請求。設備和主機之間的通信通過控制傳輸,默認地址 0,端點號 0 進行。此時,設備能從總線上得到的最大電流是 100mA。所有的 USB 設備在總線復位後其地址都爲 0,這樣主機就可以跟那些剛剛插入的設備通過地址 0 通信。

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

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

在這裏插入圖片描述

設備描述符的第 8 字節代表設備端點 0 的最大包大小。雖然說設備所返回的設備描述符(Device Descriptor)長度只有 18 字節,但系統也不在乎(枚舉過程中第一次獲取設備描述符)。此時,描述符的長度信息對它來說是最重要的。當完成第一次的控制傳輸後,也就是完成控制傳輸的狀態階段,系統會要求 hub 對設備進行再一次的復位操作(USB 規範裏面可沒這要求),再次復位的目的是使設備進入一個確定的狀態。

3.9 主機給設備分配一個地址

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

在這裏插入圖片描述

3.10 主機獲取設備的信息

主機再次發送 Get_Descriptor 請求到新地址讀取設備描述符,這次主機發送Get_Descriptor 請求會返回整個設備描述符信息,18 字節的長度,它會認真解析設備描述符的內容。設備描述符內信息包括端點 0 的最大包長度,設備所支持的配置(Configuration)個數,設備類型,VID(Vendor ID,由USB-IF分配), PID(Product ID,由廠商自己定製)等信息。

獲取完整的設備描述符:
在這裏插入圖片描述獲取配置描述符:
在這裏插入圖片描述

3.11 主機給設備掛載驅動(複合設備除外)

主機通過解析描述符後對設備有了足夠的瞭解,會選擇一個最合適的驅動給設備。 然後 announce_device 說明設備已經找到了,最後調用設備模型提供的接口 device_add 將設備添加到 usb 總線的設備列表裏,然後 usb 總線會遍歷驅動列表裏的每個驅動,調用自己的 match(usb_device_match) 函數看它們和設備或接口是否匹配,匹配的話調用 device_bind_driver 函數,現在就將控制權交到設備驅動了。

對於複合設備,通常應該是不同的接口(Interface)配置給不同的驅動,因此,需要等到當設備被配置並把接口使能後纔可以把驅動掛載上去。

3.12 設備驅動選擇一個配置

驅動(之後的事情都是有驅動來接管負責與設備的通信)根據前面設備回覆的信息,發送 Set_Configuration 請求來正式確定選擇設備的哪個配置(Configuration)作爲工作配置(對於大多數設備來說,一般只有一個配置被定義)。至此,設備處於配置狀態 (Configured),當然,設備也應該使能它的各個接口(Interface)。對於複合設備,主機會在這個時候根據設備接口信息,給它們掛載驅動。

獲取設備狀態:
在這裏插入圖片描述
主機指示設備採用的要求的配置:

在這裏插入圖片描述


參考:

1.USB枚舉過程
2.從零開始學USB(十五、USB的設備狀態)
3.詳細分析USB枚舉過程(HID鍵盤)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章