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

  • Hi David,

    David Rosen said:
    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?

    The PCD library is not the one responsible for checking or detecting that a problem occurred during the update. This library only moves the application to be DFUed in the shared memory and check if the SHA is correct. The bootloader on the network core is the one that actually performs the DFU.

    So, it seems to me that we are in a XY problem situation here.

    You said previously that you used AI to analyze the code (and I have nothing against this) but unfortunately AI is still very prone in falling into this pitfall where it tries to go too deep into a subject missing the global picture.

    David Rosen said:
    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.

    You can always try to make a PR, but in my opinion it doesn't really make sense to have a timeout in the PCD library directly. The bootloader is the one who is supposed to have the timeout.

    Also as a side note, before you go too deep developing with the nRF5340, I would recommend you to check if this actually is the best suited chip for your application. In most of the case the nRF54L series is a better fit as most of the application that use to require a nRF5340 can now be done better and easier with chips from the nRF54L series.

    Best Regards,

    Simon

  • Hi Simon,
    Thanks, that's clear. The goal behind the question was simple: if a network core update stalls in the field, the device should recover on its own, without a power cycle. We'll make sure our own update path handles that, and we won't propose a timeout in PCD.
    Thanks also for the nRF54L suggestion.
    Best regards,
    David
Related