chore: Added RAM to firmware_size_history.py script (#1830)

This commit is contained in:
jpirnay
2026-05-05 10:26:29 +02:00
parent 3b4e8f8df9
commit 47d3d1fc9c
+57 -30
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Build firmware at selected commits and report flash usage. Build firmware at selected commits and report flash and RAM usage.
Two modes (mutually exclusive, one required): Two modes (mutually exclusive, one required):
@@ -33,6 +33,9 @@ import re
import subprocess import subprocess
import sys import sys
RAM_RE = re.compile(
r"RAM:.*?(\d+)\s+bytes\s+from\s+(\d+)\s+bytes"
)
FLASH_RE = re.compile( FLASH_RE = re.compile(
r"Flash:.*?(\d+)\s+bytes\s+from\s+(\d+)\s+bytes" r"Flash:.*?(\d+)\s+bytes\s+from\s+(\d+)\s+bytes"
) )
@@ -93,9 +96,9 @@ def build_firmware(env):
return result.returncode, result.stdout + "\n" + result.stderr return result.returncode, result.stdout + "\n" + result.stderr
def parse_flash_used(output): def parse_size_line(regex, output):
"""Extract used-bytes integer from PlatformIO output, or None.""" """Extract used-bytes integer matching *regex* from PlatformIO output, or None."""
m = FLASH_RE.search(output) m = regex.search(output)
if m: if m:
return int(m.group(1)) return int(m.group(1))
return None return None
@@ -111,10 +114,10 @@ def write_csv(out, rows, fieldnames):
def format_table(rows): def format_table(rows):
"""Print rows as an aligned human-readable table to stdout.""" """Print rows as an aligned human-readable table to stdout."""
COL_COMMIT = 10 COL_COMMIT = 10
COL_FLASH = 11 COL_SIZE = 11
COL_DELTA = 7 COL_DELTA = 7
def fmt_flash(val): def fmt_size(val):
if val == "FAILED": if val == "FAILED":
return "FAILED" return "FAILED"
return f"{val:,}" return f"{val:,}"
@@ -126,25 +129,33 @@ def format_table(rows):
header = ( header = (
f"{'Commit':<{COL_COMMIT}} " f"{'Commit':<{COL_COMMIT}} "
f"{'Flash':>{COL_FLASH}} " f"{'Flash':>{COL_SIZE}} "
f"{'Delta':>{COL_DELTA}} "
f"{'RAM':>{COL_SIZE}} "
f"{'Delta':>{COL_DELTA}} " f"{'Delta':>{COL_DELTA}} "
f"Title" f"Title"
) )
sep = ( sep = (
f"{BOX_CHAR * COL_COMMIT} " f"{BOX_CHAR * COL_COMMIT} "
f"{BOX_CHAR * COL_FLASH} " f"{BOX_CHAR * COL_SIZE} "
f"{BOX_CHAR * COL_DELTA} "
f"{BOX_CHAR * COL_SIZE} "
f"{BOX_CHAR * COL_DELTA} " f"{BOX_CHAR * COL_DELTA} "
f"{BOX_CHAR * 40}" f"{BOX_CHAR * 40}"
) )
print(header) print(header)
print(sep) print(sep)
for row in rows: for row in rows:
flash_str = fmt_flash(row["flash_bytes"]) flash_str = fmt_size(row["flash_bytes"])
delta_str = fmt_delta(row["delta"]) flash_d = fmt_delta(row["flash_delta"])
ram_str = fmt_size(row["ram_bytes"])
ram_d = fmt_delta(row["ram_delta"])
print( print(
f"{row['commit']:<{COL_COMMIT}} " f"{row['commit']:<{COL_COMMIT}} "
f"{flash_str:>{COL_FLASH}} " f"{flash_str:>{COL_SIZE}} "
f"{delta_str:>{COL_DELTA}} " f"{flash_d:>{COL_DELTA}} "
f"{ram_str:>{COL_SIZE}} "
f"{ram_d:>{COL_DELTA}} "
f"{row['title']}" f"{row['title']}"
) )
@@ -173,7 +184,7 @@ def build_commits_from_list(refs):
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Measure firmware flash size across git commits.", description="Measure firmware flash and RAM size across git commits.",
epilog=( epilog=(
"Range mode walks every commit between START and END (one branch). " "Range mode walks every commit between START and END (one branch). "
"List mode builds specific refs that may come from different branches." "List mode builds specific refs that may come from different branches."
@@ -233,19 +244,22 @@ def main():
print(f" Building (env: {args.env})...", file=sys.stderr) print(f" Building (env: {args.env})...", file=sys.stderr)
rc, output = build_firmware(args.env) rc, output = build_firmware(args.env)
if rc != 0: build_failed = rc != 0
if build_failed:
print(f" BUILD FAILED (exit {rc}) -- skipping", file=sys.stderr) print(f" BUILD FAILED (exit {rc}) -- skipping", file=sys.stderr)
results.append((sha, title, None)) results.append((sha, title, None, None, True))
continue continue
used = parse_flash_used(output) flash_used = parse_size_line(FLASH_RE, output)
if used is None: ram_used = parse_size_line(RAM_RE, output)
if flash_used is None:
print(" Could not parse flash size from output -- skipping", file=sys.stderr) print(" Could not parse flash size from output -- skipping", file=sys.stderr)
results.append((sha, title, None)) results.append((sha, title, None, None, True))
continue continue
print(f" Flash used: {used:,} bytes", file=sys.stderr) ram_str = f", RAM: {ram_used:,}" if ram_used is not None else ""
results.append((sha, title, used)) print(f" Flash: {flash_used:,}{ram_str} bytes", file=sys.stderr)
results.append((sha, title, flash_used, ram_used, False))
except KeyboardInterrupt: except KeyboardInterrupt:
print("\n[info] Interrupted -- writing partial results.", file=sys.stderr) print("\n[info] Interrupted -- writing partial results.", file=sys.stderr)
@@ -258,22 +272,35 @@ def main():
# Build result rows with deltas # Build result rows with deltas
rows = [] rows = []
prev_size = None prev_flash = None
for sha, title, used in results: prev_ram = None
if used is not None and prev_size is not None: for sha, title, flash_used, ram_used, build_failed in results:
delta = used - prev_size flash_delta = ""
ram_delta = ""
if flash_used is not None and prev_flash is not None:
flash_delta = flash_used - prev_flash
if ram_used is not None and prev_ram is not None:
ram_delta = ram_used - prev_ram
if build_failed:
flash_bytes = "FAILED"
ram_bytes = "FAILED"
else: else:
delta = "" flash_bytes = flash_used if flash_used is not None else "N/A"
ram_bytes = ram_used if ram_used is not None else "N/A"
rows.append({ rows.append({
"commit": sha[:10], "commit": sha[:10],
"title": title, "title": title,
"flash_bytes": used if used is not None else "FAILED", "flash_bytes": flash_bytes,
"delta": delta, "flash_delta": flash_delta,
"ram_bytes": ram_bytes,
"ram_delta": ram_delta,
}) })
if used is not None: if flash_used is not None:
prev_size = used prev_flash = flash_used
if ram_used is not None:
prev_ram = ram_used
fieldnames = ["commit", "title", "flash_bytes", "delta"] fieldnames = ["commit", "title", "flash_bytes", "flash_delta", "ram_bytes", "ram_delta"]
if args.csv is not None: if args.csv is not None:
if args.csv == "-": if args.csv == "-":