Skip to main content
Associate II
September 30, 2023
Solved

STM32 F7: lock flash CR and avoid bus fault

  • September 30, 2023
  • 7 replies
  • 4388 views

Hi,

On a STM32 F7, I would like to lock access to the FLASH_CR by writing a wrong key to the FLASH_KEYR register. Writing a wrong key results in a bus fault (disabling the bus fault raises it to a hard fault).

Could someone help me with a way to write a wrong key to FLASH_KEYR and mask the bus fault? I do not want to mask all bus faults (just this once when writing the wrong key).

__set_FAULTMASK(1);
FLASH->KEYR = 0;
SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTPENDED_Msk;
__set_FAULTMASK(0);

This only works when stepping through a debugger but not in the regular cases.

Any suggestions would be greatly appreciated.
Thank you.

This topic has been closed for replies.
Best answer by waclawek.jan

Read out some FLASH register after you've written FLASH_KEYR and before reenabling the fault.

JW

7 replies

waclawek.jan
waclawek.janBest answer
Super User
September 30, 2023

Read out some FLASH register after you've written FLASH_KEYR and before reenabling the fault.

JW

LeeKAuthor
Associate II
October 1, 2023

Hi,

Did you mean something like this?

__set_FAULTMASK(1);
FLASH->KEYR = 0;
variable = FLASH->CR;
SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTPENDED_Msk;
__set_FAULTMASK(0);

Wondering how this disables the bus fault.

waclawek.jan
Super User
October 1, 2023

And does it?

JW

LeeKAuthor
Associate II
October 2, 2023

Nope. Still enters the bus fault handler.

Pavel A.
October 2, 2023

Need to mask (ignore) bus faults: the snippet below is for STM32H7 :

 

 

uint32_t mask = __get_FAULTMASK();
__disable_fault_irq();
SCB->CCR |= SCB_CCR_BFHFNMIGN_Msk;
__DSB();
/* do something */
__DSB();

if (SCB->SHCSR & SCB_SHCSR_BUSFAULTPENDED_Msk) {
 // oops it caused bus fault
 SCB->SHCSR &= ~SCB_SHCSR_BUSFAULTPENDED_Msk;
}

SCB->CCR &= ~SCB_CCR_BFHFNMIGN_Msk;
__set_FAULTMASK(mask);
__enable_fault_irq();

 

 

 

 

waclawek.jan
Super User
October 2, 2023

> Need to mask (ignore) bus faults:

That's what I assume __set_FAULTMASK() in the original snippet does. I have no idea what all those macros/functions you are using resolve into, but I tried to interpret the "works while single stepping" as "the usual timing stuff, fault from bus system reached via later than code clearing/reenabling fault executed.

There still may be hope in this hypothesis, maybe stuffing additional DSBs as in Pavel's code both before and after the lines writing to FLASH register (although I'd retain the readback, too).

JW

 

LeeKAuthor
Associate II
October 2, 2023

Apologize waclawek.jan
adding a FLASH register read (an extra ldr got added in assembly) actually solved the issue. I had some older debug code which was masking your solution.

I will try adding additional DSBs as you and Pavel suggested.