USB初學(一)---USB-HID的初步認識

(正在學習USB,剛剛學習,HID是最簡單的一種,但是也很麻煩)

 

HID是一種USB通信協議,無需安裝驅動就能進行交互,在學習HID之前,先來複習一下USB協議的相關內容。

 

USB設備描述符-概述

當插入USB設備後,主機會向設備請求各種描述符來識別設備。那什麼是設備描述符呢?

Descriptor即描述符,是一個完整的數據結構,可以通過C語言等編程實現,並存儲在USB設備中,用於描述一個USB設備的所有屬性,USB主機是通過一系列命令來要求設備發送這些信息的。

描述符的作用就是通過命令操作作來給主機傳遞信息,從而讓主機知道設備具有什麼功能、屬於哪一類設備、要佔用多少帶寬、使用哪類傳輸方式及數據量的大小,只有主機確定了這些信息之後,設備才能真正開始工作。

USB有那些標準描述符?

USB有5種標準描述符:設備描述符 、配置描述符、字符描述符、接口描述符、端點描述符  。

描述符之間有一定的關係,一個設備只有一個設備描述符,而一個設備描述符可以包含多個配置描述符,而一個配置描述符可以包含多個接口描述符,一個接口使用了幾個端點,就有幾個端點描述符。由此我們可以看出,USB的描述符之間的關係是一層一層的,最上一層是設備描述符,下面是配置描述符,再下面是接口描述符,再下面是端點描述符。在獲取描述符時,先獲取設備描述符,然後再獲取配置描述符,根據配置描述符中的配置集合長度,一次將配置描述符、接口描述符、端點描述符一起一次讀回。其中可能還會有獲取設備序列號,廠商字符串,產品字符串等。

 

設備描述符

struct _DEVICE_DEscriptOR_STRUCT
{
  BYTE   bLength;    //設備描述符的字節數大小
  BYTE   bDescriptorType;   //描述符類型編號,爲0x01
  WORD  bcdUSB;   //USB版本號
  BYTE  bDeviceClass;   //USB分配的設備類代碼,0x01~0xfe爲標準設備類,0xff爲廠商自定義類型,0x00不是在設備描述符中定義的,如HID
  BYTE   bDeviceSubClass;  //usb分配的子類代碼,同上,值由USB規定和分配的,HID設備此值爲0
  BYTE  bDeviceProtocl;  //USB分配的設備協議代碼,同上HID設備此值爲0
  BYTE   bMaxPacketSize0;  //端點0的最大包的大小
  WORD   idVendor;  //廠商編號
  WORD   idProduct;  //產品編號
  WORD  bcdDevice;  //設備出廠編號
  BYTE   iManufacturer;   //描述廠商字符串的索引
  BYTE   iProduct;   //描述產品字符串的索引
  BYTE   iSerialNumber;  //描述設備序列號字符串的索引
  BYTE   bNumConfiguration;   //可能的配置數量
}

 

配置描述符
struct _CONFIGURATION_DEscriptOR_STRUCT

{
  BYTE  bLength;   //配置描述符的字節數大小
  BYTE   bDescriptorType;   //描述符類型編號,爲0x02
  WORD   wTotalLength;   //配置所返回的所有數量的大小
  BYTE   bNumInterface;  //此配置所支持的接口數量
  BYTE   bConfigurationVale;   //Set_Configuration命令需要的參數值
  BYTE   iConfiguration;  //描述該配置的字符串的索引值
  BYTE  bmAttribute;  //供電模式的選擇
  BYTE   MaxPower;   //設備從總線提取的最大電流

}

 

字符描述符
struct _STRING_DEscriptOR_STRUCT

{

BYTE bLength; //字符串描述符的字節數大小
BYTE bDescriptorType; //描述符類型編號,爲0x03
BYTE SomeDescriptor[36]; //UNICODE編碼的字符串

}

 

接口描述符

struct _INTERFACE_DEscriptOR_STRUCT

{

BYTE bLength; //接口描述符的字節數大小

BYTE bDescriptorType; //描述符類型編號,爲0x04

BYTE bInterfaceNunber; //接口的編號

BYTE bAlternateSetting;//備用的接口描述符編號

BYTE bNumEndpoints; //該接口使用端點數,不包括端點0

BYTE bInterfaceClass; //接口類型 HID設備此值爲0x03

BYTE bInterfaceSubClass;//接口子類型 HID設備此值爲0或者1

BYTE bInterfaceProtocol;//接口所遵循的協議

BYTE iInterface; //描述該接口的字符串索引值

}

 

端點描述符

struct _ENDPOIN_DEscriptOR_STRUCT

