Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,13 @@ jobs:

- name: Extract flash usage
run: |
LINE=$(grep -oE 'Flash:[^(]*\(used [0-9]+ bytes from [0-9]+ bytes\)' build.log | tail -1)
USED=$(echo "$LINE" | grep -oE 'used [0-9]+' | grep -oE '[0-9]+')
TOTAL=$(echo "$LINE" | grep -oE 'from [0-9]+' | grep -oE '[0-9]+')
# Use the APPSIZE line (actual firmware.bin size vs app partition,
# from build/scripts/check_app_size.py) - NOT PlatformIO's "Flash:"
# figure, which omits MMU-alignment padding and understates the
# image the bootloader actually validates against the partition.
LINE=$(grep -oE 'APPSIZE: firmware\.bin is [0-9]+ bytes, app partition is [0-9]+ bytes' build.log | tail -1)
USED=$(echo "$LINE" | grep -oE '[0-9]+' | head -1)
TOTAL=$(echo "$LINE" | grep -oE '[0-9]+' | tail -1)
mkdir -p meta
echo "${{ matrix.env }}|${USED}|${TOTAL}" > meta/flash-${{ matrix.env }}.txt
cat meta/flash-${{ matrix.env }}.txt
Expand All @@ -144,7 +148,7 @@ jobs:
0x8000 .pio/build/${{ matrix.env }}/partitions.bin \
0xe000 "${{ steps.tools.outputs.boot_app0 }}" \
0x10000 .pio/build/${{ matrix.env }}/firmware.bin \
0x290000 .pio/build/${{ matrix.env }}/littlefs.bin
0x310000 .pio/build/${{ matrix.env }}/littlefs.bin

- name: Copy app-only image
run: |
Expand Down
59 changes: 59 additions & 0 deletions build/scripts/check_app_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# FAIL THE BUILD IF firmware.bin DOES NOT FIT THE APP PARTITION
#
# PlatformIO's "Flash: X% (used N from M)" check sums ELF sections, but the
# flashed .bin also contains MMU-alignment padding between mapped segments
# (~113KB on ESP32-C3). The bootloader validates the *full image length*
# against the app partition on every boot and refuses to boot an image that
# spills past it - an endless rst:0x3 reset loop with no error visible on
# USB-only boards. So the on-disk .bin size, not PlatformIO's figure, is the
# number that matters.
Import("env")

import csv
import os


def get_app_partition_size():
partitions = env.BoardConfig().get("build.partitions", "default.csv")
path = partitions
if not os.path.isabs(path):
candidate = os.path.join(env.subst("$PROJECT_DIR"), partitions)
if os.path.exists(candidate):
path = candidate
else:
framework_dir = env.PioPlatform().get_package_dir(
"framework-arduinoespressif32"
)
path = os.path.join(framework_dir, "tools", "partitions", partitions)
sizes = []
with open(path) as f:
for row in csv.reader(f):
if not row or row[0].strip().startswith("#") or len(row) < 5:
continue
if row[1].strip() == "app":
sizes.append(int(row[4].strip(), 0))
if not sizes:
raise RuntimeError("No app partitions found in " + path)
return min(sizes), path


def check_bin_size(source, target, env):
bin_path = env.subst("$BUILD_DIR/${PROGNAME}.bin")
bin_size = os.path.getsize(bin_path)
app_size, table = get_app_partition_size()
pct = bin_size / app_size * 100
print(
"APPSIZE: firmware.bin is %d bytes, app partition is %d bytes (%.1f%%)"
% (bin_size, app_size, pct)
)
if bin_size > app_size:
print(
"APPSIZE: ERROR - firmware.bin exceeds the app partition in %s by "
"%d bytes. The bootloader will refuse to boot this image "
"(silent rst:0x3 boot loop). Shrink the firmware or grow the app "
"partitions." % (table, bin_size - app_size)
)
env.Exit(1)


env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", check_bin_size)
8 changes: 5 additions & 3 deletions build/scripts/render_release_notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
#
# <meta-dir> holds flash-<env>.txt files, one per board, each a single line:
# <env>|<used-bytes>|<total-bytes>
# produced by the release workflow parsing PlatformIO's "Flash: ... (used X from Y)"
# output. We use PlatformIO's reported figure (not the on-disk firmware.bin size,
# which includes chip-specific MMU-alignment padding and overstates usage).
# produced by the release workflow parsing the APPSIZE line from
# build/scripts/check_app_size.py: the on-disk firmware.bin size vs the app
# partition size. The .bin size (including MMU-alignment padding) is what the
# bootloader validates against the partition, so it is the honest figure -
# PlatformIO's smaller "Flash:" number is what let an oversized C3 image ship.
Comment thread
DrewFerg11 marked this conversation as resolved.
#
# [ai-summary-file], if given and non-empty, is a short AI-generated summary of the
# commit log (see release.yml's "AI release summary" step). Best-effort only - if
Expand Down
13 changes: 13 additions & 0 deletions partitions_4MB.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Custom 4MB layout: app slots grown to 1.5MB (0x180000) each, filesystem
# shrunk to 896KB (0xE0000). The stock default.csv's 1.25MB app slots are too
# small for this firmware's ESP32-C3 image: the flashed .bin includes ~113KB
# of MMU-alignment padding beyond PlatformIO's reported "Flash" figure, and
# once the .bin exceeds the app partition the bootloader rejects the image on
# every boot (endless rst:0x3 loop with no output on USB-only boards).
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xE000, 0x2000,
app0, app, ota_0, 0x10000, 0x180000,
app1, app, ota_1, 0x190000, 0x180000,
spiffs, data, spiffs, 0x310000, 0xE0000,
coredump, data, coredump, 0x3F0000, 0x10000,
5 changes: 5 additions & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ data_dir=.pio/build/littlefs
[env]
framework=arduino
board_build.filesystem=littlefs
; Larger app slots than the stock table - see comment in partitions_4MB.csv.
; NOTE: littlefs moved from 0x290000 to 0x310000; keep release.yml merge_bin
; offsets in sync.
board_build.partitions=partitions_4MB.csv
platform=platformio/espressif32
upload_protocol=esptool

extra_scripts=
pre:build/scripts/inject_version.py
post:build/scripts/gzip_littlefs.py
post:build/scripts/check_app_size.py

lib_deps=
bblanchon/ArduinoJson@^7.3.1
Expand Down
Loading