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

Update SD+BL+APP from SDK v13 to v14 via DFU Fails

Hi. I am trying to create a dfu zip file that contains the softdevice, bootloader, and application. I am DFU upgrading an NRF52 device from SDK v13 to SDK v14 via Nordic's Android nRF Toolbox DFU app. I can create a zip file that contains the softdevice and bootloader and another zip file that contains the app. When I program the device with the softdevice+bootloader zip file, it updates successfully. However, the device exits DFU mode and I can no longer update the application. I can no longer wirelessly put the device into DFU mode. Also, updating the app first does not work. Again, the device is nonresponsive. The DFU app does not allow me to choose both zip files. Please advise on how to perform a two step DFU.

Parents
  • We've found an issue with the Secure Bootloader's bootloader copy routine ( nrf_dfu_bl_continue() in nrf_dfu_utils.c ) - the logic in this routine breaks when doing a combined softdevice and bootloader update and the new softdevice is of a different size compared to previous version.

    After the old bootloader has been swapped with the new bootloader, the new bootloader will compare itself against the banked version to verify that the MBR performed the swap correctly. The start address of BANK1, where the bootloader image is stored, is equal to the end of the SoftDevice. However, due to the change in SoftDevice size, from 0x1F000 with S132 v4.0.2 to 0x23000 with the S132 v5.0.0, the new bootloader will use 0x23000 as the start address instead of the old at 0x1F000. This leads to the memory compare operation being performed with a 0x4000 offset, which will fail.

    The workaround is to modify the nrf_dfu_bl_continue() in the SDK v14.0.0 bootloader to check both the new and the old Bank1 start addresses, i.e.

    static uint32_t nrf_dfu_bl_continue(uint32_t src_addr, nrf_dfu_bank_t * p_bank)
    {
        uint32_t       err_code      = NRF_SUCCESS;
        uint32_t       ret_val      = NRF_SUCCESS;
        uint32_t const len          = (p_bank->image_size - s_dfu_settings.sd_size);
        uint32_t       old_src_addr;
        
        // if the update is a combination of BL + SD, offset with SD size to get BL start address
        src_addr += s_dfu_settings.sd_size;
        // Offset by 16K due to change in softdevice size. 0x1F000 -> 0x23000
        old_src_addr = src_addr - 0x4000;
        
        NRF_LOG_DEBUG("Verifying BL: Addr: 0x%08x, Src: 0x%08x, Len: 0x%08x", MAIN_APPLICATION_START_ADDR, src_addr, len);
        
        //Check new and old bank1 address to prevent new bootloader from repeating the swap with wrong src_addr
        err_code = nrf_dfu_mbr_compare((uint32_t*)BOOTLOADER_START_ADDR, (uint32_t*)old_src_addr, len);
            
        // If the bootloader is the same as the banked version, the copy is finished
        ret_val = nrf_dfu_mbr_compare((uint32_t*)BOOTLOADER_START_ADDR, (uint32_t*)src_addr, len);
        if (ret_val == NRF_SUCCESS || err_code == NRF_SUCCESS)
        {
            NRF_LOG_DEBUG("Bootloader was verified");
    
            // Invalidate bank, marking completion
            nrf_dfu_invalidate_bank(p_bank);
    
            // Upon successful completion, the callback function will be called and reset the device. If a valid app is present, it will launch.
            NRF_LOG_DEBUG("Writing settings and reseting device.");
            ret_val = nrf_dfu_settings_write(reset_device_callback);
        }
        else
        {
            NRF_LOG_DEBUG("Bootloader not verified, copying: Src: 0x%08x, Len: 0x%08x", src_addr, len);
            // Bootloader is different than the banked version. Continue copy
            // Note that if the SD and BL was combined, then the split point between them is in s_dfu_settings.sd_size
            ret_val = nrf_dfu_mbr_copy_bl((uint32_t*)src_addr, len);
            if (ret_val != NRF_SUCCESS)
            {
                NRF_LOG_ERROR("Request to copy BL failed");
            }
        }
    
        return ret_val;
    }
    
  • @koniho: Yes, if you're updating to a newer SoftDevice that is larger than the SoftDevice present on the device with SDK v12.x.x or later, then you need to implement the fix mentioned above.

  • : I have SD+BL+APP from SDK v12.x.x installed and I now try to update to SDK 15.3. I created a zip with SD+BL+APP with following command:

    nrfutil pkg generate --hw-version 52 --key-file private.key \
            --application-version 2 --application application.hex \
            --sd-req 0x9D,0xB7 --softdevice softdevice.hex --sd-id 0xB7 \
            --bootloader bootloader.hex --bootloader-version 2 \
            app_dfu_package.zip

    I update with nrfutil dfu serial. Now the first step updating SoftDevice+Bootloader is successfull. But the second step updating the Application fails! Is it possible the I now have the same problem, because the softdevice size increased? nrfutil failed on "Set Packet Receipt Notification 0" => TypeError: 'NoneType' object is not iterable.

  • HI Manuel, 

    since the way we generate DFU images have changed between SDK v12.x.x and SDK v15.3 you will have to generate a SD+BL image with nrfutil v1.5.0 as its the SDK v12 bootloader that receives this image. Then after the SD+BL update you need to generate a APP image using nrfutil v5.0.0  or later. 

    Best regards

    Bjørn

Reply Children
Related