Showing results for 
Search instead for 
Did you mean: 

D-cache invalidation call causes Hard Fault (D-cache is disabled)

Associate II

Hi. I'm using an STM32H7, and I have the d-cache DISABLED in cubemx, but __DCACHE_PRESENT seems to always be set to 1 by stm32h755xx.h, anyway, and as a result, I'm getting a hardfault when X-CUBE-AZRTOS-H7 ethernet init calls SCB_CleanDCache_by_Addr().

If I just modify the code to set __DCACHE_PRESENT to 0, everything works fine.

Why is this definition being set even though I have the d cache disabled? Do I still have to worry about the cachability settings in the MPU even when the dcache is disabled, and could that be the problem that I just have something configured there wrong?

Either way, I shouldn't need to clean the dcache when it's disabled, right? So why is the auto-generated code even wasting its time doing that?

In the azure rtos port, we have:

#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
    SCB_CleanDCache_by_Addr((uint32_t*)(pktIdx -> nx_packet_data_start), pktIdx -> nx_packet_data_end - pktIdx -> nx_packet_data_start);

Should it instead be checking to see if it's ENABLED instead of present?

Pavel A.
Evangelist III

Somebody on this forum wrote that hard fault in SCB_CleanDCache when DCache is not enabled occurs because of a bug in ARM CMSIS header files, and it has been fixed in more recent CMSIS version.

So the solution may look as updating the CMSIS bundled with ST library... but the release notes of the latter say that the library depends on specific CMSIS version and warns against updating it separately.

As a conservative workaround you can check if Dcache is enabled before calling SCB_Clean/Invalidate.

​(yes, __DCACHE_PRESENT means that Dcache is present on the MCU and can be enabled).

> In the azure rtos port, we have: .....

IMHO direct calls to SCB cache APIs there should be wrapped in inlines or macros, to adapt to change of CMSIS implementation sourced from ARM.

>​(yes, __DCACHE_PRESENT means that Dcache is present on the MCU and can be enabled).

Well then that doesn't exactly seem like the proper criteria to call SCB_CleanDCache_by_Addr, does it?

No it is not. But, if __DCACHE_PRESENT is false (undefined), all the SCB_ cache APIs are no-op. Call them or not, they do nothing.

Yeah. So it now reads:

#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
		if (SCB->CCR & SCB_CCR_DC_Msk)
			SCB_CleanDCache_by_Addr((uint32_t*)(pktIdx->nx_packet_data_start), pktIdx->nx_packet_data_end - pktIdx->nx_packet_data_start);

And all is well.

The DCache being disabled seems more concerning, as if they disable it to mask some other latent coherency issues that haven't been addressed properly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

How do you mean? I have it disabled because I'm doing a lot of interprocessor communication with huge blocks of data and simply didn't want to deal with it and I simply don't need the performance boost from it.