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

OTA DFU with a timer and no button

Hi,

I just learned how to do a OTA DFU. I tried it with nrf52840 DK and was successful in it, but our custom board does not have a button on it.    In production we will like the board to start always in the DFU mode when powered ON and look for new packages for initial 30 sec and then switch back to normal application . 

I was reading a lot about DFU_BUTTONLESS example but could not figure out the right procedure to do so.  

Will I have to change the structure of my application or will this logic be implemented inside the bootloader? 

Can you please provide some guiding steps to do so and if possible a pseudo code .

Thanks

Arshdeep

  • Try using the call nrf_power_gpregret_set() instead. I tried running sd_power_gpregret_set() similar as you and did not get the return value NRF_SUCCESS. I think this is because the SoftDevice enable function isn't called yet.

    Best regards,

    Simon

  • Hi Simon,

    I tried that: 

     And now when I try to do DFU using nrfconnect mobile app. It goes till 100% but the board remains in DFU mode. May be it does flashes my new application but switches back to DFU mode within milliseconds. What will I have to do stop this ?

    int main(void)

    {

        uint32_t ret_val;

        //  sd_power_gpregret_set(0, 0xB1);

        nrf_power_gpregret_set(0xA5);

        // Protect MBR and bootloader code from being overwritten.

        ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, false);

        APP_ERROR_CHECK(ret_val);

        ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE, false);

        APP_ERROR_CHECK(ret_val);

     

        (void) NRF_LOG_INIT(app_timer_cnt_get);

        NRF_LOG_DEFAULT_BACKENDS_INIT();

     

        NRF_LOG_INFO("Inside main");

     

        ret_val = nrf_bootloader_init(dfu_observer);

        APP_ERROR_CHECK(ret_val);

        nrf_bootloader_app_start();

       

        // Should never be reached.

        NRF_LOG_INFO("After main");

    }

    Please suggest

    Thanks

  • The program execution is always starting in the bootloader, then it either enters DFU mode or the main application (depending on different conditions). That is the reason you enter the bootloader after performing a DFU, since it goes directly to the bootloader, sets the  GPREGRET register, and enters DFU mode again.

    The normal way of doing it is to set the GPREGRET register in the main application and then restarting the chip through NVIC_SystemReset() or sd_nvic_SystemReset() (see this ticket for more information). Earlier I said that you didn't need to modify the application, and I am sorry for that, I am still learning about the DFU and don't know how it all works.

    As I understand it, you would like to achieve the following:

    • Enter DFU mode and stay there for 30 seconds --> Boot the application

    There are several ways of achieving this

    • Start the bootloader-->Enter the application-->Press the reset button and start the bootloader-->Enter DFU mode and stay there for 30 seconds --> Boot the application
      • Ask Vidar in the private tickets if you have problems doing this
    • Start the bootloader-->Enter the application-->set the GPREGRET register and restart the chip-->Enter DFU mode and stay there for 30 seconds--> Boot the application
      • Here you would need to modify the application to only start the bootloader (and DFU mode) the first time:
        • One approach is to add a characteristic to your application, and do this by writing to it.
        • Another approach is to create a variable in flash that checks if the application is running for the first time, and start/not start the bootloader depending on that
    • Use the DFU buttonless example  

    Best regards,

    Simon

Related