Skip to content

Instantly share code, notes, and snippets.

@doceme
Created July 24, 2015 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doceme/5c15b84a3e8fa9cf3fbf to your computer and use it in GitHub Desktop.
Save doceme/5c15b84a3e8fa9cf3fbf to your computer and use it in GitHub Desktop.
/*
* Fault handlers, stolen from FreeRTOS web (www.FreeRTOS.org)
*
* 2009-2010 Michal Demin
*
*/
#ifdef USE_HF_DEBUG
void HardFault_Handler(void) __attribute__ ((naked));
struct stack_t {
unsigned long r0;
unsigned long r1;
unsigned long r2;
unsigned long r3;
unsigned long r12;
unsigned long lr;
unsigned long pc;
unsigned long psr;
};
#define assert_break() do { __asm volatile("bkpt 0"); while(1); } while (0)
void assert_failed(unsigned char *function, unsigned int line)
{
(void)function;
(void)line;
assert_break();
}
static void fault_halt(unsigned long *hardfault_args)
{
//(void)stack;
volatile unsigned long stacked_r0;
volatile unsigned long stacked_r1;
volatile unsigned long stacked_r2;
volatile unsigned long stacked_r3;
volatile unsigned long stacked_r12;
volatile unsigned long stacked_lr;
volatile unsigned long stacked_pc;
volatile unsigned long stacked_psr;
volatile unsigned long _CFSR;
volatile unsigned long _HFSR;
volatile unsigned long _DFSR;
volatile unsigned long _AFSR;
volatile unsigned long _BFAR;
volatile unsigned long _MMAR;
stacked_r0 = ((unsigned long)hardfault_args[0]);
stacked_r1 = ((unsigned long)hardfault_args[1]);
stacked_r2 = ((unsigned long)hardfault_args[2]);
stacked_r3 = ((unsigned long)hardfault_args[3]);
stacked_r12 = ((unsigned long)hardfault_args[4]);
stacked_lr = ((unsigned long)hardfault_args[5]);
stacked_pc = ((unsigned long)hardfault_args[6]);
stacked_psr = ((unsigned long)hardfault_args[7]);
/* Configurable Fault Status Register */
/* Consists of MMSR, BFSR and UFSR */
_CFSR = (*((volatile unsigned long *)(0xE000ED28)));
/* Hard Fault Status Register */
_HFSR = (*((volatile unsigned long *)(0xE000ED2C)));
/* Debug Fault Status Register */
_DFSR = (*((volatile unsigned long *)(0xE000ED30)));
/* Auxiliary Fault Status Register */
_AFSR = (*((volatile unsigned long *)(0xE000ED3C)));
/* Read the Fault Address Registers. These may not contain valid values.
* Check BFARVALID/MMARVALID to see if they are valid values
* MemManage Fault Address Register
*/
_MMAR = (*((volatile unsigned long *)(0xE000ED34)));
/* Bus Fault Address Register */
_BFAR = (*((volatile unsigned long *)(0xE000ED38)));
/* suppress warnings about unused variables */
(void)stacked_r0;
(void)stacked_r1;
(void)stacked_r2;
(void)stacked_r3;
(void)stacked_r12;
(void)stacked_lr;
(void)stacked_pc;
(void)stacked_psr;
(void)_CFSR;
(void)_HFSR;
(void)_DFSR;
(void)_AFSR;
(void)_BFAR;
(void)_MMAR;
/* Inspect stack->pc to locate the offending instruction. */
assert_break();
}
void HardFault_Handler(void)
{
register unsigned long *stack_pointer asm("r0");
__asm volatile (
" movs r0,#4 \n" /* load bit mask into R0 */
" movs r1, lr \n" /* load link register into R1 */
" tst r0, r1 \n" /* compare with bitmask */
" beq _MSP \n" /* if bitmask is set: stack pointer is in PSP. Otherwise in MSP */
" mrs r0, psp \n" /* otherwise: stack pointer is in PSP */
" b _GetPC \n" /* go to part which loads the PC */
"_MSP: \n" /* stack pointer is in MSP register */
" mrs r0, msp \n" /* load stack pointer into R0 */
"_GetPC: \n" /* find out where the hard fault happened */
" ldr r1,[r0,#20] \n" /* load program counter into R1. R1 contains address of the next instruction where the hard fault happened */
);
fault_halt(stack_pointer);
assert_break();
}
#endif
@doceme
Copy link
Author

doceme commented Jul 24, 2015

Fault handling for Cortex-M0. Removed the branch to fault_halt inside the inline asm (and created an proper function call) so that GCC's linker won't complain. Without this, the compiler isn't smart enough when link time optimization (-flto) is enabled and compiling anything greater than -O0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment