summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/library/pyb.rst13
-rw-r--r--stmhal/modpyb.c9
-rw-r--r--stmhal/stm32_it.c20
-rw-r--r--stmhal/stm32_it.h2
-rw-r--r--tests/pyb/pyb1.py3
5 files changed, 34 insertions, 13 deletions
diff --git a/docs/library/pyb.rst b/docs/library/pyb.rst
index 910b2f45b4..9c4933808a 100644
--- a/docs/library/pyb.rst
+++ b/docs/library/pyb.rst
@@ -80,6 +80,19 @@ Reset related functions
Activate the bootloader without BOOT\* pins.
+.. function:: fault_debug(value)
+
+ Enable or disable hard-fault debugging. A hard-fault is when there is a fatal
+ error in the underlying system, like an invalid memory access.
+
+ If the `value` argument is `False` then the board will automatically reset if
+ there is a hard fault.
+
+ If `value` is `True` then, when the board has a hard fault, it will print the
+ registers and the stack trace, and then cycle the LEDs indefinitely.
+
+ The default value is disabled, i.e. to automatically reset.
+
Interrupt related functions
---------------------------
diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c
index 53b4335e79..93ae5d40ba 100644
--- a/stmhal/modpyb.c
+++ b/stmhal/modpyb.c
@@ -38,6 +38,7 @@
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
#include "gccollect.h"
+#include "stm32_it.h"
#include "irq.h"
#include "systick.h"
#include "led.h"
@@ -64,6 +65,12 @@
#include "extmod/vfs.h"
#include "extmod/utime_mphal.h"
+STATIC mp_obj_t pyb_fault_debug(mp_obj_t value) {
+ pyb_hard_fault_debug = mp_obj_is_true(value);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_fault_debug_obj, pyb_fault_debug);
+
/// \function millis()
/// Returns the number of milliseconds since the board was last reset.
///
@@ -131,6 +138,8 @@ MP_DECLARE_CONST_FUN_OBJ_KW(pyb_main_obj); // defined in main.c
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_fault_debug), (mp_obj_t)&pyb_fault_debug_obj },
+
{ MP_OBJ_NEW_QSTR(MP_QSTR_bootloader), (mp_obj_t)&machine_bootloader_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_hard_reset), (mp_obj_t)&machine_reset_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c
index 245b2ade4b..4152050a99 100644
--- a/stmhal/stm32_it.c
+++ b/stmhal/stm32_it.c
@@ -71,6 +71,7 @@
#include STM32_HAL_H
#include "py/obj.h"
+#include "py/mphal.h"
#include "pendsv.h"
#include "irq.h"
#include "pybthread.h"
@@ -95,11 +96,6 @@ extern PCD_HandleTypeDef pcd_hs_handle;
// Set the following to 1 to get some more information on the Hard Fault
// More information about decoding the fault registers can be found here:
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0646a/Cihdjcfc.html
-#define REPORT_HARD_FAULT_REGS 0
-
-#if REPORT_HARD_FAULT_REGS
-
-#include "py/mphal.h"
STATIC char *fmt_hex(uint32_t val, char *buf) {
const char *hexDig = "0123456789abcdef";
@@ -142,7 +138,13 @@ typedef struct {
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
} ExceptionRegisters_t;
+int pyb_hard_fault_debug = 0;
+
void HardFault_C_Handler(ExceptionRegisters_t *regs) {
+ if (!pyb_hard_fault_debug) {
+ NVIC_SystemReset();
+ }
+
// We need to disable the USB so it doesn't try to write data out on
// the VCP and then block indefinitely waiting for the buffer to drain.
pyb_usb_flags = 0;
@@ -209,14 +211,6 @@ void HardFault_Handler(void) {
" b HardFault_C_Handler \n" // Off to C land
);
}
-#else
-void HardFault_Handler(void) {
- /* Go to infinite loop when Hard Fault exception occurs */
- while (1) {
- __fatal_error("HardFault");
- }
-}
-#endif // REPORT_HARD_FAULT_REGS
/**
* @brief This function handles NMI exception.
diff --git a/stmhal/stm32_it.h b/stmhal/stm32_it.h
index fc61d57be1..a168cda838 100644
--- a/stmhal/stm32_it.h
+++ b/stmhal/stm32_it.h
@@ -63,6 +63,8 @@
******************************************************************************
*/
+extern int pyb_hard_fault_debug;
+
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
diff --git a/tests/pyb/pyb1.py b/tests/pyb/pyb1.py
index 0087ec0507..00adc85533 100644
--- a/tests/pyb/pyb1.py
+++ b/tests/pyb/pyb1.py
@@ -40,3 +40,6 @@ pyb.sync()
print(len(pyb.unique_id()))
pyb.wfi()
+
+pyb.fault_debug(True)
+pyb.fault_debug(False)