Skip to content

Check the init packet before invalidating the application - #3

Open
caveman99 wants to merge 1 commit into
masterfrom
dfu-sd-check-first
Open

caveman99 wants to merge 1 commit into
masterfrom
dfu-sd-check-first

Conversation

@caveman99

@caveman99 caveman99 commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

Description of Change

The single-bank DFU erased bank 0 when the start packet arrived and checked the device type, revision and installed SoftDevice only later, in dfu_init_prevalidate() with the init packet. A package built for another SoftDevice (for example --sd-req 0x310D on a board with s145 9.0.0) was refused after the application was already gone, leaving the board in the bootloader without an application.

RRAM is written without an erase, and both write paths (flash_nrf5x_write() on serial, sd_flash_write() through pstorage on BLE) already write without one, so the bulk erase is dropped:

  • The start packet is acknowledged at once.
  • Bank 0 is marked invalid in the settings only after dfu_init_prevalidate() accepts the init packet. The settings write goes through the same pstorage queue as the data writes, so it lands before the first data packet.
  • A refused package leaves the application and the settings untouched.

The transports are unchanged. adafruit-nrfutil waits after the start packet for the old erase and then sends the image right after the init packet, so the erase could not simply move to the init packet without risking ACK timeouts on large images. The dual-bank variant (DUALBANK_FW, off by default) is not changed.

Boards that already run v0.3.0 keep the old behavior until their bootloader is updated. This should go in before the bootloader release for s145 10.0.1.

Testing

Not yet tested on hardware. To check on an nRF54L15-DK:

  • Serial DFU with adafruit-nrfutil and BLE OTA of a matching package: update completes and the application boots.
  • A package with a mismatched --sd-req, over serial and over BLE: refused, and the board boots the existing application afterwards.
  • A transfer interrupted after data has started: the board stays in the bootloader.

Summary by CodeRabbit

  • Bug Fixes
    • Single-bank firmware updates no longer erase bank 0 when processing a start packet.
    • After an init packet passes validation, the update flow reports the application-cleared status before receiving firmware data.

The single-bank DFU erased bank 0 as soon as the start packet arrived and
checked the device type, revision and installed SoftDevice only later, with
the init packet. A package built for another SoftDevice was refused after the
application was already gone, leaving the board in the bootloader.

RRAM is written without an erase, so the bulk erase is dropped. The start
packet is acknowledged at once, and bank 0 is marked invalid in the settings
only after dfu_init_prevalidate() accepts the init packet. A refused package
now leaves the application in place.
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9dcd2d49-ed03-4f9f-90c1-8333b702865d
📥 Commits

Reviewing files that changed from the base of the PR and between dbbaa99 and 1bbbadb.

📒 Files selected for processing: 1
  • lib/sdk11/components/libraries/bootloader_dfu/dfu_single_bank.c

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

The single-bank DFU flow no longer erases the application when it accepts a start packet. After init-packet prevalidation succeeds, it calls the application-cleared status handler before entering data-receive state.

Changes: Single-bank DFU flow

Layer / File(s) Summary
Initialize storage and accept the start packet
lib/sdk11/components/libraries/bootloader_dfu/dfu_single_bank.c
dfu_init sets the active storage handle to the application storage handle. The start-packet path no longer prepares an application erase. After validation and timer restart, it sets the state to ready and sends a successful callback when registered.
Update status after init-packet validation
lib/sdk11/components/libraries/bootloader_dfu/dfu_single_bank.c
After init-packet prevalidation succeeds, the flow calls dfu_cleared_func_app before entering data-receive state.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 1bbba

Single-bank DFU no longer erases the existing application before checking the init packet, so a mismatched package can be rejected while the current application stays installed. The supported targets use RRAM, which can be written without an erase, and no concrete merge-blocking defect remains. Hardware testing on the nRF54L15-DK is still pending.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: validating the init packet before invalidating the application.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

A rabbit watched the start packet pass,
No erase swept across the grass.
The init packet cleared its test,
Then data hopped into the nest.
The app stayed safe beneath the moon.

Comment @coderabbitai help to get the list of available commands.

@caveman99

Copy link
Copy Markdown
Member Author

@cvaldess could you have a look at this?

@cvaldess

Copy link
Copy Markdown

Tested on my nRF54L15-DK (s145 9.0.0, previously on v0.3.0). I flashed only this bootloader over SWD (1bbbadb, nrf54l15dk, MinSizeRel), so the application and the settings page stayed. Then BLE OTA from an iPhone, in this order:

  1. A package with --sd-req 0x310D (built for 10.0.1): refused at the init packet, and the board went back to the application on its own. On v0.3.0 the same package left this board in the bootloader without an application.
  2. A matching package (--sd-req 0x3024), cancelled partway through: the board stayed in the bootloader.
  3. The same package, complete: the application boots and the phone reconnects.
  4. The --sd-req 0x310D package again, on top of the application from step 3: refused, and the application keeps running.

Read over SWD after step 4: the application is running and bank 0 is valid with the size of the step 3 image (437048 B). The rest of the settings page is unchanged, and the application region matches that image byte for byte.

Then I repeated step 2 and read the board while it sat in the bootloader: bank 0 is BANK_INVALID_APP (0xFF) with size 0, and the rest of the settings page is unchanged. Step 3 again brought it back: the application runs, and the settings page is the same as after the first step 3.

Not covered: serial DFU (the VCOM on this DK doesn't deliver bytes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants