二:MSC的基本内容
简单来说,MSC(Mass Storage Class,即USB大容量存储设备类)是一个让USB设备能够与计算机等主机设备标准化地传输文件的通用协议。
它的核心思想,就是让一个复杂的USB设备,在主机(比如你的电脑)看来,就像一个可以直接读写的简单“移动硬盘”。这样,你就能通过“拖放”文件的方式,轻松地在设备和电脑之间交换数据了
二:MSC的工作原理
MSC协议的工作原理:一个精密的“三阶段”流程
MSC协议的核心是Bulk-Only Transport (BOT) 传输协议,它将一次完整的读写操作分解为清晰的三步:
命令传输:主机(如电脑)将想要执行的操作(比如“读取数据”)打包成一个“命令块”(Command Block Wrapper,CBW),发送给USB设备。
数据传输:根据命令的要求,数据开始在主机和设备之间流动。如果是“读取”命令,数据就从设备传向主机;如果是“写入”命令,则方向相反。
状态传输:操作完成后,设备会发回一个“状态包”(Command Status Wrapper,CSW),告诉主机刚才的命令执行成功了,还是出错了。
这个过程中,设备通过一对专门用于大量数据传输的“批量端点”(Bulk Endpoints)来高效地完成数据交换。
三:软件代码如下所示:
3.1 检测外部的存储芯片是否可以正常挂载
BOOL flash_check()
{
BYTE dat1;
BYTE dat2;
BYTE dat3;
if (!fFlashOK)
{
SPISS = 0;
shift(SFC_RDJID);
dat1 = shift(0x00);
dat2 = shift(0x00);
dat3 = shift(0x00);
SPISS = 1;
//C8 40 13 (GD25Q40)
//EF 30 13 (W25X40)
//EF 40 13 (W25Q40)
if (((dat1 == 0xef) && (dat2 == 0x30)) ||
((dat1 == 0xef) && (dat2 == 0x40)) ||
((dat1 == 0xc8) && (dat2 == 0x40)))
{
if (dat3 == 0x11)
dwMemorySize = 128*1024; //GD25Q10/W25X10
else if (dat3 == 0x12)
dwMemorySize = 256*1024; //GD25Q20/W25X20
else if (dat3 == 0x13)
dwMemorySize = 512*1024; //GD25Q40/W25X40
else if (dat3 == 0x14)
dwMemorySize = 1024*1024; //GD25Q80/W25X80
else if (dat3 == 0x18)
dwMemorySize = 16384*1024; //GD25Q128/W25X128
wSectorSize = 4*1024;
dwSectorNumber = dwMemorySize / wSectorSize;
fFlashOK = 1;
}
else
{
dwMemorySize = 0;
wSectorSize = 0;
dwSectorNumber = 0;
}
}
return fFlashOK;
}3.2 读取固定扇区的大小
void flash_readsector(DWORD addr, BYTE *pdat)
{
WORD size;
if (!flash_check()) return;
while (flash_isbusy());
SPISS = 0;
shift(SFC_READ);
shift((BYTE)(addr >> 16));
shift((BYTE)(addr >> 8));
shift((BYTE)(addr));
for (size = wSectorSize; size; size--)
{
*pdat++ = shift(0);
}
SPISS = 1;
}3.3 写入固定扇区的大小
void flash_writesector(DWORD addr, BYTE *pdat)
{
WORD size;
if (!flash_check()) return;
flash_write_enable();
SPISS = 0;
shift(SFC_SECTORER);
shift((BYTE)(addr >> 16));
shift((BYTE)(addr >> 8));
shift((BYTE)(addr));
SPISS = 1;
size = wSectorSize;
while (size)
{
flash_write_enable();
SPISS = 0;
shift(SFC_PAGEPROG);
shift((BYTE)(addr >> 16));
shift((BYTE)(addr >> 8));
shift((BYTE)(addr));
while (size--)
{
shift(*pdat++);
addr++;
if ((BYTE)(addr) == 0x00)
break;
}
SPISS = 1;
}
}
我要赚赏金
