BOT 命令块包CBW
CBW即Command Block Wrapper,命令块包)是从 USB 主机发送到设备的命令包,它由 31 个字节构成,其中包含的命令遵从接口描述表中的 bInterfaceSubClass 域所指定的命令集,一般采用 SCSI 传输命令集。 USB 设备从 CBW 中取出并执行相应命令,向主机传送指定数据及发出反映当前命令执行状态的 CSW ( Command Status Wrapper ,状态包),它由 13 个字节构成,主机根据 CSW 来判断此次操作是否正确,从而决定是继续传送数据还是进行数据传输的错误校验。事实上错误校验一直伴随着整个数据的处理过程中。
CBW 应该从数据包的边界开始,在正好传输了 31 个字节后作为短包结束。所有后续数据和 CSW 都应该从新数据包的边界开始, CBW 的说明如下表:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
struct CBW
{
DWORD dCBWSignature; //CBW的标识,固定值:43425355h (小端模式)。
DWORD dCBWTag; //主机发送的一个命令块标识,设备需要原样作为dCSWTag(CSW中的一部分)再发送给Host;主要用于关联CSW到对应的CBW。
DWORD dCBWDataTransferLength; //CBW命令要求在命令与回应之间传输的字节数。如果为0,则不传输数据。
BYTE bmCBWFlags; //反映数据传输的方向,0x00 表示来自Host,0x80 表示发至Host。
BYTE bCBWLUN; //对于有多个LUN逻辑单元的设备,用来选择具体目标。如果没有多个LUN,则写0。
BYTE bCBWCBLength; // 命令的长度,范围在0~16。
BYTE CBWCB[16]; //传输的具体命令
};
dCBWSignature :帮助指明该数据报为 CBW 的信号标记。这个字段的值为 0x43425355 (小端),表示这是一个 CBW 。
dCBWTag :主机发送的命令块标签。设备应在相关 CBW 的 dCSWTag 字段中将这个字段的内容返回给主机。 dCSWTag 将 CSW 与对应的 CBW 联系起来。
dCBWDataTransferLength :主机要求在执行 CBW 命令期间,在批量输入或批量输出端点传输数据字节数。如果该字段为 0 ,则设备和主机不应该在 CBW 和相关的 CSW 中间传输数据,设备应该忽略 bmCBWFlags 中方向位的值。注意,这个字段指明的是跟在 CBW 之后数据包的长度。
- bmCBWFlags :本字段的位定义如下:
- 位 7 :方向。 0 = 从主机到设备的 DataOut , 1 = 从设备到主机的 DataIn ;
- 位 6 :废弃的,主机应该将该位设置为 0 ;
- 位 5-0 :保留,主机应该将该位设置为 0 ;
bCBWLUN :命令块发送的设备逻辑单元号( LUN )。对于支持多个 LUN 的设备,主机应该将该字段设置为命令块寻址的 LUN 。否则应该设置为 0 。对于 U 盘主机系统来说,因为 U 盘都不支持多个 LUN ,因此该字段应该设置为 0 。
bCBWCBLength: 命令的长度,范围在0~16
CBWCB :设备将执行的命令块,对于 U 盘主机系统来说,就是将执行的 UFI 命令块。