1. 程式人生 > >STM32學習筆記之USB虛擬串列埠描述符簡介

STM32學習筆記之USB虛擬串列埠描述符簡介

Descriptor即描述符,是一個完整的資料結構,可以通過C語言等程式設計實現,並存儲在USB裝置中,用於描述一個USB裝置的所有屬性,USB主機是通過一系列命令來要求裝置傳送這些資訊的。它的作用就是通過如問答節中的命令***作來給主機傳遞資訊,從而讓主機知道裝置具有什麼功能、屬於哪一類裝置、要佔用多少頻寬、使用哪類傳輸方式及資料量的大小,只有主機確定了這些資訊之後,裝置才能真正開始工作,所以描述符也是十分重要的部分,要好好掌握。標準的描述符有5種,USB為這些描述符定義了編號:

1——裝置描述符

2——配置描述符

3——字元描述符

4——介面描述符

5——端點描述符

上面的描述符之間有一定的關係,一個裝置只有一個裝置描述符,而一個裝置描述符可以包含多個配置描述符,而一個配置描述符可以包含多個介面描述符,一個介面使用了幾個端點,就有幾個端點描述符。這間描述符是用一定的欄位構成的,分別如下說明:

1、裝置描述符

struct _DEVICE_DEscriptOR_STRUCT

{

BYTE bLength; //裝置描述符的位元組數大小,為0x12

BYTE bDescriptorType; //描述符型別編號,為0x01

WORD bcdUSB; //USB版本號

BYTE bDeviceClass; //USB分配的裝置類程式碼,0x01~0xfe為標準裝置類,0xff為廠商自定義型別

//0x00不是在裝置描述符中定義的,如HID

BYTE bDeviceSubClass; //usb分配的子類程式碼,同上,值由USB規定和分配的

BYTE bDeviceProtocl; //USB分配的裝置協議程式碼,同上

BYTE bMaxPacketSize0; //端點0的最大包的大小

WORD idVendor; //廠商編號

WORD idProduct; //產品編號

WORD bcdDevice; //裝置出廠編號

BYTE iManufacturer; //描述廠商字串的索引

BYTE iProduct; //描述產品字串的索引

BYTE iSerialNumber; //描述裝置序列號字串的索引

BYTE bNumConfiguration; //可能的配置數量

}

2、配置描述符

struct _CONFIGURATION_DEscriptOR_STRUCT

{

BYTE bLength; //裝置描述符的位元組數大小,為0x12

BYTE bDescriptorType; //描述符型別編號,為0x01

WORD wTotalLength; //配置所返回的所有數量的大小

BYTE bNumInterface; //此配置所支援的介面數量

BYTE bConfigurationVale; //Set_Configuration命令需要的引數值

BYTE iConfiguration; //描述該配置的字串的索引值

BYTE bmAttribute; //供電模式的選擇

BYTE MaxPower; //裝置從匯流排提取的最大電流

}

3、字元描述符

struct _STRING_DEscriptOR_STRUCT

{

BYTE bLength; //裝置描述符的位元組數大小,為0x12

BYTE bDescriptorType; //描述符型別編號,為0x01

BYTE SomeDescriptor[36]; //UNICODE編碼的字串

}

4、介面描述符

struct _INTERFACE_DEscriptOR_STRUCT

{

BYTE bLength; //裝置描述符的位元組數大小,為0x12

BYTE bDescriptorType; //描述符型別編號,為0x01

BYTE bInterfaceNunber; //介面的編號

BYTE bAlternateSetting;//備用的介面描述符編號

BYTE bNumEndpoints; //該介面使用端點數,不包括端點0

BYTE bInterfaceClass; //介面型別

BYTE bInterfaceSubClass;//介面子型別

BYTE bInterfaceProtocol;//介面所遵循的協議

BYTE iInterface; //描述該介面的字串索引值

}

5、端點描述符

struct _ENDPOIN_DEscriptOR_STRUCT

{

BYTE bLength; //裝置描述符的位元組數大小,為0x12

BYTE bDescriptorType; //描述符型別編號,為0x01

BYTE bEndpointAddress; //端點地址及輸入輸出屬性

BYTE bmAttribute; //端點的傳輸型別屬性

WORD wMaxPacketSize; //端點收、發的最大包的大小

BYTE bInterval; //主機查詢端點的時間間隔

}

