8000 stmhal: Print more information at HardFault time. · mimoccc/circuitpython@41b688e · GitHub
[go: up one dir, main page]

Skip to content

Commit 41b688e

Browse files
dhylandsdpgeorge
authored andcommitted
stmhal: Print more information at HardFault time.
1 parent 89f2ddd commit 41b688e

File tree

1 file changed

+56
-18
lines changed

1 file changed

+56
-18
lines changed

stmhal/stm32_it.c

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ extern PCD_HandleTypeDef pcd_handle;
9494

9595
#include "py/mphal.h"
9696

97-
char *fmt_hex(uint32_t val, char *buf) {
97+
STATIC char *fmt_hex(uint32_t val, char *buf) {
9898
const char *hexDig = "0123456789abcdef";
9999

100100
buf[0] = hexDig[(val >> 28) & 0x0f];
@@ -110,30 +110,32 @@ char *fmt_hex(uint32_t val, char *buf) {
110110
return buf;
111111
}
112112

113-
void print_reg(const char *label, uint32_t val) {
113+
STATIC void print_reg(const char *label, uint32_t val) {
114114
char hexStr[9];
115115

116116
mp_hal_stdout_tx_str(label);
117117
mp_hal_stdout_tx_str(fmt_hex(val, hexStr));
118118
mp_hal_stdout_tx_str("\r\n");
119119
}
120-
#endif // REPORT_HARD_FAULT_REGS
121120

122-
/**
123-
* @brief This function handles NMI exception.
124-
* @param None
125-
* @retval None
126-
*/
127-
void NMI_Handler(void) {
128-
}
121+
// The ARMv7M Architecture manual (section B.1.5.6) says that upon entry
122+
// to an exception, that the registers will be in the following order on the
123+
// // stack: R0, R1, R2, R3, R12, LR, PC, XPSR
124+
125+
typedef struct {
126+
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
127+
} ExceptionRegisters_t;
128+
129+
void HardFault_C_Handler(ExceptionRegisters_t *regs) {
130+
print_reg("R0 ", regs->r0);
131+
print_reg("R1 ", regs->r1);
132+
print_reg("R2 ", regs->r2);
133+
print_reg("R3 ", regs->r3);
134+
print_reg("R12 ", regs->r12);
135+
print_reg("LR ", regs->lr);
136+
print_reg("PC ", regs->pc);
137+
print_reg("XPSR ", regs->xpsr);
129138

130-
/**
131-
* @brief This function handles Hard Fault exception.
132-
* @param None
133-
* @retval None
134-
*/
135-
void HardFault_Handler(void) {
136-
#if REPORT_HARD_FAULT_REGS
137139
uint32_t cfsr = SCB->CFSR;
138140

139141
print_reg("HFSR ", SCB->HFSR);
@@ -144,13 +146,49 @@ void HardFault_Handler(void) {
144146
if (cfsr & 0x8000) {
145147
print_reg("BFAR ", SCB->BFAR);
146148
}
147-
#endif // REPORT_HARD_FAULT_REGS
149+
/* Go to infinite loop when Hard Fault exception occurs */
150+
while (1) {
151+
__fatal_error("HardFault");
152+
}
153+
}
148154

155+
// Naked functions have no compiler generated gunk, so are the best thing to
156+
// use for asm functions.
157+
__attribute__((naked))
158+
void HardFault_Handler(void) {
159+
160+
// From the ARMv7M Architecture Reference Manual, section B.1.5.6
161+
// on entry to the Exception, the LR register contains, amongst other
162+
// things, the value of CONTROL.SPSEL. This can be found in bit 3.
163+
//
164+
// If CONTROL.SPSEL is 0, then the exception was stacked up using the
165+
// main stack pointer (aka MSP). If CONTROL.SPSEL is 1, then the exception
166+
// was stacked up using the process stack pointer (aka PSP).
167+
168+
__asm volatile(
169+
" tst lr, #4 \n" // Test Bit 3 to see which stack pointer we should use.
170+
" ite eq \n" // Tell the assembler that the nest 2 instructions are if-then-else
171+
" mrseq r0, msp \n" // Make R0 point to main stack pointer
172+
" mrsne r0, psp \n" // Make R0 point to process stack pointer
173+
" b HardFault_C_Handler \n" // Off to C land
174+
);
175+
}
176+
#else
177+
void HardFault_Handler(void) {
149178
/* Go to infinite loop when Hard Fault exception occurs */
150179
while (1) {
151180
__fatal_error("HardFault");
152181
}
153182
}
183+
#endif // REPORT_HARD_FAULT_REGS
184+
185+
/**
186+
* @brief This function handles NMI exception.
187+
* @param None
188+
* @retval None
189+
*/
190+
void NMI_Handler(void) {
191+
}
154192

155193
/**
156194
* @brief This function handles Memory Manage exception.

0 commit comments

Comments
 (0)
0