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

Buttonless Secure DFU with WDT needs DFU twice

I use nrf51822xxAC,SDK 12.2,Buttonless Secure DFU and WDT in application.

I added NRF_WDT->RR[0] = WDT_RR_RR_Reload; to the wait_for_event loop in the DFU to pet the dog.

But it needs to DFU twice to let the chip run into application.

The same question in this link.

Could anyone help me?

Parents
  • When I debug the bootloader, I found the wait_for_event() can be entered again and agian. So the NRF_WDT->RR[0] = WDT_RR_RR_Reload will be called frequently. Here is the code:

    static void wait_for_event()
    {
        // Transport is waiting for event?
        while(true)
        {
            NRF_WDT->RR[0] = WDT_RR_RR_Reload;
            // Can't be emptied like this because of lack of static variables
            app_sched_execute();
        }
    }
    
    
    void nrf_dfu_wait()
    {
        NRF_WDT->RR[0] = WDT_RR_RR_Reload;
        app_sched_execute();
    }
    
    
    uint32_t nrf_dfu_init()
    {
        uint32_t ret_val = NRF_SUCCESS;
        uint32_t enter_bootloader_mode = 0;
    
        NRF_LOG_INFO("In real nrf_dfu_init\r\n");
    
        nrf_dfu_settings_init();
    
        // Continue ongoing DFU operations
        // Note that this part does not rely on SoftDevice interaction
        ret_val = nrf_dfu_continue(&enter_bootloader_mode);
        if(ret_val != NRF_SUCCESS)
        {
            NRF_LOG_INFO("Could not continue DFU operation: 0x%08x\r\n");
            enter_bootloader_mode = 1;
        }
    
        // Check if there is a reason to enter DFU mode
        // besides the effect of the continuation
        if (nrf_dfu_enter_check())
        {
            NRF_LOG_INFO("Application sent bootloader request\n");
            enter_bootloader_mode = 1;
        }
    
        if(enter_bootloader_mode != 0 || !nrf_dfu_app_is_valid())
        {
            timers_init();
            scheduler_init();
    
            // Initializing transports
            ret_val = nrf_dfu_transports_init();
            if (ret_val != NRF_SUCCESS)
            {
                NRF_LOG_INFO("Could not initalize DFU transport: 0x%08x\r\n");
                return ret_val;
            }
    
            (void)nrf_dfu_req_handler_init();
    
            // This function will never return
            NRF_LOG_INFO("Waiting for events\r\n");
            wait_for_event();
            NRF_LOG_INFO("After waiting for events\r\n");
        }
    
        if (nrf_dfu_app_is_valid())
        {
            NRF_LOG_INFO("Jumping to: 0x%08x\r\n", MAIN_APPLICATION_START_ADDR);
            nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR);
        }
    
        // Should not be reached!
        NRF_LOG_INFO("After real nrf_dfu_init\r\n");
        return NRF_SUCCESS;
    }
    
Reply
  • When I debug the bootloader, I found the wait_for_event() can be entered again and agian. So the NRF_WDT->RR[0] = WDT_RR_RR_Reload will be called frequently. Here is the code:

    static void wait_for_event()
    {
        // Transport is waiting for event?
        while(true)
        {
            NRF_WDT->RR[0] = WDT_RR_RR_Reload;
            // Can't be emptied like this because of lack of static variables
            app_sched_execute();
        }
    }
    
    
    void nrf_dfu_wait()
    {
        NRF_WDT->RR[0] = WDT_RR_RR_Reload;
        app_sched_execute();
    }
    
    
    uint32_t nrf_dfu_init()
    {
        uint32_t ret_val = NRF_SUCCESS;
        uint32_t enter_bootloader_mode = 0;
    
        NRF_LOG_INFO("In real nrf_dfu_init\r\n");
    
        nrf_dfu_settings_init();
    
        // Continue ongoing DFU operations
        // Note that this part does not rely on SoftDevice interaction
        ret_val = nrf_dfu_continue(&enter_bootloader_mode);
        if(ret_val != NRF_SUCCESS)
        {
            NRF_LOG_INFO("Could not continue DFU operation: 0x%08x\r\n");
            enter_bootloader_mode = 1;
        }
    
        // Check if there is a reason to enter DFU mode
        // besides the effect of the continuation
        if (nrf_dfu_enter_check())
        {
            NRF_LOG_INFO("Application sent bootloader request\n");
            enter_bootloader_mode = 1;
        }
    
        if(enter_bootloader_mode != 0 || !nrf_dfu_app_is_valid())
        {
            timers_init();
            scheduler_init();
    
            // Initializing transports
            ret_val = nrf_dfu_transports_init();
            if (ret_val != NRF_SUCCESS)
            {
                NRF_LOG_INFO("Could not initalize DFU transport: 0x%08x\r\n");
                return ret_val;
            }
    
            (void)nrf_dfu_req_handler_init();
    
            // This function will never return
            NRF_LOG_INFO("Waiting for events\r\n");
            wait_for_event();
            NRF_LOG_INFO("After waiting for events\r\n");
        }
    
        if (nrf_dfu_app_is_valid())
        {
            NRF_LOG_INFO("Jumping to: 0x%08x\r\n", MAIN_APPLICATION_START_ADDR);
            nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR);
        }
    
        // Should not be reached!
        NRF_LOG_INFO("After real nrf_dfu_init\r\n");
        return NRF_SUCCESS;
    }
    
Children
No Data
Related