cancel
Showing results for 
Search instead for 
Did you mean: 

With an optimization of debug or none I can compile and run my application but using anything O2 > causes a HardFault_Handler() trigger. What might cause this? using stm32h735

ulao
Associate III
 
6 REPLIES 6

Bad or poorly constructed code? Optimization tends to highlight latent issues.

Stack size? Alignment?

Clocks, Flash wait-states?

Perhaps have the Hard Fault Handler output some actionable data, the MCU provides a lot of detail, inspect it.

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

Check your variables used global and modified in IRQ is marked _IO or volatile.

PHolt.1
Senior II

It might be this

https://www.eevblog.com/forum/programming/gcc-arm32-compiler-too-clever-or-not-clever-enough/msg4373119/#msg4373119

-O2 or above replaces loops and such with library functions, and if you have not got these included then it will crash.

Otherwise, single stepping through the code, and using the stack trace, is the way.

ulao
Associate III

how can you capture this, the break point in the HardFault_Handler never hits and the compiler says No source available for "HardFault_Handler() at 0x800dd34"

also seem it occurs before I enter main. A breakpoint in main is never hit.

I guess because I'm debuging the release version?

I even added a trace on one of the GPIO pins to catch it on my scope. I put one at the beginning of the app and one in the main loop. Neither show up. Like the app crashes before it starts.

I am able to step thru the assembly but what would be a way to see the  (UFSR) - register.

 using the SFR I can see the UFSR register but it's null

Register:         CFSR_UFSR_BFSR_MMFSR

Address:         0xe000ed28

Value:            null

Size:            32

Reset value:         0x0

Reset mask:         0xFFFFFFFF

Access permission:   RW

Read action:      

ulao
Associate III

Ok here we go found the culprit. Sadly this is not my code ( new guy on the job ) but I know putting in this return prevents the fault

int Read_Flash32(uint32_t address)   //Reads 32 bits of data

{ return 0;

//   uint32_t temp1;

   uint32_t temp;

//   temp1 = (uint32_t *)address;

//   temp = &temp1;

   uint32_t *data;

   temp = 0;

   data = 0;

   *data = *(__IO uint32_t *)address;

   temp = *data;

.

.

.

}

So I really need to see my SCB registers for fault reason & location but in release mode I can not. Of course debug code has no fault. How can I do this?

interestingly if I put a trace in my code for some poormans debug I do see it but not if I put it in the Read_Flash32. It would seem the fault is generated by ASM and not by the running code. Putting the return in there seem to negate the fault maybe becase the ASM was not built.

ASM with return

080063a8 <Read_Flash32>:

 80063a8:   2000        movs   r0, #0

 80063aa:   4770        bx   lr

ASM with code that cause fault

080063a8 <Read_Flash32>:

 80063a8:   2300        movs   r3, #0

 80063aa:   6802        ldr   r2, [r0, #0]

 80063ac:   601b        str   r3, [r3, #0]

 80063ae:   deff        udf   #255   ; 0xff

ulao
Associate III

huh..

When the compiler analyzed the code, it saw that the pointer had been set to 0. Even though 0 is a reasonable value for our code, it is unlikely to be correct because reading location 0 is not that common.

So putting in the code to halt my program isn’t a bad choice, but the compiler should have generated a message, warning that I was dereferencing a null pointer.

so I can NOT set to 0 or use -fno-delete-null-pointer-checks

?