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

Just curious, what's your _SYNC_t?

JP_ama
Associate III

@AScha.3 

So I integrated the latest version of FatFs into my project. Not only did that not solve the problem, it actually made it worse. Reading directory contents now fails more frequently.

@David Littell

_SYNC_t is osSemaphoreId_t

However, it doesn't make any difference whether FS_REENTRANT is enabled or disabled and according to the FatFs website reentrancy should be irrelevant in my case anyways because I am using only one volume (http://elm-chan.org/fsw/ff/doc/config.html#fs_reentrant). But I've tested both, without success.

>it actually made it worse

What a pity. I use it , because the filex i had to use on new H563 with Azure Rots made only problems.

Fatfs running fine . here. 

i dont know...but you said: Reading and writing files via USB always works perfectly fine. - so here you dont use fatfs ? because if fatfs here no problem, then the reason is not fatfs at all.

If you feel a post has answered your question, please click "Accept as Solution".

@AScha.3 

No, I don't use FatFs with the USB Mass Storage Class because there is no need or reason to do so. The USB Mass Storage Class only uses my SPI driver read/write/erase functions for the W25Q128. Works great, that's why I suspected FatFs is the problem in the first place. FatFs diskio is using the exact same read/write/erase functions in my driver.

Are there multiple tasks at different priorities that can make FatFS calls?  In any case I'd suggest that the semaphore should be replaced with a priority-inversion-safe mutex.  The semantics of the synchronization object imply that a mutex should have been used in the first place, not a semaphore.

sorry, not clear to me : on USB -> device -> write to W25Q128 ?

and on the W25Q128 write by spi - ok. no filesystem needed - right?

what is the fatfs then doing?

If you feel a post has answered your question, please click "Accept as Solution".

@David Littell 

No, it's only one task and the only thing this task does is occasionally list the files in a directory.

Thanks!

@AScha.3 

The USB Mass Storage is used to transfer filter files from a computer to the flash memory. No FatFs, just direct access via SPI driver. FatFs is used by the firmware on the STM32 to list the available files and to load them. While an actual file is loaded, SAI DMA is stopped, so that works without any issues. But listing files and scrolling through directories has to be available during audio processing. It is important to note, that USB and FatFs are never accessing the W25Q128 at the same time.

ah, ok, maybe i understand now.

but how you sync the accesses ? in some way, you have two fatfs systems running, a: on pc, b: on stm-cpu, but how the stm -fatfs knows, that all files are closed and fat tables are valid now? and how it knows, it should do a cold start, because something in the files/fat/data is changed now ?

If you feel a post has answered your question, please click "Accept as Solution".

@AScha.3 

Firmware detects if a USB cable is plugged in. As long as this is the case, the file manager task is suspended. File list gets updated every time you navigate into a different directory.

But in any case, the USB part is irrelevant for this issue. During all my tests there was no USB connection. Completely removing all USB related code does not change anything. USB is only used to transfer filter files to flash memory. After this is done once and there is some content on the flash memory, all USB related code is not needed and can be removed for testing.

My point why I brought this up was to illustrate that the low level SPI driver works reliably. It constantly gets interrupted during larger file transfers (read and write) but this does not create any issues at all. So I was just thinking why would the W25Q128 SPI driver be the issue when all I do is quickly list the files in a directory. This is a lot less data, no write access at all, very simple.