本文共 12539 字,大约阅读时间需要 41 分钟。
温故而知新, 记录点usb四种传输相关的内容。
根据usb协议ch8, ch9等章节, 传输分四种,控制, 批量,中断, 等时。
* 一个传输由多个事务组成。如建立(setup)事务, 读数据(IN)事务, 写数据(OUT)事务等等。
* 一个事务一般有三个阶段(三种包), 即令牌->数据->握手, 这三个阶段有些是可选的。
令牌包打头: 说明我(主机)要干什么, 有四种命令, SETUP, IN, OUT, SOF。
IN/OUT 标志读/写数据。
SETUP 设置/建立, 只用于控制传输,
SOF 全称 Start Of Frame即标识帧的开始。这个包只用于全速以上的设备。 作用有以下几种:
1). 标志帧的开始。
2). 内部带有一个Frame ID, usb设备可基于帧号做一些事情。
3). 对于全速设备, 主机端会每隔1ms发送一个SOF, 高速设备, 125us发送一个SOF, 防止usb设备进入suspend状态。
1ms间隔的我们叫帧, 125us间隔的我们叫微帧, 即1ms内有8个微帧, 其中这些微帧的Frame ID不变, 即仅1ms帧号才家一次。
ok, 举点例子更清楚。
比如最常见的Get_Descriptor这个命令, 即枚举过程中通过端点0获取设备描述符这个动作。
1). 这个动作算一次传输
2). 这个传输是控制传输
3). 控制传输按事务分 通常 有三个阶段。建立事务 -> 数据事务 -> 状态事务
4). 建立事务,
* 先发setup令牌, 包结构简单 [Sync][PID][ADDR][ENDP][CRC5][EOP], 内部含有usb设备地址(0~127), 控制端点0
* 再发个具体Get_Descriptor这个命令, 跟在SETUP令牌后面, 主机端继续发数据包
[Sync][PID][DATA0][CRC16][EOP] 其中DATA0就是usb设备请求, 根据ch9, 该数据为8位数据,
查看usb/ch9.h,
struct usb_ctrlrequest { › __u8 bRequestType; › __u8 bRequest; › __le16 wValue; › __le16 wIndex; › __le16 wLength; } __attribute__ ((packed));
bRequestType即协议中的bmRequestType, 是bitmap格式。
D7: 数据传输方向, 0: Host->Device, 1: Device->Host
D6...5: 类型, 0 - Standard, 1 - Class, 2 - Vendor, 3 - Reserved
D4...0: Recipient(收件人) 0 - Device, 1 - Interface, 2 - Endpoint, 3 - Other, 4 ... 31 - Reserved
bRequest即具体的命令,
GET_DESCRIPTOR即一个标准的设备请求。
bmRquestType = 10000000B,
bRquest = 0x6,
ok, 该请求就发送给设备端了, 这个事务就等握手阶段了。等带设备端返回ACK包, 则说明设备端接收到了, 可以发具体的读数据请求事务。
握手包总共也是四种, ACK, NAK, STALL, NYET。
字面意思
ACK - 确认(收到)。
NAK - 未确认。 只能设备发给主机, 一般是设备忙或者没有数据要返回就发NAK。
STALL - 瘫痪。不支持的控制请求, 控制请求失败或终端失败等。
NYET - Not Yet, 还不行... 高速以上设备才有。协议说和PING命令有关, 具体碰到再理解...
是的, 控制传输的建立事务阶段终于结束了, 下一步, 具体的数据包...
5). 数据事务
前面建立的是Get_Descriptor事务, 那紧跟着的就是一次读数据事务。
发令牌 IN - > 设备发DATA0 - > ACK, 数据不够就继续读
发令牌 IN - > 设备发DTAA1 - > ACK...
......
6). 状态事务
设备描述符收到后, 主机端需要发起一个状态事务。嗯 这次是写数据, 需要跟设备说, 我收到啦!!
发令牌 OUT -> 主机端发长度为0的数据包 -> 设备回复ACK
ok, 以上就是一次完整的GET_DESCRIPTOR 控制传输。
bulk传输, 非常常用的一种传输方式。
枚举, 配置等动作完成后, 如果该usb设备有提供bulk端点, 我们就可以利用该bulk端点进行批量传输。
bulk in 端点可以读数据, bulk out端点可以写数据。
相对于控制传输, bulk/isoc/interrupt传输都没有建立阶段。 都是直接批量事务走起。
一个批量事务 也是三个阶段
1). 发令牌包, IN/OUT 即读还是写
2). 读 - 那就设备端给数据, 或者不给那就报错。 写 - 那就host发数据包。
数据包格式 [SYNC][PID][DATA][CRC16] 其中 DATA数据域的长度根据协议是这样描述的。
低速设备, 最多8byte...好少, 所以1.1只能用于一些HID设备了...
全速设备, 1023byte,
高速设备, 1024byte,
超速设备, 貌似格式有点变化...需要仔细看下3.0协议...
ok, 这是协议里定义的最大size。设备/端点描述符里其实有最大size的定义。所以具体采用的最大size, lsusb -v看一看吧。
比如我的usb读卡器,
river@river-VirtualBox:~/mount/rootfs$ lsusb -s 1:4 -vBus 001 Device 004: ID 14cd:1212 Super Top microSD card reader (SY-T18)Couldn't open device, some information will be missingDevice Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x14cd Super Top idProduct 0x1212 microSD card reader (SY-T18) bcdDevice 1.00 iManufacturer 1 iProduct 3 iSerial 2 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 32 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 8 Mass Storage bInterfaceSubClass 6 SCSI bInterfaceProtocol 80 Bulk-Only iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 0
看到了吧wMaxPacketSize... 512byte。
嗯, 所以这玩意bulk传输时, 一个IN/OUT 数据包, 最多就是512byte。
ftrace查看下usb的log
Line 14: <...>-1454 [002] d... 21815.916651: xhci_inc_enq: BULK 00000000e4ad58e6: enq 0x000000003784ca00(0x000000003784c000) deq 0x000000003784c9f0(0x000000003784c000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 1 Line 17: <...>-1454 [002] d... 21815.917057: xhci_inc_enq: BULK 00000000c99f84e6: enq 0x000000003784ad80(0x000000003784a000) deq 0x000000003784ad70(0x000000003784a000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 0 Line 20: <...>-1454 [002] d... 21817.931934: xhci_inc_enq: BULK 00000000e4ad58e6: enq 0x000000003784ca10(0x000000003784c000) deq 0x000000003784ca00(0x000000003784c000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 1 Line 23: <...>-1454 [002] d... 21817.932936: xhci_inc_enq: BULK 00000000c99f84e6: enq 0x000000003784ad90(0x000000003784a000) deq 0x000000003784ad80(0x000000003784a000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 0 Line 26: <...>-1454 [002] d... 21819.948060: xhci_inc_enq: BULK 00000000e4ad58e6: enq 0x000000003784ca20(0x000000003784c000) deq 0x000000003784ca10(0x000000003784c000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 1 Line 29: <...>-1454 [002] d... 21819.948468: xhci_inc_enq: BULK 00000000c99f84e6: enq 0x000000003784ada0(0x000000003784a000) deq 0x000000003784ad90(0x000000003784a000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 0 Line 32: <...>-1454 [002] d... 21821.964510: xhci_inc_enq: BULK 00000000e4ad58e6: enq 0x000000003784ca30(0x000000003784c000) deq 0x000000003784ca20(0x000000003784c000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 1 Line 35: <...>-1454 [002] d... 21821.964936: xhci_inc_enq: BULK 00000000c99f84e6: enq 0x000000003784adb0(0x000000003784a000) deq 0x000000003784ada0(0x000000003784a000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 0 Line 38: <...>-1454 [002] d... 21823.980658: xhci_inc_enq: BULK 00000000e4ad58e6: enq 0x000000003784ca40(0x000000003784c000) deq 0x000000003784ca30(0x000000003784c000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 1 Line 41: <...>-1454 [002] d... 21823.980864: xhci_inc_enq: BULK 00000000c99f84e6: enq 0x000000003784adc0(0x000000003784a000) deq 0x000000003784adb0(0x000000003784a000) segs 2 stream 0 free_trbs 508 bounce 512 cycle 0
3). 最后, 同样是握手包阶段。ACK, 那就确认了。
isochronous传输
继续看下isco, 即等时传输。字面意思即是定时定量的传...保证时延...用于usb音视频等设备。 比如uvc webcam一类的。
根据协议来, 等时传输, 就两个阶段, 令牌包->数据包。是的, 没有握手阶段, 即没有对端的确认包。 也就是说不管对端是收到与否, 我都按我的规则来读写。。。这样来保证等时。。。
嗯, 也就是说bulk传输如果是NAK等握手包, 那么需要重传机制。 等时传输, 那就丢了就丢了, 尽量保证看到的听到的是最近的画面和声音 和 直播, 视频聊天, 电话等场景类似。 时延优先...
看下usb_in_a_nutshell.pdf这篇文档, 描述的很好, 记录下...
Isochronous Transfers provide• Guaranteed access to USB bandwidth.• Bounded latency.• Stream Pipe - Unidirectional• Error detection via CRC, but no retry or guarantee of delivery.• Full & high speed modes only.• No data toggling.
关于数据包的 Size, 和bulk一样 , 也根据usb设备描述符来。比如我的uvc摄像头, 高分辨率,高帧率的, 对应wMaxPacketSize肯定就大点, 低分辨率低帧率高压缩比的wMaxPacketSize就小点。
说到uvc, 我这边遇到个问题, 我的罗技摄像头采用等时传输, 按照描述符中给的maxpackesize请求读数据, 可每次uvc摄像头给的数据都比我请求的小... 关于这种情况, 写数据发生呢肯定是异常的, 读数据嘛, 设备端给多少是设备说了算的, 所以也算不得异常。 但xhci控制器 还是会报个 Short Packet上来, 就是短包。 本来嘛, 报就报了呗, 就按正常的情况处理下, 继续就是了。PC上也是这样处理的。 但是却苦了我的FPGA验证环境了......
我的FPGA验证环境, 就塞了一个cpu核进去, 主频也就20Mhz.... 按usb2.0 高速设备的协议....
125us就是一个微帧了... 也就是差不多125us就是一个isoc传输.....
每次isoc传输, 都报Short Packet错误....
1s内得有8000次短包消息.... 我的20Mhz cpu就处理不过来了....
最后xhci模块的Event Ring Buffer就爆炸了...
具体log如下:
v4l2_cam-937 [000] dnh1 1769.737663: xhci_handle_event: EVENT: TRB 0000000039050dd0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.737771: xhci_handle_event: EVENT: TRB 0000000039050de0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.737878: xhci_handle_event: EVENT: TRB 0000000039050df0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.737986: xhci_handle_event: EVENT: TRB 0000000039050e00 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.738094: xhci_handle_event: EVENT: TRB 0000000039050e10 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.738201: xhci_handle_event: EVENT: TRB 0000000039050e20 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.738308: xhci_handle_event: EVENT: TRB 0000000039050e30 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.740535: xhci_handle_event: EVENT: TRB 0000000039050e40 status 'Ring Overrun' len 0 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.740605: xhci_handle_event: EVENT: TRB 0000000039050e40 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.740715: xhci_handle_event: EVENT: TRB 0000000039050e50 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.740824: xhci_handle_event: EVENT: TRB 0000000039050e60 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.740933: xhci_handle_event: EVENT: TRB 0000000039050e70 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741041: xhci_handle_event: EVENT: TRB 0000000039050e80 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741149: xhci_handle_event: EVENT: TRB 0000000039050e90 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741257: xhci_handle_event: EVENT: TRB 0000000039050ea0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741365: xhci_handle_event: EVENT: TRB 0000000039050eb0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741473: xhci_handle_event: EVENT: TRB 0000000039050ec0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741580: xhci_handle_event: EVENT: TRB 0000000039050ed0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741688: xhci_handle_event: EVENT: TRB 0000000039050ee0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741795: xhci_handle_event: EVENT: TRB 0000000039050ef0 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.741902: xhci_handle_event: EVENT: TRB 0000000039050f00 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.742010: xhci_handle_event: EVENT: TRB 0000000039050f10 status 'Short Packet' len 180 slot 1 ep 3 type 'Transfer Event' flags e:c v4l2_cam-937 [000] dnh1 1769.742118: xhci_handle_event: EVENT: TRB 0000000000000000 status 'Event Ring Full Error' len 0 slot 0 ep 0 type 'Host Controller Event' flags e:c
ok... 未完待续...
转载地址:http://bscrj.baihongyu.com/