1. 程式人生 > >Linux USB 驅動開發(一)—— USB裝置基礎概念

Linux USB 驅動開發(一)—— USB裝置基礎概念

Linux USB 驅動開發(一)—— USB裝置基礎概念

 

        在終端使用者看來,USB裝置為主機提供了多種多樣的附加功能,如檔案傳輸,聲音播放等,但對USB主機來說,它與所有USB裝置的介面都是一致的。一個USB裝置由3個功能模組組成:USB匯流排介面USB邏輯裝置功能單元:

a -- 這裡的USB匯流排介面指的是USB裝置中的序列介面引擎(SIE);

b -- USB邏輯裝置被USB系統軟體看作是一個端點的集合

c -- 功能單元被客戶軟體看作是一個介面的集合。SIE、端點和介面都是USB裝置的組成單元;

 

        為了更好地描述USB裝置的特徵,USB提出了裝置架構的概念。從這個角度來看,可以認為USB裝置是由一些配置介面端點組成,即一個USB裝置可以含有一個或多個配置,在每個配置中可含有一個或多個介面,在每個介面中可含有若干個端點。其中,配置和介面是對USB裝置功能的抽象,實際的資料傳輸由端點來完成。在使用USB裝置前,必須指明其採用的配置和介面。這個步驟一般是在裝置接入主機時裝置進行列舉時完成的

這些單元之間的關係如下:

 

裝置通常有一個或多個配置;

配置通常有一個或多個介面;

介面通常有一個或多個設定;

介面有零或多個端點。

 

       這樣的概念太抽象了,可以這樣看:有一個裝置,如支援視訊和音訊的一個播放器。那麼,對於上面提到的4個描述符,對它們設定的時候,它們分別對於哪一個描述符呢?  

      從我現在的理解來看,這樣一個裝置對應一個裝置描述符,支援視訊的功能對應一個介面描述符,支援音訊功能的對應一個介面描述符。為了支援視訊,在下層有多個埠同時工作為提供視訊資料傳輸的支援,所以有多個端點描述符

 

      USB裝置使用各種描述符來說明其裝置架構,包括裝置描述符、配置描述符、介面描述符、端點描述符和字串描述符,他們通常被儲存在USB裝置的韌體程式中

1、裝置描述符

      裝置代表一個USB裝置,它由一個或多個配置組成。裝置描述符用於說明裝置的總體資訊,並指明其所含的配置的個數。一個USB裝置只能有一個裝置描述符

 
  1. struct usb_device_descriptor

  2. {

  3. _ _u8 bLength; //描述符長度

  4. _ _u8 bDescriptorType; //描述符型別編號

  5.  
  6. _ _le16 bcdUSB; //USB版本號

  7. _ _u8 bDeviceClass; //USB分配的裝置類code

  8. _ _u8 bDeviceSubClass;// USB分配的子類code

  9. _ _u8 bDeviceProtocol; //USB分配的協議code

  10. _ _u8 bMaxPacketSize0; //endpoint0最大包大小

  11. _ _le16 idVendor; //廠商編號

  12. _ _le16 idProduct; //產品編號

  13. _ _le16 bcdDevice; //裝置出廠編號

  14. _ _u8 iManufacturer; //描述廠商字串的索引

  15. _ _u8 iProduct; //描述產品字串的索引

  16. _ _u8 iSerialNumber; //描述裝置序列號字串的索引

  17. _ _u8 bNumConfigurations; //可能的配置數量

  18. } _ _attribute_ _ ((packed));

 

 

 

2、配置描述符

       一個USB裝置可以包含一個或多個配置,如USB裝置的低功耗模式和高功耗模式可分別對應一個配置。在使用USB裝置前,必須為其選擇一個合適的配置。配置描述符用於說明USB裝置中各個配置的特性,如配置所含介面的個數等。USB裝置的每一個配置都必須有一個配置描述符。

 
  1. struct usb_config_descriptor

  2. {

  3. _ _u8 bLength; //描述符長度

  4. _ _u8 bDescriptorType; //描述符型別編號

  5.  
  6. _ _le16 wTotalLength; //配置所返回的所有資料的大小

  7. _ _u8 bNumInterfaces; // 配置所支援的介面數

  8. _ _u8 bConfigurationValue; //Set_Configuration命令需要的引數值

  9. _ _u8 iConfiguration; //描述該配置的字串的索引值

  10. _ _u8 bmAttributes; //供電模式的選擇

  11. _ _u8 bMaxPower; //裝置從匯流排提取的最大電流

  12. } _ _attribute_ _ ((packed));

 

 

