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
6 changes: 6 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ scripts/capture_patterns.py --host cube.local <pattern id>` (frames come from
watchdog's backtrace, printed mid-write, panicked the cube ("Cache disabled
but cached memory region accessed", reset reason "interrupt watchdog"). Sleep
a minimum each pass, as `Updates::animationLoop` and `Renderer::loop` do.
- **The image must fit 0x1E0000 bytes.** Some cubes still have Arduino's old
`min_spiffs.csv` partition table (1,966,080-byte app slots), and a partition
table only changes over USB. A bigger image fails every update path at 99%
with `ESP_ERR_INVALID_SIZE`; v0.6.0 was 17 KB over. `scripts/size_guard.py`
fails the build first. Silent assertions buy ~59 KB; `-Os` would buy more
but slows rendering.
- **Never flash `firmware.factory.bin` to a cube that is set up.** The merged
image's padding covers NVS (0x9000-0xDFFF) and wipes WiFi, settings and the
Spotify login. Update with the upload card or ArduinoOTA; over USB write only
Expand Down
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ upload_port = cube.local
; copy in hub and lp-p2p.
extra_scripts =
scripts/idf_scripts.py
scripts/size_guard.py
; arduino-esp32's component manifest pulls in RainMaker, Insights, Zigbee,
; speech recognition, Modbus and more, whether or not the sketch uses them.
; The cube uses none of them. Removing them shortens the build and drops the
Expand Down
34 changes: 34 additions & 0 deletions scripts/size_guard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""Fails the build when firmware.bin would not fit an older cube's app slot.

Some cubes in the field still have the partition table from before
min_spiffs_s3.csv: Arduino's min_spiffs.csv, whose app slots are 0x1E0000
bytes. A partition table only changes over USB, so those cubes keep it through
every OTA update, and an image larger than the slot fails at 99% with
ESP_ERR_INVALID_SIZE -- the upload card, ArduinoOTA and the GitHub updater
alike. v0.6.0 was 17 KB over and could not reach them.

Keep this until no cube with the old table is left.
"""

Import("env")

import os

OLD_APP_SLOT = 0x1E0000 # app0/app1 in min_spiffs.csv


def check_size(source, target, env):
path = target[0].get_abspath()
size = os.path.getsize(path)
margin = OLD_APP_SLOT - size
if margin < 0:
print(
"\n*** %s is %d bytes, %d over the %d-byte app slot that cubes with the "
"old min_spiffs.csv partition table have. They could not install it. "
"See scripts/size_guard.py.\n" % (os.path.basename(path), size, -margin, OLD_APP_SLOT)
)
env.Exit(1)
print("Old-layout app slot: %d bytes free (image %d of %d)" % (margin, size, OLD_APP_SLOT))


env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", check_size)
6 changes: 5 additions & 1 deletion sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ CONFIG_ARDUINO_RUN_NO_AFFINITY=y
CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO=y

# Optimize for speed. The IDF default (-Og) is for debugging; the render loop's
# per-pixel work runs measurably faster at -O2. Flash has plenty of room.
# per-pixel work runs measurably faster at -O2.
CONFIG_COMPILER_OPTIMIZATION_PERF=y
# Assertions still stop the cube, but without compiling in each one's file
# name and expression: about 59 KB, which keeps the image inside the 0x1E0000
# app slots of cubes still on the old partition table (scripts/size_guard.py).
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

# CPU, RTOS, console
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
Expand Down
Loading