具體分析如下:

1、描述裝置型別Device Descriptor

      包含了裝置名稱,類別,生產廠家等等資訊,通過得到的這些資訊Host會去找到合適的裝置驅動程式在主機上載入驅動。

/* USB Standard Device Descriptor */
const u8 Virtual_Com_Port_DeviceDescriptor[] =
  {
    0x12,   /* bLength */  //USB裝置描述符的總長度固定為18個位元組,因此為12H
    USB_DEVICE_DESCRIPTOR_TYPE,     /* bDescriptorType */  //USB裝置描述符的型別值,固定為01H
    0x00,                               //USB遵循的規範版本號,USB2.0; 0xXXYZ,XX為主版本號,Y為次版本號,Z為子次版本號
    0x02,   /* bcdUSB = 2.00 */
    0x02,   /* bDeviceClass: CDC */       //USB所遵循的標準裝置類。0表示裝置的介面相互獨立,分別屬於不同的裝置類;
                                       //1~FEH之間表示USB協議中定義的某個類。03H表示HID類,02H表示CDC類。
                                       //FFH表示供應商自定義的裝置類
    0x00,   /* bDeviceSubClass */       //USB裝置所屬的標準裝置子類。對於顯示裝置類(04H),包含3個子類,
                                       //子類程式碼01H表示CRT顯示器,02H表示平面顯示器,03H表示3D顯示器。
                                       //bDeviceClass為0時,該值為0;該值為FFH時,表示供應商自定義的裝置子類
    0x00,   /* bDeviceProtocol */       //採用的裝置類協議。該值為FFH時表示裝置類協議由供應商自定義
    0x40,   /* bMaxPacketSize0 */       //端點0所支援最大資料包長度(位元組),低速為8,全速為8,16,32或64,高速為64
    0x83,                               //裝置供應商id,使主機為其載入合適驅動
    0x04,   /* idVendor = 0x0483 */
    0x40,                               //產品id,用於區分不同的usb裝置
    0x57,   /* idProduct = 0x7540 */
    0x00,                               //裝置版本號,幫助主機載入合適驅動
    0x01,   /* bcdDevice = 1.00 */
    1,              /* Index of string descriptor describing manufacturer */  //若沒有,可為0
    2,              /* Index of string descriptor describing product */          //若沒有,可為0
    3,              /* Index of string descriptor describing the device's serial number */       //若沒有,可為0
    0x01    /* bNumConfigurations */    //USB裝置所支援的配置數
  };

2、配置描述符Config Descriptor

    包含了介面型別,最大功耗(電流),供電方式等等資訊,事實上這個配置描述項不僅僅是剛才說的這些作用,更多地,它需要通知主機裝置所使用的ENDpoint的情況,使用的類驅動型別,等等資訊

