usb音效卡驅動(一) USB描述符

2021-10-14 16:58:34 字數 3341 閱讀 9144

前面看了核心的啟動,接下來就是驅動的學習。

正好手邊有乙個usb音效卡,就準備以此為基礎,進行usb音效卡驅動的學習。

因此,在學些usb音效卡之前,先看看usb驅動。然後再是alsa驅動,然後再是兩者的結合

任何usb裝置,都有一段資料,用來描述自己。比如自己有什麼功能,自己的廠商id是多少等等

有個組織,定義了這段資料的組織形式和意義,這段資料稱為usb描述符。這個組織叫usb-if(usb implementers forum)

usb描述符,邏輯上分成三個層級:配置,介面,端點

乙個usb裝置描述符,可能包含多個配置,乙個配置可能包含多個介面,乙個介面可能包含多個端點。

上述每乙個邏輯體,在linux中都有乙個資料結構與之對應。

配置描述符:

struct usb_config_descriptor  __attribute__ (

(packed)

);

介面描述符:

struct usb_inte***ce_descriptor  __attribute__ (

(packed)

);

端點描述符:

struct usb_endpoint_descriptor  __attribute__ (

(packed)

);

除了上面的三個描述以外,還有乙個重要的描述,那就是裝置描述符:

struct usb_device_descriptor  __attribute__ (

(packed)

);

現在我們知道了usb裝置大概有哪些資訊,接下來檢視一下,應該怎麼才能獲取到上面的這些

當乙個新的裝置,插入usb 匯流排後,這些資訊該如何獲取呢?

第一步:如何檢測到硬體已經被插入

常規的usb介面,有四根線,gnd線,vcc線,d+線,d-線。在hub端d+,d-分別接了乙個15k的下拉電阻到地。

而在裝置端,d+或者d-端接了乙個1.5k的上拉電阻。低速裝置接在d-端。高速和全速裝置接在d+端。

當裝置插入hub時,hub能通過d+,d-上面的變化來區分裝置的型別。

第二步:如何區分全速裝置和高速裝置

對於全速裝置和高速裝置而言,他們的上拉電阻都接在了d+端。為了進一步區分這兩種裝置。需要進行一定的通訊。

為了簡化通訊的細節,現在大致描述如下:

當裝置進入復位狀態之後,裝置持續一段時間的向hub傳送訊號。這個訊號就是給d-持續輸出17.87ma的電流。

hub因為有自己的電阻,所以,它能檢查到一定的電壓,大概為800mv

hub在檢查到持續了一段時間的800mv的電壓之後,就知道,哦,原來這是乙個高速裝置。

hub在接下來100us內,進行響應。告訴裝置,我已經知道你是高速裝置了,並且我也切換到了高速模式下了。

裝置在接受到hub的響應之後,就將自己切換到高速裝置的電路上。

上面所述的5個步驟,在電氣訊號上面的詳細描述,可以參考:

第三步:獲取裝置描述符

現在,裝置已經連上,接下來,就是獲取裝置的資訊(裝置描述符)。但是在此之前,需要明白乙個東西:那就是usb的資料報,到底是怎麼組織的。

usb資料報的組織

我們都知道電訊號只能傳遞0和1的邏輯值。在usb的世界裡,將這些0和1排列組合,組成7種基本的資訊,稱為域,分別叫做:同步域(sync),標識域(pid),位址域(addr),端點域(endp),幀號域(frame),資料域(data),校驗域(crc)

在這些域的上層,則定義4種包:令牌包,資料報,握手包,特殊包。這些包都是由上面介紹的域組合而成。

令牌包有四種,分別為:輸入,輸出,設定,幀起始。前面三種的域的組成情況一樣,為sync+pid+addr+endp+crc.第四種的域組成為,sync+pid+frame+crc

資料報有兩種,分別為:data0,data1。他們的域組成一樣都為:sync+pid+data+crc

握手包,只有一種,它的域組成為:sync+pid