3、介面描述符

      一個配置可以包含一個或多個介面,例如對一個光碟機來說,當用於檔案傳輸時,使用其大容量儲存介面;而當用於播放CD時,使用其音訊介面。介面是端點的集合,可以包含一個或多個可替換設定,使用者能夠在USB處於配置狀態時改變當前介面所含的個數和特性。介面描述符用於說明裝置中各個介面的特性,如介面所屬的裝置類及其子類等。USB裝置的每個介面都必須有一個介面描述符

 
  1. struct usb_interface_descriptor

  2. {

  3. _ _u8 bLength; //描述符長度

  4. _ _u8 bDescriptorType; //描述符型別

  5.  
  6. _ _u8 bInterfaceNumber; // 介面的編號

  7. _ _u8 bAlternateSetting; //備用的介面描述符編號

  8. _ _u8 bNumEndpoints; //該介面使用的端點數,不包括端點0

  9. _ _u8 bInterfaceClass; //介面型別

  10. _ _u8 bInterfaceSubClass; //介面子型別

  11. _ _u8 bInterfaceProtocol; //介面所遵循的協議

  12. _ _u8 iInterface; //描述該介面的字串索引值

  13. } _ _attribute_ _ ((packed));

 

 

4、端點描述符

 

      端點是USB裝置中的實際物理單元,USB資料傳輸就是在主機和USB裝置各個端點之間進行的。端點一般由USB介面晶片提供,例如Freescale公司的MC68HC908JB8和MC9S12UF32。USB裝置中的每一個端點都有唯一的端點號,每個端點所支援的資料傳輸方向一般而言也是確定的:或是輸入(IN),或是輸出(OUT)。也有些晶片提供的端點的資料方向是可以配置的,例如MC68HC908JB8包含有兩個用於資料收發的端點:端點1和端點2。其中端點1只能用於資料傳送,即支援輸入(IN)操作;端點2既能用於資料傳送,也可用於資料接收,即支援輸入(IN)和輸出(OUT)操作。而MC9S12UF32具有6個端點。

     利用裝置地址、端點號和傳輸方向就可以指定一個端點,並與它進行通訊。端點的傳輸特性還決定了其與主機通訊是所採用的傳輸型別,例如控制端點只能使用控制傳輸。根據端點的不同用途,可將端點分為兩類:0號端點和非0號端點。

      0號端點比較特殊,它有資料輸入IN和資料輸出OUT兩個物理單元,且只能支援控制傳輸。所有的USB裝置都必須含有一個0號端點,用作預設控制管道。USB系統軟體就是使用該管道與USB邏輯裝置進行配置通訊的。0號端點在USB裝置上的以後就可以使用,而非0號端點必須要在配置以後才可以使用。

     根據具體應用的需要,USB裝置還可以含有多個除0號端點以外的其他端點。對於低速裝置,其附加的端點數最多為2個;對於全速/高速裝置,其附加的端點數最多為15個。

 
  1. struct usb_endpoint_descriptor

  2. {

  3. _ _u8 bLength; //描述符長度

  4. _ _u8 bDescriptorType; //描述符型別

  5. _ _u8 bEndpointAddress; //端點地址:0~3位是端點號,第7位是方向(0-OUT,1-IN)

  6. _ _u8 bmAttributes; //端點屬性:bit[0:1] 的值為00表示控制,為01表示同步,為02表示批量,為03表示中斷

  7. _ _le16 wMaxPacketSize; //// 本端點接收或傳送的最大資訊包的大小

  8. _ _u8 bInterval;//輪詢資料傳送端點的時間間隔

  9. //對於批量傳送的端點以及控制傳送的端點,此域忽略

  10. //對於同步傳送的端點,此域必須為1

  11. _ _u8 bRefresh;

  12. _ _u8 bSynchAddress;

  13. } _ _attribute_ _ ((packed));

 

 

 

