Hard Fault calling SCB_DisableDCache() or SCB_CleanDCache()
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-03 6:56 AM
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:
- This routine is called just once in the main program after peripheral initialization (inside a more complex wrapping function)
- Cache memories are enabled in the main (as usual)
- 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
- Labels:
-
U-Boot
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-08 6:29 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 6:30 AM - edited ‎2024-07-22 6:31 AM
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
