diff --git a/board/early_init.h b/board/early_init.h index 3b66262381b..b5c36619524 100644 --- a/board/early_init.h +++ b/board/early_init.h @@ -63,3 +63,19 @@ void early_initialization(void) { jump_to_bootloader(); } } + +// we might hit NMI / HardFault close to brown-out. +// we don't want to infinitely loop, so let's set a logging cookie and reset. +#define NMI_COOKIE 0x4E4D4921U +#define HARDFAULT_COOKIE 0x48464C54U +extern uint32_t fault_cookie; + +void NMI_Handler(void) { + fault_cookie = NMI_COOKIE; + NVIC_SystemReset(); +} + +void HardFault_Handler(void) { + fault_cookie = HARDFAULT_COOKIE; + NVIC_SystemReset(); +} diff --git a/board/health.h b/board/health.h index 24e6a8dfb64..69e2630bf0f 100644 --- a/board/health.h +++ b/board/health.h @@ -7,6 +7,8 @@ #define HEALTH_FLAG_HEARTBEAT_LOST (1U << 4) #define HEALTH_FLAG_SAFETY_RX_CHECKS_INVALID (1U << 5) #define HEALTH_FLAG_SOM_RESET_TRIGGERED (1U << 6) +#define HEALTH_FLAG_NMI_RESET (1U << 7) +#define HEALTH_FLAG_HARDFAULT_RESET ((uint16_t)1U << 8) struct __attribute__((packed)) health_t { uint32_t uptime_pkt; diff --git a/board/main.c b/board/main.c index 01c7e245592..da7e8e3f215 100644 --- a/board/main.c +++ b/board/main.c @@ -316,6 +316,14 @@ int main(void) { led_set(LED_GREEN, false); led_set(LED_BLUE, false); + if (fault_cookie == NMI_COOKIE) { + reset_flags |= HEALTH_FLAG_NMI_RESET; + } + if (fault_cookie == HARDFAULT_COOKIE) { + reset_flags |= HEALTH_FLAG_HARDFAULT_RESET; + } + fault_cookie = 0U; + print("**** INTERRUPTS ON ****\n"); enable_interrupts(); diff --git a/board/main_comms.h b/board/main_comms.h index 1f02bd0afb9..8c75ed47721 100644 --- a/board/main_comms.h +++ b/board/main_comms.h @@ -22,6 +22,7 @@ static int get_health_pkt(void *dat) { health->flags_pkt |= heartbeat_lost ? HEALTH_FLAG_HEARTBEAT_LOST : 0U; health->flags_pkt |= safety_rx_checks_invalid ? HEALTH_FLAG_SAFETY_RX_CHECKS_INVALID : 0U; health->flags_pkt |= bootkick_reset_triggered ? HEALTH_FLAG_SOM_RESET_TRIGGERED : 0U; + health->flags_pkt |= reset_flags; health->safety_tx_blocked_pkt = safety_tx_blocked; health->safety_rx_invalid_pkt = safety_rx_invalid; diff --git a/board/main_declarations.h b/board/main_declarations.h index af2a299374d..920e5ae66bb 100644 --- a/board/main_declarations.h +++ b/board/main_declarations.h @@ -12,6 +12,7 @@ void pwm_set(TIM_TypeDef *TIM, uint8_t channel, uint8_t percentage); extern uint8_t hw_type; extern board *current_board; extern uint32_t uptime_cnt; +extern uint16_t reset_flags; // heartbeat state extern uint32_t heartbeat_counter; diff --git a/board/main_definitions.h b/board/main_definitions.h index 3f408cd58ef..6996c8939c9 100644 --- a/board/main_definitions.h +++ b/board/main_definitions.h @@ -6,6 +6,7 @@ uint8_t hw_type = 0; board *current_board; uint32_t uptime_cnt = 0; +uint16_t reset_flags = 0U; // heartbeat state uint32_t heartbeat_counter = 0; diff --git a/board/stm32h7/stm32h7x5_flash.ld b/board/stm32h7/stm32h7x5_flash.ld index 2c0c19d0939..ae8800e7de1 100644 --- a/board/stm32h7/stm32h7x5_flash.ld +++ b/board/stm32h7/stm32h7x5_flash.ld @@ -54,6 +54,8 @@ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ enter_bootloader_mode = 0x38001FFC; +fault_cookie = 0x38003FFC; + _estack = 0x20020000; /* end of RAM */ _app_start = 0x08020000; /* Reserve Sector 0(128K) for bootloader */ diff --git a/python/__init__.py b/python/__init__.py index 1a6ab7d994a..be86a233932 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -146,6 +146,8 @@ class Panda: HEALTH_FLAG_HEARTBEAT_LOST = 1 << 4 HEALTH_FLAG_SAFETY_RX_CHECKS_INVALID = 1 << 5 HEALTH_FLAG_SOM_RESET_TRIGGERED = 1 << 6 + HEALTH_FLAG_NMI_RESET = 1 << 7 + HEALTH_FLAG_HARDFAULT_RESET = 1 << 8 H7_DEVICES = [HW_TYPE_RED_PANDA, HW_TYPE_TRES, HW_TYPE_CUATRO, HW_TYPE_BODY] SUPPORTED_DEVICES = H7_DEVICES @@ -549,6 +551,8 @@ def health(self): "sbu1_voltage_mV": a[17], "sbu2_voltage_mV": a[18], "som_reset_triggered": bool(flags & self.HEALTH_FLAG_SOM_RESET_TRIGGERED), + "nmi_reset": bool(flags & self.HEALTH_FLAG_NMI_RESET), + "hardfault_reset": bool(flags & self.HEALTH_FLAG_HARDFAULT_RESET), "sound_output_level": a[19], "temperature": a[20] - 40.0, }