Skip to main content
iTTy
Associate III
July 3, 2024
Question

Hard Fault calling SCB_DisableDCache() or SCB_CleanDCache()

  • July 3, 2024
  • 2 replies
  • 1969 views

Hi there.

As usual, I'm there with a new issue... :grinning_face_with_sweat:

Developing a custom Bootloader, I'm trying to disable both Instruction and Data chaches.

As I read on the ST AN4839, before deactivating the DCache, I would also Clean it.

No problem with the Icache, but I'm experiencing Hard Fault adding Dcache cleaning and/or disabling.

void DoJump2App(u32t uiAPPaddress)
{
	/*.-.-.| Local Varibles |.-.-.*/

	/*.-.-.| Execution |.-.-.*/
	SCB_DisableICache();
	SCB_CleanDCache();
	SCB_DisableDCache();
	
	uiResetKey = RESET_DRV_BTL_KEY;							// Clear RESET key
	pJump2App = (pFunction)(*(volatile u32t*)(uiAPPaddress + 4));

	__set_MSP(*(volatile u32t*)uiAPPaddress);				// Initialize user application's Stack Pointer
	__ISB();												// Instruction Synchronization Barrier
	pJump2App();
}

Above the example of the routine I'm testing.

To be noticed that:

  1. This routine is called just once in the main program after peripheral initialization (inside a more complex wrapping function)
  2. Cache memories are enabled in the main (as usual)
  3. If I move SCB_DisableDCache() and/or SCB_CleanDCache() functions call directly in the main program, prior this function, there is no problem...

What I'm mistaking?

Context: I'm working on a custom board quipped with an STM32H755BIT MCU, using CubeIDE 1.13.2, CubeMX6.9.2 and Firmware package STM32Cube FW_H7 V1.11.0

Thanks in advance for your support!

iTTy

 

 

This topic has been closed for replies.

2 replies

ST Employee
July 8, 2024

Hello @iTTy ,

You can try to add some memory barrier and instruction barrier instructions here is an example form which you can inspire:

void DoJump2App(uint32_t uiAPPaddress)
{
 /*.-.-.| Local Variables |.-.-.*/
 typedef void (*pFunction)(void);
 pFunction pJump2App;

 /*.-.-.| Execution |.-.-.*/
 __disable_irq(); // Disable interrupts

 // Disable ICache
 SCB_DisableICache();

 // Clean and disable DCache
 SCB_CleanDCache();
 __DSB(); // Data Synchronization Barrier
 SCB_DisableDCache();
 __DSB(); // Data Synchronization Barrier
 __ISB(); // Instruction Synchronization Barrier

 // Clear RESET key
 uiResetKey = RESET_DRV_BTL_KEY;

 // Set the jump address
 pJump2App = (pFunction)(*(volatile uint32_t*)(uiAPPaddress + 4));

 // Initialize user application's Stack Pointer
 __set_MSP(*(volatile uint32_t*)uiAPPaddress);

 // Instruction Synchronization Barrier
 __ISB();

 // Jump to application
 pJump2App();
}

 check also this article for tips on Hardfault debugging.
Regards

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
iTTy
iTTyAuthor
Associate III
July 22, 2024

Hi @STea ,

thanks for your reply and for the interesting article you linked: I will study it better in next days!

Actually I didn't test your proposal because I moved misleading instruction in another place for "architectural" reasons...
I suppose, it will be anyway better to "bound" such instructions with synchronization boundaries as you proposed to improve the software reliability.

Anyway, for my understanding, what is the best practice/rationale to apply these boundaries? Where and when I should remember to apply them?

Thank you again,

iTTy