1. 将整个Flash作为U盘的空间
Flash大小为4MB,SPI NorFlash的Sector大小为4KB,所以MSC_MEMORY_BLOCK_SIZE设置为4096.。
3个函数的实现如下,这里写Memory时没有按Flash的Page编程方式,而是每64字节写一次,测试是正常可以读写的,不建议实际应用中这样处理,可能会出问题。
void massFormat(uint8_t lun)
{
sflashErase(SFLASH_START_ADDR, SFLASH_SIZE / 4096);
}
void massWriteMemory(uint8_t lun)
{
uint32_t count;
count = (gScsiInfo.length > gMscBotData.len) ? gMscBotData.len : gScsiInfo.length;
if(((SFLASH_START_ADDR + gScsiInfo.offset) % 4096) == 0)
sflashErase(SFLASH_START_ADDR + gScsiInfo.offset, 1);
sflashWrite(SFLASH_START_ADDR + gScsiInfo.offset, gMscBotData.dat, count);
gScsiInfo.offset += count;
gScsiInfo.length -= count;
gMscCSW.dDataResidue -= count;
if(gScsiInfo.length == 0 || gMscBotState == MSC_BOT_CSW_Send)
{
mscBotSendCSW(MSC_BOT_CSW_CMD_PASSED);
}
}
void massReadMemory(uint8_t lun)
{
uint32_t count;
uint8_t pBuf[BULK_MAX_PACKET_SIZE];
count = (gScsiInfo.length > BULK_MAX_PACKET_SIZE) ? BULK_MAX_PACKET_SIZE : gScsiInfo.length;
sflashRead(SFLASH_START_ADDR + gScsiInfo.offset, pBuf, count);
usbWriteBuf(EP_MSC_IN, pBuf, count);
gScsiInfo.offset += count;
gScsiInfo.length -= count;
gMscCSW.dDataResidue -= count;
if(gScsiInfo.length == 0)
{
gMscBotState = MSC_BOT_DATA_IN_LAST;
}
}
格式化后查看DBR,依然使用FAT12,Reserved sectors只需要1个,扇区大小为4096,总扇区数为1024,正好大小为4MB。
2. 将Flash空间作为一个文件。
为了节约RAM,FAT扇区大小仍然取最小值512字节,而MSC_MEMORY_BLOCK_SIZE需要和扇区大小一致。
为了减少簇数,簇的大小选择64KB,即DBR中修改如下:
64 * 1024 / FAT_SECTOR_SIZE, //the sector size of cluster - 0x000d
FAT表的数据如下:
0xf8, 0xff, 0xff,
0x03, 0x40, 0x00, 0x05, 0x60, 0x00, 0x07, 0x80, 0x00, 0x09, 0xa0, 0x00,
0x0b, 0xc0, 0x00, 0x0d, 0xe0, 0x00, 0x0f, 0x00, 0x01, 0x11, 0x20, 0x01,
0x13, 0x40, 0x01, 0x15, 0x60, 0x01, 0x17, 0x80, 0x01, 0x19, 0xa0, 0x01,
0x1b, 0xc0, 0x01, 0x1d, 0xe0, 0x01, 0x1f, 0x00, 0x02, 0x21, 0x20, 0x02,
0x23, 0x40, 0x02, 0x25, 0x60, 0x02, 0x27, 0x80, 0x02, 0x29, 0xa0, 0x02,
0x2b, 0xc0, 0x02, 0x2d, 0xe0, 0x02, 0x2f, 0x00, 0x03, 0x31, 0x20, 0x03,
0x33, 0x40, 0x03, 0x35, 0x60, 0x03, 0x37, 0x80, 0x03, 0x39, 0xa0, 0x03,
0x3b, 0xc0, 0x03, 0x3d, 0xe0, 0x03, 0x3f, 0x00, 0x04, 0x41, 0xf0, 0xff,
massWriteMemory中修改写文件的部分,当地址对齐NorFlash的扇区地址时需要擦除整个Sector(因为这里是把整个Flash作为文件,所以不需要考虑多擦除的情况)
if(gScsiInfo.offset >= (FAT_RESERVE_SIZE + ROOT_SIZE + FAT_SIZE * 2) * FAT_SECTOR_SIZE)
{//SFALSH Area
offset = gScsiInfo.offset - (FAT_RESERVE_SIZE + ROOT_SIZE + FAT_SIZE * 2) * FAT_SECTOR_SIZE;
if((offset % 4096) == 0)
{
sflashErase(offset, 1);
}
sflashWrite(offset, gMscBotData.dat, count);
}
massReadMemory也只需要改读文件部分
if(gScsiInfo.offset >= (FAT_RESERVE_SIZE + FAT_SIZE * 2 + ROOT_SIZE) * FAT_SECTOR_SIZE)
{//SFLASH Area
offset = gScsiInfo.offset - (FAT_RESERVE_SIZE + FAT_SIZE * 2 + ROOT_SIZE) * FAT_SECTOR_SIZE;
sflashRead(offset, buf, count);
pBuf = (uint8_t *)buf;
offset = 0;
}