Skip to content

Commit 27c149e

Browse files
committed
stmhal: Add pyb.fault_debug() function, to control hard-fault behaviour.
This new function controls what happens on a hard-fault: - debugging disabled: board will do a reset - debugging enabled: board will print registers and stack and flash LEDs The default is disabled, ie to do a reset. This is different to previous behaviour which flashed the LEDs and waited indefinitely.
1 parent bffda45 commit 27c149e

File tree

5 files changed

+34
-13
lines changed

5 files changed

+34
-13
lines changed

docs/library/pyb.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ Reset related functions
8080

8181
Activate the bootloader without BOOT\* pins.
8282

83+
.. function:: fault_debug(value)
84+
85+
Enable or disable hard-fault debugging. A hard-fault is when there is a fatal
86+
error in the underlying system, like an invalid memory access.
87+
88+
If the `value` argument is `False` then the board will automatically reset if
89+
there is a hard fault.
90+
91+
If `value` is `True` then, when the board has a hard fault, it will print the
92+
registers and the stack trace, and then cycle the LEDs indefinitely.
93+
94+
The default value is disabled, i.e. to automatically reset.
95+
8396
Interrupt related functions
8497
---------------------------
8598

stmhal/modpyb.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "lib/oofatfs/ff.h"
3939
#include "lib/oofatfs/diskio.h"
4040
#include "gccollect.h"
41+
#include "stm32_it.h"
4142
#include "irq.h"
4243
#include "systick.h"
4344
#include "led.h"
@@ -64,6 +65,12 @@
6465
#include "extmod/vfs.h"
6566
#include "extmod/utime_mphal.h"
6667

68+
STATIC mp_obj_t pyb_fault_debug(mp_obj_t value) {
69+
pyb_hard_fault_debug = mp_obj_is_true(value);
70+
return mp_const_none;
71+
}
72+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_fault_debug_obj, pyb_fault_debug);
73+
6774
/// \function millis()
6875
/// Returns the number of milliseconds since the board was last reset.
6976
///
@@ -131,6 +138,8 @@ MP_DECLARE_CONST_FUN_OBJ_KW(pyb_main_obj); // defined in main.c
131138
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
132139
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
133140

141+
{ MP_OBJ_NEW_QSTR(MP_QSTR_fault_debug), (mp_obj_t)&pyb_fault_debug_obj },
142+
134143
{ MP_OBJ_NEW_QSTR(MP_QSTR_bootloader), (mp_obj_t)&machine_bootloader_obj },
135144
{ MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&machine_reset_obj },
136145
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },

stmhal/stm32_it.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#include STM32_HAL_H
7272

7373
#include "py/obj.h"
74+
#include "py/mphal.h"
7475
#include "pendsv.h"
7576
#include "irq.h"
7677
#include "pybthread.h"
@@ -95,11 +96,6 @@ extern PCD_HandleTypeDef pcd_hs_handle;
9596
// Set the following to 1 to get some more information on the Hard Fault
9697
// More information about decoding the fault registers can be found here:
9798
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0646a/Cihdjcfc.html
98-
#define REPORT_HARD_FAULT_REGS 0
99-
100-
#if REPORT_HARD_FAULT_REGS
101-
102-
#include "py/mphal.h"
10399

104100
STATIC char *fmt_hex(uint32_t val, char *buf) {
105101
const char *hexDig = "0123456789abcdef";
@@ -142,7 +138,13 @@ typedef struct {
142138
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
143139
} ExceptionRegisters_t;
144140

141+
int pyb_hard_fault_debug = 0;
142+
145143
void HardFault_C_Handler(ExceptionRegisters_t *regs) {
144+
if (!pyb_hard_fault_debug) {
145+
NVIC_SystemReset();
146+
}
147+
146148
// We need to disable the USB so it doesn't try to write data out on
147149
// the VCP and then block indefinitely waiting for the buffer to drain.
148150
pyb_usb_flags = 0;
@@ -209,14 +211,6 @@ void HardFault_Handler(void) {
209211
" b HardFault_C_Handler \n" // Off to C land
210212
);
211213
}
212-
#else
213-
void HardFault_Handler(void) {
214-
/* Go to infinite loop when Hard Fault exception occurs */
215-
while (1) {
216-
__fatal_error("HardFault");
217-
}
218-
}
219-
#endif // REPORT_HARD_FAULT_REGS
220214

221215
/**
222216
* @brief This function handles NMI exception.

stmhal/stm32_it.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
******************************************************************************
6464
*/
6565

66+
extern int pyb_hard_fault_debug;
67+
6668
void NMI_Handler(void);
6769
void HardFault_Handler(void);
6870
void MemManage_Handler(void);

tests/pyb/pyb1.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,6 @@
4040
print(len(pyb.unique_id()))
4141

4242
pyb.wfi()
43+
44+
pyb.fault_debug(True)
45+
pyb.fault_debug(False)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy