USB枚舉過程詳述

     本系統中所謂USB設備與主機是通過檢測Vcc上拉電阻的變化來確定是否有設備連接的。在D12內部集成了1.5kΩ的上拉電阻,默認狀態下不與Vcc相連,程序運行時可以向D12發送連接命令使1.5kΩ電阻連接到Vcc,這樣主機便檢測到有設備連接。

它的枚舉過程分析如下。

設備連接到總線後,設備從總線獲得5V電源,程序首先初始化,端口,然後向D12發出USB連接命令。主機檢測到設備連接。主機向設備發出第一個信號:總線復位。總線復位產生一箇中斷,並且D12器件在默認地址0處使能,以便在接下來的枚舉過程中使用地址0傳輸命令和數據,同時中斷寄存器的總線復位位被置爲1。在程序中的表現是,D12向主循環請求中斷,進入中斷處理程序USB_int_handler(),讀取中斷寄存器,確定中斷的類型,進行相應的處理。

主機使用默認地址0讀取設備描述符。

具體過程是:主機向D12發送第一個Setup包,每個Setup包都是8個字節,第一個包Get Descriptor的內容爲:80 06 00 01 00 00 40 00 ,數據爲16進製表示。其中的40表示返回的數據最大長度爲40H字節。此Setup包存儲在D12的端點0緩衝區中,併產生一個外部中斷。(這時在D12的中斷寄存器中保存了中斷的類型:端點0的OUT中斷,即中斷寄存器字節1的值應爲0x01)進入中斷服務程序後,由於D12端點0的緩衝區只有16個字節,所以單片機就先發送16個字節的設備描述符。

當主機接收到這16個字節的字符後,就認爲真正有設備連接了。

地址分配。

主機向D12發送第二個Setup包,這是一個含有指定地址的數據包,其內容一般爲:00 05 02 00 00 00 00 00 ,其中的02就表示主機爲設備分配的地址爲0x02,在以後的通信裏設備就只對0x02地址的信息作出應答。D12收到這個Setup包後同樣產生一箇中斷(端點0的OUT中斷),需要注意的是單片機處理這個中斷時需要向主機返回一個長度爲0的空數據包。

主機從新的地址獲取設備描述符。

主機收到設備發來的空的應答數據包後,確認地址分配成功。然後主機向D12發送第三個Setup包,再次要求獲取設備描述符。這個Setup包的內容一般是:80 06 00 01 00 00 12 00 。與上次不同的是,這次要求實際的描述符長度,其中的12(十六進制數)表示要求得到全部18字節的設備描述符。因爲每次只能發送16字節,因此程序中要分兩次完成此要求。第一次16字節,第二次2字節。

主機讀取配置描述符。

成功得到18字節的設備描述符後,主機向D12發送第四個Setup包,要求得到設備的配置描述符。這個Setup包的數據爲:80 06 00 02 00 00 09 00 。其中的09指定設備返回9字節數據,這正是配置描述符的長度。

讀取描述符集合。

成功得到9字節的配置描述符後,主機向D12發送第五個Setup包,要求得到設備的配置描述符、接口描述符、端點描述符的集合。這次Setup包的內容是:80 06 00 02 00 00 FF 00 。由於不知道描述符集合的真實長度,因此它要求得到256字節。

到這一步,主機現在應該已經發現新硬件併爲新設備安裝好驅動程序。對於以上過程,主機是在總線驅動層處理,下面的一步,也是典型枚舉過程的最後一步,就需要設備驅動程序來做了。

數值配置。主機得到各種描述符之後,認爲設備的信息已經齊全,便對設備進行配置,使設備從地址狀態進入配置狀態。

主機向D12發送第六個Setup包,其數據爲:00 09 01 00 00 00 00 00 。程序中需要調用Set Configuration()函數處理此事件,允許所有端點進入工作狀態。

至此,USB枚舉過程結束,設備可以正常使用了。在這個過程中D12指示燈根據通信的狀況間歇閃爍。

 

USB  最主要的的是要理解   USB主機發送命令給設備,設備要對主機的命令進行響應, USB通訊的基本單位爲 “包”   理解好“包”這個概念是學習USB的關鍵所在。
包有如下分類:
分別是令牌包、數據包、握手包和特殊包(其實是由PID決定的)
令牌包:可分爲輸入包、輸出包、設置包和幀起始包(注意這裏的輸入包是用於設置輸入命令的,輸出包是用來設置輸出命令的,而不是放據數的)其中輸入包、輸出包和設置包的格式都是一樣的: SYNC+PID+ADDR+ENDP+CRC5(五位的校驗碼)
幀起始包: SYNC+PID+11位FRAM+CRC5(五位的校驗碼)
數據包:分爲DATA0包和DATA1包,當USB發送數據的時候,當一次發送的數據長度大於相應端點的容量時,就需要把數據包分爲好幾個包,分批發送,DATA0包和DATA1包交替發送,即如果第一個數據包是DATA0,那第二個數據包就是DATA1。但也有例外情況,在同步傳輸中(四類傳輸類型中之一),所有的數據包都是爲DATA0,格式如下:
SYNC+PID+0~1023字節+CRC16
握手包:結構最爲簡單的包,格式如下
SYNC+PID
下面舉幾個例子來說明USB的通訊過程:
1:主機想要向設備傳送一串數據。 過程如下:
(1)   主機向從機發送 “令牌包”,令牌包的類型爲輸出包,表示主機要向從機發送數據了。
(2)   主機向從機發送完令牌以後,USB處理器件根據發送的令牌,會將中斷狀態寄存器標誌置位,從機CPU通過查詢USB處理器件的中斷狀態寄存器,對主機的令牌包進行響應
(3)   從機判別出中斷類型,於是,準備從主機接收數據。
(4)   從機準備好了,於是主機開始發送“數據包” 這時,USB處理器件會自動將從主發送過來的數據放如它的內部緩衝區內,接收完這個數據包後,從機向主機發送“應答包” 
這就是一個完整的通訊過程。
由以上可以看出,USB若是想要傳送數據,那麼主機必須先發一個 IN 或OUT的令牌包,然後發送DATA0,或DATA1數據包。
簡單的用現實生活中的事件進行描述:  老闆想讓員工去做一件事情,老闆 先會發出命令,告訴要做什麼事情,員工準備好以後呢,老闆再把做這件事情的經費發放給員工,當員工把發放的經費清點以後,發現數目正確,他會給老闆一個迴應信息,告訴老闆,錢已經收到了,而且數目正確。
老闆想讓員工做的事:  對應USB通訊裏的令牌包。
老闆想要發放的經費:  對應USB通訊裏的數據包。
員工給老闆的迴應:    對應USB通訊裏的握手包。
這裏尤其需要注意一個問題就是:
USB主機向設備發送令牌包的時候,接收令牌是有USB器件來完成的,而不是有從機CPU來完成的,如主機發送一個如下的令牌:
SYNC+PID+ADDR+ENDP+CRC5
USB器件回根據PID的類型來判斷是哪種類型的令牌 根據ADDR的值來判斷是否是和自己通訊,根據ENDP的值來判斷是和哪個端點進行通訊,根據校驗來判斷,數據傳送是否無誤。根據以上的令牌包信息,USB器件會將其內部的中斷狀態寄存器相應的位置位,從機CPU可以查詢這個中斷狀態寄存器來進行相應的操作。 

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