OFF CHIP OTA UPDATE using external flash

I am working on this project off chip ota update on nRF5_SDK  using ecample/thread/dfu

by now, i have done changes in these functions on_data_obj_create_request() and on_data_obj_write_request(). initially these functions were erasing and writing data in internal flash which I changed to qspi functions like nrf_drv_qspi_erase() and nrf_drv_qspi_write(). and it works perfectly.

Later i changed functions for hash verification which is also working but i am not sure about what should be the next step so that bootloader changes the earlier application with the new firmware image.

  • My suggestion is that you verify that the data in qspi_flash.txt matches the *.bin file you uploaded and that the bootloader has correctly copied the same data to FLASH.

  • but because of above error download fails before writing the last block so how i will verify what you suggested ? 

    download to external flash is not getting completed and there are two types of error during download . either Object size must be page aligned or "Creating the object with size 0x%08x would overflow firmware size.\r\n"
    "Offset is 0x%08x and firmware size is 0x%08x."

  • I thought the issue had been resolved since the last log you posted showed that both the transfer and post-validation were successful.

    Priyesh Shahi said:
    download to external flash is not getting completed and there are two types of error during download . either Object size must be page aligned or "Creating the object with size 0x%08x would overflow firmware size.\r\n"
    "Offset is 0x%08x and firmware size is 0x%08x."

    My suggestion then is that you retrace the changes you've made to pinpoint what caused this problem. I assume you don't encounter this issue when you run the unmodified SDK application, correct?

  • Hi 

    I have solved the above problems. from last conversation to till today 

    1: now both size matches 

    2: download is complete.

    3: Hash verification and crc is completed and it working fine

    4: i have started log in bootloader  so now i am able to see the problem of bootloader reset.

    i have changed the image_copy function and in logs i can see it is working and writes my image completely .

    static uint32_t image_copy(uint32_t dst_addr,
                               uint32_t src_addr,
                               uint32_t size,
                               uint32_t progress_update_step)
    {
        if (src_addr == dst_addr)
        {
            NRF_LOG_DEBUG("No copy needed");
            return NRF_SUCCESS;
        }
    
        ASSERT(src_addr >= dst_addr);
        ASSERT(progress_update_step > 0);
        ASSERT((dst_addr % CODE_PAGE_SIZE) == 0);
    
        uint32_t max_safe_progress_upd_step = (src_addr - dst_addr)/CODE_PAGE_SIZE;
        ASSERT(max_safe_progress_upd_step > 0);
    
        uint32_t ret_val = NRF_SUCCESS;
        uint32_t pages_left = CEIL_DIV(size, CODE_PAGE_SIZE);
    
        //Firmware copying is time consuming operation thus watchdog handling is started
        nrf_bootloader_wdt_init();
    
        progress_update_step = MIN(progress_update_step, max_safe_progress_upd_step);
    
        while (size > 0)
        {
            uint32_t pages;
            uint32_t bytes;
            if (pages_left <= progress_update_step)
            {
                pages = pages_left;
                bytes = size;
            }
            else
            {
                pages = progress_update_step;
                bytes = progress_update_step * CODE_PAGE_SIZE;
            }
            // Erase the target pages
            ret_val = nrf_dfu_flash_erase(dst_addr, pages, NULL);
            if (ret_val != NRF_SUCCESS)
            {
                return ret_val;
            }
    
            // Flash one page
    
            uint32_t m_buffer_rx[bytes];
    
            if(nrf_drv_qspi_read(m_buffer_rx, bytes,firmware_flash_addr ) != NRFX_SUCCESS)
            {
              NRF_LOG_INFO("Failed read application for bootloader reset in Ext Flash.\r\n");
            }
            else
            {
              NRF_LOG_INFO("Succsessfully read application for bootloader reset from: 0x%lX\r\n",firmware_flash_addr);
              WAIT_FOR_PERIPH();
              NRF_LOG_DEBUG("Copying 0x%x to 0x%x, size: 0x%x", src_addr, dst_addr, bytes);
              ret_val = nrf_dfu_flash_store(dst_addr,
                                          (uint32_t *)m_buffer_rx,
                                          ALIGN_NUM(sizeof(uint32_t), bytes),
                                          NULL);
            }
            //NRF_LOG_DEBUG("Copying 0x%x to 0x%x, size: 0x%x", src_addr, dst_addr, bytes);
            //ret_val = nrf_dfu_flash_store(dst_addr,
            //                              (uint32_t *)src_addr,
            //                              ALIGN_NUM(sizeof(uint32_t), bytes),
            //                              NULL);
    
    
            if (ret_val != NRF_SUCCESS)
            {
                return ret_val;
            }
            else
            {
              NRF_LOG_INFO("flash store successfull...\r\n");
            }
    
            pages_left  -= pages;
            size        -= bytes;
            dst_addr    += bytes;
            src_addr    += bytes;
            s_dfu_settings.write_offset += bytes;
            firmware_flash_addr += bytes; 
    
            //store progress in flash on every successful chunk write
            ret_val = nrf_dfu_settings_write_and_backup(NULL);
            if (ret_val != NRF_SUCCESS)
            {
                NRF_LOG_ERROR("Failed to write image copying progress to settings page.");
                return ret_val;
            }
        }
    
        return ret_val;
    }

    here is the log of that 

    but after this in app_activate() function there is crc calculation on bank 0 and  crc calculation fails and there is an error.

    the code of app_activate() function

    static uint32_t app_activate(void)
    {
        // This function is only in use when new app is present in Bank 1
        uint32_t const image_size  = s_dfu_settings.bank_1.image_size;
    
        uint32_t src_addr    = s_dfu_settings.progress.update_start_address;
        uint32_t ret_val     = NRF_SUCCESS;
        uint32_t target_addr = nrf_dfu_bank0_start_addr() + s_dfu_settings.write_offset;
        uint32_t length_left = (image_size - s_dfu_settings.write_offset);
        uint32_t crc;
    
        NRF_LOG_DEBUG("Enter nrf_dfu_app_continue");
    
        src_addr += s_dfu_settings.write_offset;
    
        if (src_addr == target_addr)
        {
            length_left = 0;
        }
    
        ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
        if (ret_val != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("Failed to copy firmware.");
            return ret_val;
        }
    
        // Check the CRC of the copied data. Enable if so.
        crc = crc32_compute((uint8_t*)nrf_dfu_bank0_start_addr(), image_size, NULL);
    
        if (crc == s_dfu_settings.bank_1.image_crc)
        {
            NRF_LOG_DEBUG("Setting app as valid");
            s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
            s_dfu_settings.bank_0.image_crc = crc;
            s_dfu_settings.bank_0.image_size = image_size;
        }
        else
        {
            NRF_LOG_ERROR("CRC computation failed for copied app: "
                          "src crc: 0x%08x, res crc: 0x%08x",
                          s_dfu_settings.bank_1.image_crc,
                          crc);
        }
    
        return ret_val;
    }
    



    i want to know why this crc calculation fails because before bootloader reset same crc calculation is correct. 

    here is more log which is from bootloader

    0> 
    00> <debug> app: Copying 0xBE000 to 0x59000, size: 0x8000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00059000, src=0x2001FED8, len=32768 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x00059000, pending 0
    00> 
    00> <info> app: flash store successfull...
    00> 
    00> 
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x200012EC, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    00> 
    00> <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x20000F68, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x00061000, len=5 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x00061000, pending 0
    00> 
    00> <info> app: Succsessfully read application for bootloader reset from: 0x160000
    00> 
    00> 
    00> 
    00> <debug> app: Copying 0xC6000 to 0x61000, size: 0x4F30
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00061000, src=0x2002C218, len=20272 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x00061000, pending 0
    00> 
    00> <info> app: flash store successfull...
    00> 
    00> 
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x200012EC, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    00> 
    00> <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x20000F68, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    00> 
    00> <error> app: CRC computation failed for copied app: src crc: 0xBF28E606, res crc: 0x5B2DA0B8
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FF000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FF000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FF000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FF000, src=0x200012EC, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FF000, pending 0
    00> 
    00> <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    00> 
    00> <debug> nrf_dfu_settings: Writing settings...
    00> 
    00> <debug> nrf_dfu_settings: Erasing old settings at: 0x000FE000
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x000FE000, len=1 pages), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash erase success: addr=0x000FE000, pending 0
    00> 
    00> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x000FE000, src=0x20000F68, len=896 bytes), queue usage: 1
    00> 
    00> <debug> nrf_dfu_flash: Flash write success: addr=0x000FE000, pending 0
    00> 
    00> <debug> app: Resetting bootloader.
    00> 
    00> <info> nrf_dfu_settings: B<info> app: Inside main
    00> 
    00> 
    00> 
    00> <debug> app: In nrf_bootloader_init
    00> 
    00> <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    00> 
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00> 
    00> <debug> nrf_dfu_settings: Using settings page.
    00> 
    00> <debug> nrf_dfu_settings: Copying forbidden parts from backup page.
    00> 
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00> 
    00> <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.
    00> 
    00> <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.
    00> 
    00> <debug> app: Enter nrf_bootloader_fw_activate
    00> 
    00> <info> app: No firmware to activate.
    00> 
    00>  feeding watchdog.
    00> 
    00> <debug> app: timer_activate (0x20000018)
    00> 
    00> <debug> app: in weak nrf_dfu_init_user
    00> 
    00> <debug> app: timer_stop (0x20000008)
    00> 
    00> <debug> app: timer_activate (0x20000008)
    00> 
    00> <info> app: Entering DFU mode.
    00> 
    00> <debug> app: Initializing transports (found: 0)
    00> 
    00> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    00> 
    00> <debug> app: Enter main loop
    00> 

  • Are you copying the image from bank 1 in external flash? I can't tell from your code snippet where the image is copied from.

Related