FatFS - 无法格式化驱动器,FR_MKFS_ABORTED

问题描述 投票:0回答:3

我正在使用 w25qxx 芯片和 STM32CubeIDE 上的 STM32F4xx 在 SPI 闪存上实现文件系统。我已经通过 SPI 成功创建了 w25 的基本 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;

这是调试器读取变量的内容:

enter image description here

这会导致

n_clst
设置为
4294935040
,因为它是无符号的,但如果变量带符号,则计算的实际结果将是
-32256
。你可以想象,这似乎不是一个准确的计算。

我使用的设备具有 16M 位 (2MB) 的存储空间,分为 512 个大小为 4kb 的扇区。最小可擦除块大小为 32kb。如果您需要有关我正在使用的闪存芯片的更多信息,本 pdf 第 5 页概述了所有规格。

这就是我的

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()
方法的更深入的文档,检查此处,该方法有一些变体。

c++ embedded stm32 stm32f4 fatfs
3个回答
4
投票

这里:

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/


0
投票

好吧,我认为真正的问题是 IOCTL 调用 GET_BLOCK_SIZE 来获取块大小返回的是扇区大小而不是块中的扇区数。 对于 SPI Flash,通常为 1。


0
投票

我正在写类似的笔记。 我正在使用 w25qxx 芯片(具有 Winbond 25Q32JVSIQ)和 STM32CubeIDE 上的 STM32U0xx MCU 在 SPI 闪存上实现文件系统。

你能帮我完成第一步吗?

到目前为止,我已经做了这些事情:

  1. 我已经从 http://elm-chan.org/fsw/ff/arc/ff15.zip
  2. 下载了 FatFs 模块 (ff15.zip)
  3. 并将内容提取到 STM32CubeIDE 项目可访问的位置。
  4. 将必要的源文件(ff.c、ffsystem.c、ffunicode.c、diskio.c、ff.h、ffconf.h、diskio.h)从 FatFs 源文件夹(ff15/source)复制到 STM32CubeIDE 项目目录中.

你能帮我下一步做什么吗?我想,我需要修改 ffconf.h 文件并设置低级磁盘 I/O 功能。

© www.soinside.com 2019 - 2024. All rights reserved.