FreeRTOS+FAT + USB Mass Storage Device Class

Hello, I have project which implements FreeRTOS+FAT and USB Host configured as MSC Class. The goal is to transfer files from PC to devboard’s FAT inside RAM. The problems is, when I am creating or updating existing files from PC I see that correct data are transfered to RAM but FAT itself won’t notice those changes, for example upon opening modified file or creating new one invoking fffopen will return NULL or will show old file size. After some code scavenging I found that this is happening due to page buffering/caching. I’ve managed to solve this problem by setting IOMANAGERCACHESIZE to minimal value (2). This seemed to resolve problem but I am not sure if it’s correct way to disable/limit? buffering or is this only working by accident. Could you confirm this or propose different workaround ? Thanks in advance Mateusz

FreeRTOS+FAT + USB Mass Storage Device Class

Does this help? https://www.freertos.org/FreeRTOS-Plus/FreeRTOSPlusFAT/EmbeddedFileSystemConfiguration.html#ffconfigCACHEWRITE_THROUGH

FreeRTOS+FAT + USB Mass Storage Device Class

Hi Mateusz, does your embedded device also make changes to the same FAT partition? The two ways of access are really incompatible, both the PC and the embedded device have a FAT driver, and both have low-level access. And even if +FAT has read-only access, the partition might not always be stable. USB has low-level SCSI access to the partition. At certain moments (during updates), the drive will contain incomplete or inconsistent information. Normally, a FAT driver will lock a directory and it will lock the File Allocation Table. But in your situation, these locks are useless. Can’t you unmount the drive as long as USB is active, and remount it as soon as USB disconnects? Using 2 cache buffers would be very inefficient when using an SD-card. Your partition is stored in RAM, so you will notice less that there is extra copying.

FreeRTOS+FAT + USB Mass Storage Device Class

Hi Hein, Thank you for response. I am familiar with what you wrote. Basically I am looking for a way to sync/update +FAT after host/PC actions. I developed system such way that there is no concurrent access to device’s FAT. Is there any way to request +FAT synchronization(refetch/flush cache buffers ?). I am thinking that I could send such request after USB write etc. That way I could configure +FAT to use more cache buffers I am afraid that unmounting/mounting +FAT is not possible as user will have to unplug device after each file update etc. Temporarily I am using ramdisk but in future application will use eMMC which is practically the SD card so as you said, using 2 cache buffers will be inefficient. Richard I’ve already set ffconfigCACHEWRITETHROUGH to 1 but it didn’t help 🙁 Any ideas ?

FreeRTOS+FAT + USB Mass Storage Device Class

If you can avoid that the two drivers work simultaneously on the same partition, there might be a way. I suppose that you’ve seen where +FAT flushes the cache:
FF_Error_t FF_FlushCache( FF_IOManager_t *pxIOManager );
Here below is a sketch for a function that will invalidate all buffers: ~~~ FFErrort FFInvalidateCache( FFIOManagert *pxIOManager ) { BaseTypet xIndex; FFErrort xError;
if( pxIOManager == NULL )
{
    xError = FF_ERR_NULL_POINTER | FF_FLUSHCACHE;
}
else
{
    xError = FF_ERR_NONE;

    FF_PendSemaphore( pxIOManager->pvSemaphore );
    {
        for( xIndex = 0; xIndex < pxIOManager->usCacheSize; xIndex++ )
        {
            /* If a buffers has no users and if it has been modified... */
            if( ( pxIOManager->pxBuffers[ xIndex ].usNumHandles != 0 ) ||
                ( pxIOManager->pxBuffers[ xIndex ].bModified == pdTRUE ) )
            {
                /* Can not flush all caches. */
                xError++;
            }
            else
            {
                /* Mark the buffer as invalid so that it won't be used again. */
                pxIOManager->pxBuffers[ xIndex ].bValid = pdFALSE;
            }
        }
    }

    FF_ReleaseSemaphore( pxIOManager->pvSemaphore );
}

/* Function successful if it returns 0. */
return xError;
} /* FF_FlushCache() */ /*———————————————————–*/ ~~~ Now before USB becomes active, you can call both functions: ~~~ FFFlushCache( pxIOManager ); if( FFInvalidateCache( pxIOManager ) != 0 ) { /* Not all buffers could be invalidated. */ } ~~~ Note that there is more caching: ~~~

define ffconfigHASH_CACHE 1 /* Enable HASH to speed up file creation. */

define ffconfigPATH_CACHE 1 /* Enables a simply Path Caching mechanism

                          * that increases performance of repeated
                          * operations. */
~~~ You could try to switch them off, in case they’re enabled. Hein

FreeRTOS+FAT + USB Mass Storage Device Class

Hein, Small update, I’ve managed to solve this issue using snippet that you uploaded 🙂 I would like to thank you very much for help. As always your responses are 100% valid and quick as possible 🙂 Best regards Mateusz

FreeRTOS+FAT + USB Mass Storage Device Class

Good to hear, thanks. Now you can use a normal cache size again to make it run more efficiently. I think that 4 KB ( 8 sectors ) is a good size. Regards, Hein