Showing results for 
Search instead for 
Did you mean: 

STM32F4: FAT on NVM memory

Pilous Droip


I have 2 disks.

  1. disk is SD card with FAT. Here is all working
  2. disk is NVM N25Q256A. Here I have problems.

For NVM memory I set sector to 4096 with page 256 bytes. This memory has erase sector 4kB. Datasheet of this memory I attached. And my problem is with FAT on NVM by spi.

I can create file, I can delete file, I can list files on NVM. But when I try modify file of read file, procesor stop.

And now I'm thinking of a badly formatted NVM.

retSD = f_mount((FATFS*) &FFS_DEV_FatFS[FFS_DEV_NVM], "/NVM", 1);
        if (retSD == FR_NO_FILESYSTEM) {
                FRESULT res;
                MKFS_PARM opt;
                memset((void*) &opt, 0, sizeof(opt));
                opt.fmt = FM_FAT; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
                opt.n_fat = 1; /* Number of FATs */
                opt.align = 0; /* Data area alignment (sector) */
                opt.n_root = 0; /* Number of root directory entries */
                opt.au_size = 4096; /* Cluster size (byte) */
                res = f_mkfs("/NVM", &opt, nvm_mkfs_work, sizeof nvm_mkfs_work);  // BYTE nvm_mkfs_work[8*FF_MAX_SS];
                if (FR_OK != res) {
                    Error("ERROR %d - FAIL.", res);
                } else {
                    Info("NVM-FS formatted OK.");

Is this formatting OK?

Here is log of actual settings for formated disc.

log: FFS MOUNT: ret=0 for '/NVM', type=1
log: NVM: FFS: n_rootdir=512, csize=8, ssize=8, last_clst=0, free_clst=0, n_fatent=501, fsize=2, volbase=63, fatbase=64, dirbase=66, database=98

And my other test function (for work with NVM):

  1. create file. Creating a clean text file is a success. But appending text to an existing file failed.
void CreateFiles(void) {
    FRESULT fr;
    FIL fil;
    Info("Create or append file: %s", "/NVM/test.txt");
    /* Open or create a log file and ready to append */
    fr = open_append(&fil,  "/NVM/test.txt");
    if (fr != FR_OK)
    RTC_Time_t _time;
    /* Append a line */
    Info("Print data to file: %02u/%02u/%u, %2u:%02u",, _time.month, _time.year, _time.hours, _time.minutes);
    f_printf(&fil, "%02u/%02u/%u, %2u:%02u\n",, _time.month, _time.year, _time.hours, _time.minutes);
    /* Close the file */
FRESULT open_append(
        FIL *fp, /* [OUT] File object to create */
        const char *path /* [IN]  File name to be opened */
) {
    FRESULT fr;
    fr = f_open(fp, path, FA_WRITE | FA_OPEN_ALWAYS);
    if (fr == FR_OK) {
        fr = f_lseek(fp, f_size(fp));
        if (fr != FR_OK)
    return fr;
  1. Read from file. When I changed path to sd card, everything working. From NVM fail.
void ReadFile(void) {
    FRESULT fr;
    char readBuf[256];
    FIL stream;
    char *pLine;
    Info("Read file: %s", "/NVM/test.txt");
    /* Open a text file */
    fr = f_open(&stream, "/NVM/test.txt", FA_READ);
    if (fr)
    pLine = f_gets(readBuf, 8, &stream);  // for tests, read only  8 bytes
    Debug("%s", readBuf);
    /* Close the file */
  1. Delete file
void DeleteFile(void) {
    FRESULT fr;
    Info("Delete file: %s", "/NVM/test.txt");
    fr = f_unlink("/NVM/test.txt");
    if (fr) {
        Error("Failed to delete file. fr=%u", fr);
    } else {
        Info("The file have successfully been deleted.");


Are you talking about elm-chan's FatFs? Then you should perhaps go and read its documentation. I don't use it, but to me, this appears to be a good starting point for your problem.


Pilous Droip

I have been reading the documentation for 3 days. But now I don't know where to look. :relieved_face:

Validate the DISKIO layer throughly, debugging via the top level is a waste of time if the the low-level fails to perform it's basic job requirements.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Well, I gave you a link above...

If you intend to use both SD card and the sFLASH, you'll need to set both those parameters to 512 and 4096, and as written there, implement GET_SECTOR_SIZE command in disk_ioctl().

And as Clive said, verify, what happens at the device level. That's usual debugging: place strategical breakpoints and observe data going in and out; checking the actual content of the target memory at strategic moments.


Pilous Droip

Now I find out that the diskio will be OK. Because read and write works. Using debug, I found an error in the RTOS stack setup. Ie. now i will try to dedicate to the RTOS page.

If I find a bug, I will try to describe it.