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.
|
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
|
Interrupt related functions
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "lib/oofatfs/ff.h"
|
#include "lib/oofatfs/ff.h"
|
||||||
#include "lib/oofatfs/diskio.h"
|
#include "lib/oofatfs/diskio.h"
|
||||||
#include "gccollect.h"
|
#include "gccollect.h"
|
||||||
|
#include "stm32_it.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
@ -64,6 +65,12 @@
|
|||||||
#include "extmod/vfs.h"
|
#include "extmod/vfs.h"
|
||||||
#include "extmod/utime_mphal.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()
|
/// \function millis()
|
||||||
/// Returns the number of milliseconds since the board was last reset.
|
/// 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[] = {
|
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___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_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_hard_reset), (mp_obj_t)&machine_reset_obj },
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&machine_info_obj },
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include STM32_HAL_H
|
#include STM32_HAL_H
|
||||||
|
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
|
#include "py/mphal.h"
|
||||||
#include "pendsv.h"
|
#include "pendsv.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "pybthread.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
|
// 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:
|
// 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
|
// 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) {
|
STATIC char *fmt_hex(uint32_t val, char *buf) {
|
||||||
const char *hexDig = "0123456789abcdef";
|
const char *hexDig = "0123456789abcdef";
|
||||||
@ -142,7 +138,13 @@ typedef struct {
|
|||||||
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
|
uint32_t r0, r1, r2, r3, r12, lr, pc, xpsr;
|
||||||
} ExceptionRegisters_t;
|
} ExceptionRegisters_t;
|
||||||
|
|
||||||
|
int pyb_hard_fault_debug = 0;
|
||||||
|
|
||||||
void HardFault_C_Handler(ExceptionRegisters_t *regs) {
|
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
|
// 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.
|
// the VCP and then block indefinitely waiting for the buffer to drain.
|
||||||
pyb_usb_flags = 0;
|
pyb_usb_flags = 0;
|
||||||
@ -209,14 +211,6 @@ void HardFault_Handler(void) {
|
|||||||
" b HardFault_C_Handler \n" // Off to C land
|
" 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.
|
* @brief This function handles NMI exception.
|
||||||
|
@ -63,6 +63,8 @@
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
extern int pyb_hard_fault_debug;
|
||||||
|
|
||||||
void NMI_Handler(void);
|
void NMI_Handler(void);
|
||||||
void HardFault_Handler(void);
|
void HardFault_Handler(void);
|
||||||
void MemManage_Handler(void);
|
void MemManage_Handler(void);
|
||||||
|
@ -40,3 +40,6 @@ pyb.sync()
|
|||||||
print(len(pyb.unique_id()))
|
print(len(pyb.unique_id()))
|
||||||
|
|
||||||
pyb.wfi()
|
pyb.wfi()
|
||||||
|
|
||||||
|
pyb.fault_debug(True)
|
||||||
|
pyb.fault_debug(False)
|
||||||
|
Loading…
Reference in New Issue
Block a user