FatFS - 无法格式化驱动器,FR_MKFS_ABORTED
Posted
技术标签:
【中文标题】FatFS - 无法格式化驱动器,FR_MKFS_ABORTED【英文标题】:FatFS - Cannot format drive, FR_MKFS_ABORTED 【发布时间】:2021-05-26 00:22:24 【问题描述】:我是嵌入式开发的新手,我的任务是在 SPI 闪存上实现文件系统。我在 STM32CubeIDE 上使用 w25qxx 芯片和 STM32F4xx。我已经成功地为 w25 over SPI 创建了基本的 i/o,能够一次写入和读取扇区。
在我的 user_diskio.c 中,我已经实现了所有需要的 i/o 方法,并验证了它们已正确链接并被调用。
在我的 main.cpp 中,我使用f_mkfs()
格式化驱动器,然后获得可用空间,最后打开和关闭一个文件。但是,f_mkfs()
不断返回 FR_MKFS_ABORTED
。 (FF_MAX_SS 设置为 16384)
fresult = FR_NO_FILESYSTEM;
if (fresult == FR_NO_FILESYSTEM)
BYTE work[FF_MAX_SS]; // Formats the drive if it has yet to be formatted
fresult = f_mkfs("0:", FM_ANY, 0, work, sizeof work);
f_getfree("", &fre_clust, &pfs);
total = (uint32_t)((pfs->n_fatent - 2) * pfs->csize * 0.5);
free_space = (uint32_t)(fre_clust * pfs->csize * 0.5);
fresult = f_open(&fil, "file67.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
f_puts("This data is from the FILE1.txt. And it was written using ...f_puts... ", &fil);
fresult = f_close(&fil);
fresult = f_open(&fil, "file67.txt", FA_READ);
f_gets(buffer, f_size(&fil), &fil);
f_close(&fil);
在调查我的ff.c
后,代码似乎在第 5617 行停止:
if (fmt == FS_FAT12 && n_clst > MAX_FAT12) return FR_MKFS_ABORTED; /* Too many clusters for FAT12 */
n_clst
在某些条件逻辑之前的几行计算,在第 5594 行:
n_clst = (sz_vol - sz_rsv - sz_fat * n_fats - sz_dir) / pau;
这是调试器读取变量的内容:
这导致n_clst
被设置为4294935040
,因为它是无符号的,但如果变量是有符号的,则执行计算的实际结果将是-32256
。可以想象,这似乎不是一个准确的计算。
我使用的设备有 16M 位 (2MB) 的存储空间,分为 512 个 4kb 的扇区。最小可擦除块大小为 32kb。如果您需要有关我正在使用的闪存芯片的更多信息,page 5 of this pdf outlines all of the specs.
这就是我的USER_ioctl()
的样子:
DRESULT USER_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
/* USER CODE BEGIN IOCTL */
UINT* result = (UINT*)buff;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, GPIO_PIN_SET);
switch (cmd)
case GET_SECTOR_COUNT:
result[0] = 512; // Sector and block sizes of
return RES_OK;
case GET_SECTOR_SIZE:
result[0] = 4096;
return RES_OK;
case GET_BLOCK_SIZE:
result[0] = 32768;
return RES_OK;
return RES_ERROR;
/* USER CODE END IOCTL */
我尝试过使用 f_mkfs()
的参数,将 FM_ANY 换成 FM_FAT、FM_FAT32 和 FM_EXFAT(以及在我的 ffconf.h
中启用 exFat。我还尝试使用 au 的多个值而不是默认值. 对于我正在使用的f_mkfs()
方法的更深入的文档,check here,这种方法有一些变体。
【问题讨论】:
我使用 FatFS 来访问我通过 USB 提供的 SPI 闪存芯片。 Clifford 是对的,如果你只想要内部访问,其他文件系统会更好。 【参考方案1】:这里:
fresult = f_mkfs("0:", FM_ANY, 0, work, sizeof work);
第二个参数无效。它应该是指向 MKFS_PARM
结构的指针或默认选项为 NULL,如 http://elm-chan.org/fsw/ff/doc/mkfs.html 中所述。
你应该有类似的东西:
MKFS_PARM fmt_opt = FM_ANY, 0, 0, 0, 0;
fresult = f_mkfs("0:", &fmt_opt, 0, work, sizeof work);
除了您的媒体(SPI 闪存)不太可能使用默认选项 - 文件系统无法像 SD 卡那样从媒体获取格式化参数。您必须提供必要的格式信息。
鉴于您的擦除块大小,我猜:
MKFS_PARM fmt_opt = FM_ANY, 0, 32768, 0, 0;
但需要明确的是,我从未将 ELM FatFS(STM32Cube 包含的)与 SPI 闪存一起使用 - 可能还有其他问题。我也不使用 STM32CubeMX - 我可能认为该版本具有不同的接口,但我建议使用 ELM 的最新代码,而不是 ST 可能的僵化版本。
另一个考虑因素是,由于磨损均衡问题,FatFs 并不是特别适合您的媒体。此外,ELM FatFs 没有日志记录或检查/修复功能,因此不是断电安全的。这对于无法轻松备份或修复的不可移动媒体尤其重要。
您可能会考虑专门为 SPI NOR 闪存设计的文件系统,例如 SPIFFS,或电源故障安全 LittleFS。这是STM32中LittleFS的一个例子:https://uimeter.com/2018-04-12-Try-LittleFS-on-STM32-and-SPI-Flash/
【讨论】:
非常感谢您的帮助!我决定切换到 littleFS。至于方法中的 bad 参数,我认为您指的是 FatFS 的不同分布。我使用的是 STM32CubeIDE 自带的,并在链接中记录。 @JonathanJust - 同一个库不同版本;我正在使用一个更旧的版本,它完全没有 opt 参数。 LittleFS 的好决定。我通常会避免大多数 STM32Cube 废话。它是来自各种来源和质量参差不齐的文档记录不佳的零件的集合——最糟糕的是 ST 自己提供的零件。他们的 HAL 是一条因文档而变得更糟的狗。您可以编写自己的错误,不需要芯片供应商为您编写;-)以上是关于FatFS - 无法格式化驱动器,FR_MKFS_ABORTED的主要内容,如果未能解决你的问题,请参考以下文章
STM32之独立版USB(Host)驱动+MSC+Fatfs移植
STM32CubeMX学习笔记(27)——FatFs文件系统使用(操作SD卡)