From 15dabfa6409d5e886c3852b8baf701c9be5dbad7 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Sat, 8 Aug 2026 10:43:27 +0100 Subject: [PATCH] Encapsulate rolloverMillis with a read-only accessor rolloverMillis (millis()-rollover counter, incremented in wled.cpp's main loop) was WLED_GLOBAL. json.cpp and one usermod (quinled-an-penta) only ever read it for uptime reporting, so it gets a by-value getter - getRolloverMillis() - instead of a mutable reference: an accidental write from outside wled.cpp is now a build error instead of a silent bug. Also fixed the one external consumer found: usermods/quinled-an-penta read rolloverMillis directly (same uptime-string idiom as json.cpp, literally copy-pasted per its own comment). Updated to use the new accessor. No behavior change - purely a storage/access-pattern change. Verified: - esp32dev builds and links cleanly via `pio run -e esp32dev`. - usermods env (builds all 59 usermods, including the fixed quinled-an-penta) builds and links cleanly via `pio run -e usermods`. - Repo-wide grep confirms no remaining raw references to rolloverMillis outside wled.cpp. Co-Authored-By: Claude Sonnet 5 --- usermods/quinled-an-penta/quinled-an-penta.cpp | 2 +- wled00/fcn_declare.h | 3 +++ wled00/json.cpp | 2 +- wled00/wled.cpp | 7 +++++++ wled00/wled.h | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/usermods/quinled-an-penta/quinled-an-penta.cpp b/usermods/quinled-an-penta/quinled-an-penta.cpp index b90a9f9419..ea6e34c5c6 100644 --- a/usermods/quinled-an-penta/quinled-an-penta.cpp +++ b/usermods/quinled-an-penta/quinled-an-penta.cpp @@ -354,7 +354,7 @@ class QuinLEDAnPentaUsermod : public Usermod // Always draw these two on the bottom char charUptime[charPerRow+1]; - sprintf(charUptime, "Uptime: %ds", int(millis()/1000 + rolloverMillis*4294967)); // From json.cpp + sprintf(charUptime, "Uptime: %ds", int(millis()/1000 + getRolloverMillis()*4294967)); // From json.cpp oledDisplay->drawStr(0, 53, charUptime); char charWledVersion[charPerRow+1]; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 18327eb877..a8869ac065 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -294,6 +294,9 @@ bool isAsterisksOnly(const char* str, byte maxLen); void handleSettingsSet(AsyncWebServerRequest *request, byte subPage); bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply=true); +//wled.cpp +uint16_t getRolloverMillis(); + //udp.cpp void notify(byte callMode, bool followUp=false); uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, const uint8_t* buffer, uint8_t bri=255, bool isRGBW=false); diff --git a/wled00/json.cpp b/wled00/json.cpp index d68b76f59b..2da409dd87 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -886,7 +886,7 @@ void serializeInfo(JsonObject root) // Total PSRAM size in MB, round up to correct for allocator overhead root[F("psrSz")] = (ESP.getPsramSize() + (1024U * 1024U - 1)) / (1024U * 1024U); #endif - root[F("uptime")] = millis()/1000 + rolloverMillis*4294967; + root[F("uptime")] = millis()/1000 + getRolloverMillis()*4294967; char time[32]; getTimeString(time); diff --git a/wled00/wled.cpp b/wled00/wled.cpp index d5125c30e2..5c75805cc5 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -25,6 +25,13 @@ #endif extern "C" void usePWMFixedNMI(); +// millis()-rollover counter (millis() wraps every ~50 days) - previously +// WLED_GLOBAL. json.cpp and usermods only ever read it for uptime reporting, +// so it gets a by-value getter rather than a mutable reference: an accidental +// write from outside this file is now a build error instead of a silent bug. +static uint16_t rolloverMillis = 0; +uint16_t getRolloverMillis() { return rolloverMillis; } + /* * Main WLED class implementation. Mostly initialization and connection logic */ diff --git a/wled00/wled.h b/wled00/wled.h index 9bafb49196..b5d881e4dc 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -758,7 +758,7 @@ WLED_GLOBAL unsigned long ntpLastSyncTime _INIT(NTP_NEVER); WLED_GLOBAL unsigned long ntpPacketSentTime _INIT(NTP_NEVER); WLED_GLOBAL IPAddress ntpServerIP; WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390); -WLED_GLOBAL uint16_t rolloverMillis _INIT(0); +// rolloverMillis is private to wled.cpp - use getRolloverMillis() instead. WLED_GLOBAL float longitude _INIT(WLED_LON); WLED_GLOBAL float latitude _INIT(WLED_LAT); WLED_GLOBAL time_t sunrise _INIT(0);