現在有了這些包之後,我們使用這4種包來定義各種不同的事務。目前就定義了3種事務,稱為:in事務,out事務,setup事務。

每種事務,都由三個階段組成:令牌包階段,資料報階段,握手包階段

令牌包階段:啟動輸入、輸出、設定事務

資料報階段:按照輸入、輸出傳送相應的資料

握手包階段:返回資料的接收情況

現在知道了3種事務之後,就可以使用這3中事務,進行傳輸了,傳輸也分成了4種:中斷傳輸,批量傳輸,同步傳輸,控制傳輸

中斷傳輸:由out事務和in事務構成

批量傳輸:由out事務和in事務構成

同步傳輸:由out事務和in事務構成

控制傳輸:由setup事務,(out事務,in事務)構成

現在知道了上面的東西,就可以進一步知道,怎麼獲取裝置描述符了。

在裝置才連上hub時,此時裝置還處於一種預設的狀態,它沒有位址,為了能夠響應主機發出的請求。它將位址0作為預設位址。

那麼獲取裝置描述的過程,大致描述如下:

第一階段

首先使用乙個get_descriptor這個請求。這個請求使用的是setup事務,它由令牌包,資料報,握手包組成.

然後再次發乙個資料輸入的請求。這個請求使用的是in事務,它同樣由令牌包,資料報,握手包組成。

然後再次傳送乙個資料輸出請求——用於通知裝置,get_descriptor請求的狀態。這次使用的是out事務,它同樣有三個階段

現在主機已經擁有了usb裝置的描述符資訊。

第二階段

已經知道了部分資料之後,需要為該裝置分配位址。

發出乙個set_address請求。這個請求跟第一階段的第一步幾乎一樣,使用的是setup事務

本次的資料為位址,但是位址已經放在了set_address請求中了。所以不需要傳輸資料。

為了獲得set_address請求是否成功,需要接受裝置的響應。因此傳送乙個資料輸入請求,即跟第一階段的第二步一樣。

第三階段

當一切正常之後,就使用新的位址,重新獲取裝置描述符。獲取裝置描述符的過程見第一階段,長度稍有不同,不過不影響整個過程的理解

除了裝置描述符以外,還需要獲取其他的描述符。如配置描述符,介面描述符,端點描述符,字串描述符等。

根據這些描述符的內容,選擇不同的驅動程式

至此,整個裝置才算是完完全全的能被使用了。

注意,注意:上面所有的步驟,建立在兩個前提下。1.預設所有的操作都正常;2.描述過程時使用的是資料報中的更加抽象的語言。並沒有引入具體的二進位制數值

本篇相當於,usb裝置的乙個列舉過程。

接下來一篇,用於說明,音訊裝置描述符的相關細節

關於usb描述符

usb 的描述符主要有裝置描述符,裝置限定描述符,介面描述符,端點描述符,字串描述符等等,usb的描述符之間的關係是一層一層的,首先最上層的是裝置描述符,然後是配置描述符,在下面的是介面描述符,最後是端點描述符.描述符在乙個usb的裝置中所起的作用是十分重要的,在裝置連線到usb主機以後,主機首先是...

USB 描述符詳解

usb描述符的分類與介紹 usb的符述符分為幾類?有人可能會答 裝置描述符 配置描述符 介面描述符 端點描述符 字串描述符等。但這裡說的不是這樣的。上面的幾類描述符屬於usb標準描述符。另外還有hid描述符和hub描述符。所以分類是這樣的 1.標準描述符 1 裝置描述符 2 配置描述符 3 字串描述...

USB描述符總結

usb描述符總結 參考 一 usb描述符 主機識別usb裝置的根據,主機根據裝置的描述符來載入相應的驅動程式。二 描述符的分類 三大類 標準類描述符 裝置類描述符 廠商描述符。具體如下圖 三 使用的幾種類 裝置類deviceclass 介面類inte ceclass 四 標準描述符 1.裝置描述符 ...