fix(firmware): net_guard boot-state seed + no spurious disconnect
- Seed s_up from WiFi.status() in net_guard_start so the first STA_GOT_IP (fired during setup's busy-wait, before onEvent was registered) is not missed — prevents a reconnect flap on every boot. - Drop WiFi.disconnect() from net_guard_tick; WiFi.begin() alone re-associates cleanly and avoids a spurious STA_DISCONNECTED that was double-logging EVT_WIFI_DOWN on every retry. - Re-check s_up after the millis() timing gate to close the GOT_IP-vs-tick race. - Document the volatile-only shared-state contract.
This commit is contained in:
@@ -10,6 +10,9 @@ uint32_t net_guard_next_backoff_ms(uint32_t attempt) {
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include "event_log.h"
|
#include "event_log.h"
|
||||||
|
|
||||||
|
// Shared with the WiFi event task. 32-bit aligned loads/stores are atomic on
|
||||||
|
// Xtensa; volatile suffices. Tick re-evaluates every loop iteration, so stale
|
||||||
|
// reads self-correct within ~200ms.
|
||||||
static const DeviceConfig* s_cfg = nullptr;
|
static const DeviceConfig* s_cfg = nullptr;
|
||||||
static volatile uint8_t s_last_disconnect = 0;
|
static volatile uint8_t s_last_disconnect = 0;
|
||||||
static volatile bool s_up = false;
|
static volatile bool s_up = false;
|
||||||
@@ -36,6 +39,10 @@ static void on_wifi_event(WiFiEvent_t event, WiFiEventInfo_t info) {
|
|||||||
|
|
||||||
void net_guard_start(const DeviceConfig& cfg) {
|
void net_guard_start(const DeviceConfig& cfg) {
|
||||||
s_cfg = &cfg;
|
s_cfg = &cfg;
|
||||||
|
// Seed s_up from the current WiFi state. setup()'s busy-wait on
|
||||||
|
// WiFi.begin() can produce a STA_GOT_IP before onEvent() is registered;
|
||||||
|
// without this seed, the first tick would force a spurious reconnect.
|
||||||
|
if (WiFi.status() == WL_CONNECTED) s_up = true;
|
||||||
WiFi.onEvent(on_wifi_event);
|
WiFi.onEvent(on_wifi_event);
|
||||||
WiFi.setAutoReconnect(false); // we drive reconnect ourselves
|
WiFi.setAutoReconnect(false); // we drive reconnect ourselves
|
||||||
}
|
}
|
||||||
@@ -47,8 +54,11 @@ uint8_t net_guard_last_disconnect_reason() { return s_last_disconnect; }
|
|||||||
extern "C" void net_guard_tick() {
|
extern "C" void net_guard_tick() {
|
||||||
if (s_up || s_cfg == nullptr) return;
|
if (s_up || s_cfg == nullptr) return;
|
||||||
if (millis() < s_next_retry_ms) return;
|
if (millis() < s_next_retry_ms) return;
|
||||||
|
if (s_up) return; // re-check after the timing gate — closes GOT_IP-vs-tick race
|
||||||
s_attempts++;
|
s_attempts++;
|
||||||
WiFi.disconnect(false, false);
|
// WiFi.begin() alone re-associates cleanly; a prior WiFi.disconnect() call
|
||||||
|
// synchronously emits STA_DISCONNECTED on the event task, which would
|
||||||
|
// double-log EVT_WIFI_DOWN (reason=ASSOC_LEAVE) on every retry.
|
||||||
WiFi.begin(s_cfg->wifi_ssid.c_str(), s_cfg->wifi_pass.c_str());
|
WiFi.begin(s_cfg->wifi_ssid.c_str(), s_cfg->wifi_pass.c_str());
|
||||||
s_next_retry_ms = millis() + net_guard_next_backoff_ms(s_attempts);
|
s_next_retry_ms = millis() + net_guard_next_backoff_ms(s_attempts);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user