cancel
Showing results for 
Search instead for 
Did you mean: 

Can be SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr safely called when cache is disabled ?

Giacomo
Associate II

I'm working with an STM32H753II on an HMI application.

I use Keil IDE and middlewares to access filesystem data. So i end up using the SD card CMSIS driver developed by ARM Ltd.

With data and instruction cache disabled, i'm experiencing an IMPRECISERR bus fault reading from the SD card. The same software works without any issue with ICache and DCache enabled. Searching around for the cause, i see that the CMSIS driver (MCI_STM32H7xx.c) calls cache maintenance functions SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr without checking if cache is enabled.

SCB_CleanDCache_by_Addr ((uint32_t *)daddr, (int32_t)(block_count * block_size));

I modify the driver to call SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr only if cache enabled. Like this:

if ((SCB->CCR & SCB_CCR_DC_Msk) != 0U)
{ // If Data Cache is enabled
    SCB_CleanDCache_by_Addr ((uint32_t *)daddr, (int32_t)(block_count * block_size));
}

Other drivers also written by ARM Ltd., like USB Driver (USBH_H2_STM32H7xx.c), performs the same check before calling SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr.

With this modification all seems to work fine. No IMPRECISERR also with cache disabled. Now, looking around in Cortex-M7 User Guide and MCU documentation i can't find explicit statement that says SCB->DCCMVAC / SCB->DCIMVAC should not be written when DCache is disabled.

So reach my question: can be SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr safely called when cache is disabled ? If yes, the cause may be another ?

Thanks

2 REPLIES 2
Piranha
Chief II

My experience on F7 also shows that no, but I've not searched for a documentation on this. In my code I enclose cache management functions in a conditional macro and enable it on a project scope.

bb1
Associate III

Cleaning the cache when it's not enabled is OK. The problem is cleaning the cache if it was never initialized. The whole thing needs to be invalidated after reset before it you can safely enable it, clean it, or invalidate it by address.

Calling SCB_InvalidateDCache at startup will allow you to use any of the d-cache maintenance operations regardless of whether the d-cache is enabled. This isn't needed if you call SCB_EnableDCache as it includes invalidation.