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

SDK12.2 Secure DFU Timeout

I want to add a timeout to the secure DFU bootloader if I enter it from the application. I found this post here devzone.nordicsemi.com/.../ but unfortuately I can't use the WDT because my application is using it with a quick timeout. What's the best way to a timeout using the app_timer module?

Cheers, Darren

  • Are you disabling the WDT before you jump to the bootloader or are you feeding the WDT in the bootloader? If its the first, then I was thinking that you could just reinitialize the WDT in the bootloader with a longer timeout.

  • Bjorn,

    My understanding is there is no way to disable or change the watchdog once it has be started, correct? Right now I start the watchdog in my application, and then when I enter the bootloader from the app via DFU, I kick the watchdog in nrf_dfu::wait_for_event.

    Thanks

  • You are correct, the WDT cannot be re-configured once it has been started. Using the app_timer module for this is overkill, I suggest using the RTC driver instead and then resetting the counter everytime the bootloader is handling a request.

    In order to do this you have to add the following snippets to nrf_dfu.c:

    #include "nrf_drv_rtc.h"
    const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2);
    
    static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
    {
        if (int_type == NRF_DRV_RTC_INT_COMPARE0)
        {
            sd_nvic_SystemReset();
        }
    }
    
    static void rtc_init()
    {
        uint32_t err_code;
    
        nrf_drv_rtc_config_t rtc_config = NRF_DRV_RTC_DEFAULT_CONFIG;
        // Set counter frequency to 8, given by (32768/(PRESCALER+1)) 
        rtc_config.prescaler = 4095;
    
        //Initialize the RTC peripheral 
        err_code = nrf_drv_rtc_init(&rtc,&rtc_config, rtc_handler);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_INFO("Could not initalize RTC: \r\n");
        }
        
        //Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
        err_code = nrf_drv_rtc_cc_set(&rtc, 0, 120*8 , true);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_INFO("Could not initalize CC value: \r\n");
        }
        
        nrf_drv_rtc_enable(&rtc);   
    }
    

    After adding the code above you only have to call rtc_init() in nrf_dfu_init().

    Resetting the counter is done writing directly by triggering the RTC2 Clear task, i.e. call the following snippet in nrf_dfu_req_handler_on_req() in nrf_dfu_req_handling.c

    // Clear the counter variable
    NRF_RTC2->TASKS_CLEAR = 1;
    
  • Bjorn,

    Thanks for your help, you solution is great! Would it be a good idea to disable the timer in the rtc_handler() before resetting? I don't want that timer running in the application code.

    Thanks, Darren

  • Yes, that is a good suggestion, call nrf_drv_rtc_disable and then nrf_drv_rtc_uninit in the rtc_handler(). Not sure if you must call nrf_drv_rtc_disable before calling nrf_drv_rtc_uninit, but better safe than sorry.

Related