Skip to content

Check the ESP32's documented sizes, and correct them - #70

Merged
theAndreas merged 1 commit into
masterfrom
esp32-sizes-checked
Aug 24, 2026
Merged

Check the ESP32's documented sizes, and correct them#70
theAndreas merged 1 commit into
masterfrom
esp32-sizes-checked

Conversation

@theAndreas

Copy link
Copy Markdown
Collaborator

Follow-up to the find in #69: the ESP32 was the one target whose sizes documented-sizes.py did not cover, and it had rotted far enough that the same file contradicted itself.

What was wrong

platform/esp32/README.md said, in its verification block:

RAM:    10.8%  of 320 KB
Flash:  17.5%  of 3.2 MB

and, three paragraphs down, that the image was "about 1.05 MB" against a 3.19 MB app slot — i.e. about a third, not a sixth. Two halves of one file disagreeing by a factor of two, from a build predating the two web pages and the network update. Nothing caught it because the AVR and the RP2350 have CI checks and the ESP32 did not.

Measured on a current build: 16 % of 320 KB and 33 % of the 3.19 MB app slot. The derived slot table was mildly stale too — --fix turned 31/83/55 into 33/85/57.

Why flash is measured off firmware.bin, not off sections

This is the part worth reviewing. The obvious implementation — sum the sections at flash addresses, as rp2350_sizes does — is wrong here. The S3's ELF carries .ext_ram.dummy (1 114 080 bytes), .flash_rodata_dummy (851 968) and .dram0.dummy: padding and aliases the loader never writes. Summing them counts over a megabyte that is not in the image.

So flash is os.path.getsize(firmware.bin) — not a reconstruction of the artefact but the artefact, the bytes esptool wrote and the app partition receives. That is the same lesson the AVR figure already carries in this script's docstring, where asking avr-size replaced adding .text to .data and being wrong by six bytes.

RAM has no such trap once the dummy is skipped: .dram0.data + .dram0.bss land within two bytes of what PlatformIO prints (52 158 against 52 160), so a percentage with a point of slack is safe.

Hence the two flags — --esp32-bin for flash, --esp32-elf for RAM. Passing one without the other is refused rather than silently skipping the RAM figure.

Unmeasurable claims removed rather than left to rot

  • The parts table row now points at the slot table instead of repeating a percentage.
  • "The image is about 1.05 MB" is gone; the slot table says the same thing three ways and is checked.

CI

The existing firmware job runs the check against the image it just built, next to where the rp2350 and avr-dx jobs already do. The file's header comment said the size check belonged to the AVR job; it now says all three run it.

Verified

  • The full check passes on current builds of all three targets: avr-dx 37/10, esp32 16/33 and 33 85 57, rp2350 15/16, web 69 11 57 6.7.
  • It fails when it should: editing the flash figure to 17 gives documented 16 17, measured 16 33 and exit 1.
  • The paired-argument guard fires: --esp32-bin alone exits with "…go together".
  • The toolchain lookup works with no ESP32_SIZE set — it globs PlatformIO's toolchain-xtensa-esp-elf, which the firmware job installs as part of building.

CLAUDE.md's "Sizes in prose" section gains the two new flags and a sentence on why the ESP32 needs two paths, so the next person does not "tidy away" the asymmetry.

🤖 Generated with Claude Code

The ESP32 was the one target whose figures no check covered, and it showed:
the README's verification block read 10.8 % RAM and 17.5 % flash, from a
build before the two pages and the network update existed, while the app slot
table further down the same file put the image at three times that share. Two
halves of one file disagreeing by a factor of two, for long enough that
neither looked suspicious.

Measured now: 16 % of 320 KB and 33 % of the 3.19 MB app slot. The derived
table was mildly stale too and --fix corrected it - 31/83/55 became 33/85/57.

Flash is the size of firmware.bin rather than a sum over sections, and that is
the whole reason this check took a moment to get right. The S3's ELF carries
.ext_ram.dummy, .flash_rodata_dummy and .dram0.dummy - padding and aliases the
loader never writes - so adding up what sits at a flash address counts over a
megabyte that is not in the image. The image file is not a reconstruction of
the artefact, it is the artefact. Same lesson as the AVR figure, where asking
avr-size replaced adding .text to .data and being wrong by six bytes. RAM has
no such trap once the dummy is skipped: .dram0.data plus .dram0.bss land
within two bytes of what PlatformIO prints.

The two mentions that cannot be checked are gone rather than left to rot: the
parts table now points at the slot table instead of repeating a percentage,
and "the image is about 1.05 MB" is replaced by the table that says the same
thing three ways and is measured.

The firmware CI job runs it, so this cannot drift again without failing the
pull request that caused it.

Verified: the check passes on a current build of all three targets, fails with
exit 1 when a number is edited to a wrong one, and refuses --esp32-bin without
--esp32-elf rather than silently skipping the RAM figure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@theAndreas
theAndreas merged commit c739f6d into master Aug 24, 2026
8 checks passed
@AndreasBur
AndreasBur deleted the esp32-sizes-checked branch August 25, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants