内容原创,未经本人同意请勿转载。联系本人:jianshu_kevin@126.com
PIPE
usb通信的最基本形式是通过USB设备里的endpoint,而主机和endpoit之间的数据传输就是通过pipe
通信方式
USB的所有通信都是由host发起的,总线采用轮询方式和设备进行通信
endpoint
端点是有方向的,主机到从机成为out端点,从机到主机成为in端点。从这个说明看出端点是单方向的。(除了0端点)
管道通信方式
pipe中的数据通信方式有两种,一种是stream
一种是message
。message
要求进出进出方向必须要求同一个管道,默认就使用ep0
作为message
管道
传输方式
USB endpiont有四种类型,分别对应了不同的数据传输方式,分别为control transfers控制传输
、interrupt transfers中断传输
、Bluk Data transfers批量传输
、Isochronous Data Tranfers等时传输
控制传输
通常用于配置设备,获取设备信息,发送命令到设备
逻辑设备
逻辑设备就是一系列端点的组合,逻辑设备与主机之间的通信发生在一个主机的缓冲区和设备的一个端点之间。
---------------------------
host
---------------------------
| buf | buf | buf |
---------------------------
[] [] []
[] [] []
[] [] []------->pipe
[] [] []
[] [] []
---------------------------
{ |ep| } {| ep| |ep| }-->interface
---------------------------
logic device
---------------------------
interface
一个逻辑设备可能包含若干个接口,每个接口包含1个或多个端点。每个接口表示一种功能。内核里一个接口对应一个驱动程序。例如usb扬声器就包含一个键盘接口和一个音频流接口
gadget
class协议
USB协议中除了定义一些通用软硬件电气特性,还包含各种各样的class协议,用来为不同的功能定义各自的标准接口
和具体总线上的数据交互内容和格式
。例如u盘的Mass storage class
、通用数据交换CDC class
为何USB都在PCI设备中
访问设备文件时经常看到usb在pci目录中,这是因为通常usb的root hub包含在了pci设备中。
usbfs
usbfs提供了用户空间可以访问usb硬件设备的接口
设备描述符、配置描述符、接口描述符、端点描述符
协议里规定一个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创建的
*/
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协议里为每一种class、subclass、protocol定义了一个数值。没一个接口或者设备都属于一个class。
设备class和接口class有何区别?
USB设备号
单纯的USB主设备号有两个USB_MAJOR
,USB_DEVICE_MAJOR
。其中USB_DEVICE_MAJOR
是为usbfs而生的。USB_MAJOR
才是真正的USB设备主设备号,但是一般的USB设备都是模拟成其他的设备,比如USB键盘、硬盘等。这类设备和其他子系统关联,那么设备号就不再使用USB_MARJOR
设备号了,属于哪个子系统就使用该子系统的设备号。例如USB硬盘的主设备号是8
。这里的USB设备准确的说应该是USB接口。
挂起状态
协议里规定所有的USB设备都需要支持挂起,已达到省电的目的,在设备指定时间内(3ms)没有数据传输,就进入挂起状态。当收到一个non-idle
信号,就会被唤醒。