材料
- W25QXX驱动参考:https://github.com/iammingge/Driver_W25Qxx.git
- FATFS文件系统下载地址:https://github.com/abbrev/fatfs.git
- 基于上述两个库和合宙csdk构建fatfs文件系统📎usr_fatsfs_w25Q128_test.rar
工程目录
![](https://img-blog.csdnimg.cn/img_convert/96dc749b7ca17a39ea037211318dddf8.png)
- W25Qxx驱动(W25Qxx.c、W25Qxx.h)
- fatfs库(diskio.c、diskio.h、ff.c、ff.h、ffconf.h、ffsystem.c、ffunicode.c)
- 中间调用 (usr_lib_fatfs.c、usr_lib_fatfs.h)
- 测试应用(example_main.c)
如何适配具体芯片
- 在usr_lib_fatfs.c,在spi_delay_ms、spi_readWrite、spi_cs_h、spi_cs_l、spi_init这几个函数中添加具体的操作函数,根据具体芯片确定
- 在diskio.c中的disk_status、disk_read、disk_write、disk_ioctl这几个函数中添加具体W25Qxx的操作函数
DSTATUS disk_status (BYTE pdrv) {
DSTATUS status = STA_NOINIT; // 设备状态
switch(pdrv)
{
case DISK_SPI:
if(W25Qxx_ID_Manufacturer(&testdev) == sFLASH_ID)
{
status = 0; // 设备ID读取成功
}
else
{
status = STA_NOINIT; // 设备ID读取失败
}
break;
default:
status = STA_NOINIT;
}
return status;
}
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count) {
DRESULT status = RES_PARERR;
switch(pdrv)
{
case DISK_SPI:
for(;count>0;count--)
{
W25Qxx_Read(&testdev, buff, sector*FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE, &err);
if (err != W25Qxx_ERR_NONE){
status = RES_ERROR;
return status;
}
sector++;
buff+=FLASH_SECTOR_SIZE;
}
status = RES_OK;
break;
default:
status = RES_PARERR;
}
return status;
}
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count) {
DRESULT status = RES_PARERR;
switch(pdrv)
{
case DISK_SPI:
for(;count>0;count--){
W25Qxx_Program(&testdev, (uint8_t *)buff, sector*FLASH_SECTOR_SIZE, FLASH_SECTOR_SIZE, &err);
if (err != W25Qxx_ERR_NONE){
status = RES_ERROR;
return status;
}
sector++;
buff+=FLASH_SECTOR_SIZE;
}
status = RES_OK;
break;
default:
status = RES_PARERR;
}
return status;
}
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff) {
DRESULT status = RES_PARERR;
switch (pdrv)
{
case DISK_SPI:
switch(cmd)
{
case CTRL_SYNC:
status = RES_OK;
break;
/* 扇区数量:6MB*1024*1024/4096=1536 */
case GET_SECTOR_COUNT:
*(DWORD *)buff = FLASH_SECTOR_COUNT;
break;
/* 扇区大小 */
case GET_SECTOR_SIZE:
*(WORD *) buff = FLASH_SECTOR_SIZE;
break;
/* 擦除的扇区个数 */
case GET_BLOCK_SIZE:
*(DWORD *)buff = FLASH_BLOCK_SIZE;
break;
case CTRL_TRIM:
status = RES_OK;
break;
}
status = RES_OK;
break;
default:
status = RES_PARERR;
}
return status;
}
DWORD get_fattime (void) {
}
应用
#include "usr_lib_fatfs.h"
luat_rtos_task_handle fatfs_task_handle;
FATFS fs; // FATFS文件系统结构体对象
FIL fnew; // FIL文件结构体对象
FRESULT res_flash; // 文件操作结果结构体对象
UINT fnum; // 文件读写数量
BYTE ReadBuffer[1024] = {0}; // 读缓冲区
BYTE WriteBuffer[] = "FATFS测试"; // 写缓冲区
static void task_test_fatfs(void *param)
{
w25qxx_init();
res_flash = f_mount(&fs, "1:", 1); // 挂载时会对SPI设备初始化
LUAT_DEBUG_PRINT("res_flash %d\r\n", res_flash);
if (res_flash == FR_NO_FILESYSTEM) // 判断是否有文件系统,没有则格式化并创建
{
LUAT_DEBUG_PRINT("没有检测到文件系统...开始进行格式化...\r\n");
res_flash = f_mkfs("1:", 1, 0, 4096);
LUAT_DEBUG_PRINT("res_flash %d\r\n", res_flash);
if (res_flash == FR_OK) // 格式化成功
{
LUAT_DEBUG_PRINT("已成功格式化\r\n");
res_flash = f_mount(NULL, "1:", 1); // 格式化后先取消挂载
res_flash = f_mount(&fs, "1:", 1); // 重新挂载
LUAT_DEBUG_PRINT("res_flash %d\r\n", res_flash);
}
else
{
LUAT_DEBUG_PRINT("格式化失败\r\n");
}
}
else if (res_flash != FR_OK)
{
LUAT_DEBUG_PRINT("FatFS文件系统挂载失败(%d)\r\n", res_flash);
}
else
{
LUAT_DEBUG_PRINT("FatFS文件系统挂载成功,可以开始读写测试。\r\n");
usr_get_fatfs_free("1:");
usr_get_fatfs_list_files("1:");
}
res_flash = f_open(&fnew, "1:/FatFS读写测试文件.txt", FA_CREATE_NEW | FA_WRITE | FA_READ);
LUAT_DEBUG_PRINT("res_flash %d\r\n", res_flash);
if (res_flash == FR_OK)
{
LUAT_DEBUG_PRINT("打开/创建 FatFS读写测试文件.txt 成功。\r\n\r\n");
res_flash = f_write(&fnew, WriteBuffer, sizeof(WriteBuffer), &fnum); // 将写缓冲区内容写入到文件内
if (res_flash == FR_OK)
{
LUAT_DEBUG_PRINT("写入的字节数据大小:%d\n", fnum);
LUAT_DEBUG_PRINT("写入的内容为:%s\r\n\r\n", WriteBuffer);
}
else
{
LUAT_DEBUG_PRINT("写入失败(%d)\n", res_flash);
}
}
else
{
LUAT_DEBUG_PRINT("打开/创建文件失败!!!\r\n");
}
f_close(&fnew);
while (1)
{
luat_rtos_task_sleep(1000);
}
}
static void task_demo_fatfs(void)
{
luat_rtos_task_create(&fatfs_task_handle, 4096, 20, "fatfs", task_test_fatfs, NULL, NULL);
}
INIT_TASK_EXPORT(task_demo_fatfs, "1");