cancel
Showing results for 
Search instead for 
Did you mean: 

FATFS f_open fails when data cache is enabled

SPfis.1
Associate II

When enabled Data cache for example in main:

/* Enable D-Cache---------------------------------------------------------*/
  SCB_EnableDCache();

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

/* USER CODE BEGIN enableSDDmaCacheMaintenance */
#define ENABLE_SD_DMA_CACHE_MAINTENANCE  1 
/* USER CODE END enableSDDmaCacheMaintenance */

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

#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
            /*
            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:

if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
                             (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"

11 REPLIES 11

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.

https://github.com/STMicroelectronics/STM32CubeF7/blob/f8bda023e34ce9935cb4efb9d1c299860137b6f3/Drivers/CMSIS/Core/Include/core_cm7.h#L5