fix: Watchdog wirksam machen, Factory-Reset im App-Task, Resetzähler-Retry

- vApplicationIdleHook() füttert den Watchdog nicht mehr (sdk/Platform/Sys/wm_main.c,
  dokumentiert als Patch 4 in sdk/PATCHES.md). Bisher fütterte der Idle-Task den
  Watchdog bei jedem Leerlauf, auch wenn ein Task deadlockt (z.B. nl_app_lock() hält
  und nie freigibt) - der Watchdog konnte so nie greifen.
- Neues Konsolenkommando `wdtest` (Parser in nl_console_cmd.c/.h, Ausführung in
  nl_console.c, Host-Test in test_console_cmd.c): hält nl_app_lock() für immer, damit
  light_task und app_task blockieren und nur der Watchdog-Reset den Chip retten kann.
- nl_app_request_factory_reset() (nl_app.h) setzt nur ein volatile Flag; app_task
  prüft es in der Hauptschleife und ruft nl_app_factory_reset() selbst auf, da nur der
  App-Task die Flash-Stores besitzt. Das Konsolenkommando `factory` ruft jetzt diese
  Funktion statt nl_app_factory_reset() direkt aufzurufen, um die Race mit
  nl_state_log_append()/nl_resetcnt_clear() im App-Task zu vermeiden. Der Bootpfad
  (Bootzähler >= 5) ruft weiterhin direkt nl_app_factory_reset() auf.
- nl_resetcnt_clear() wird nur noch als erledigt markiert, wenn es 0 zurückgibt, damit
  ein fehlgeschlagener Clear in der nächsten Schleifeniteration erneut versucht wird.
This commit is contained in:
Michael Sauer
2026-09-11 20:53:25 +02:00
parent 488dac9167
commit 4f270ad79b
8 changed files with 42 additions and 9 deletions
+8 -4
View File
@@ -22,6 +22,7 @@
static tls_os_mutex_t *s_lock;
static nl_settings_t s_settings;
static volatile uint32_t s_light_beat;
static volatile bool s_factory_reset_requested;
static u32 s_app_stack[1024];
static u32 s_light_stack[512];
@@ -44,6 +45,8 @@ int nl_app_save_settings(void)
return r;
}
void nl_app_request_factory_reset(void) { s_factory_reset_requested = true; }
void nl_app_factory_reset(void)
{
printf("factory reset\r\n");
@@ -130,10 +133,11 @@ static void app_task(void *arg)
tls_os_time_delay(HZ / 10); /* 100 ms */
now = nl_app_now_ms();
if (!counter_cleared && now - boot_ms >= NL_RESETCNT_CLEAR_MS) {
nl_resetcnt_clear();
counter_cleared = true;
}
if (!counter_cleared && now - boot_ms >= NL_RESETCNT_CLEAR_MS)
counter_cleared = nl_resetcnt_clear() == 0;
if (s_factory_reset_requested)
nl_app_factory_reset(); /* does not return */
nl_app_lock();
due = nl_ctrl_persist_due(now, &pending);