diff options
| author | Angus Gratton <angus@redyak.com.au> | 2025-10-15 09:58:41 +1100 |
|---|---|---|
| committer | Angus Gratton <angus@redyak.com.au> | 2025-10-15 16:34:05 +1100 |
| commit | 2f88c1e795334ab064b058bf28dfb38a59836a71 (patch) | |
| tree | c8be20762891d4dfa4cdbb6e61eaf97605aef2e4 | |
| parent | 00a926e99e45cf17cc96f73476fb9def2af567aa (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/Makefile | 4 | ||||
| -rwxr-xr-x | ports/esp32/tools/metrics_esp32.py | 72 |
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): |