5、字串描述符

      在USB裝置中通常還含有字串描述符,以說明一些專用資訊,如製造商的名稱、裝置的序列號等。它的內容以UNICODE的形式給出,且可以被客戶軟體所讀取。對USB裝置來說,字串描述符是可選的。

 
  1. struct usb_string_descriptor

  2. {

  3. _ _u8 bLength; //描述符長度

  4. _ _u8 bDescriptorType; //描述符型別

  5.  
  6. _ _le16 wData[1];

  7. } _ _attribute_ _ ((packed));

 

 

 

6、管道

      在USB系統結構中,可以認為資料傳輸時在USB主機軟體與USB裝置的各個端點之間直接進行的,它們之間的連線稱為管道。管道是在USB裝置的配置過程中建立的。管道是對USB主機與USB裝置間通訊流的抽象,表示USB主機的資料緩衝區與USB裝置的端點之間存在著邏輯資料傳輸,而實際的資料傳輸是由USB匯流排介面層來完成的。

     管道與USB裝置中的端點一一對應。一個USB裝置含有多少個端點,其與USB主機進行通訊時就可以使用多少條管道,且端點的型別決定了管道中資料的傳輸型別,例如中斷端點對應中斷管道,且該管道只能進行中斷傳輸。不論存在著多少條管道,在各個管道中進行的資料傳輸都是相互獨立的。

 

7、USB端點分類

      USB 通訊的最基本形式是通過端點。一個USB端點只能向一個方向傳輸資料(從主機到裝置(稱為輸出端點)或者從裝置到主機(稱為輸入端點))。端點可被看作一個單向的管道。

     USB 端點有 4 種不同型別, 分別具有不同的資料傳送方式:

1) 控制CONTROL 

    控制端點被用來控制對USB裝置的不同部分訪問. 通常用作配置裝置、獲取裝置資訊、傳送命令到裝置或獲取裝置狀態報告。這些端點通常較小。每個 USB 裝置都有一個控制端點稱為"端點 0", 被 USB 核心用來在插入時配置裝置。USB協議保證總有足夠的頻寬留給控制端點傳送資料到裝置.

2) 中斷INTERRUPT 

     每當 USB 主機向裝置請求資料時,中斷端點以固定的速率傳送小量的資料。此為USB 鍵盤和滑鼠的主要的資料傳送方法。它還用以傳送資料到USB裝置來控制裝置。通常不用來傳送大量資料。USB協議保證總有足夠的頻寬留給中斷端點傳送資料到裝置.

3) 批量BULK

    批量端點用以傳送大量資料。這些端點通常比中斷端點大得多. 它們普遍用於不能有任何資料丟失的情況。USB 協議不保證傳輸在特定時間範圍內完成。如果總線上沒有足夠的空間來發送整個BULK包,它被分為多個包進行傳輸。這些端點普遍用於印表機、USB Mass Storage和USB網路裝置上。

4) 等時ISOCHRONOUS 

    等時端點也批量傳送大量資料, 但是這個資料不被保證能送達。這些端點用在可以處理資料丟失的裝置中,並且更多依賴於保持持續的資料流。如音訊和視訊裝置等等。

    控制和批量端點用於非同步資料傳送,而中斷和等時端點是週期性的。這意味著這些端點被設定來在固定的時間連續傳送資料,USB 核心為它們保留了相應的頻寬。

 

 
  1. struct usb_host_endpoint{

  2. struct usb_endpoint_descriptor desc;//端點描述符

  3. struct list_head urb_list;//此端點的URB對列,由USB核心維護

  4. void *hcpriv;

  5. struct ep_device *ep_dev; /* For sysfs info */

  6. unsigned char*extra;/* Extra descriptors */

  7. int extralen;

  8. int enabled;

  9. };

 

     當呼叫USB裝置驅動呼叫usb_submit_urb提交urb請求時,將呼叫int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb)把此urb增加到urb_list的尾巴上。(hcd: Host Controller Driver,對應資料結構struct usb_hcd )