catch faults

This commit is contained in:
Matthew Kennedy 2023-01-05 16:56:28 -08:00
parent 86f175454f
commit 60445fbed3
3 changed files with 136 additions and 1 deletions

View File

@ -164,7 +164,7 @@ CPPSRC = $(ALLCPPSRC) \
ASMSRC = $(ALLASMSRC)
# List ASM with preprocessor source files here.
ASMXSRC = $(ALLXASMSRC)
ASMXSRC = $(ALLXASMSRC) main_hardfault_asm.S
# Inclusion directories.
INCDIR = $(CONFDIR) \

View File

@ -15,6 +15,8 @@
#include "wideband_config.h"
#include <cstring>
using namespace wbo;
/*
@ -77,3 +79,101 @@ int main() {
}
}
}
typedef enum {
Reset = 1,
NMI = 2,
HardFault = 3,
MemManage = 4,
BusFault = 5,
UsageFault = 6,
} FaultType;
#define bkpt() __asm volatile("BKPT #0\n")
extern "C" void HardFault_Handler_C(void* sp) {
//Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
//Get thread context. Contains main registers including PC and LR
struct port_extctx ctx;
memcpy(&ctx, sp, sizeof(struct port_extctx));
//Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
FaultType faultType = (FaultType)__get_IPSR();
(void)faultType;
//For HardFault/BusFault this is the address that was accessed causing the error
uint32_t faultAddress = SCB->BFAR;
//Flags about hardfault / busfault
//See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
bool isFaultPrecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 1) ? true : false);
bool isFaultImprecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 2) ? true : false);
bool isFaultOnUnstacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 3) ? true : false);
bool isFaultOnStacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 4) ? true : false);
bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 7) ? true : false);
(void)isFaultPrecise;
(void)isFaultImprecise;
(void)isFaultOnUnstacking;
(void)isFaultOnStacking;
(void)isFaultAddressValid;
//Cause debugger to stop. Ignored if no debugger is attached
bkpt();
NVIC_SystemReset();
}
extern "C" void UsageFault_Handler_C(void* sp) {
//Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
//Get thread context. Contains main registers including PC and LR
struct port_extctx ctx;
memcpy(&ctx, sp, sizeof(struct port_extctx));
//Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
FaultType faultType = (FaultType)__get_IPSR();
(void)faultType;
//Flags about hardfault / busfault
//See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
bool isUndefinedInstructionFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 0) ? true : false);
bool isEPSRUsageFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 1) ? true : false);
bool isInvalidPCFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 2) ? true : false);
bool isNoCoprocessorFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 3) ? true : false);
bool isUnalignedAccessFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 8) ? true : false);
bool isDivideByZeroFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 9) ? true : false);
(void)isUndefinedInstructionFault;
(void)isEPSRUsageFault;
(void)isInvalidPCFault;
(void)isNoCoprocessorFault;
(void)isUnalignedAccessFault;
(void)isDivideByZeroFault;
bkpt();
NVIC_SystemReset();
}
extern "C" void MemManage_Handler_C(void* sp) {
//Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
//Get thread context. Contains main registers including PC and LR
struct port_extctx ctx;
memcpy(&ctx, sp, sizeof(struct port_extctx));
//Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
FaultType faultType = (FaultType)__get_IPSR();
(void)faultType;
//For HardFault/BusFault this is the address that was accessed causing the error
uint32_t faultAddress = SCB->MMFAR;
//Flags about hardfault / busfault
//See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
bool isInstructionAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 0) ? true : false);
bool isDataAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 1) ? true : false);
bool isExceptionUnstackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 3) ? true : false);
bool isExceptionStackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 4) ? true : false);
bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 7) ? true : false);
(void)isInstructionAccessViolation;
(void)isDataAccessViolation;
(void)isExceptionUnstackingFault;
(void)isExceptionStackingFault;
(void)isFaultAddressValid;
bkpt();
NVIC_SystemReset();
}

View File

@ -0,0 +1,35 @@
.syntax unified
.cpu cortex-m3
.thumb
.align 2
.thumb_func
.type HardFault_Handler, %function
.type UsageFault_Handler, %function
.type MemManage_Handler, %function
.global HardFault_Handler
.global BusFault_Handler
HardFault_Handler:
BusFault_Handler:
tst LR, #4
ite EQ
mrseq R0, MSP
mrsne R0, PSP
b HardFault_Handler_C
.global UsageFault_Handler
UsageFault_Handler:
tst LR, #4
ite EQ
mrseq R0, MSP
mrsne R0, PSP
b UsageFault_Handler_C
.global MemManage_Handler
MemManage_Handler:
tst LR, #4
ite EQ
mrseq R0, MSP
mrsne R0, PSP
b MemManage_Handler_C