基于STM32F103的USB学习笔记33 - Mass Storage之BOT

本文深入解析了Bulk Only Transport(BOT)协议的工作原理,包括其关键组件CBW(Command Block Wrapper)和CSW(Command Status Wrapper)的结构与功能。阐述了USB主机与设备间数据传输的流程,以及如何通过EP1和EP2端点实现数据、命令和状态的传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BOT是Bulk Only Transport的缩写。数据、命令、状态都通过Bulk端点传输(没有使用到中断、控制端点),这里用到的是EP1和EP2,2个端点都是Bulk的模式,这就是所谓的Bulk Only,即在EP1和EP2上传输的数据再包一层协议。

命令/数据/状态的协议如下图所示:

【CBW】

CBW是Command Block Wrapper的缩写。USB主机通过OUT端点发送CBW包,这样设备才知道接下来需要接收什么样数据还是发送对应的数据。一个CBW包结构如下图所示:

dCBWSignature: 固定为43425355h(小端),表示这段数据是CBW。

dCBWTag:  HOST发送的命令标记。设备在CSW.dCSWTag返回这个值,表示当前CSW是响应对应的CBW。

dCBWDataTransferLength: 主机期望的数据长度(Data-Out或Data-In过程中的数据长度)。如果为0,则没有Data过程。

bmCBWFlags: 

        Bit 7:数据方向,0表示Data Out,HOST到设备;1表示Data In,设备到HOST。

        Bit6: 不再使用(Obsolete). HOST设置为0.

        Bit5-0: 预留位,HOST设置为0

bCBWLUN: HOST告知设备该CBW是给哪个LUN的。如果设备不支持LUN,这个值为0.

bCBWCBLength: CBWCB的有效长度。有效值1到16,其他值无效。

CBWCB: 设备执行的命令块。设备应该可以解释这个数据区域的第bCBWCBLength个字节,这个字节由bInterfaceSubClass指定的类决定它的含义。如果设备支持的命令集使用长度小于16(10h)字节的命令块,则应首先传输有效字节,从偏移量15(Fh)处的字节开始。设备应该忽略CBWCB中偏移地址(15 + bCBWCBLength - 1)的内容。

typedef struct _Bulk_Only_CBW
{
  uint32_t dSignature;
  uint32_t dTag;
  uint32_t dDataLength;
  uint8_t  bmFlags;
  uint8_t  bLUN;
  uint8_t  bCBLength;
  uint8_t  CB[16];
}stBulkOnlyCBW;

【CSW】

CSW是Command Status Wrapper的缩写。一个CSW包结构如下图所示:

dCSWSignature: 固定为53425355h(小端),表示这段数据是CSW。

dCSWTag: 与dCBWTag相等,用于关联CSW到对应的CBW。

dCSWDataResidue: 对于DATA OUT,设备告知HOST处理的实际数据量;对于DATA IN,设备告知HOST实际发送的数据。DCSWDataRemain不得超过dCBWDataTransferLength中发送的值。

bCSWStatus: bCSWStatus表示命令是否成功。

描述
00h命令成功
01h命令失败
02h相位错误
03h和04h不再使用
05h到FFh预留

1. 端点函数

void EP1_IN_Callback(void)
{
    mscBotIn();
}

void EP2_OUT_Callback(void)
{
    mscBotOut();
}

2. mscBotOut

首先从OUT端点的Buffer中读入HOST发送过来的数据。

gMscBotData.len = USB_SIL_Read(USB_MSC_EP_OUT, gMscBotData.dat);

EP OUT数据主要分2种情况:

    switch(gMscBotState)
    {
        case MSC_BOT_IDLE:
            break;
        case MSC_BOT_DATA_OUT:
            break;
        default:
            break;
    }

如果当前状态是IDLE,则读入的数据是CBW,CBW解析依据SCSI的命令。

如果状态是DATA OUT,则表明是数据。

3. mscBotIn

IN数据的含义分3种情况:MSC_BOT_CSW_Send是指已经发送完CSW,MSC_BOT_ERROR是指BOT传输出错了,这2个状态都是将状态设置为IDLE,并且OUT端点设置为可接收;MSC_BOT_DATA_IN是HOST读入数据,只需要支持SCI命令SCSI_READ10;BOT_DATA_IN_LAST表示数据已经完全读入。

void mscBotIn(void)
{
    switch(gMscBotState)
    {
        case MSC_BOT_CSW_Send:
        case MSC_BOT_ERROR:
            break;
        case MSC_BOT_DATA_IN:
            break;
        case MSC_BOT_DATA_IN_LAST:
            break;
        default:
            break;
    }
}

4. HOST开始是发送CBW到设备,此时gMscBotState的状态应该是MSC_BOT_IDLE,

void mscBotOut(void)
{
    gMscBotData.len = USB_SIL_Read(USB_MSC_EP_OUT, gMscBotData.dat);
    switch(gMscBotState)
    {
        case MSC_BOT_IDLE:
            mscBotCBWDecode();
            break;
        case MSC_BOT_DATA_OUT:
            break;
        default:
            break;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值