cancel
Showing results for 
Search instead for 
Did you mean: 

FatFs unrealiable under high load on STM32H743

JP_ama
Associate III

Hello,

I am using a STM32H743 with a W25Q128 external flash memory running FreeRTOS and FatFs. USB is configured for mass storage, to copy files from a computer to the flash memory. The following function is used to list all the files and directories in a directory and put them in a list:

 

 

void IndexFilesInDir(const char *path, SFileMgrList* psReturnList)
{
    FRESULT res;
    DIR dir;
    FILINFO fno;
    uint8_t u8Count = 0;

    res = f_opendir(&dir, path); /* Open the directory */
    if(strlen(path) != 0)
    {
    	strcpy(&psReturnList->cFilename[0][0], "...");
    	psReturnList->bIsDir[0] = true;
    	psReturnList->bHasParentDirectory = true;
    	u8Count++;
    }
    else
    {
    	psReturnList->bHasParentDirectory = false;
    }
    if (res == FR_OK) {
        for (;;) {
            res = f_readdir(&dir, &fno);                   /* Read a directory item */
            if (res != FR_OK || fno.fname[0] == 0 || u8Count >= 128) break;  /* Error or end of dir */
               	if (fno.fattrib & AM_DIR && strstr(fno.fname, "System Volume Information") == NULL)
               	{
               		psReturnList->bIsDir[u8Count] = true;
               		strcpy(&psReturnList->cFilename[u8Count][0], fno.fname);
                   	u8Count++;
               	}
               	else
               	{
               		char *dot = strrchr(fno.fname, '.');
               		// Is this a .wav file?
               		if (dot != NULL && strcmp(dot, ".wav") == 0)
               		{
               			psReturnList->bIsDir[u8Count] = false;
               			strcpy(&psReturnList->cFilename[u8Count][0], fno.fname);
               			u8Count++;
               		}
               	}
        }
        psReturnList->endIndex = u8Count;
        f_closedir(&dir);
    } else {
        printf("Failed to open \"%s\". (%u)\n", path, res);
    }
}

 

 

This is based on the example from the FatFs website. Everything works fine until I start processing some audio data (= lots of SAI DMA interrupts). Then f_readdir returns random garbage or does not all the files or it lists files from another directory from time to time. Here's what I've tried and observed:

- Disabling the caches doesn't solve or change the problem.

- Reading and writing files via USB always works perfectly fine, even under high load conditions. I conclude from this that my low level SPI driver for the W25Q128 works fine.

- FatFs is only used in one Task.

- The microcontroller is not overloaded, other RTOS Tasks still work fine. Temporarily removing all the other tasks does not help or change anything.

 

Does anyone have any idea what could be causing this behavior?

Thanks!

22 REPLIES 22
JP_ama
Associate III

So I tried something else. I went back to my previous Nucleo board with the STM32F439. The code is the same, just with shorter filter lengths because the F4 is obviously not as powerful as an H7. And the F4 doesn't show this weird behavior at all, even at much higher processor loads. The only thing I noticed was that on the F4 it won't list more than eight files in a directory with very high loads (>90%) at 96k. But never random stuff or nameless directories that don't exist. Which already happens at 48k with the H7 (with longer filters but less cpu load though).

JP_ama
Associate III

Alright, so I have finally found the time to continue work on this project and did some further testing. To verify the low level Disk IO driver is working properly I added some additional testing:

1.) Preload the relevant sectors containing the FAT tables at the beginning of the program and copy them into some section of RAM (guaranteed correct data, identified by sector number)

2.) Start the signal processing

3.) Whenever FatFs is calling the ReadSector() function, compare the sector data that is being read with the preloaded sectors stored in RAM

 

Note: File contents are never changed during runtime, it's read-only. Unfortunately, it has turned out that the correct reading of these sectors occasionally fails. So, some of you guys were right, it's actually not a FatFs problem. However, I don't understand why the SPI communication is unstable under high load. I dumped the data when the data read did not match the data stored in RAM, and it showed that sometimes sections of a sector were missing, sections were repeated, etc. This explains the random garbage output when listing files.

My idea now would be to perhaps rewrite the SPI Flash driver using DMA. Or does anyone have a different suggestion? I still don't understand why and how the data corruption is happening. The timings of the W25Qxx flash are not critical and should not have any problems with interruptions and waiting times.

 

Thanks!

Update: The problem was solved by implementing large data transfer via DMA when reading a sector.