This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF9160 FOTA not switching to secondary after boot_request_upgrade() and sys_reboot()

Hi,

In our firmware we're writing the entire contents of our UPDATE.BIN file successfully with flash_img_buffered_write's, but after boot_request_upgrade and a sys_reboot, it is still loading the original firmware from FLASH_AREA_IMAGE_PRIMARY rather than secondary. Our updated firmware has an higher hardcoded version string that we printk for verification.

We're using the latest V1.0.0 tag, 1.0.1 modem firmware, etc. CONFIG_BOOTLOADER_MCUBOOT=y is all properly set, etc.

Any pointers?

Thx!

  • Hi GJSea, 

    Could you provide us some more of your code where you handle FOTA ? I assume you are writing your own code based on our libraries, could you list the libraries you are using ?

    Please make sure that you have boot_write_img_confirmed() in your new firmware as showed in our example. Otherwise the next reset it will return back to the Primary image. 

    When you write using flash_img_buffered_write() do you flush the flash ? that what we do at: 

     https://github.com/NordicPlayground/fw-nrfconnect-nrf/blob/b456fb40c4912e3d435b9ee029d8ef24b113f7d0/subsys/net/lib/fota_download/src/fota_download.c#L59

    You need to do that before resetting. 

    I assume you have tested with our http application update and it worked fine ? 

  • Hi,

    Yes the code was from fota_download, except we read the firmware bits from a file on SPI flash storage that we previously loaded over http (so we can cater for interrupted OTA byte range streaming). This has all been CRC32 checked so the integrity of the firmware binary stored in SPI flash that we're doing f_reads from is correct. I stripped the error checking out from the paste of the code below to help in legibility.

    Yes we have the boot_write_img_confirmed at the beginning of our main.

    int err = flash_img_init(&flash_img);
    
    bytesRemaining = filesize;
    while(bytesRemaining > 0)
    {
    	int readAmount = MIN(bytesRemaining, DOWNLOAD_MAX_FRAGMENT_SIZE);
    
        fileResult = f_read(fwFile, recv_buf, readAmount, &dr);       
        err = flash_img_buffered_write(&flash_img, (uint8_t *) recv_buf, readAmount, false);
        bytesRemaining -= readAmount;
    }
    
    // Write with 0 length to flush the write operation to flash. 
    flash_img_buffered_write(&flash_img,(uint8_t *)recv_buf, 0, true);
    
    boot_request_upgrade(BOOT_UPGRADE_TEST);
    
    // Reboot system to apply the firmware.
    sys_reboot(SYS_REBOOT_COLD);

    Thx!

  • Hi GJSea, 

    It looks fine to me. Could you post the UART logging when you update and the device get reset? 

    I talked to the team and got some suggestion:

    - To use CONFIG_IMG_BLOCK_BUF_SIZE instead of DOWNLOAD_MAX_FRAGMENT_SIZE when calculating readAmount

    - Before triggering the reset, could you check flash_img.bytes_written if it matches with the image size ? 

  • Also, could you try adding a small delay before triggering the reset ? (1 -2 seconds for example)

  • Hi,

    So I did all three things above to no avail (CONFIG_IMG_BLOCK_BUF_SIZE, checking flash_img.bytes_written, and the small delay).

    I ended up debugging mcuboot\boot\bootutil\src\LOADER.C to diagnose this further:


    In boot_validate_slot(...) boot_check_header_erased is the function that is failing.

    flash_area_erased_val() returns 0xFF, as is comparing it to hdr->ih_magic (IMAGE_MAGIC) which contains values other than 0xFF, so returning -1 hence boot_validated_swap_type eventually loads the PRIMARY image again.

    So why is the ih_magic number from the SECONDARY's boot_read_image_header() not returning 0xFF?

    Thanks

Related