{

BYTE bLength; //端點描述符的字節數大小

BYTE bDescriptorType; //描述符類型編號,爲0x05

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

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

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

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

}

 

HID設備描述符

溫習了以上內容,我們再來看看HID協議與這些描述符之間的關係。

當插入USB設備後,主機會向設備請求各種描述符來識別設備。

爲了把一個設備識別爲HID類別,設備在定義描述符的時候必須遵守HID規範。

從框圖中,可以看出除了USB標準定義的一些描述符外,HID設備還必須定義HID描述符。另外設備和主機的通信是通過報告的形式來實現的,所以還必須定義報告描述符;而物理描述符不是必需的。還有就是HID描述符是關聯於接口(而不是端點)的,所以設備不需要爲每個端點都提供一個HID描述符。

接口描述符中bInterfaceClass的值必須爲0x03,bInterfaceSubClass的值爲0或1,爲1表示HID設備符是一個啓動設備(Boot Device,一般對PC機而言纔有意義,意思是BIOS啓動時能識別並使用您的HID設備,且只有標準鼠標或鍵盤類設備才能成爲Boot Device。如果爲0則只有在操作系統啓動後才能識別並使用您的HID設備)。

USB HID類描述符的結構

偏移量

大小

描述

0

bLength

1

數字

此描述符的長度(以字節爲單位)

1

bDescriptorType

1

常量

描述符種類(此處爲0x21即HID類描述符)

2

bcdHID

2

數字

HID規範版本號(BCD碼),採用4個16進制的BCD格式編碼,如版本1.0的BCD碼爲0x0100,版本爲1.1的BCD碼爲0x0110

4

bCountryCode

1

數字

硬件目的國家的識別碼(BCD碼)(見表3)

5

bNumDescritors

1

數字

支持的附屬描述符數目

6

bDescriptorType

1

常量

HID相關描述符的類型

0x21:HID描述符

0x22:報告描述符

0x23:物理描述符

7

wDescriptorLength

2

數字

報告描述符總長度

9

bDescriptorType

1

常量

用於識別描述符類型的常量,使用在有一個以上描述符的設備

10

wDescriptorLength

2

數字

描述符總長度,使用在有一個以上描述符的設備

 

報告描述符

報告描述符比較複雜,它是以item形式排列組合而成,無固定長途,用戶可以自定義長度以及每一bit的含義。item類型分三種:main,global和local,其中main類型又可分爲5種tag:

  • input item tag:指的是從設備的一個或多個類似控制管道得到的數據
  • output item tag:指的是發送給一個或多個類似控制管道的數據
  • feature item tag:表示設備的輸入輸出不面向最終用戶
  • collection item tag:一個有意義的input,output和feature的組合項目
  • end collection item tag:指定一個collectionitem的終止

每一個main item tag(input,output,feature)都表明了來自一個特定管道的數據的大小,數據相對還是獨立,以及其他相關信息。在此之前,global和local item定義了數據的最大值和最小值,等等。local item僅僅描述下一個main item定義的數據域,而global item是這一個報告描述符中所有後續數據段的默認屬性。

 一個報告描述符可能包含多個main item,爲了準確描述來自一個控制管道的數據,一個報告描述符必須包括以下內容:

  • input(output,feature)
  • usage
  • usage page
  • Logical Minimum
  • Logical Maximum
  • Report Size
  • Report Count

下面用一個三鍵鼠標舉例說明:

Usage Page (Generic Desktop);    //global item

Usage (Mouse);    //global item
Collection (Application);    //Start Mouse collection
Usage (Pointer);    //
Collection (Physical);    //Start Pointer collection
Usage Page (Buttons)
Usage Minimum (1),
Usage Maximum (3),
Logical Minimum (0),
Logical Maximum (1) ;   //Fields return values from 0 to 1
Report Count (3),
Report Size (1);   //Create three 1 bit fields (button 1, 2, & 3)
Input (Data, Variable, Absolute);   //Add fields to the input report.
Report Count (1),
Report Size (5);   //Create 5 bit constant field
Input (Constant), ;Add field to the input report
Usage Page (Generic Desktop),
Usage (X),
Usage (Y),
Logical Minimum (-127),
Logical Maximum (127);    //Fields return values from -127 to 127
Report Size (8),
Report Count (2);    //Create two 8 bit fields (X & Y position)
Input (Data, Variable, Relative);   //Add fields to the input report
End Collection;   //Close Pointer collection
End Collection;   //Close Mouse collection

 

item的數據格式有兩種,分別是短item和長item。

短item格式

bSize

0:0個字節

1:1個字節

2:2個字節

