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

BLE DFU WDT SDK15.2 bug?

Hi all

nrf52840 Development board,sdk is nRF5_SDK_15.2.0_9412b96,PC is windows 10 .My testing master device is cell phone(Huawei HTC and so on,android system),and using "nrf toolbox" APP.

I added watchdog  function in my application,and then when I test the ble dfu ,I found that  the watchdog feeding in the bootloader did not happen during app FW activation.

nrf_bootloader_wdt_feed_timer_start(reduced_timeout_ticks, wdt_feed_timer_handler);

wdt_feed_timer_handler is not called any time.Is this an SDK bug?

Thanks,

mijiale

The log as follosw:

Parents
  • Hi ,

    the WDT is started in the nrf_bootloader_init() function if dfu_enter is true. 

    void nrf_bootloader_wdt_init(void)
    {
        static bool initialized = false;
    
        if (initialized)
        {
            return;
        }
    
        if (nrf_wdt_started())
        {
            uint32_t wdt_ticks = nrf_wdt_reload_value_get();
    
            NRF_LOG_INFO("WDT enabled CRV:%d ticks", wdt_ticks);
    
            //wdt_ticks must be reduced to feed the watchdog before the timeout.
            uint32_t reduced_timeout_ticks = MAX((int32_t)wdt_ticks - MAX_FLASH_OP_TIME_TICKS,
                                                 NRF_BOOTLOADER_MIN_TIMEOUT_TICKS);
    
            /* initial watchdog feed */
            wdt_feed();
    
            NRF_LOG_INFO("Starting a timer (%d ticks) for feeding watchdog.", reduced_timeout_ticks);
            nrf_bootloader_wdt_feed_timer_start(reduced_timeout_ticks, wdt_feed_timer_handler);
    
            NVIC_EnableIRQ(WDT_IRQn);
        }
        else
        {
            NRF_LOG_INFO("WDT is not enabled");
        }
    
        initialized = true;
    }
    

    The WDT is also started prior to initiating any image_copy operation

    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 src_addr: 0x%x, dst_addr: 0x%x", src_addr, dst_addr);
            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
            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;
            }
    
            pages_left  -= pages;
            size        -= bytes;
            dst_addr    += bytes;
            src_addr    += bytes;
            s_dfu_settings.write_offset += 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;
    }

    The image_copy() function is used by app_activate()

    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;
    }

    So the WDT should fire during the Application activation phase. The log you attached does not seem to be in the case, can you attach it again? Is the DFU update failing or does it go through with no errors or issues? If it is very small application then it could be that its written to flash before the WDT timer fires?

    Best regards

    Bjørn

  • nrf_bootloader_wdt_init() function is called twice

    The first is in nrf_bootloader_init() functon

    The second in image_copy() function

    I have test that the timeout of rtc timer can feed wdt when nrf_bootloader_wdt_init() function is called in  nrf_bootloader_init() functon

    But the timeout of rtc timer can not feed wdt when nrf_bootloader_wdt_init() function is called

    in  image_copy() function

Reply
  • nrf_bootloader_wdt_init() function is called twice

    The first is in nrf_bootloader_init() functon

    The second in image_copy() function

    I have test that the timeout of rtc timer can feed wdt when nrf_bootloader_wdt_init() function is called in  nrf_bootloader_init() functon

    But the timeout of rtc timer can not feed wdt when nrf_bootloader_wdt_init() function is called

    in  image_copy() function

Children
No Data
Related