Showing results for 
Search instead for 
Did you mean: 

FATFS f_open fails when data cache is enabled

Associate II

When enabled Data cache for example in main:

/* Enable D-Cache---------------------------------------------------------*/

I think I am supposed to uncomment L63 in sd_diskio.c to activate Cache maintenance:

/* USER CODE BEGIN enableSDDmaCacheMaintenance */
/* USER CODE END enableSDDmaCacheMaintenance */

That way the following code is activated after reading from the SD card via DMA:

            the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
            adjust the address and the D-Cache size to invalidate accordingly.
            alignedAddr = (uint32_t)buff & ~0x1F;
            SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));

I found that through the FATFS my 32 Byte aligned buffer is not anymore aligned when it reaches that function in sd_diskio.c. Some Bytes will be probably used by the FATFS. Those leading bytes are overwritten by the Cache invalidate function.

Therefore f_open call is failing.

I could fix this behavior by adding the two lines:

alignedAddr = (uint32_t)buff & ~0x1F;
SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, ((uint32_t)buff - alignedAddr));

right before the DMA setup function in sd_diskio.c around L216:

                             (uint32_t) (sector),
                             count) == MSD_OK)

I did not check yet, maybe it needs to be added elsewhere.

Side note: I lately discoverd another problem with the same function see "Read From SD Card gets stuck in a While-Loop"


Doing a cache clean also cannot solve the problem. I explained it with an example in my other post down there.

The SCB_***() functions themselves can be called from multiple threads and interrupts without any problems. But, indeed, managing buffers properly is a task for a driver and/or higher level code.

By the way, the Rx code in the snippet up there does invalidation immediately after the Rx is started not waiting until it is completed.

I gave a link to a commit with critical changes for SCB_***Cache_by_Addr() functions in core_cm7.h file. Well... That's the file I meant.