PCD synchronous network-core copy: supported timeout and recovery contract?

Hello,

Could Nordic clarify the supported deadline and recovery behavior of pcd_network_core_update() when the network core never changes its command status?

At sdk-nrf main d859511bfbbf30f8f8ba0e39e8cd89e90d57a812, network_core_pcd_cmdset() in subsys/pcd/src/pcd.c publishes the command and then waits in one-second busy-wait iterations while the status stays unchanged (lines 193-200). There is no deadline branch. When this runs before the application starts, for example from the bootloader, nothing in the application (such as a USB recovery path) can regain control. The NCS v3.4.1 release has the same loop (pcd.c lines 220-227 at the v3.4.1 tag).

The synchronous API documents success or an error code but no timeout (include/dfu/pcd.h lines 42-52). The asynchronous pcd_network_core_update_initiate() returns before completion (lines 54-68), and its finished-check timer handler also has no deadline (pcd.c lines 136-145).

Related earlier work and reports:
- sdk-nrf pull request 5580 (2021) proposed making pcd_network_core_update() optionally non-blocking; it was closed without merging: github.com/.../5580
- "nrf5340 net core upgrade": the update hangs in network_core_pcd_cmdset() while pcd_fw_copy_status_get() keeps returning 0: devzone.nordicsemi.com/.../nrf5340-net-core-upgrade
- "nrf5340 Serial recovery for the NET-core": devzone.nordicsemi.com/.../nrf5340-serial-recovery-for-the-net-core
- "Issue with nRF5340 Net core serial recovery": devzone.nordicsemi.com/.../issue-with-nrf5340-net-core-serial-recovery
These may have different causes; they are context for the wait contract, not proof of one common fault.

Questions:
1. Is an indefinite wait intended for an unresponsive network core, or would you accept a configurable or caller-selected deadline with an explicit timeout result?
2. What is the supported maximum time for the copy and for the version read, and which clock is usable before application entry?
3. What is the recovery contract for an interrupted copy? A safe timeout must stop the network core before returning ownership of the borrowed source or version buffer, restore the security domain, and define retry behavior for a partially copied destination. Replacing the busy-wait with a sleep, or returning after an arbitrary counter, would leave those ownership and recovery questions open.

We are asking rather than sending a patch, because a patch needs this contract first. sdk-nrf has GitHub issues disabled, so we are asking here. This comes from reading the source; nothing was built, measured or run on hardware.

This write-up was prepared with AI assistance and checked by me.

  • Hi,

    1. Is an indefinite wait intended for an unresponsive network core, or would you accept a configurable or caller-selected deadline with an explicit timeout result?

    I quickly checked and from what I understand, it looks like there is no timeout in this API directly. Instead, if the DFU goes bad, the status should change to indicate that something went bad and the waiting loop should exit just fine then. The burden of checking if the update was successful or not falls on the bootloader (MCBoot) not this API.

    2. What is the supported maximum time for the copy and for the version read, and which clock is usable before application entry?

    I haven't seen any timeout there, so I guess there is no maximum time. But it is hard to affirm that there is none just reading the code. There may be some other watchdog mechanism that could trigger. So to be certain this would require a bit of testing.

    3. What is the recovery contract for an interrupted copy? A safe timeout must stop the network core before returning ownership of the borrowed source or version buffer, restore the security domain, and define retry behavior for a partially copied destination. Replacing the busy-wait with a sleep, or returning after an arbitrary counter, would leave those ownership and recovery questions open.

    For good practice and an example on how to use that API, you can check the "nRF5340: Network core bootloader" sample (link).

    Best regards,

    Simon

  • Hi Simon,

    Thank you for looking into this.

    To narrow it down: a failed copy that the network core reports is fine. b0n writes the failed status and the wait loop exits, as you describe and as the netboot sample shows. Our question is the case where nothing on the network core ever writes the status, for example:
    - b0n is missing or erased (as in DevZone 104608);
    - the network core faults before b0n reads the command;
    - the network core cannot write to the shared RAM (the problem the comment above the one-second wait in pcd.c mentions).

    In those cases network_core_pcd_cmdset() only exits when the status changes, so MCUboot waits forever, before any application code runs that could recover.

    Two short questions:

    1. Is a hardware watchdog the intended protection for that case, and is there a recommended setup? MCUboot can feed a watchdog (BOOT_WATCHDOG_FEED), but nothing feeds it inside the PCD wait, so its timeout would have to cover the longest copy. Would MCUboot then start the same update again after the reset?

    2. If not, would Nordic accept a pull request adding an optional deadline, off by default so today's behaviour is unchanged? On expiry it would force the network core off before handing the source buffer back, and return a timeout error.

    Best regards,

    David

Related