2

I am using stm32f4. I have a hardfault error at sometimes, when I write new code in to the flash. So I check the Fault Registers like in below:

SerialPrint("Fault: %08x  %08x %08x\n",SCB->HFSR, SCB->CFSR, SCB->BFAR);

Output results:

SCB->HFSR = 0x40000000
SCB->CFSR = 0x00008200
SCB->BFAR = 0xb1584604

It seems to Bus Fault. And it's address 0xb1584604 . How can I find, which part in this address ? How can I find the error with this address ?

gogogo
  • 283
  • 1
  • 12
  • when you write to flash, you need to disable all interrupts and dma. The code that writes the flash must execute in ram. Otherwise you get a hard fault. – Kartman Nov 17 '21 at 09:14
  • I did this when I faced with this error, but it didnt work. I get hardfault again. I want to detect with BFAR register to find the error . – gogogo Nov 17 '21 at 09:55
  • BFAR gives me 0xb1584604 address but how can I use that to find error's cause – gogogo Nov 17 '21 at 09:55

1 Answers1

2

Your SCB->CFSR.BFARVALID bit is set, so that means SCB->BFAR does hold a 'real' value.
But in this case, 0xb1584604 is probably not a valid address for your device - there's nothing there for the core to read or write.
The other bit set in SCB->CFSR is LSPERR which indicates that "A bus fault occurred during floating-point lazy state preservation" - this to me hints that you might have stack corruption problems (but it is only a guess).
Do you know where your stack is, how large it is, and how much of it your code uses?

Take a look at your LR (Link Register) - you'll probably see a number there starting with 0xFFFFFFxx.
If the last digit is a 1 or a 9, then read the return stack pointer value from MSP, otherwise if it ends in a D, read the pointer from PSP.
Now compare that pointer value with the start & end addresses of your stack - is it lower than the end address, and safely higher than the start address?
Since you appear to have your micro's FPU (floating point unit) enabled (otherwise LSPERR wouldn't get set), you need to be sure that you have at least 104 bytes of free stack space to store both the core and FPU registers on the stack if an interrupt occurs or your code executes a call instruction.
Remember that the stack pointer starts off at the end address (the higher number) and 'grows' downwards towards the start address, so the difference between the start address and the MSP (or PSP) needs to be at least 104.
If you turn off the FPU, you need less stack space because an interrupt or call only pushes the core registers, which only takes 32 bytes.


Some additional reading material which might help:
- Segger AN00016 - Analyzing HardFaults on Cortex-M CPU
- Keil AN209 - Using Cortex-M3/M4/M7 Fault Exceptions
- How to debug a HardFault on an ARM Cortex-M MCU
- STM32 Cortex®-M4 MCUs and MPUs programming manual

brhans
  • 14,373
  • 3
  • 34
  • 49
  • A very valuable comment, I will think about it and provide feedback. Thank you for the explanation – gogogo Nov 17 '21 at 13:46