C++ FatFS-无法格式化驱动器,FR_MKFS_已中止

C++ FatFS-无法格式化驱动器,FR_MKFS_已中止,c++,embedded,stm32,stm32f4,fatfs,C++,Embedded,Stm32,Stm32f4,Fatfs,我是嵌入式开发新手,一直负责在SPI闪存上实现文件系统。我在STM32CubeIDE上使用w25qxx芯片和STM32F4xx。我已经成功地为w25 over SPI创建了基本I/o,能够一次写入和读取扇区 在我的user_diskio.c中,我实现了所有需要的I/o方法,并验证了它们是否正确链接和被调用 在my main.cpp中,我使用f_mkfs()格式化驱动器,然后获得可用空间,最后打开并关闭一个文件。但是,f_mkfs()不断返回FR_mkfs\u ABORTED。(FF_MAX_SS

我是嵌入式开发新手,一直负责在SPI闪存上实现文件系统。我在STM32CubeIDE上使用w25qxx芯片和STM32F4xx。我已经成功地为w25 over SPI创建了基本I/o,能够一次写入和读取扇区

在我的user_diskio.c中,我实现了所有需要的I/o方法,并验证了它们是否正确链接和被调用

在my main.cpp中,我使用
f_mkfs()
格式化驱动器,然后获得可用空间,最后打开并关闭一个文件。但是,
f_mkfs()
不断返回
FR_mkfs\u ABORTED
。(FF_MAX_SS设置为16384)

在调查我的
ff.c
时,代码似乎停在第5617行:

if(fmt==FS_FAT12&&n_clst>MAX_FAT12)返回FR_MKFS_中止;/*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。如果你需要我使用的闪存芯片的更多信息

这就是我的
用户\u 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 out替换为FM_FAT、FM_FAT32和FM_EXFAT(同时在我的
ffconf.h
中启用EXFAT)。我还尝试过对au使用多个值,而不是默认值。有关
f_mkfs()的更深入文档
我正在使用的方法,这种方法有一些变化。

这里:

fresult = f_mkfs("0:", FM_ANY, 0, work, sizeof work);
第二个参数无效。它应该是指向
MKFS\u PARM
结构的指针,或者默认选项为NULL,如中所述

您应该有如下内容:

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 FATF(STM32Cube合并)与SPI闪存一起使用过-可能还有其他问题。我也没有使用STM32CubeMX-我认为该版本可能有不同的接口,但我建议使用ELM的最新代码,而不是ST可能的石化版本

另一个需要考虑的问题是,由于磨损均衡问题,FatFs并不特别适合您的介质。此外,ELM FatFs没有日志记录或检查/修复功能,因此不具备电源故障保护功能。这对于无法轻松备份或修复的不可移动介质尤为重要


你可以考虑一个专门为SPI和Flash设计的文件系统,例如电源故障。这里有一个在TM32中使用LITTLFS的例子:

我已经用FATFS访问了一个我在USB上可用的SPI闪存芯片。克利福德是正确的,如果你只想要内部访问,其他文件系统就更好了。非常感谢你的帮助!决定切换到littleFS。至于方法中的坏参数,我想您指的是另一个FATF发行版。我使用的是STM32CubeIDE,并记录在链接中。@JonathanJust-同一个库的不同版本;我使用的是一个更旧的版本,完全没有opt参数。这是一个很好的决定LittleFS。我通常会避免大部分STM32Cube的胡说八道。它是一个从各种来源和不同质量收集的记录不好的零件的集合-最糟糕的是由ST自己贡献的零件。他们的HAL是一只被文件弄得更糟的狗。你可以自己写错误,你不需要芯片供应商为你做;-)
 MKFS_PARM fmt_opt = {FM_ANY, 0, 32768, 0, 0};