Skip to content

Commit 2f88c1e

Browse files
committed
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 <[email protected]>
1 parent 00a926e commit 2f88c1e

File tree

2 files changed

+43
-33
lines changed

2 files changed

+43
-33
lines changed

ports/esp32/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,10 @@ monitor:
9898
$(call RUN_IDF_PY,$(DEVICE) monitor)
9999

100100
size:
101-
$(call RUN_IDF_PY,size)
101+
$(call RUN_IDF_PY,size $(SIZE_FLAGS))
102102

103103
size-components:
104-
$(call RUN_IDF_PY,size-components)
104+
$(call RUN_IDF_PY,size-components $(SIZE_FLAGS))
105105

106106
size-files:
107107
$(call RUN_IDF_PY,size-files)

ports/esp32/tools/metrics_esp32.py

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,22 +27,22 @@
2727
#
2828
# 5) If all goes well, it will run for a while and then print a Markdown
2929
# formatted table of binary sizes, sorted by board+variant.
30-
#
31-
# Note that for ESP32-S3 and C3, IRAM and DRAM are exchangeable so the IRAM size
32-
# column of the table is really D/IRAM.
30+
import json
3331
import os
3432
import re
3533
import shutil
3634
import sys
3735
import subprocess
3836
from dataclasses import dataclass
3937

40-
IDF_VERS = ("v5.4.2",)
38+
IDF_VERS = ("v5.5.1", "v5.4.2")
4139

4240
BUILDS = (
4341
("ESP32_GENERIC", ""),
4442
("ESP32_GENERIC", "D2WD"),
4543
("ESP32_GENERIC", "SPIRAM"),
44+
("ESP32_GENERIC_C2", ""),
45+
("ESP32_GENERIC_C6", ""),
4646
("ESP32_GENERIC_S3", ""),
4747
("ESP32_GENERIC_S3", "SPIRAM_OCT"),
4848
)
@@ -60,9 +60,9 @@ class BuildSizes:
6060
idf_ver: str
6161
board: str
6262
variant: str
63-
bin_size: str = ""
64-
dram_size: str = ""
65-
iram_size: str = ""
63+
bin_size: int | str = ""
64+
dram_size: int = 0
65+
iram_size: int = 0
6666

6767
def print_summary(self, include_ver=False):
6868
print(f"BOARD={self.board} BOARD_VARIANT={self.variant}")
@@ -80,17 +80,28 @@ def print_table_heading():
8080
"|-------|---------------|-------------|-------------|------------------|------------------|"
8181
)
8282

83-
def print_table_row(self, print_board):
83+
def print_table_row(self, print_board, baseline=None):
84+
def compare(field):
85+
this = getattr(self, field)
86+
if baseline and isinstance(this, int):
87+
base = getattr(baseline, field)
88+
delta = this - base
89+
pct = ((this / base) * 100) - 100
90+
plus = "+" if delta >= 0 else ""
91+
return f"{this} ({plus}{delta}/{pct:.1f})"
92+
else:
93+
return str(this)
94+
8495
print(
8596
"| "
8697
+ " | ".join(
8798
(
8899
self.board if print_board else "",
89100
self.variant if print_board else "",
90101
self.idf_ver,
91-
self.bin_size,
92-
self.iram_size,
93-
self.dram_size,
102+
compare("bin_size"),
103+
compare("iram_size"),
104+
compare("dram_size"),
94105
)
95106
)
96107
+ " |"
@@ -131,25 +142,19 @@ def run_make(self, target):
131142

132143
def make_size(self):
133144
try:
134-
size_out = self.run_make("size")
135-
try:
136-
# pre IDF v5.4 size output
137-
# "Used static DRAM:" or "Used stat D/IRAM:"
138-
RE_DRAM = r"Used stat(?:ic)? D.*: *(\d+) bytes"
139-
RE_IRAM = r"Used static IRAM: *(\d+) bytes"
140-
self.dram_size = re.search(RE_DRAM, size_out).group(1)
141-
self.iram_size = re.search(RE_IRAM, size_out).group(1)
142-
except AttributeError:
143-
# IDF v5.4 size output is much nicer formatted
144-
# Note the pipes in these expressions are not the ASCII/RE |
145-
RE_DRAM = r"│ *DI?RAM *│ *(\d+)"
146-
RE_IRAM = r"│ *IRAM *│ *(\d+)"
147-
self.dram_size = re.search(RE_DRAM, size_out).group(1)
148-
self.iram_size = re.search(RE_IRAM, size_out).group(1)
149-
150-
# This line is the same on before/after versions
151-
RE_BIN = r"Total image size: *(\d+) bytes"
152-
self.bin_size = re.search(RE_BIN, size_out).group(1)
145+
size_out = self.run_make("size SIZE_FLAGS='--format json'")
146+
size_out = size_out[size_out.rindex("{") :]
147+
size_out = json.loads(size_out)
148+
149+
def sum_sizes(*keys):
150+
return sum(size_out.get(k, 0) for k in keys)
151+
152+
# Different targets report DRAM, IRAM, and/or D/IRAM separately
153+
self.dram_size = sum_sizes(
154+
"used_dram", "diram_data", "diram_bss", "diram_rodata", "diram_other"
155+
)
156+
self.iram_size = sum_sizes("used_iram", "diram_text", "diram_vectors")
157+
self.bin_size = size_out["total_size"]
153158
except subprocess.CalledProcessError:
154159
self.bin_size = "build failed"
155160

@@ -184,11 +189,16 @@ def main(do_clean):
184189

185190
# print everything again as a table sorted by board+variant
186191
last_bv = ""
192+
baseline_sizes = None
187193
BuildSizes.print_table_heading()
188194
for build_sizes in sorted(sizes):
189195
bv = (build_sizes.board, build_sizes.variant)
190-
build_sizes.print_table_row(last_bv != bv)
196+
new_board = last_bv != bv
197+
if new_board:
198+
baseline_sizes = None
199+
build_sizes.print_table_row(last_bv != bv, baseline_sizes)
191200
last_bv = bv
201+
baseline_sizes = build_sizes
192202

193203

194204
def idf_git(*commands):

0 commit comments

Comments
 (0)