|
|
|
@ -36,7 +36,53 @@ |
|
|
|
|
#include "stm32f1xx_it.h" |
|
|
|
|
|
|
|
|
|
/* USER CODE BEGIN 0 */ |
|
|
|
|
|
|
|
|
|
#include "utils/debug.h" |
|
|
|
|
/**
|
|
|
|
|
* Hard Fault diagnosis function (for use with debugger) |
|
|
|
|
* |
|
|
|
|
* Source: |
|
|
|
|
* http://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
|
|
|
|
|
*/ |
|
|
|
|
static void __attribute__((noreturn)) __attribute__((used)) |
|
|
|
|
prvGetRegistersFromStack(uint32_t *pulFaultStackAddress) |
|
|
|
|
{ |
|
|
|
|
/* These are volatile to try and prevent the compiler/linker optimising them
|
|
|
|
|
away as the variables never actually get used. If the debugger won't show the |
|
|
|
|
values of the variables, make them global my moving their declaration outside |
|
|
|
|
of this function. */ |
|
|
|
|
volatile __attribute__((unused)) uint32_t r0; |
|
|
|
|
volatile __attribute__((unused)) uint32_t r1; |
|
|
|
|
volatile __attribute__((unused)) uint32_t r2; |
|
|
|
|
volatile __attribute__((unused)) uint32_t r3; |
|
|
|
|
volatile __attribute__((unused)) uint32_t r12; |
|
|
|
|
volatile __attribute__((unused)) uint32_t lr; /* Link register. */ |
|
|
|
|
volatile __attribute__((unused)) uint32_t pc; /* Program counter. */ |
|
|
|
|
volatile __attribute__((unused)) uint32_t psr;/* Program status register. */ |
|
|
|
|
|
|
|
|
|
r0 = pulFaultStackAddress[ 0 ]; |
|
|
|
|
r1 = pulFaultStackAddress[ 1 ]; |
|
|
|
|
r2 = pulFaultStackAddress[ 2 ]; |
|
|
|
|
r3 = pulFaultStackAddress[ 3 ]; |
|
|
|
|
|
|
|
|
|
r12 = pulFaultStackAddress[ 4 ]; |
|
|
|
|
lr = pulFaultStackAddress[ 5 ]; |
|
|
|
|
pc = pulFaultStackAddress[ 6 ]; |
|
|
|
|
psr = pulFaultStackAddress[ 7 ]; |
|
|
|
|
|
|
|
|
|
error("Hard fault."); |
|
|
|
|
|
|
|
|
|
dbg("r0 = 0x%08"PRIu32, r0); |
|
|
|
|
dbg("r1 = 0x%08"PRIu32, r1); |
|
|
|
|
dbg("r2 = 0x%08"PRIu32, r2); |
|
|
|
|
dbg("r3 = 0x%08"PRIu32, r3); |
|
|
|
|
dbg("r12 = 0x%08"PRIu32, r12); |
|
|
|
|
dbg("LR = 0x%08"PRIu32, lr); |
|
|
|
|
dbg("PC = 0x%08"PRIu32, pc); |
|
|
|
|
dbg("PSR = 0x%08"PRIu32, psr); |
|
|
|
|
|
|
|
|
|
/* When the following line is hit, the variables contain the register values. */ |
|
|
|
|
for (;;); |
|
|
|
|
} |
|
|
|
|
/* USER CODE END 0 */ |
|
|
|
|
|
|
|
|
|
/* External variables --------------------------------------------------------*/ |
|
|
|
@ -65,6 +111,20 @@ void HardFault_Handler(void) |
|
|
|
|
{ |
|
|
|
|
/* USER CODE BEGIN HardFault_IRQn 0 */ |
|
|
|
|
|
|
|
|
|
// Branch to HF reporting routine
|
|
|
|
|
|
|
|
|
|
__asm volatile ( |
|
|
|
|
" tst lr, #4 \n" |
|
|
|
|
" ite eq \n" |
|
|
|
|
" mrseq r0, msp \n" |
|
|
|
|
" mrsne r0, psp \n" |
|
|
|
|
" ldr r1, [r0, #24] \n" |
|
|
|
|
" ldr r2, =prvGetRegistersFromStack \n" |
|
|
|
|
" bx r2 \n" |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// NOTE: Dead code follows
|
|
|
|
|
|
|
|
|
|
/* USER CODE END HardFault_IRQn 0 */ |
|
|
|
|
while (1) |
|
|
|
|
{ |
|
|
|
@ -80,7 +140,7 @@ void HardFault_Handler(void) |
|
|
|
|
void MemManage_Handler(void) |
|
|
|
|
{ |
|
|
|
|
/* USER CODE BEGIN MemoryManagement_IRQn 0 */ |
|
|
|
|
|
|
|
|
|
error("Memory management fault."); |
|
|
|
|
/* USER CODE END MemoryManagement_IRQn 0 */ |
|
|
|
|
while (1) |
|
|
|
|
{ |
|
|
|
@ -96,7 +156,7 @@ void MemManage_Handler(void) |
|
|
|
|
void BusFault_Handler(void) |
|
|
|
|
{ |
|
|
|
|
/* USER CODE BEGIN BusFault_IRQn 0 */ |
|
|
|
|
|
|
|
|
|
error("Prefetch fault."); |
|
|
|
|
/* USER CODE END BusFault_IRQn 0 */ |
|
|
|
|
while (1) |
|
|
|
|
{ |
|
|
|
@ -112,7 +172,7 @@ void BusFault_Handler(void) |
|
|
|
|
void UsageFault_Handler(void) |
|
|
|
|
{ |
|
|
|
|
/* USER CODE BEGIN UsageFault_IRQn 0 */ |
|
|
|
|
|
|
|
|
|
error("Usage fault."); |
|
|
|
|
/* USER CODE END UsageFault_IRQn 0 */ |
|
|
|
|
while (1) |
|
|
|
|
{ |
|
|
|
|