Give the 4MB T3-S3 boards an app partition that fits - #10978
Conversation
device-install.sh read the spiffs offset out of the .mt.json metadata into SPIFFS_OFFSET, but flashed the littlefs image at $OFFSET -- a separate variable still holding the hardcoded 0x300000 default. The metadata value was never used, so any board with a non-default partition table had its filesystem written to the wrong place. Unify on SPIFFS_OFFSET, and guard both metadata overrides so a table that omits ota_1 or spiffs falls back to the built-in default instead of handing esptool an empty offset. Quote both offsets at the call site: the spiffs one is newly consumed from jq, and a multi-line result would otherwise word-split into esptool's argv and silently mis-pair address with file. device-install.bat already does all of this correctly; this brings the shell script to parity.
tlora-t3s3-v1 and tlora-t3s3-epaper have overflowed the shared 4MB partition-table.csv app slot (ota_0 = 0x250000 = 2,424,832 bytes) on every develop build since 22072c5 (2026-06-20). The last green build, ca7d826, cleared it by 881 bytes; develop is now ~38.7KB over. These envs have no board_level, so they only build in the full matrix on push to develop -- which is why no PR ever caught it. Add partition-table-t3s3.csv, dedicated to the 4MB ESP32-S3FH4R2 T3-S3 boards, and point all three t3s3 envs at it: app ota_0 0x010000 0x290000 (was 0x250000, +256KB) flashApp ota_1 0x2A0000 0x0A0000 (unchanged size) spiffs 0x340000 0x0C0000 (was 0x100000, -256KB) The headroom comes out of spiffs, not flashApp: the unified BLE OTA image is 636,544 bytes against a 655,360 byte slot, so ota_1 has nothing to give. The table is contiguous, ends exactly on the 4MB boundary, keeps both app partitions 64KB-aligned, and leaves the littlefs image these boards ship well inside the remaining 768KB. Verified with a Docker build of all three envs: tlora-t3s3-v1 2,463,504 91.7% tlora-t3s3-epaper 2,458,487 91.5% tlora-t3s3-epaper-inkhud 2,400,851 89.4% Trimming was considered and rejected. The entire emoji set is 6,304 bytes (measured A/B build), and cutting traffic management plus the paxcounter, storeforward, rangetest and atak modules recovers 46,636 -- enough to land at 99.7% full, i.e. weeks of headroom at develop's observed growth rate, in exchange for shipping a feature-reduced board. The slot was simply mis-sized for a board this full. Note this changes flash layout: existing T3-S3 units must be erased and factory-flashed once to pick up the new offsets. They already cannot run a current develop build, so no working configuration regresses.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
📝 WalkthroughWalkthroughT3S3 PlatformIO environments now select an explicit partition table. The device installer defines fallback offsets, conditionally uses valid firmware metadata offsets, and flashes OTA and SPIFFS images using the resolved values. ChangesPartition-aware firmware flashing
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
⚡ Try this PR in the Web FlasherWarning This is an automated, unreviewed CI test build. Back up your device configuration Supported boards built by this PR (27)
Build artifacts expire on 2026-08-09. Updated for |
* fix(device-install): flash littlefs at the offset from firmware metadata device-install.sh read the spiffs offset out of the .mt.json metadata into SPIFFS_OFFSET, but flashed the littlefs image at $OFFSET -- a separate variable still holding the hardcoded 0x300000 default. The metadata value was never used, so any board with a non-default partition table had its filesystem written to the wrong place. Unify on SPIFFS_OFFSET, and guard both metadata overrides so a table that omits ota_1 or spiffs falls back to the built-in default instead of handing esptool an empty offset. Quote both offsets at the call site: the spiffs one is newly consumed from jq, and a multi-line result would otherwise word-split into esptool's argv and silently mis-pair address with file. device-install.bat already does all of this correctly; this brings the shell script to parity. * fix(tlora-t3s3): give the 4MB T3-S3 boards an app partition that fits tlora-t3s3-v1 and tlora-t3s3-epaper have overflowed the shared 4MB partition-table.csv app slot (ota_0 = 0x250000 = 2,424,832 bytes) on every develop build since 22072c5 (2026-06-20). The last green build, ca7d826, cleared it by 881 bytes; develop is now ~38.7KB over. These envs have no board_level, so they only build in the full matrix on push to develop -- which is why no PR ever caught it. Add partition-table-t3s3.csv, dedicated to the 4MB ESP32-S3FH4R2 T3-S3 boards, and point all three t3s3 envs at it: app ota_0 0x010000 0x290000 (was 0x250000, +256KB) flashApp ota_1 0x2A0000 0x0A0000 (unchanged size) spiffs 0x340000 0x0C0000 (was 0x100000, -256KB) The headroom comes out of spiffs, not flashApp: the unified BLE OTA image is 636,544 bytes against a 655,360 byte slot, so ota_1 has nothing to give. The table is contiguous, ends exactly on the 4MB boundary, keeps both app partitions 64KB-aligned, and leaves the littlefs image these boards ship well inside the remaining 768KB. Verified with a Docker build of all three envs: tlora-t3s3-v1 2,463,504 91.7% tlora-t3s3-epaper 2,458,487 91.5% tlora-t3s3-epaper-inkhud 2,400,851 89.4% Trimming was considered and rejected. The entire emoji set is 6,304 bytes (measured A/B build), and cutting traffic management plus the paxcounter, storeforward, rangetest and atak modules recovers 46,636 -- enough to land at 99.7% full, i.e. weeks of headroom at develop's observed growth rate, in exchange for shipping a feature-reduced board. The slot was simply mis-sized for a board this full. Note this changes flash layout: existing T3-S3 units must be erased and factory-flashed once to pick up the new offsets. They already cannot run a current develop build, so no working configuration regresses.
Problem
tlora-t3s3-v1andtlora-t3s3-epaperhave exceeded the app slot of the sharedpartition-table.csv(ota_0 = 0x250000= 2,424,832 B) on every develop build since 22072c5 (2026-06-20). The last green build,ca7d82629, cleared it by 881 bytes. develop today is ~38.7 KB over:These envs have no
board_level, sobin/generate_ci_matrix.py --level promits them — they only build in the full matrix on push to develop. That's why no PR ever caught it. The board never really had room; TMM nexthop (#10745) just tipped it.Fix
A dedicated
partition-table-t3s3.csvfor the 4 MB ESP32-S3FH4R2 T3-S3 boards, wired to all three t3s3 envs:appota_00x0100000x2900000x250000)flashAppota_10x2A00000x0A0000spiffs0x3400000x0C00000x100000)The headroom comes out of
spiffs, notflashApp. The unified BLE OTA image (meshtastic/esp32-unified-otav1.0.1,mt-esp32s3-ota.bin) is 636,544 B against a 655,360 B slot, soota_1has nothing to give. The table is contiguous, ends exactly at 4 MiB, and keeps both app partitions 64 KB-aligned.This follows existing precedent —
partition-table-8MB.csv,default_8MB.csv, anddefault_16MB.csvare already selected per-variant viaboard_build.partitions.Why not trim instead
Measured, not estimated:
-D EXCLUDE_EMOJI(guard already exists, unused)espressif/network_provisioningHAS_TRAFFIC_MANAGEMENT=0+ exclude paxcounter/storeforward/rangetest/atakThe full trim clears the cap by only 8,413 bytes — weeks of headroom at develop's observed ~38 KB/3-weeks growth — in exchange for shipping a feature-reduced board. The slot was mis-sized, not the firmware.
(For the record:
EXCLUDE_EMOJIalso cannot be enabled as-is.numEmotesbecomes 0, the clamp atCannedMessageModule.cpp:1835setsemotePickerIndex = -1, and:1016then readsemotes[-1].label. Reachable via CardKBfn+e.)Flasher fix (first commit)
bin/device-install.shread the spiffs offset from.mt.jsonintoSPIFFS_OFFSET, then flashed littlefs at$OFFSET— a different variable still holding the hardcoded0x300000. The metadata value was never used. Under the new table that writes the filesystem intoflashApp, clobbering the OTA image.Unified on
SPIFFS_OFFSET, guarded both metadata overrides against empty/nulljq results, and quoted the offsets at the call site.device-install.batalready did all three correctly; this brings the shell script to parity.Verification
Docker build of all three envs against the new table:
tlora-t3s3-v1tlora-t3s3-epapertlora-t3s3-epaper-inkhudPartition table validated for contiguity, 64 KB app alignment, and exact 4 MiB end.
bash -n+ shellcheck clean on the flasher.Existing T3-S3 units must be erased and factory-flashed once to pick up the new offsets; an OTA across the boundary would land the image at the wrong address. No working configuration regresses — these boards already cannot run a current develop build.
Downstream flashers that hardcode
0x260000/0x300000for ESP32 (web flasher, mobile apps) will need the same metadata-driven offset handling thatdevice-install.sh/.batnow use.Follow-up (not in this PR)
Once this is green, adding
board_level = prto the t3s3 envs would make PR CI catch the next overflow instead of develop.Summary by CodeRabbit
Bug Fixes
Configuration