esp8266/main: Print error information on crash-induced reboots.

This commit adds an optional configuration option for the ESP8266 port
that, if the board rebooted due to a crash, will print to stdout some
information about the error that triggered the issue.

It is not possible using regular SDK functions to intercept errors and
print information at that stage, and the only error response from the
board is to reboot itself.  This is the next best thing, print some
error information just once at boot time after the crash - the least
invasive option given the situation we're in.

This is disabled by default, and can be enabled by enabling
MICROPY_HW_HARD_FAULT_DEBUG in the port configuration - obviously with a
small increase in the firmware code footprint.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
Alessandro Gatti
2025-06-01 18:54:37 +02:00
committed by Damien George
parent 4227654d42
commit e4c0e2b73d
2 changed files with 65 additions and 0 deletions

View File

@@ -49,6 +49,64 @@
static char heap[38 * 1024];
#if MICROPY_HW_HARD_FAULT_DEBUG
static void format_hex(uint32_t hex, char *buffer) {
static const char table[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
int offset = 7;
uint32_t value = hex;
while (offset >= 0) {
buffer[offset--] = table[value & 0x0F];
value >>= 4;
}
}
static void print_reset_info(void) {
struct rst_info *rst_info = system_get_rst_info();
if ((rst_info->reason == REASON_WDT_RST) || (rst_info->reason == REASON_EXCEPTION_RST) || (rst_info->reason == REASON_SOFT_WDT_RST)) {
char buffer[8];
mp_hal_stdout_tx_str("\r\n\r\nThe system restarted due to an error.\r\n\r\nReason: ");
switch (rst_info->reason) {
case REASON_WDT_RST:
mp_hal_stdout_tx_str("WDT");
break;
case REASON_EXCEPTION_RST:
mp_hal_stdout_tx_str("EXCEPTION");
break;
case REASON_SOFT_WDT_RST:
mp_hal_stdout_tx_str("SOFT_WDT");
break;
default:
assert(!"Should not ever get here.");
break;
}
mp_hal_stdout_tx_str(" Cause: ");
format_hex(rst_info->exccause, buffer);
mp_hal_stdout_tx_strn(buffer, sizeof(buffer));
mp_hal_stdout_tx_str(" EPC1: ");
format_hex(rst_info->epc1, buffer);
mp_hal_stdout_tx_strn(buffer, sizeof(buffer));
mp_hal_stdout_tx_str(" EPC2: ");
format_hex(rst_info->epc2, buffer);
mp_hal_stdout_tx_strn(buffer, sizeof(buffer));
mp_hal_stdout_tx_str(" EPC3: ");
format_hex(rst_info->epc3, buffer);
mp_hal_stdout_tx_strn(buffer, sizeof(buffer));
mp_hal_stdout_tx_str(" Exception Vector address: ");
format_hex(rst_info->excvaddr, buffer);
mp_hal_stdout_tx_strn(buffer, sizeof(buffer));
mp_hal_stdout_tx_str(" DEPC: ");
format_hex(rst_info->depc, buffer);
mp_hal_stdout_tx_strn(buffer, sizeof(buffer));
mp_hal_stdout_tx_str("\r\n\r\n");
}
}
#endif
static void mp_reset(void) {
mp_stack_set_top((void *)0x40000000);
mp_stack_set_limit(8192);
@@ -114,6 +172,10 @@ void init_done(void) {
pyexec_event_repl_init();
#endif
#if MICROPY_HW_HARD_FAULT_DEBUG
print_reset_info();
#endif
#if !MICROPY_REPL_EVENT_DRIVEN
soft_reset:
for (;;) {

View File

@@ -117,6 +117,9 @@
#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
#define MICROPY_ESP8266_APA102 (1)
// Print error information at reboot time if the board crashed.
#define MICROPY_HW_HARD_FAULT_DEBUG (0)
// No blocking wait-for-event on ESP8266, only non-blocking pump of the "OS" event
// loop
//