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

How to stay in bootloader in case of faulty app?

Hello,

I want to prevent a scenario where I successfully perform a DFU with a faulty firmware image. I have a bootloader that handles firmware updates both for the NRF5 itself and another external chipset. It once happened that we accidentally flashed a firmware image meant for the external chip onto the NRF5, and we "bricked" it (we had to reflash with a JLink).

Our board doesn't have a physical button or something that we could use to do something like in the examples (press button during reset), so I'm trying to figure out a way to protect ourselves from such a scenario in the future.

I was thinking of using a combination of WDT and the GPREGRET. Something like setting a bit in the GPREGRET, starting the watchdog timer in the bootloader and expect it to be refreshed in the main app. The GPREGRET bit should also be cleared first thing in the main app. Then I could check the GPREGRET in the bootloader and decide whether to stay or not.

Would such an approach work? Is it possible to start the WDT in the bootloader and refresh it in the main app as I mentioned?

Thanks for your help!

EDIT: I already took measures to prevent flashing an image to the wrong chipset. I'm just trying to make my bootloader more reliable.

What happens in case of a successful DFU with a faulty FW image is that the bootloader considers the app to be correct, jumps to the main app, but finds only garbage there. The device is bricked from that point on because even though the device boots from the bootloader, the bootloader always jumps to the main app because, in the end, the app is still considered correct.

  • I think it's a good idea.

    In your bootloader you can simply check if the GPREGRET flag is set then it should be something wrong with the app and stay in DFU mode. If it's not set then you set it and start the WDT expecting the flag to be cleared when the app start.

    Another option is to set a timer when bootloader start, for example it waits for 5 seconds if there is no DFU connection, then it will start the application. So you can recover if there is anything wrong. The draw back is a latency of a few seconds after the device powered until it operates.

  • Hi ! 

    I've tried to insert a timer in the bootloader. The result is that the MCU does wait for the indicated delay before launching the app, but it does not advertise as a DFU targ. 

    I've tried to insert the timer at different places in the bootloader code (which is the 'secure_bootloader_ble_s132_pca10040') and it does not work (I've inserted the 'main' function of this code below). 

    My questions are : 

    1. Where should I insert the timer so it still advertise ?

    2. Where in the bootloader is the avdertisement managed ? 

    I am using SES on windows for a nrf52832

    Thank you !

    int main(void)
    {
        uint32_t ret_val;
    
        // Must happen before flash protection is applied, since it edits a protected page.
        nrf_bootloader_mbr_addrs_populate();
        
        // 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(nrf_bootloader_dfu_timer_counter_get);
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("Inside main");
    
        ret_val = nrf_bootloader_init(dfu_observer);
        APP_ERROR_CHECK(ret_val);
    
        nrf_delay_ms(10000);
    
        NRF_LOG_FLUSH();
    
        NRF_LOG_ERROR("After main, should never be reached.");
        NRF_LOG_FLUSH();
    
        APP_ERROR_CHECK_BOOL(false);
    }

  • Hi Jerome, 
    This is a very old case. Please create a new case for your issue. 
    From what I can see you are doing a 10 seconds delay. It's not a timer. Please look for how we do the inactivity app timer in our bootloader. You can configure a similar app timer that does the wait. It's the same app timer that you can find in our example, for example battery update timer in ble_app_hrs. 

Related