本文主要介绍了如何基于TinyUSB库实现用片外Flash作为介质的U盘读写

1. 部分接口函数的修改

在官方example的源码基础上,修改成访问外部Flash只需要修改以下几个回调函数的内容:

  • tud_msc_capacity_cb 获取磁盘块大小和数量回调,决定了PC端显示U盘的存储空间
  • tud_msc_read10_cb 读数回调,PC端读取文件的处理
  • tud_msc_write10_cb 写数据回调,PC端写入文件处理

1.1 磁盘的大小块信息如下(GD25Q127):

1
2
3
4
5
6
7
8
9
10
enum { // 16M
DISK_BLOCK_NUM = 4096,
DISK_BLOCK_SIZE = 4096
};

void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size) {
(void) lun;
*block_count = DISK_BLOCK_NUM; // 4096
*block_size = DISK_BLOCK_SIZE; // 4096
}

此外,tusb_config中需要修改一下MSC缓冲区大小

1
2
3
4
...
// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_EP_BUFSIZE 4096
...

EP Buffer 设置程4096的原因是外部Flash最小支持扇区擦除,一个扇区为4096个字节

1.2 读写数据接口

读写接口需要调用SPI-Flash驱动接口对片外Flash进行读写,这部分的实现可以参照《[[片外Flash驱动程序]]》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize) {
(void) lun;
// out of ramdisk
if ( lba >= DISK_BLOCK_NUM ) return -1;
spi_flash_read(buffer, (uint32_t)(lba << 12) + offset, bufsize);
return bufsize;
}

int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize) {
(void) lun;
// out of range
if ( lba >= DISK_BLOCK_NUM ) return -1;
spi_flash_sector_erase((lba << 12));
spi_flash_write(buffer, (lba << 12) + offset, bufsize);
return bufsize;
}

2. 实现效果