Commit Graph
3 Commits
Author SHA1 Message Date
joluxerandGitHub a2c38a9b76 build: copy firmware artifacts with ELF-extracted build timestamp (opt-in) (#24794)
New post-build script pio-tools/timestamp-firmware.py copies firmware
artifacts to timestamped filenames when append_timestamp = 1 is set in
the [tasmota] section of platformio_override.ini. Default off; standard
builds unaffected.

The timestamp is extracted from the ELF symbol table via nm: named PROGMEM
symbols mdate_P and mtime_P in GetBuildDateAndTime() carry __DATE__ and
__TIME__ respectively. Reading them from the ELF guarantees the filename
timestamp matches exactly the one the firmware reports at boot. No -g flag required.

Artifacts written with timestamp suffix (e.g. tasmota-4M-2026-05-01T19-02-06):
  .bin, .bin.gz, .factory.bin (ESP32)  ->  build_output/firmware/
  .elf                                 ->  build_output/firmware/
  .map.gz                              ->  build_output/map/

support_rtc.ino: mtime_P introduced as a named PROGMEM variable so nm can
locate __TIME__ by symbol name on all platforms, including ESP32 where
PSTR() is a no-op. Flash impact: +4 B; all other memory unchanged.
2026-06-13 12:23:56 +02:00
joluxerandGitHub 58b7d9d639 JsonParser: fix NULL deref on OOM in token buffer access paths (#24792)
On platforms without exceptions (-fno-exceptions, e.g. ESP8266),
new[] returns nullptr on allocation failure instead of throwing.
The missing NULL check caused a hard crash (load/store to address
derived from nullptr+offset) whenever the token buffer could not
be allocated.

Fix all four paths that dereference _tokens without a NULL guard,
and implement the existing TODO in parse() to ensure _token_len=0
invariant holds after OOM, consistent with the zero-error design.
2026-05-27 23:31:32 +02:00
joluxerandGitHub ba88358ed6 ESP8266: fix heap metric functions and add OOM diagnostics (#24777)
* ESP8266: fix ESP_getMaxAllocHeap() and ESP_getHeapFragmentation()

Both functions returned wrong values: ESP_getMaxAllocHeap() returned
ESP.getFreeHeap() (total free, not largest contiguous block);
ESP_getHeapFragmentation() read ummHeapInfo.maxFreeContiguousBlocks,
which is only valid immediately after a umm_info() heap walk.

Fix: cache the result of umm_max_block_size() in ESP_UpdateHeapMetrics().
The cache is refreshed once per second when SetOption130 is active, and
on demand in CmndStatus() before Status 4 is output. Both getter functions
read the cached value; the call site overhead is a single integer read.

umm_max_block_size() is unconditionally available (UMM_INFO is hardcoded
in the Arduino ESP8266 umm_malloc_cfg.h), so no build flags are required.

Status 4 (StatusMEM) gains two ESP8266-specific fields: MaxFreeBlock (KB)
and Frag (%).

* ESP8266: add heap OOM diagnostics, Status 4 fields, Status 44 dump

OOM event monitoring (requires UMM_INLINE_METRICS or UMM_STATS_FULL):
- ESP_HeapOomCheck(): called once per second; logs the OOM counter delta
  when the counter changes ("OOM: count N (+M)")
- ESP_HeapOomTest(): logs current OOM count on demand

Status 4 (StatusMEM) gains additional ESP8266-specific fields when the
corresponding build flags are active:
- OomCount: cumulative out-of-memory events (UMM_INLINE_METRICS or
  UMM_STATS_FULL)
- HeapLwm (KB): heap low-watermark since boot (UMM_STATS_FULL)
- MaxAllocSz (bytes): peak single allocation size (UMM_STATS_FULL)

Status 44 (ESP8266-only diagnostic command):
- Triggers umm_info(nullptr, true) to print a full heap block map to
  the serial console
- Calls ESP_HeapOomTest() to log the current OOM count
- Returns {"Status44":{"HeapDump":"serial"}}
- Status 44 is accepted regardless of MAX_STATUS

Build flags UMM_STATS_FULL and UMM_INLINE_METRICS can be enabled via
platformio_override.ini build_flags; documented in
platformio_override_sample.ini.
2026-05-25 17:25:04 +02:00