rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
main_hardfault.c
Go to the documentation of this file.
1/**
2 * @file main_hardfault.c
3 *
4 * This black magic improves hard fault debugging experience
5 *
6 * http://www.chibios.com/forum/viewtopic.php?t=2506
7 */
8
9#include "hal.h"
10
11#include <string.h>
12
13/**
14 * Executes the BKPT instruction that causes the debugger to stop.
15 */
16#define bkpt() __asm volatile("BKPT #0\n")
17
18void NMI_Handler(void) {
19 NVIC_SystemReset();
20}
21
22//See http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABBGBEC.html
23typedef enum {
24 Reset = 1,
25 NMI = 2,
30} FaultType;
31
32void logHardFault(uint32_t type, uintptr_t faultAddress, void* sp, struct port_extctx* ctx, uint32_t csfr);
33
34void HardFault_Handler_C(void* sp) {
35 //Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
36 //Get thread context. Contains main registers including PC and LR
37 struct port_extctx ctx;
38 memcpy(&ctx, sp, sizeof(struct port_extctx));
39
40 //Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
41 volatile FaultType faultType = (FaultType)__get_IPSR();
42 (void)faultType;
43 //For HardFault/BusFault this is the address that was accessed causing the error
44 volatile uint32_t faultAddress = SCB->BFAR;
45
46 //Flags about hardfault / busfault
47 //See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
48 volatile bool isFaultPrecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 1) ? true : false);
49 volatile bool isFaultImprecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 2) ? true : false);
50 volatile bool isFaultOnUnstacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 3) ? true : false);
51 volatile bool isFaultOnStacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 4) ? true : false);
52 volatile bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 7) ? true : false);
53 (void)isFaultPrecise;
54 (void)isFaultImprecise;
55 (void)isFaultOnUnstacking;
56 (void)isFaultOnStacking;
57 (void)isFaultAddressValid;
58
59 logHardFault(faultType, faultAddress, sp, &ctx, SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos);
60
61 // check if debugger is connected
62 if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
63 {
64 bkpt();
65 }
66 NVIC_SystemReset();
67}
68
69void UsageFault_Handler_C(void* sp) {
70 //Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
71 //Get thread context. Contains main registers including PC and LR
72 struct port_extctx ctx;
73 memcpy(&ctx, sp, sizeof(struct port_extctx));
74
75 //Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
76 volatile FaultType faultType = (FaultType)__get_IPSR();
77 (void)faultType;
78 //Flags about hardfault / busfault
79 //See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
80 volatile bool isUndefinedInstructionFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 0) ? true : false);
81 volatile bool isEPSRUsageFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 1) ? true : false);
82 volatile bool isInvalidPCFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 2) ? true : false);
83 volatile bool isNoCoprocessorFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 3) ? true : false);
84 volatile bool isUnalignedAccessFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 8) ? true : false);
85 volatile bool isDivideByZeroFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 9) ? true : false);
86 (void)isUndefinedInstructionFault;
87 (void)isEPSRUsageFault;
88 (void)isInvalidPCFault;
89 (void)isNoCoprocessorFault;
90 (void)isUnalignedAccessFault;
91 (void)isDivideByZeroFault;
92
93 logHardFault(faultType, 0, sp, &ctx, SCB->CFSR);
94
95 // check if debugger is connected
96 if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
97 {
98 bkpt();
99 }
100 NVIC_SystemReset();
101}
102
103void MemManage_Handler_C(void* sp) {
104 //Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info
105 //Get thread context. Contains main registers including PC and LR
106 struct port_extctx ctx;
107 memcpy(&ctx, sp, sizeof(struct port_extctx));
108
109 //Interrupt status register: Which interrupt have we encountered, e.g. HardFault?
110 FaultType faultType = (FaultType)__get_IPSR();
111 (void)faultType;
112 //For HardFault/BusFault this is the address that was accessed causing the error
113 volatile uint32_t faultAddress = SCB->MMFAR;
114
115 //Flags about hardfault / busfault
116 //See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference
117 volatile bool isInstructionAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 0) ? true : false);
118 volatile bool isDataAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 1) ? true : false);
119 volatile bool isExceptionUnstackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 3) ? true : false);
120 volatile bool isExceptionStackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 4) ? true : false);
121 volatile bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 7) ? true : false);
122 (void)isInstructionAccessViolation;
123 (void)isDataAccessViolation;
124 (void)isExceptionUnstackingFault;
125 (void)isExceptionStackingFault;
126 (void)isFaultAddressValid;
127
128 logHardFault(faultType, faultAddress, sp, &ctx, SCB->CFSR);
129
130 // check if debugger is connected
131 if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
132 {
133 bkpt();
134 }
135 NVIC_SystemReset();
136}
void UsageFault_Handler_C(void *sp)
void NMI_Handler(void)
void MemManage_Handler_C(void *sp)
void logHardFault(uint32_t type, uintptr_t faultAddress, void *sp, struct port_extctx *ctx, uint32_t csfr)
void HardFault_Handler_C(void *sp)
FaultType
@ UsageFault
@ BusFault
@ Reset
@ NMI
@ MemManage
@ HardFault