feat: Add watchdog reset detection and status reporting (Issue #300)

- Detect if MCU was reset by IWDG watchdog timeout at startup
- Log watchdog reset events to debug terminal (USB CDC)
- Store watchdog reset flag for status reporting to Jetson
- Watchdog timer configured with 2-second timeout in safety_init()
- Main loop calls safety_refresh() to kick the watchdog every iteration

The IWDG (Independent Watchdog) resets the MCU if the main loop
hangs and fails to call safety_refresh() within the timeout window.
This provides hardware-enforced detection of software failures.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
sl-mechanical 2026-03-04 08:44:19 -05:00
parent 87bb2999c2
commit 73742fe726

View File

@ -27,6 +27,7 @@
#include "power_mgmt.h" #include "power_mgmt.h"
#include "battery.h" #include "battery.h"
#include "coulomb_counter.h" #include "coulomb_counter.h"
#include "watchdog.h"
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -42,6 +43,9 @@ extern volatile uint8_t cdc_estop_clear_request;
/* BNO055 active flag (set if BNO055 initialized successfully) */ /* BNO055 active flag (set if BNO055 initialized successfully) */
static bool bno055_active = false; static bool bno055_active = false;
/* Watchdog reset flag (set if MCU was reset by IWDG timeout) */
static bool g_watchdog_reset_detected = false;
/* /*
* Apply a PID tuning command string from the USB terminal. * Apply a PID tuning command string from the USB terminal.
* Format: P<kp> I<ki> D<kd> T<setpoint_deg> M<max_speed> ? * Format: P<kp> I<ki> D<kd> T<setpoint_deg> M<max_speed> ?
@ -119,6 +123,9 @@ int main(void) {
HAL_Init(); HAL_Init();
SystemClock_Config(); SystemClock_Config();
/* Detect watchdog reset (Issue #300) — must be before safety_init() */
g_watchdog_reset_detected = watchdog_was_reset_by_watchdog();
/* USB CDC */ /* USB CDC */
USBD_Init(&hUsbDevice, &SaltyLab_Desc, 0); USBD_Init(&hUsbDevice, &SaltyLab_Desc, 0);
USBD_RegisterClass(&hUsbDevice, &USBD_CDC); USBD_RegisterClass(&hUsbDevice, &USBD_CDC);
@ -128,6 +135,11 @@ int main(void) {
status_init(); status_init();
HAL_Delay(3000); /* Wait for USB host to enumerate */ HAL_Delay(3000); /* Wait for USB host to enumerate */
/* Log watchdog reset event if it occurred (Issue #300) */
if (g_watchdog_reset_detected) {
printf("[WATCHDOG] MCU reset by IWDG timeout detected. Main loop may have hung.\n");
}
/* Init IMU (MPU6000 via SPI1 — mpu6000.c wraps icm42688 + complementary filter) */ /* Init IMU (MPU6000 via SPI1 — mpu6000.c wraps icm42688 + complementary filter) */
int imu_ret = mpu6000_init() ? 0 : -1; int imu_ret = mpu6000_init() ? 0 : -1;