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?

  • 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;
    }
    
  • Hi Kamisen,

    Seems that I found the problem, it was with wait_for_event(). Inside that function we call sd_app_evt_wait(); This call won't return if you don't have any application event or receive Softdevice event. If you replace that function with simply __WFI(), then we can be sure the CPU wake up and do WDT feeding every time we have a BLE activity. This worked for me :

    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
            __WFI();
    
            app_sched_execute();
        }
    }
    

    A better way of doing this is to setup a timer with a timeout smaller than 2 seconds to feed the dog.

  • Sadly it is still not work for me. After adding the __WFI(); the DFU still needs to do twice. And the first time DFU's transmit speed is much slower. And I found my nrf_dfu.c doesn't have sd_app_evt_wait(); in wait_for_event(). My sdk is 12.2. I knew it can use timer to feed the dog in bootloader but when I added it, the storage is over the limit.

  • Sorry I was testing on SDK v13.

    I still don't understand what you mean by "DFU still need to do twice" or "twice means that only entering bootloader twice by LED indicating. " Could you describe what exactly you see ? until which stage the first DFU process get to before it reset ?

    1. The 51822 chip is running into application(WDT runs too)
    2. Use iOS nRF toolbox to do DFU with the relating secure Zip file that have application but no bootloader or softdevice in it.(The first time DFU)
    3. The DFU finish in App but the 51822 chip is still adverting as DfuTarg and run in bootloader proram not in application.
    4. Use iOS nRF toolbox to do DFU with the same secure Zip file again.(The second time DFU)
    5. The DFU finish in App and the 51822 chip runs into application.
Related