2012-02-14 20:42:09 +01:00
|
|
|
/*
|
|
|
|
* cm3_fault_handlers.c
|
|
|
|
*
|
|
|
|
* Created on: Apr 24, 2011
|
|
|
|
* Author: msmith
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdint.h>
|
2013-04-16 22:03:08 +02:00
|
|
|
#include "inc/dcc_stdio.h"
|
2012-02-14 20:42:09 +01:00
|
|
|
#ifdef STM32F4XX
|
2013-04-16 22:03:08 +02:00
|
|
|
# include <stm32f4xx.h>
|
2012-02-14 20:42:09 +01:00
|
|
|
#endif
|
|
|
|
#ifdef STM32F2XX
|
2013-04-16 22:03:08 +02:00
|
|
|
# include <stm32f2xx.h>
|
2012-02-14 20:42:09 +01:00
|
|
|
#endif
|
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
#define FAULT_TRAMPOLINE(_vec) \
|
|
|
|
__attribute__((naked, no_instrument_function)) \
|
|
|
|
void \
|
|
|
|
_vec##_Handler(void) \
|
|
|
|
{ \
|
|
|
|
__asm(".syntax unified\n" \
|
|
|
|
"MOVS R0, #4 \n" \
|
|
|
|
"MOV R1, LR \n" \
|
|
|
|
"TST R0, R1 \n" \
|
|
|
|
"BEQ 1f \n" \
|
|
|
|
"MRS R0, PSP \n" \
|
|
|
|
"B " #_vec "_Handler2 \n" \
|
|
|
|
"1: \n" \
|
|
|
|
"MRS R0, MSP \n" \
|
|
|
|
"B " #_vec "_Handler2 \n" \
|
|
|
|
".syntax divided\n"); \
|
|
|
|
} \
|
|
|
|
struct hack
|
2012-02-14 20:42:09 +01:00
|
|
|
|
|
|
|
struct cm3_frame {
|
2013-05-19 16:37:30 +02:00
|
|
|
uint32_t r0;
|
|
|
|
uint32_t r1;
|
|
|
|
uint32_t r2;
|
|
|
|
uint32_t r3;
|
|
|
|
uint32_t r12;
|
|
|
|
uint32_t lr;
|
|
|
|
uint32_t pc;
|
|
|
|
uint32_t psr;
|
2012-02-14 20:42:09 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
FAULT_TRAMPOLINE(HardFault);
|
|
|
|
FAULT_TRAMPOLINE(BusFault);
|
|
|
|
FAULT_TRAMPOLINE(UsageFault);
|
|
|
|
|
|
|
|
/* this is a hackaround to avoid an issue where dereferencing SCB seems to result in bad codegen and a link error */
|
2013-05-19 16:37:30 +02:00
|
|
|
#define SCB_REG(_reg) (*(uint32_t *)&(SCB->_reg))
|
2012-02-14 20:42:09 +01:00
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
void HardFault_Handler2(struct cm3_frame *frame)
|
2012-02-14 20:42:09 +01:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
dbg_write_str("\nHARD FAULT");
|
|
|
|
dbg_write_hex32(frame->pc);
|
|
|
|
dbg_write_char('\n');
|
|
|
|
dbg_write_hex32(SCB_REG(HFSR));
|
|
|
|
dbg_write_char('\n');
|
|
|
|
for (;;) {
|
|
|
|
;
|
|
|
|
}
|
2012-02-14 20:42:09 +01:00
|
|
|
}
|
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
void BusFault_Handler2(struct cm3_frame *frame)
|
2012-02-14 20:42:09 +01:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
dbg_write_str("\nBUS FAULT");
|
|
|
|
dbg_write_hex32(frame->pc);
|
|
|
|
dbg_write_char('\n');
|
|
|
|
dbg_write_hex32(SCB_REG(CFSR));
|
|
|
|
dbg_write_char('\n');
|
|
|
|
dbg_write_hex32(SCB_REG(BFAR));
|
|
|
|
dbg_write_char('\n');
|
|
|
|
for (;;) {
|
|
|
|
;
|
|
|
|
}
|
2012-02-14 20:42:09 +01:00
|
|
|
}
|
|
|
|
|
2013-05-19 16:37:30 +02:00
|
|
|
void UsageFault_Handler2(struct cm3_frame *frame)
|
2012-02-14 20:42:09 +01:00
|
|
|
{
|
2013-05-19 16:37:30 +02:00
|
|
|
dbg_write_str("\nUSAGE FAULT");
|
|
|
|
dbg_write_hex32(frame->pc);
|
|
|
|
dbg_write_char('\n');
|
|
|
|
dbg_write_hex32(SCB_REG(CFSR));
|
|
|
|
dbg_write_char('\n');
|
|
|
|
for (;;) {
|
|
|
|
;
|
|
|
|
}
|
2012-02-14 20:42:09 +01:00
|
|
|
}
|