fix(sacn): ein nicht gestarteter Empfangs-Task darf die Lampe nicht unbrauchbar machen

nl_sacn_beat ist ein Pflichtterm in der Wachhund-Bedingung. Schlug tls_os_task_create()
fehl, bewegte sich der Herzschlag nie, der Wachhund wurde nie gefuettert und die Lampe
setzte sich alle 20 s zurueck - ohne Weg hinein. Ein Zusatzdienst muss zu "kein sACN"
degradieren, nicht zu "keine Lampe".

nl_sacn_running() meldet den Fehlschlag, app_main merkt ihn sich einmal als
sacn_required, und eine Zeile auf der Konsole macht ihn sichtbar.
This commit is contained in:
Michael Sauer
2026-09-20 01:16:42 +02:00
parent 5c17c94dbc
commit c70b6db4b8
3 changed files with 30 additions and 4 deletions
+8 -2
View File
@@ -164,6 +164,7 @@ static void app_task(void *arg)
nl_light_state_t last, initial, pending; nl_light_state_t last, initial, pending;
bool have_last, after_ota; bool have_last, after_ota;
bool light_alive = false, net_alive = false, http_alive = false, sacn_alive = false; bool light_alive = false, net_alive = false, http_alive = false, sacn_alive = false;
bool sacn_required;
uint8_t boots; uint8_t boots;
uint32_t boot_ms, light_seen, net_seen, http_seen, sacn_seen; uint32_t boot_ms, light_seen, net_seen, http_seen, sacn_seen;
@@ -243,6 +244,10 @@ static void app_task(void *arg)
nl_sacn_apply_settings(&sacn_boot); nl_sacn_apply_settings(&sacn_boot);
} }
nl_sacn_start(); nl_sacn_start();
/* Nur ein tatsaechlich gestarteter Task darf den Wachhund mitbestimmen: ohne Task
* bewegt sich nl_sacn_beat nie, die Bedingung waere nie erfuellt und die Lampe liefe
* in eine endlose Reset-Schleife. Ein Zusatzdienst faellt dann eben aus. */
sacn_required = nl_sacn_running();
light_seen = s_light_beat; light_seen = s_light_beat;
net_seen = nl_net_beat; net_seen = nl_net_beat;
@@ -278,7 +283,8 @@ static void app_task(void *arg)
/* Feed the watchdog only once the light, network, HTTP and sACN tasks have each /* Feed the watchdog only once the light, network, HTTP and sACN tasks have each
* made progress since the last feed - a single stuck task (e.g. nl_app_lock() held * made progress since the last feed - a single stuck task (e.g. nl_app_lock() held
* forever) must still starve the watchdog, not just the light task. */ * forever) must still starve the watchdog, not just the light task. Ausnahme: der
* sACN-Task, wenn er gar nicht erst angelegt werden konnte (sacn_required). */
if (s_light_beat != light_seen) { if (s_light_beat != light_seen) {
light_seen = s_light_beat; light_seen = s_light_beat;
light_alive = true; light_alive = true;
@@ -295,7 +301,7 @@ static void app_task(void *arg)
sacn_seen = nl_sacn_beat; sacn_seen = nl_sacn_beat;
sacn_alive = true; sacn_alive = true;
} }
if (light_alive && net_alive && http_alive && sacn_alive) { if (light_alive && net_alive && http_alive && (sacn_alive || !sacn_required)) {
light_alive = net_alive = http_alive = sacn_alive = false; light_alive = net_alive = http_alive = sacn_alive = false;
tls_watchdog_clr(); tls_watchdog_clr();
} }
+17 -2
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <string.h> #include <string.h>
#include "wm_include.h" #include "wm_include.h"
@@ -24,6 +25,12 @@ static volatile bool s_dirty = true;
volatile uint32_t nl_sacn_beat; volatile uint32_t nl_sacn_beat;
/* Faellt nur aus, wenn der Task gar nicht erst entsteht. app_main fragt das ab: ohne Task
* bewegt sich nl_sacn_beat nie, und eine Wachhund-Bedingung, die trotzdem darauf besteht,
* wuerde die Lampe im 20-s-Takt endlos zuruecksetzen - ein Zusatzdienst darf sie nicht
* unbrauchbar machen. */
static volatile bool s_running = true;
void nl_sacn_apply_settings(const nl_settings_t *s) void nl_sacn_apply_settings(const nl_settings_t *s)
{ {
nl_dmx_cfg_t c; nl_dmx_cfg_t c;
@@ -153,6 +160,14 @@ static void sacn_task(void *arg)
void nl_sacn_start(void) void nl_sacn_start(void)
{ {
tls_os_task_create(NULL, "nl_sacn", sacn_task, NULL, (u8 *)s_stack, sizeof(s_stack), if (tls_os_task_create(NULL, "nl_sacn", sacn_task, NULL, (u8 *)s_stack, sizeof(s_stack),
NL_SACN_PRIO, 0); NL_SACN_PRIO, 0) != TLS_OS_SUCCESS) {
s_running = false;
printf("sacn: task create failed - receiver off\r\n");
}
}
bool nl_sacn_running(void)
{
return s_running;
} }
+5
View File
@@ -1,6 +1,7 @@
#ifndef NL_SACN_H #ifndef NL_SACN_H
#define NL_SACN_H #define NL_SACN_H
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "config/nl_settings.h" #include "config/nl_settings.h"
@@ -14,4 +15,8 @@ extern volatile uint32_t nl_sacn_beat;
void nl_sacn_apply_settings(const nl_settings_t *s); void nl_sacn_apply_settings(const nl_settings_t *s);
void nl_sacn_start(void); void nl_sacn_start(void);
/* false, wenn der Empfangs-Task nicht angelegt werden konnte. Dann bewegt sich
* nl_sacn_beat nie und der Wachhund darf ihn nicht mehr verlangen. */
bool nl_sacn_running(void);
#endif #endif