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.
This commit is contained in:
parent
bffda45154
commit
27c149efe0
|
@ -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
|
||||
---------------------------
|
||||
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -63,6 +63,8 @@
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
extern int pyb_hard_fault_debug;
|
||||
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
|
|
|
@ -40,3 +40,6 @@ pyb.sync()
|
|||
print(len(pyb.unique_id()))
|
||||
|
||||
pyb.wfi()
|
||||
|
||||
pyb.fault_debug(True)
|
||||
pyb.fault_debug(False)
|
||||
|
|
Loading…
Reference in New Issue