const u8 Virtual_Com_Port_ConfigDescriptor[] =
  {
    /*Configuation Descriptor*/
    0x09,   /* bLength: Configuation Descriptor size */           //配置描述符的長度,固定為9位元組,09H
    USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */        //配置描述符型別,固定位02H
    VIRTUAL_COM_PORT_SIZ_CONFIG_DESC,       /* wTotalLength:no of returned bytes */        //配置資訊總長度,配置描述符、介面描述符、端點描述符長度總和
    0x00,
    0x02,   /* bNumInterfaces: 2 interface */            //所支援的介面數, 最小值為1
    0x01,   /* bConfigurationValue: Configuration value */     //USB裝置的配置值
    0x00,   /* iConfiguration: Index of string descriptor describing the configuration */ //字串描述符索引,若沒有,可為0
    0xC0,   /* bmAttributes: self powered */   //配置特性,可按位定址,第六位置1表示用匯流排電源,第五位置1表示支援遠端喚醒,其他欄位保留
                                               //一般0~4位置0,第7位置1
    0x00,   /* MaxPower 0 mA */                   //USB裝置執行時所支援的最大電流,2mA為單位
    /*Interface Descriptor*/
    0x09,   /* bLength: Interface Descriptor size */         //介面描述符長度,固定為9位元組,09H
    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */  //介面描述符的型別值,固定位04H
    /* Interface descriptor type */
    0x00,   /* bInterfaceNumber: Number of Interface */          //USB介面的介面號
    0x00,   /* bAlternateSetting: Alternate setting */          //USB介面的可替換設定值
    0x01,   /* bNumEndpoints: One endpoints used */              //USB介面所使用的介面總數
    0x02,   /* bInterfaceClass: Communication Interface Class */    //USB介面所屬的裝置類,1~FEH表示某個裝置類;FFH表示供應商自定義
    0x02,   /* bInterfaceSubClass: Abstract Control Model */
    0x01,   /* bInterfaceProtocol: Common AT commands */       //介面所採用的裝置類協議
    0x00,   /* iInterface: */                                   //USB介面字串描述符的索引值
    /*Header Functional Descriptor*/
    0x05,   /* bLength: Endpoint Descriptor size */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x00,   /* bDescriptorSubtype: Header Func Desc */
    0x10,   /* bcdCDC: spec release number */
    0x01,
    /*Call Managment Functional Descriptor*/
    0x05,   /* bFunctionLength */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x01,   /* bDescriptorSubtype: Call Management Func Desc */
    0x00,   /* bmCapabilities: D0+D1 */
    0x01,   /* bDataInterface: 1 */
    /*ACM Functional Descriptor*/
    0x04,   /* bFunctionLength */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
    0x02,   /* bmCapabilities */
    /*Union Functional Descriptor*/
    0x05,   /* bFunctionLength */
    0x24,   /* bDescriptorType: CS_INTERFACE */
    0x06,   /* bDescriptorSubtype: Union func desc */
    0x00,   /* bMasterInterface: Communication class interface */
    0x01,   /* bSlaveInterface0: Data Class Interface */
    /*Endpoint 2 Descriptor*/                               //端點描述符長度固定為7位元組,07H
    0x07,   /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
    0x82,   /* bEndpointAddress: (IN2) */
    0x03,   /* bmAttributes: Interrupt */
    VIRTUAL_COM_PORT_INT_SIZE,      /* wMaxPacketSize: */
    0x00,
    0xFF,   /* bInterval: */
    /*Data class interface descriptor*/
    0x09,   /* bLength: Endpoint Descriptor size */
    USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
    0x01,   /* bInterfaceNumber: Number of Interface */
    0x00,   /* bAlternateSetting: Alternate setting */
    0x02,   /* bNumEndpoints: Two endpoints used */
    0x0A,   /* bInterfaceClass: CDC */
    0x00,   /* bInterfaceSubClass: */
    0x00,   /* bInterfaceProtocol: */
    0x00,   /* iInterface: */
    /*Endpoint 3 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
    0x03,   /* bEndpointAddress: (OUT3) */
    0x02,   /* bmAttributes: Bulk */
    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
    0x00,
    0x00,   /* bInterval: ignore for Bulk transfer */
    /*Endpoint 1 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
    0x81,   /* bEndpointAddress: (IN1) */
    0x02,   /* bmAttributes: Bulk */
    VIRTUAL_COM_PORT_DATA_SIZE,             /* wMaxPacketSize: */
    0x00,
    0x00    /* bInterval */
  };

由於上面我們在設定了使用USB CDC類,我們就要按照CDC的規則來設定,

按照CDC協議的內容FunctionalDescriptor只包含如下幾個:

Header Functional Descriptor:

Abstract Control Management functional Descriptor :定義了Communication Class Interface所支援的命令集合。具         體到下面的內容為:裝置不支援Send_Break,Set_line_Coding,Set_Control_Line_State,Get_Line_Coding,               Set_Comm_Feature,Clear_Comm_Feature,Get_Comm_Feature請求和Serial_State,Network_Connection消        息,也就是說禁用所有可選Abstract Control Model*的訊息和請求,緊緊保留了必需的                                                            SEND_ENCAPSULATED_COMMAND,Get_ENCAPSULATED_COMMAND請求和RESPONSE_AVAILABLE訊息。

Data class interface descriptor:

Call Manageament Functional Descriptor:該描述項定義了相關管理呼叫的約束和方式,裝置傳送接收管理資訊使用通訊類介面,裝置不自己呼叫管理功能。

UNION function descriptor:就是起到聯絡各個獨立的Interface,描述其之間的關係的作用。