fix: size CURRENT.UF2 to the real installed app, not the max region - #20
Conversation
CURRENT.UF2 (the on-the-fly dump of whatever's currently flashed, generated by read_block()) has reported and generated content sized to TRUE_USER_FLASH_SIZE - the max possible app+SoftDevice region - rather than how big the actually-installed app is. On a RAK4631 running Meshtastic 2.7.26, that meant CURRENT.UF2 was ~390KB larger than the official firmware image (3728 vs 2966 UF2 blocks), padding out with whatever's physically sitting in flash past the real app+SD boundary. Copying CURRENT.UF2 back onto the drive to restore the app it came from - a workaround documented as working by users hitting stuck-in- DFU-mode bugs (adafruit#201) - reproducibly hung the device on real RAK4631 hardware while investigating the nrfx/tinyusb bump in #19, on both this repo's current bootloader and the bumped one (a control test on the unmodified bootloader hung the same way, ruling out the bump as the cause). adafruit#38 (2018) fixed a related CURRENT.UF2 problem by sizing it off bootloader_settings.bank_0_size - the real recorded size of the currently-installed app - instead of a fixed constant. That fix has no trace left in the current file; this restores the same idea (current_flash_size(), with the same zero/erased-flash fallback to the max region) grafted onto the current SoftDevice-decoupled code from adafruit#128, which computes the max bound differently (TRUE_USER_FLASH_SIZE) than the 2018 code did. Verified: all 14 boards still build via tools/build_all.py. Hardware retest of the exact CURRENT.UF2 dump-and-restore sequence that hung before is next. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe update process records the written application size. The virtual FAT filesystem uses this value to calculate ChangesUF2 application sizing
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The change sizes CURRENT.UF2 to the installed application and records that size for UF2 installs; no actionable merge-blocking risk remains, so the PR is merge-ready after normal checks. Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Hardware test: confirmed fixed, on the same RAK4631 that reproduced the hangFound a second bug needed to make this fix actually take effect for the common case (app flashed via plain UF2 drag-and-drop, not DFU-serial): Verified on hardware, step by step:
Both commits in this PR are needed together — |
ghostfat.c's current_flash_size() (this branch's other commit) reads bootloader_settings.bank_0_size to size CURRENT.UF2 to the real installed app. But tud_msc_write10_complete_cb()'s app-completion branch never set update_status.app_size before calling bootloader_dfu_update_process() - it stayed 0 from the initial memset, so bank_0_size was always recorded as 0 for any app flashed via plain UF2 drag-and-drop (as opposed to the DFU-serial protocol, which transmits size upfront and was unaffected). Verified on hardware: after this fix, CURRENT.UF2 exactly matches the real firmware size (1518592 bytes, matching the official release UF2 byte for byte) instead of the previous 1908736 bytes of padding. The CURRENT.UF2 dump-and-restore sequence that reproducibly hung the device before now completes in ~2 seconds with no hang. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
#20 root-caused and fixed what this note previously flagged as an open mystery hit during this PR's hardware testing.
* fix: bump lib/nrfx and lib/tinyusb together, fix the fallout Renovate's PR #11 (nrfx digest) and #12 (tinyusb digest) each failed CI on every board. Investigated both: - nrfx alone (bumped to Renovate's target, nrfx 4.5.0/1b7bedb) breaks the build immediately: nrfx 4.0 restructured its whole layout (mdk/ -> bsp/stable/mdk/, etc.), so this repo's Makefile IPATHs can't find nrf.h at all. That's a real rework, not a digest bump - pinned to v3.14.0 instead, the last tag before the 4.0 restructure. - tinyusb alone (Renovate's target, 5c0e31c) fails to compile against the old 2019 nrfx pin: its nrf5x USB port calls nrfx's chip-errata functions (nrf52_errata_199()) that don't exist yet at that nrfx version. The two submodules move together. With nrfx at v3.14.0 and tinyusb at 5c0e31c, three more issues surfaced, all fixed here: - tinyusb merged device/usbd_control.c into usbd.c; the Makefile's hardcoded tinyusb C_SRC list still named the now-gone file. - nrfx renamed nrf_wdt_started()/nrf_wdt_request_status() in the WDT HAL (see lib/nrfx/CHANGELOG.md) - the one in-repo call site needed updating. - nrfx's gcc_startup_<mcu>.S (since nrfx 3.x) copies .data via __data_start/__data_end (no trailing underscore) instead of this repo's __data_start__/__data_end__, plus three new RAM-loaded regions (.sdata/.tdata/.fast) nothing here uses. Added alias symbols and zero-length filler for the unused regions to linker/nrf_common.ld - deliberately not swapping in nrfx's own updated linker script, which also redefines .bss/.noinit placement and would fight this repo's board .ld files' fixed-address NOINIT region (BLE bond exchange across a DFU reset). Verified: all 14 boards build and link clean via tools/build_all.py. Not done here: real hardware testing. This is still the multi-year boot-critical submodule bump AGENTS.md already flagged as needing it before merge - a clean build is necessary, not sufficient. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs: record the CURRENT.UF2 restore gotcha found during hardware testing Real RAK4631 hardware testing for this branch (see PR #19) hit this: restoring an app via ghostfat's live CURRENT.UF2 dump left the device hung on boot even though the bytes matched what was there before. A normal release UF2 or OTA-DFU flash both worked fine immediately after. Recording it so it doesn't get mistaken for a regression from this PR's actual change (nrfx/tinyusb) next time someone hits it. * docs: update the CURRENT.UF2 gotcha now that it's fixed, not untriaged #20 root-caused and fixed what this note previously flagged as an open mystery hit during this PR's hardware testing. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Summary
While hardware-testing #19 (nrfx/tinyusb bump) on a real RAK4631, restoring the app via the bootloader's own
CURRENT.UF2(a live dump of the app region, generated byghostfat.c'sread_block()) reproducibly hung the device — even though the bytes being written back were byte-identical to what was already there. A control test confirmed this is pre-existing, not caused by #19: the unmodified, currently-shipped bootloader hangs the exact same way.Digging into it turned up real history:
CURRENT.UF2currently reports/generates content sized toTRUE_USER_FLASH_SIZE— the max possible app+SoftDevice region — regardless of how big the actually-installed app is. On the test device (RAK4631, Meshtastic 2.7.26), that's ~390KB more than the real firmware image (3728 vs 2966 UF2 blocks), padding out with whatever's physically sitting in flash past the real app+SD boundary.CURRENT.UF2problem by sizing it offbootloader_settings.bank_0_size(the real recorded size of the currently-installed app) instead of a fixed constant. That fix has no trace left in the current file — it was dropped somewhere along the way, likely during #128's SoftDevice-decoupling rewrite in 2020 (whose own checklist claimsCURRENT.UF2was tested working at the time).CURRENT.UF2back onto the drive as a working community-known recovery trick for devices stuck in DFU mode — so this round-trip is supposed to be reliable, not "expected to be flaky."Fix
Two commits, both required together:
ghostfat.c: restores the same idea as the 2018 fix —current_flash_size(), readingbootloader_settings.bank_0_sizewith the same zero/erased-flash fallback to the max region — grafted onto the current SoftDevice-decoupled code, which computes the max bound differently (TRUE_USER_FLASH_SIZE, not the 2018 code's constant).msc_uf2.c: found while testing commit 1 —bank_0_sizewas still being recorded as 0 for any app flashed via plain UF2 drag-and-drop (as opposed to DFU-serial, which populates it correctly), becausetud_msc_write10_complete_cb()'s app-completion branch never setupdate_status.app_sizebefore callingbootloader_dfu_update_process(). Commit 1 does nothing for the common case without this.Test plan
tools/build_all.py— all 14 boards build cleanCURRENT.UF2dump-and-restore sequence that hung before, on the same RAK4631 — confirmed fixed. After both commits:CURRENT.UF2reports exactly 1518592 bytes, an exact match with the official release UF2 (previously 1908736 bytes of padding). Dumped it and copied it straight back — device rebooted in ~2 seconds and came back fully functional, versus the previous indefinite hang / 36-second-then-still-broken behavior (details in PR comments).bank_0_sizefix in particular is board-independent (it's in sharedusb/code, notsrc/boards/), but broader testing before merge is still reasonable for boot-critical code like this.Summary by CodeRabbit