nRF5340 Upgrade of App and Net core firmware

Hi, 

I am using SDK 1.9.1 and nRF5340.

Scenario

I am investigating the following scenario:

  • files containing the firmware upgrade for the app and/or net cores will be initially stored in the filesystem partition (extenal flash) as they are produced during the compilation phase (app_update.bin and net_core_app_update.bin);
  • on request, the upgrade of the app or net core will start;
  • the request will be handled by the firmware running in the app core: the request will specify the file to use for the upgrade;
  • the file containing the upgrade will be first validated; if validation is passed, the file will be copy into the mcuboot_secondary partition (external flash, but at the moment internal) and MCUBoot will take over the control of this phase and perform the upgrade of the core;
  • due a bug, i cannot used the external flash to store the new image of the app and net core, so at the moment internal flash will be used; but the final goal is to use the external spi flash.

Looking in the documentation and in some tickets, I understood that one possible way to do it would be to use the DFU taget library. Here below  the pseudo-code:

uint8_t buffer[1024] = {0};

(void)fileOpen("app_update.bin", READ_MODE, handle);

(void)fileRead(handle, &buffer[0], 4);    /* read the first 4 bytes at the beginning of the upgrade bin file */

int imageType = dfu_target_img_type(const void *const &buffer[0], sizeof(buffer));

/* imageType should be 0x01,  DFU_TARGET_IMAGE_TYPE_MCUBOOT */

uint32_t fileSize = fileSize("app_update.bin"); 

int ret = dfu_target_init(imageType, fileSize, NULL);

if (ret < 0) return;
uint32_t offset = 0;
do
{
    uint32_t bytesRead = fileRead(handle, offset, &buffer[0], sizeof(buffer)); 
    ret = dfu_target_write(&buffer[0], bytesRead);
    fileSize -= bytesRead;
	offset += bytesRead;
}while ((filesize > 0) && (ret > 0)); 

if ((filesize == 0) && (ret == 0))
{
	dfu_target_done(true);
}
else
{
	dfu_target_done(false);
	dfu_target_reset();
	/*Reset the nRF5340 */
}

When the upgraded app firmware restarts, the function  boot_write_img_confirmed()  will be invoked.

Using the app nRF Connect Device Manager i am able to update both app and net core.

In my actual project i have defined only mcuboot_secondary partition.

I can see that with the app is possible to swap the firmware, instead with the netcore is not.

Questions:

  1. is the reported approach correct ? If not, could you kindly indicate an example that suites my scenario ?
  2. Can it work also for the network core ? How do i specify the core to be updated ? Basically, doing the same thing that nRF Connect Device Manager does.
  3. Is there a function that perform the validation of the bin files before being copy in the DFU target ?
  4. I saw that there is DFU multi-image library. is there any example using that ? is the zip file produced during the compilation that need to be sent to the DFU target? 

Thanks in advance for your kind help.

Parents
  • Hi Simon,

    thanks for the detailed information and sorry for my late feedback.

    Regarding the code, what it was missing was the allocation for the mcuboot buffer: unfortunately dfu_target_mcuboot_set_buf is not part of the single image DFU library so i noticed that i had to add it only when the fw crashed and the assert told me to invoke this function.

    My configuration place the mcuboot_secondary in the EXTERNAL FLASH, for both the app and net core.

    In order to have it properly executed, i had to introduce the patch in the loader.c for the MCUboot reported in these links: link1 and link2.

    Neverteless, the patched MCUBoot works ONLY FOR THE APP CORE: having the netcore new image in the external flash causes a bus fault:

    #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(PM_CPUNET_B0N_ADDRESS)
            /* If the update is valid, and it targets the network core: perform the
             * update and indicate to the caller of this function that no update is
             * available
             */
            if (upgrade_valid && reset_addr > PM_CPUNET_B0N_ADDRESS) {
                struct image_header *hdr = (struct image_header *)secondary_fa->fa_off;
                uint32_t vtable_addr = (uint32_t)hdr + hdr->ih_hdr_size;
                uint32_t *net_core_fw_addr = (uint32_t *)(vtable_addr); /*!!! BUS FAULT !!! */
                uint32_t fw_size = hdr->ih_img_size;
                BOOT_LOG_INF("Starting network core update");
                rc = pcd_network_core_update(net_core_fw_addr, fw_size);
    

    I saw that the same thing was reported in this ticket

    Is a solution planned for the netcore with this configuration (that is one only mcuboot seconday in the external flash) ? Or are there any configuration parameters that i am missing to enable such of management ?

    Thanks in advance !

    Kind regards

    Riccardo 

  • As a temporary fix, could you try to modify loader.c as the customer did in this reply:  RE: nRF5340 non-simultaneous netcore updates with external QSPI ,it seems like he was able to perform a netcore update with the secondary slot in external flash with that modifications:

    " I can now perform net and app core updates one at a time from a single secondary slot on the external qspi in a way that still allows for reversion of the application core."

    Based on that, I will see if I can create a hooks file that achieves the same, which is a better approach than modifying mcuboot and the loader.c file.

    Best regards,

    Simon

Reply Children
No Data
Related