cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746 Startup-Problem with DCache - AN4667

michael2399
Associate II
Posted on December 16, 2016 at 11:08

Hello,

I have problems with a STM32F746 and DCache. Without DCache my software runs perfectly. If I enable the DCache (first invalidate it and the Enable), then I can't start the board.

I have check my source code, the document (Programmer Manual from STM32, the AN4839 [L1-Cache on STM32F7], the errata of Cortex M7 and STM32F746, but I have no idea.

After a power on, the processor runs in a hard fault. The IMPRECISERR in System Control - Bus Fault Status register and the AXIM-Bit in ABFSR (Auxiliary Bus Fault Status register) are set. The AXIM Type is 2.

If I understand this bits right then someone write (due to the IMPRECISERR) on wrong address via the AXIM-Bus. The AXIM-Slaves are the FLASH, SRAM, FMC and QUAD-SPI. I don't use FMC and Quad-SPI. FLASH is read only - therefor I suggest the problem is according to the SRAM. This can match to a problem with the DCache. (Incorrect invalidate?)

In the AN4667 (STM32F7 Series system architecture and performance) I found one sentence which I don't understand: Page 43 - last sentence (Chapter 4.2 Tips, last sentence).

'It is not recommended to enable the cache before calling the main function, that is, before the scatter load phase, because a hard fault may occur'.

What means this? Why a hard fault does occur? Is this a reason for my problem?

Best regards, Michael

#ada #stm32f7 #startup #dcache
11 REPLIES 11
Posted on December 21, 2016 at 13:28

Hello,

thanks a lot for helping. I found my mistake. The problem was in the Invalidate procedure of the cache. I had unroll the two loops (for ways and sets). If I use exactly the same routine like in core_cm7 then my ada project works fine.

sets = (uint32_t)(CCSIDR_SETS(ccsidr));
 do {
 ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
 do {
 SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
 ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
 #if defined ( __CC_ARM )
 __schedule_barrier();
 #endif
 } while (ways--);
 } while(sets--);
 __DSB();�?�?�?�?�?�?�?�?�?�?�?�?

The problem wasdefinitely my bad Invalidation of the Cache.

Only one think I don't understand: is there a timing issue or what could be the problem?

Best regards Michael

Posted on February 06, 2018 at 09:28

I know, there is later answer, but I had similar problem now.

I think, the cause of this issue is overwriting of local variables on the stack on background by L1 cache, while the loop is in progress. The same problem was in SCB_DisableDCache() function. This problem was already solved.

Update of core_cm7.h file from latest version of CMSIS (I think it is V5.2.0 now) is need.

The variables sets, ways, cssidr are declared with register keywords -> then they are not located in RAM and cache background processes has not impact on them. 

Unfortunately only SCB_DisableDCache() was fixed in CMSIS V5.2.0.

But, after adding the register keyword to variables in SCB_InvalidateDCache() function, it helps me.

for example:

    register uint32_t ccsidr;       

    register uint32_t sets;            

    register uint32_t ways;

    SCB->CSSELR = 0U; /*(0U << 1U) | 0U;*/  /* Level 1 data cache */

    __DSB();

    ccsidr = SCB->CCSIDR;

                                            /* invalidate D-Cache */

    sets = (uint32_t)(CCSIDR_SETS(ccsidr));

    do {

      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));

      do {

        SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |

                      ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk)  );

        &sharpif defined ( __CC_ARM )

          __schedule_barrier();

        &sharpendif

      } while (ways-- != 0U);

    } while(sets-- != 0U);