3:4個字節

bType

0:main

1:global

2:local

3:保留

bTag

item類型

8:input

9:output

A:collection

B:feature

C:end collection

 

長item,其bType位值爲3,bTag值爲F

bDataSize

0:0個字節

1:1個字節

2:2個字節

3:4個字節

bLongItemTag

0:main

1:global

2:local

3:保留

data 數據

 

物理描述符用來描述行爲特性,是可選的。

USB HID類可採用的通信管道

所有的HID設備通過USB的控制管道(默認管道,即端點0)和中斷管道與主機通信。

控制管道主要用於以下3個方面:

接收/響應USB主機的控制請示及相關的類數據

在USB主機查詢時傳輸數據(如響應Get_Report請求等)

接收USB主機的數據

中斷管道主要用於以下兩個方面:

USB主機接收USB設備的異步傳輸數據

USB主機發送有實時性要求的數據給USB設備

從USB主機到USB設備的中斷輸出數據傳輸是可選的,當不支持中斷輸出數據傳輸時,USB主機通過控制管道將數據傳輸給USB設備。

表1、USB HID規範定義的HID設備可用端點

管道

要求

說明

控制(端點0)

必須

傳輸USB描述符、類請求代碼以及供查詢的消息數據等

中斷輸入

必須

傳輸從設備到主機的輸入數據

中斷輸出

可選

傳輸從主機到設備的輸出數據

 

HID設備6種特定請求

 

HID類請求(命令)包格式

偏移量

大小

說明

0

bmRequestType

1

HID設備類請求特性如下:
位7:
0=從USB HOST到USB設備
1=從USB設備到USB HOST
位6~5:
01=請求類型爲設備類請求
位4~0:
0001=請求對象爲接口(interface)

因而,針對HID的設備類請求,僅僅10100001和00100001有效

1

bRequest

1

HID類請求(參考下表)

2

wValue

2

高字節說明描述符的類型

0x21:HID描述符

0x22:報告描述符

0x23:物理描述符

低字節爲非0值時被用來選定實體描述符。

4

wIndex

2

2字節數值,根據不同的bRequest有不同的意義

6

wLength

2

該請求的數據段長度

HID類請求

數值

HID類請求描述符

註釋

0x01

GET_REPORT

 主機用控制傳輸從設備接收數據,所有HID類設備都要支持這個請求;

0x02

GET_IDLE

 主機讀取設備當前的空閒速率,設備可以不支持此請求;

0x03

GET_PROTOCOL

僅僅適應於支持啓動功能的HID設備(Boot Device)

0x09

SET_REPORT

 設備用控制傳輸接收主機的數據,設備可以不支持此請求;

0x0A

SET_IDLE

 設置閒置狀態,設備可不支持此請求;

0x0B

SET_PROTOCOL

僅僅適應於支持啓動功能的HID設備(Boot Device)

 

GET_REPORT:主機通過控制端點獲取一個Report

描述

bmRequestType

0xA1

 

bRequest

0x01

 

wValue

高字節表示報告類型

0x01:input

0x02:output

0x03:feature

other:reserved

低字節表示ReportID,如不使用設爲0

 

wIndex

HID的interface索引值

 

wLength

Report長度

 

Data

Report內容

 

 

SET_REPORT:主機發送一個Report給設備,用以設置input,output或者feature

描述

bmRequestType

0x21

 

bRequest

0x09

 

wValue

高字節表示報告類型

0x01:input

0x02:output

0x03:feature

other:reserved

低字節表示ReportID,如不使用設爲0

 

wIndex

HID的interface索引值

 

wLength

Report長度

 

Data

Report內容

 

 

GET_IDLE

描述

bmRequestType

0xA1

 

bRequest

0x02

 

wValue

高字節0

低字節表示ReportID,如不使用設爲0

 

wIndex

HID的interface索引值

 

wLength

1

 

Data

空閒速率

 

 

SET_IDLE

描述

bmRequestType

0x21

 

bRequest

0x0A

 

wValue

新的速率

低字節表示ReportID,如不使用設爲0

 

wIndex

HID的interface索引值

 

wLength

0

 

Data

 

 

GET_PROTOCOL

描述

bmRequestType

0xA1

 

bRequest

0x03

 

wValue

0

 

wIndex

HID的interface索引值

 

wLength

1

 

Data

0 = Boot Protocol

1 = Report Protocol

 

 

SET_PROTOCOL

描述

bmRequestType

0x21

 

bRequest

0x0B

 

wValue

0 = Boot Protocol

1 = Report Protocol

 

wIndex

HID的interface索引值

 

wLength

0

 

Data

 

 

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