cancel
Showing results for 
Search instead for 
Did you mean: 

How to get the value of the program counter ?

PierreG-S
Associate II

Hello,

 

Sometimes I have my stm32F7 going in hardfault_handler, so for my customers I have to display on a screen the last address where the software crashed, then I can analyse which problem occure the crash. So I want to get the value "pc" (program counter) like I can see in the Fault Analyzer of stm32cubeide.

 

I tried many supossed solutions :

__attribute__ ((__noinline__)) void *get_pc()
{
   return __builtin_return_address(0);
}

 or

static __inline__ void *get_pc(void)
{
   void *pc;
   asm("mov %0, pc" : "=r"(pc));
   return pc;
}

but it only return the value of the current function called, and not the same value as in the Fault Analyzer of stm32cubeide.

 

Is there a solution ?

 

Thank you

1 ACCEPTED SOLUTION

Accepted Solutions
PierreG-S
Associate II

Ok for those who are intersted by a solution, I found what I wanted : get the program counter before the hardfault_handler, the same value as showed in the Fault Analyzer of stm32cubeide. I am worrking on a stm32f7 for information.

 

Here is the code in the function HardFault_Handler() :

// Put this struct in your ".h"  
typedef struct
{
    uint32_t r0;
    uint32_t r1;
    uint32_t r2;
    uint32_t r3;
    uint32_t r12;
    uint32_t lr;
    uint32_t pc;
    uint32_t psr;
} ExceptionStackFrame;

void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

	uint32_t current_psp = __get_PSP();
	ExceptionStackFrame *hardfault_stack_frame = (ExceptionStackFrame *)(current_psp);
	uint32_t pc_value_at_fault = hardfault_stack_frame->pc;							  

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

View solution in original post

2 REPLIES 2

The PC value you are looking for is at the stack, so trick is to determine address of stack at fault handler entry, without C having disturbed that already.

@Tesla DeLorean  published this - note that despite Keil in its name there's a section telling how to do this using gcc, too.

JW

PierreG-S
Associate II

Ok for those who are intersted by a solution, I found what I wanted : get the program counter before the hardfault_handler, the same value as showed in the Fault Analyzer of stm32cubeide. I am worrking on a stm32f7 for information.

 

Here is the code in the function HardFault_Handler() :

// Put this struct in your ".h"  
typedef struct
{
    uint32_t r0;
    uint32_t r1;
    uint32_t r2;
    uint32_t r3;
    uint32_t r12;
    uint32_t lr;
    uint32_t pc;
    uint32_t psr;
} ExceptionStackFrame;

void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

	uint32_t current_psp = __get_PSP();
	ExceptionStackFrame *hardfault_stack_frame = (ExceptionStackFrame *)(current_psp);
	uint32_t pc_value_at_fault = hardfault_stack_frame->pc;							  

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}