Linux USB 3.0驅動分析(一)—— 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設備使用各種描述符來說明其設備架構,包括設備描述符、配置描述符、接口描述符、端點描述符和字符串描述符,他們通常被保存在USB設備的固件程序中

路徑:include/uapi/linux/usb/ch9.h


1、設備描述符

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

struct usb_device_descriptor {
    __u8  bLength; ///長度
    __u8  bDescriptorType; ///描述符類型

    __le16 bcdUSB; //USB spec的版本號,一個設備如果能夠進行高速傳輸,那么它設備描述符里的bcdUSB這一項就應該為0200H。
    __u8  bDeviceClass;///設備類型
    __u8  bDeviceSubClass;///設備子類型
    __u8  bDeviceProtocol;///協議
    __u8  bMaxPacketSize0;///最大傳輸大小
    __le16 idVendor;///廠商 ID
    __le16 idProduct;///設備 ID
    __le16 bcdDevice;/// 設備版本號
    __u8  iManufacturer; //描述廠商字符串的索引
    __u8  iProduct; //描述產品字符串的索引
    __u8  iSerialNumber;///序列號
    __u8  bNumConfigurations;/// 設備當前速度模式下支持的配置數量。有的設備可以在多個速度模式下操作,這里包括的只是當前速度模式下的配置數目,不是總的配置數目
} __attribute__ ((packed));


2、配置描述符

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

struct usb_config_descriptor {
	__u8  bLength;                //描述符長度
	__u8  bDescriptorType;        //這里的值並不僅僅可以為USB_DT_CONFIG,還可以為USB_DT_OTHER_SPEED_CONFIG

    __le16 wTotalLength;         //使用GET_DESCRIPTOR請求從設備里獲得配置描述符信息時,返回的數據長度
    __u8  bNumInterfaces;       //這個配置包含的接口數量
    __u8  bConfigurationValue;    //對於擁有多個配置的幸運設備來說,可以拿這個值為參數,使用SET_CONFIGURATION請求來改變正在被使用的 USB配置,bConfigurationValue就指明了將要激活哪個配置。咱們的設備雖然可以有多個配置,但同一時間卻也只能有一個配置被激活。捎帶着提一下,SET_CONFIGURATION請求也是標准的設備請求之一,專門用來設置設備的配置。
    __u8  iConfiguration;      //描述配置信息的字符串描述符的索引值
    __u8  bmAttributes;         //這個字段表征了配置的一些特點,比如bit 6為1表示self-powered,bit 5為1表示這個配置支持遠程喚醒。另外,它的bit 7必須為1
    __u8  bMaxPower;          //設備正常運轉時,從總線那里分得的最大電流值,以2mA為單位。設備可以使用這個字段向hub表明自己需要的的電流,但如果設備需求過於旺盛,請求的超出了hub所能給予的,hub就會直接拒絕還記得struct usb_device結構里的bus_mA嗎?它就表示hub所能夠給予的。計算機的usb端口可以提供最多500mA的電流
} __attribute__ ((packed));


3、接口描述符

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

struct usb_interface_descriptor   
{  
     __u8  bLength;//接口描述符長度  
    __u8 bDescriptorType;//接口描述符類型  

    __u8 bInterfaceNumber;//接口號。每個配置可以包含多個接口,這個值就是它們的索引值。  
    __u8 bAlternateSetting;//接口使用的是哪個可選設置。協議里規定,接口默認使用的設置總為0號設置。  
    __u8 bNumEndpoints;//接口擁有的端點數量。這里並不包括端點0,因為端點0是控制傳輸,是所有的設備都必須提供的,所以這里就沒必要多此一舉的包括它了。對於hub,因為它的傳輸是中斷傳輸,所以此值為1(不包括端點0)  
    __u8 bInterfaceClass;  //接口類型
    __u8 bInterfaceSubClass;//接口子類型。對於hub,這個值是零  
    __u8 bInterfaceProtocol;  //接口所遵循的協議
    __u8 iInterface;  //描述該接口的字符串索引值

} __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個。

struct usb_endpoint_descriptor {   ///USB 端點描述符(每個USB設備最多有16個端點)
	__u8  bLength;             ///描述符的字節長度
    __u8  bDescriptorType;        ///描述符類型,對於端點就是USB_DT_ENDPOIN
    __u8  bEndpointAddress;    ///bit0~3表示端點地址,bit8 表示方向,輸入還是輸出
    __u8  bmAttributes;        ///屬性(bit0、bit1構成傳輸類型,00--控制,01--等時,10--批量,11--中斷)
  	__le16 wMaxPacketSize;        ///端點一次可以處理的最大字節數
  	__u8  bInterval;            ///希望主機輪詢自己的時間間隔

     /* NOTE:  these two are _only_ in audio endpoints. */
      /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
    __u8  bRefresh;  //對於批量傳送的端點以及控制傳送的端點,此域忽略
    __u8  bSynchAddress; //對於同步傳送的端點,此域必須為1
} __attribute__ ((packed));


5、字符串描述符

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

struct usb_string_descriptor
{
    _ _u8 bLength; //描述符長度
    _ _u8 bDescriptorType; //描述符類型

    _ _le16 wData[1];
} _ _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 核心為它們保留了相應的帶寬。


參考:

Linux USB 驅動開發(一)—— USB設備基礎概念_知秋一葉-CSDN博客_linux usb設備開發

Linux USB基礎之描述符(一)_楓瀟瀟-CSDN博客_linux 設備描述符



免責聲明!

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



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