cancel
Showing results for 
Search instead for 
Did you mean: 

Fault handler, stack frame

britboy787
Associate II

Hi.

I am trying to test out a fault handler for our STM32G (right now, the fault handler just tries to determine the location of the code that caused the fault).

If I force a fault (divide by zero) in "normal" non-interrupt handler code, I can easily read the stack frame, find the PC and determine the location of the fault (stack frame is located in the process stack).

If I force a fault in an interrupt handler (USART1, using HAL code), the stack frame on the main stack does not make sense to me (what I think the PC is, does not point to a location in flash memory). If I add 0x50 to the address in the MSP, then I can see a stack frame with the correct PC.

Is there a section in PM0214 that can explain what I'm seeing?

I attached a few screenshots from the debugger in STM32CubeIDE that show the call stack and memory.

In my example, the MSP in the fault handler points to 0x2001fde8, and the LR is 0xfffffff1.  The stack frame I'm expecting to see is at 0x2001fe38.

Thank you!

 

1 ACCEPTED SOLUTION

Accepted Solutions
waclawek.jan
Super User

Do you know if there's a way to tell the compiler to not modify the stack?

If "compiler" is gcc, there's the "naked" attribute; but then you are not really supposed to write C code in that function.

And YMMV, but it may be simpler to write true asm in a separate source, rather than inline asm within C source.

JW

View solution in original post

5 REPLIES 5
waclawek.jan
Super User

Your attachments are not visible due to a problem with the forum.

Meantime, you may perhaps try to post textual version of the call stack/memory/registers content.

JW

britboy787
Associate II

Thank you for taking a look at this.

I think I know what's going on that's causing the discrepancy.

I took a look at the assembly listing for the hard fault handler (written in C) and the initial instructions for the handler modify the main stack:

void HardFault_Handler(void)
{
 8001c54:	b580      	push	{r7, lr}
 8001c56:	b086      	sub	sp, #24
 8001c58:	af00      	add	r7, sp, #0
  /* USER CODE BEGIN HardFault_IRQn 0 */

By the time the code I wrote gets executed, the MSP doesn't point to the stack frame that I care about.

Do you know if there's a way to tell the compiler to not modify the stack?  Should I just write the handler in assembly?

The handler works fine when the frame is on the process stack.

Thanks!

waclawek.jan
Super User

Do you know if there's a way to tell the compiler to not modify the stack?

If "compiler" is gcc, there's the "naked" attribute; but then you are not really supposed to write C code in that function.

And YMMV, but it may be simpler to write true asm in a separate source, rather than inline asm within C source.

JW

britboy787
Associate II

Thank you.

I used the naked attribute with inline assembly to save the stack pointer and call a function which inspects the stack frame.  Everything appears to be working now.

 

Thank you for the help!

Hello @britboy787 

If @waclawek.jan answred your question please accept it as solution. 

Thank you

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.