usb中的endpoint(端点)和传输模式
端点:
端点位于USB 外设内部,所有通信数据的来源或目的都基于这些端点,是一个可寻址的FIFO。
每个USB 外设有一个唯一的地址,可能包含最多十六个端点。主机通过发出器件地址和每次数据传输的端点号,向一个具体端点(FIFO)发送数据。
每个端点的地址为0 到15,一个端点地址对应一个方向。所以,端点2-IN 与端点2-OUT 完全不同(一个端点是否能够同时配置为IN和OU,要看具体的芯片手册,STM32F103的每个端口都可以配置为双向,但是SAM9G45的端点就不可以,只能配置为一个方向【端点0除外】)。 每个器件有一个默认的双向控制端点0,因此不存在端点0-IN 和端点0-OUT。
在一个USB设备中会有很多endpoint,最多有16个。而我用的S5PV210处理器中有 16个,分别为EP0 – EP15。一个EP本质上讲是FIFO,也就是一段缓冲区,我们可以这样理解一个USB OTG设备就是有很多个缓冲区的集合。
虽然有16个端点,但是我们通常只会用到3个。比较常用的做法是EP0用做传输配置和控制信息,EP1做IN_EP,EP2做OUT_EP。
IN_EP的作用是用于把数据从Host传到Device中。而OUT_EP的作用是用于把数据从Device传送到Host中。即他们分别用做发送和接收。
USB四种传输模式
控制传输、批量传输、中断传输、同步传输
USB 有上述四种传输类型。枚举期间外设告诉主机每个端点支持哪种传输类型。
USB设备驱动向USB控制器驱动请求的每次传输被称为一个事务(Transaction),
事务有四种类型:Bulk Transaction、Control Transaction、Interrupt Transaction和Isochronous Transaction。
数据包包含部分:
每次事务都会分解成若干个数据包在USB总线上传输。每次传输必须历经两个或三个部分,第一部分——USB控制器向USB设备发出命令,
第二部分——USB控制器和USB设备之间传递读写请求,其方向主要看第一部分的命令是读还是写,第二部分有时候可以没有。
第三部分——握手信号。
批量(Bulk)传输事务
作用:主要应用在数据大量数据传输和接受数据上同时又没有带宽和间隔时间要求的情况下;
特点:要求保证传输。打印机和扫描仪属于这种类型这种类型的设备
适合于传输非常慢和大量被延迟的传输,可以等到所有其它类型的数据的传输完成之后再传输和接收数据。
批量数据传输分三个阶段:
第一部分——令牌阶段。
Host端发出一个Bulk的令牌请求。
如果令牌是IN请求 ,则是从Device到Host的请求;
如果令牌是OUT请求,则是从Host到Device端的请求。
第二部分——传送数据的阶段。
根据先前请求的令牌的类型,数据传输有可能是IN方向,也有可能是OUT方向。传输数据的时候用DATA0和DATA1令牌携带着数据交替传送。
数据传输格式DATA1和DATA0,这两个是重复数据,确保在1数据丢失时0可以补上,不至于数据丢失。
第三部分——握手阶段。
如果数据是IN 方向,握手信号应该是Host端发出;
如果数据是OUT方向,握手信号应该是Device端发出。
握手信号可以为ACK, 表示正常响应,
NAK, 表示没有正确传送。
STALL,表示出现主机不可预知的错误。
控制(Control)传输
作用:USB系统软件用来主要进行查询配置和给USB设备发送通用的命令;
特点:控制传输是双向传输,数据量通常较小;数据传送是无损性的。
数据宽度:控制传输方式可以包括8、16、32和64字节的数据,这依赖于设备和传输速度。
控制传输典型地用在主计算机和USB外设之间的端点0(EP0)之间的传输
控制传输也分为三个阶段,即令牌阶段、数据传送阶段、握手阶段
中断(Interrupt)传输事务
作用:主要用于定时查询设备是否有中断数据要传输;
特点:设备的端点模式器的结构决定了它的查询频率从1到255ms之间。
典型的应用在少量的分散的不可预测数据的传输键盘操纵杆和鼠标就属于这一类型
(数据量很小)
中断方式传输是单向的并且对于host 来说只有输入(IN)的方式
在中断事务中,也分为三个阶段,即令牌阶段、数据传输阶段、握手阶段
同步(Isochronous)传输事务
作用:用于时间严格并具有较强容错性的流数据传输,或者用于要求恒定的数据传输率的即时应用中。例如执行即时通话的网络电话。
特点:保证传输的同步性。保证每秒有固定的传输量。
(与Bulk传输不同)同步传输允许有一定的误码率。(这样符合视频会议等传输的需求,因为视频会议首先要保证实时性,在一定条件下,允许有一定的误码率。)
同步传输事务有只有两个阶段,即令牌阶段、数据阶段,因为不关心数据的正确性,故没有握手阶段。
一个USB设置可以有多个配置,在初始化的过程中,会选择一个默认的配置,选择的方法根据驱动实现而不一样,linux usb会选择第一个标准的配置。
出处:http://blog.csdn.net/leumber/article/details/72765902
USB描述符解析
USB描述符信息会被存储在USB设备中,在设备枚举过程中,USB主机会向USB设备发送GetDescriptor请求,USB设备在收到这个请求之后,会将USB描述符信息返回给USB主机,USB主机分析返回来的数据,判断出该设备是哪一种USB设备,按照描述符中的一些配置信息与设备建立相应的数据通道。USB描述符信息在USB协议中有详细描述。
标准的USB设备有5种USB描述符:设备描述符,配置描述符,字符串描述符,接口描述符,端点描述符。下面详解:
1.设备描述符 一个设备只有一个设备描述符,列出这个设备的配置参数
typedef struct _USB_DEVICE_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
WORD bcdUSB,
BYTE bDeviceClass,
BTYE bDeviceSubClass,
BYTE bDeviceProtol,
BYTE bMaxPacketSize0,
WORD idVenderI,
WORD idProduct,
WORD bcdDevice,
BYTE iManufacturer,
BYTE iProduct,
BYTE iSerialNumber,
BYTE iNumConfiguations
}USB_DEVICE_DESCRIPTOR;
bLength : 描述符大小.固定为0x12.
bDescriptorType : 设备描述符类型.固定为0x01.
bcdUSB : USB 规范发布号.表示了本设备能适用于那种协议,如2.0=0200,1.1=0110等.
bDeviceClass :类型代码(由USB指定)当它的值是0时,表示所有接口在配置描述符里,并且所有接口是独立的。当它的值是1到FEH时,表示不同的接口关联的。当它的值是FFH时,它是厂商自己定义的.
bDeviceSubClass : 子类型代码(由USB分配).如果bDeviceClass值是0,一定要设置为0.其它情况就跟据USB-IF组织定义的编码.
bDeviceProtocol : 协议代码(由USB分配).如果使用USB-IF组织定义的协议,就需要设置这里的值,否则直接设置为0。如果厂商自己定义的可以设置为FFH.
bMaxPacketSize0 : 端点0最大分组大小(只有8,16,32,64有效).
idVendor : 供应商ID(由USB分配).
idProduct : 产品ID(由厂商分配).由供应商ID和产品ID,就可以让操作系统加载不同的驱动程序.
bcdDevice : 设备出产编码.由厂家自行设置.
iManufacturer : 厂商描述符字符串索引.索引到对应的字符串描述符.为0则表示没有.
iProduct : :产品描述符字符串索引.同上.
iSerialNumber : 设备序列号字符串索引.同上.
bNumConfigurations : 可能的配置数.指配置字符串的个数
2.配置描述符 一个设备中可以有多个配置描述符,每套配置描述符含有接口描述符,端点描述符
typedef struct _USB_CONFIGURATION_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
WORD wTotalLength,
BYTE bNumInterfaces,
BYTE bConfigurationValue,
BYTE iConfiguration,
BYTE bmAttributes,
BYTE MaxPower
}USB_CONFIGURATION_DESCRIPTOR;
bLength: 描述符大小.固定为0x09.
bDescriptorType: 配置描述符类型.固定为0x02.
wTotalLength: 整个数据的长度.指此配置返回的配置描述符,接口描述符以及端点描述符的全部大小.
bNumInterfaces: 配置所支持的接口数.指该配置配备的接口数量,也表示该配置下接口描述符数量.
bConfigurationValue:当使用SetConfiguration和GetConfiguration请求时所指定的配置索引值
iConfiguration: 用于描述该配置字符串描述符的索引.
bmAttributes: 供电模式选择.D7:总线供电,D6:自供电,D5:远程唤醒,D4~D0:保留
MaxPower: 总线供电的USB设备的最大消耗电流.以2mA为单位.例如0x32为50*2=100mA
3.接口描述符 一个配置描述符内可以含有多个接口,数量由配置描述符决定
typedef struct _USB_INTERFACE_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
BYTE bInterfaceNumber,
BYTE bAlternateSetting,
BYTE bNumEndpoint,
BYTE bInterfaceClass,
BYTE bInterfaceSubClass,
BYTE bInterfaceProtocol,
BYTE iInterface
}USB_INTERFACE_DESCRIPTOR;
bLength:描述符大小.固定为0x09
bDescriptorType:接口描述符类型.固定为0x04
bInterfaceNumber:该接口的编号
bAlternateSetting:用于为上一个字段选择可供替换的位置.即备用的接口描述符标号
bNumEndpoint:使用的端点数目.端点0除外
bInterfaceClass:类型代码(由USB分配)
bInterfaceSubClass:子类型代码(由USB分配)
bInterfaceProtocol:协议代码(由USB分配)
iInterface:字符串描述符的索引
4.端点描述符 每个接口所需要的端点及其设置,数量由配置描述符决定
typedef struct _USB_ENDPOINT_DESCRIPTOR_
{
BYTE bLength,
BYTE bDescriptorType,
BYTE bEndpointAddress,
BYTE bmAttributes,
WORD wMaxPacketSize,
BYTE bInterval
}USB_ENDPOINT_DESCRIPTOR;
bLength : 描述符大小.固定为0x07.
bDescriptorType : 接口描述符类型.固定为0x05.
bEndpointType : USB设备的端点地址.D7端点方向,对于控制端点可以忽略,1/0:IN/OUT.D6-D4,保留.D3-D0:端点号.
bmAttributes : 端点属性.D7-D2,保留.D1-D0,传输类型:00控制,01同步,02批量,03中断.
wMaxPacketSize : 本端点接收或发送的最大信息包大小.
bInterval : 轮询数据传送端点的时间间隔.对于批量传送和控制传送的端点忽略.对于同步传送的端点,必须为1,对于中断传送的端点,范围为1-255.
5.字符串描述符 字符串描述符是可选的.如果不支持字符串描述符,其设备,配置,接口描述符内的所有字符串描述符索引都必须为0,每个字符串描述符都有一个索引,USB主机会在请求时按照顺序获取对应的字符串描述符,默认0位语言字符串描述符,后边都由每个描述符内容中指定,一般1为设备厂商字符串描述符,2为产品描述符,3为设备序列号字符串描述符,4为接口描述符
typedef struct _USB_STRING_DESCRIPTION_
{
BYTE bLength,
BYTE bDescriptionType,
BYTE bString[];
}USB_STRING_DESCRIPTION;
bLength : 描述符大小.由整个字符串的长度加上bLength和bDescriptorType的长度决定.
bDescriptorType : 接口描述符类型.固定为0x03.
bString[] : Unicode编码字符串.
下边是一套USB_CCID的设备描述符、配置描述符、接口描述符、端点描述符和字符串描述符
CCID描述符配置