內容原創(chuàng),未經本人同意請勿轉載。聯(lián)系本人:jianshu_kevin@126.com
PIPE
usb通信的最基本形式是通過USB設備里的endpoint,而主機和endpoit之間的數(shù)據傳輸就是通過pipe
通信方式
USB的所有通信都是由host發(fā)起的,總線采用輪詢方式和設備進行通信
endpoint
端點是有方向的,主機到從機成為out端點,從機到主機成為in端點。從這個說明看出端點是單方向的。(除了0端點)
管道通信方式
pipe中的數(shù)據通信方式有兩種,一種是stream一種是message。message要求進出進出方向必須要求同一個管道,默認就使用ep0作為message管道
傳輸方式
USB endpiont有四種類型,分別對應了不同的數(shù)據傳輸方式,分別為control transfers控制傳輸、interrupt transfers中斷傳輸、Bluk Data transfers批量傳輸、Isochronous Data Tranfers等時傳輸
控制傳輸通常用于配置設備,獲取設備信息,發(fā)送命令到設備
邏輯設備
邏輯設備就是一系列端點的組合,邏輯設備與主機之間的通信發(fā)生在一個主機的緩沖區(qū)和設備的一個端點之間。
---------------------------
host
---------------------------
| buf | buf | buf |
---------------------------
[] [] []
[] [] []
[] [] []------->pipe
[] [] []
[] [] []
---------------------------
{ |ep| } {| ep| |ep| }-->interface
---------------------------
logic device
---------------------------
interface
一個邏輯設備可能包含若干個接口,每個接口包含1個或多個端點。每個接口表示一種功能。內核里一個接口對應一個驅動程序。例如usb揚聲器就包含一個鍵盤接口和一個音頻流接口
gadget
class協(xié)議
USB協(xié)議中除了定義一些通用軟硬件電氣特性,還包含各種各樣的class協(xié)議,用來為不同的功能定義各自的標準接口和具體總線上的數(shù)據交互內容和格式。例如u盤的Mass storage class、通用數(shù)據交換CDC class
為何USB都在PCI設備中
訪問設備文件時經??吹絬sb在pci目錄中,這是因為通常usb的root hub包含在了pci設備中。
usbfs
usbfs提供了用戶空間可以訪問usb硬件設備的接口
設備描述符、配置描述符、接口描述符、端點描述符
協(xié)議里規(guī)定一個usb設備必須支持這四大描述符。字符串描述符是可選的
/* host-side wrapper for one interface setting's parsed descriptors */
struct usb_host_interface {
struct usb_interface_descriptor desc; //接口描述符
int extralen;
unsigned char *extra; /* Extra descriptors */ //其他描述符
/* array of desc.bNumEndpoint endpoints associated with this
* interface setting. these will be in no particular order.
*/
struct usb_host_endpoint *endpoint; //端點描述符
char *string; /* iInterface string, if present */ //用來保存從設備上讀取出來的字符串描述符
};
/* USB_DT_INTERFACE: Interface descriptor */
struct usb_interface_descriptor {
__u8 bLength; //==9
__u8 bDescriptorType; //==4
__u8 bInterfaceNumber;
__u8 bAlternateSetting;
__u8 bNumEndpoints;
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
__u8 iInterface; //對應字符串描述符的索引值
} __attribute__ ((packed));
| bDescriptorType | Value |
|---|---|
| DEVICE | 1 |
| CONFIGURATION | 2 |
| STRING | 3 |
| INTERFACE | 4 |
| ENDPOINT | 5 |
| DEVICE_QUALIFIER | 6 |
| OHTER_SPEED_CONFIGURATION | 7 |
| INTERFACE_POWER | 8 |
struct usb_host_endpoint {
struct usb_endpoint_descriptor desc;
struct usb_ss_ep_comp_descriptor ss_ep_comp;
struct list_head urb_list;
void *hcpriv;
/****************提供給sysfs用的
wy@am:/proc$ ls /sys/bus/usb/devices/usb1/ep_00/
bEndpointAddress bInterval bLength bmAttributes direction interval power type uevent wMaxPacketSize
上面這個文件就是通過usb_create_ep_files創(chuàng)建的
*/
struct ep_device *ep_dev; /* For sysfs info */
unsigned char *extra; /* Extra descriptors */
int extralen;
int enabled;
};
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
__u8 bLength; //==7/9
__u8 bDescriptorType; //==5
__u8 bEndpointAddress; //bit7 表示方向,bit0-3表示端點號
/*bit1-0 表示傳輸類型,
00 控制
01 iosh( 等時)
10 批量
11 中斷
*/
__u8 bmAttributes;
//最大長度
__le16 wMaxPacketSize;
__u8 bInterval;
///////////////////////////下面這兩個字段只在audio設備中有
/* NOTE: these two are _only_ in audio endpoints. */
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
__u8 bRefresh;
__u8 bSynchAddress;
} __attribute__ ((packed));
//配置描述符
struct usb_config_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__le16 wTotalLength;
__u8 bNumInterfaces;
__u8 bConfigurationValue; //表明了正在被使用的USB配置,雖然USB設備可能包含多個配置,但是同一時刻只能又一個配置生效
__u8 iConfiguration; //配置描述符的字符串描述索引值
__u8 bmAttributes;
__u8 bMaxPower;
} __attribute__ ((packed));
設置
一個接口包含多個設置,每個設置對應不同的描述符
class
每個接口都包含一個class,class下面有分subclass。usb協(xié)議里為每一種class、subclass、protocol定義了一個數(shù)值。沒一個接口或者設備都屬于一個class。
設備class和接口class有何區(qū)別?
USB設備號
單純的USB主設備號有兩個USB_MAJOR,USB_DEVICE_MAJOR。其中USB_DEVICE_MAJOR是為usbfs而生的。USB_MAJOR才是真正的USB設備主設備號,但是一般的USB設備都是模擬成其他的設備,比如USB鍵盤、硬盤等。這類設備和其他子系統(tǒng)關聯(lián),那么設備號就不再使用USB_MARJOR設備號了,屬于哪個子系統(tǒng)就使用該子系統(tǒng)的設備號。例如USB硬盤的主設備號是8。這里的USB設備準確的說應該是USB接口。
掛起狀態(tài)
協(xié)議里規(guī)定所有的USB設備都需要支持掛起,已達到省電的目的,在設備指定時間內(3ms)沒有數(shù)據傳輸,就進入掛起狀態(tài)。當收到一個non-idle信號,就會被喚醒。