summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngus Gratton <angus@redyak.com.au>2025-10-15 09:58:41 +1100
committerAngus Gratton <angus@redyak.com.au>2025-10-15 16:34:05 +1100
commit2f88c1e795334ab064b058bf28dfb38a59836a71 (patch)
treec8be20762891d4dfa4cdbb6e61eaf97605aef2e4
parent00a926e99e45cf17cc96f73476fb9def2af567aa (diff)
esp32: Update tools/metrics_esp32.py to use JSON output.
Much cleaner. Also add deltas to the output table for easier interpretation. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
-rw-r--r--ports/esp32/Makefile4
-rwxr-xr-xports/esp32/tools/metrics_esp32.py72
2 files changed, 43 insertions, 33 deletions
diff --git a/ports/esp32/Makefile b/ports/esp32/Makefile
index 7f31ea691..d0984127c 100644
--- a/ports/esp32/Makefile
+++ b/ports/esp32/Makefile
@@ -98,10 +98,10 @@ monitor:
$(call RUN_IDF_PY,$(DEVICE) monitor)
size:
- $(call RUN_IDF_PY,size)
+ $(call RUN_IDF_PY,size $(SIZE_FLAGS))
size-components:
- $(call RUN_IDF_PY,size-components)
+ $(call RUN_IDF_PY,size-components $(SIZE_FLAGS))
size-files:
$(call RUN_IDF_PY,size-files)
diff --git a/ports/esp32/tools/metrics_esp32.py b/ports/esp32/tools/metrics_esp32.py
index 70f049c3b..ad4acf6c7 100755
--- a/ports/esp32/tools/metrics_esp32.py
+++ b/ports/esp32/tools/metrics_esp32.py
@@ -27,9 +27,7 @@
#
# 5) If all goes well, it will run for a while and then print a Markdown
# formatted table of binary sizes, sorted by board+variant.
-#
-# Note that for ESP32-S3 and C3, IRAM and DRAM are exchangeable so the IRAM size
-# column of the table is really D/IRAM.
+import json
import os
import re
import shutil
@@ -37,12 +35,14 @@ import sys
import subprocess
from dataclasses import dataclass
-IDF_VERS = ("v5.4.2",)
+IDF_VERS = ("v5.5.1", "v5.4.2")
BUILDS = (
("ESP32_GENERIC", ""),
("ESP32_GENERIC", "D2WD"),
("ESP32_GENERIC", "SPIRAM"),
+ ("ESP32_GENERIC_C2", ""),
+ ("ESP32_GENERIC_C6", ""),
("ESP32_GENERIC_S3", ""),
("ESP32_GENERIC_S3", "SPIRAM_OCT"),
)
@@ -60,9 +60,9 @@ class BuildSizes:
idf_ver: str
board: str
variant: str
- bin_size: str = ""
- dram_size: str = ""
- iram_size: str = ""
+ bin_size: int | str = ""
+ dram_size: int = 0
+ iram_size: int = 0
def print_summary(self, include_ver=False):
print(f"BOARD={self.board} BOARD_VARIANT={self.variant}")
@@ -80,7 +80,18 @@ class BuildSizes:
"|-------|---------------|-------------|-------------|------------------|------------------|"
)
- def print_table_row(self, print_board):
+ def print_table_row(self, print_board, baseline=None):
+ def compare(field):
+ this = getattr(self, field)
+ if baseline and isinstance(this, int):
+ base = getattr(baseline, field)
+ delta = this - base
+ pct = ((this / base) * 100) - 100
+ plus = "+" if delta >= 0 else ""
+ return f"{this} ({plus}{delta}/{pct:.1f})"
+ else:
+ return str(this)
+
print(
"| "
+ " | ".join(
@@ -88,9 +99,9 @@ class BuildSizes:
self.board if print_board else "",
self.variant if print_board else "",
self.idf_ver,
- self.bin_size,
- self.iram_size,
- self.dram_size,
+ compare("bin_size"),
+ compare("iram_size"),
+ compare("dram_size"),
)
)
+ " |"
@@ -131,25 +142,19 @@ class BuildSizes:
def make_size(self):
try:
- size_out = self.run_make("size")
- try:
- # pre IDF v5.4 size output
- # "Used static DRAM:" or "Used stat D/IRAM:"
- RE_DRAM = r"Used stat(?:ic)? D.*: *(\d+) bytes"
- RE_IRAM = r"Used static IRAM: *(\d+) bytes"
- self.dram_size = re.search(RE_DRAM, size_out).group(1)
- self.iram_size = re.search(RE_IRAM, size_out).group(1)
- except AttributeError:
- # IDF v5.4 size output is much nicer formatted
- # Note the pipes in these expressions are not the ASCII/RE |
- RE_DRAM = r"│ *DI?RAM *│ *(\d+)"
- RE_IRAM = r"│ *IRAM *│ *(\d+)"
- self.dram_size = re.search(RE_DRAM, size_out).group(1)
- self.iram_size = re.search(RE_IRAM, size_out).group(1)
-
- # This line is the same on before/after versions
- RE_BIN = r"Total image size: *(\d+) bytes"
- self.bin_size = re.search(RE_BIN, size_out).group(1)
+ size_out = self.run_make("size SIZE_FLAGS='--format json'")
+ size_out = size_out[size_out.rindex("{") :]
+ size_out = json.loads(size_out)
+
+ def sum_sizes(*keys):
+ return sum(size_out.get(k, 0) for k in keys)
+
+ # Different targets report DRAM, IRAM, and/or D/IRAM separately
+ self.dram_size = sum_sizes(
+ "used_dram", "diram_data", "diram_bss", "diram_rodata", "diram_other"
+ )
+ self.iram_size = sum_sizes("used_iram", "diram_text", "diram_vectors")
+ self.bin_size = size_out["total_size"]
except subprocess.CalledProcessError:
self.bin_size = "build failed"
@@ -184,11 +189,16 @@ def main(do_clean):
# print everything again as a table sorted by board+variant
last_bv = ""
+ baseline_sizes = None
BuildSizes.print_table_heading()
for build_sizes in sorted(sizes):
bv = (build_sizes.board, build_sizes.variant)
- build_sizes.print_table_row(last_bv != bv)
+ new_board = last_bv != bv
+ if new_board:
+ baseline_sizes = None
+ build_sizes.print_table_row(last_bv != bv, baseline_sizes)
last_bv = bv
+ baseline_sizes = build_sizes
def idf_git(*commands):