基于STM32F103的USB学习笔记38 - Mass Storage之SPI Flash做U盘

72 篇文章 36 订阅

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;
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值