I can't enter into DFU secure bootloader from ble_app_beacon application.

I want implement beacon function on my Qualcomm BSP board.

However, I'm testing with nRF52 DK in advance.

And need DFU OTA update for my F/W application.

So I'm implementing it by referring to some examples.

1. ble_app_beacon

2. ble_app_buttonless_dfu

3. secure_bootloader

Based on ble_beacon example, a code was added to enter secure_bootloader for DFU update.

    // Start execution.
    NRF_LOG_INFO("Beacon example started.");
    advertising_start();

    // Enter main loop.
    for (;; )
    {
        //NRF_LOG_INFO("loop %d", loop);
        nrf_delay_ms(1000);
        NRF_LOG_INFO("timer %d", loop++);
        //NRF_LOG_FLUSH();

        if (loop >= 10) {
            loop = 0;
            NRF_LOG_INFO("detect 10secs.");

            NRF_LOG_INFO("clear gpregret(0).");
            sd_power_gpregret_clr(0, 0xFFFFFFFF);

            NRF_LOG_INFO("set 0xB1 to gpregret(0).");
            sd_power_gpregret_set(0, BOOTLOADER_DFU_START);

            NRF_LOG_INFO("shoutdown for goto DFU");
            nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
        }
        idle_state_handle();
        
    }

This is simple, application will start advertising for beacon broadcast.

And then will enter DFU secure bootloader after 10secs later.

 

<info> app: Setting vector table to bootloader: 0x00078000
<info> app: Setting vector table to main app: 0x00026000
<info> app_timer: RTC: initialized.
<info> app: Beacon example started.
<info> app: timer 0
<info> app: timer 1
<info> app: timer 2
<info> app: timer 3
<info> app: timer 4
<info> app: timer 5
<info> app: timer 6
<info> app: timer 7
<info> app: timer 8
<info> app: timer 9
<info> app: detect 10secs.
<info> app: clear gpregret(0).
<info> app: set 0xB1 to gpregret(0).
<info> app: shoutdown for goto DFU
<info> app: Power management wants to reset to DFU mode.
<info> app: Power management allowed to reset to DFU mode.
<info> app: Setting vector table to bootloader: 0x00078000
<info> app: Setting vector table to main app: 0x00026000

But it can't enter DFU secure bootloader, and then will start application soon.

This is bootloader code

int main(void)
{
    uint32_t ret_val;
    uint32_t gpregret = 0;

    // 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);
    APP_ERROR_CHECK(ret_val);
    ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE);
    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");

    sd_power_gpregret_get(0, &gpregret);

    if (gpregret == 0xB1) {
        NRF_LOG_INFO("Detect gpregret 0xB1 for init bootloader");
        ret_val = nrf_bootloader_init(dfu_observer);
        APP_ERROR_CHECK(ret_val);
    } else {
        NRF_LOG_INFO("Not detect gpregret 0xB1. will start application");
        nrf_bootloader_app_start();
    }

    NRF_LOG_FLUSH();

    NRF_LOG_ERROR("After main, should never be reached.");
    NRF_LOG_FLUSH();

    APP_ERROR_CHECK_BOOL(false);
}

Please advise me.

Thanks.

  • Hello,

    I would recommend that you try to debug your bootloader while the application is running to check if the program reaches the if statement (gpregret == 0xB1) in main() after the 10 second timeout has expired.

    Also, I see you have made some modifications to the bootloader. Please note that the original bootloader will also enter DFU mode when the BOOTLOADER_DFU_START flag is set as long as you build with the NRF_BL_DFU_ENTER_METHOD_GPREGRET symbol enabled in sdk_config.h

    Best regards,

    Vidar

  • Hi Vidar.

    Thanks for your comment.

    I checked bootloader, so gpregret was not set 0xB1 but 0x00.

    My beacon application was set gpregret(0) to 0xB1 like this

                NRF_LOG_INFO("clear gpregret(0).");
                sd_power_gpregret_clr(0, 0xFFFFFFFF);
    
                NRF_LOG_INFO("set 0xB1 to gpregret(0).");
                sd_power_gpregret_set(0, BOOTLOADER_DFU_START);

    Why did not change gpregret(0) value?

    Thanks.

  • Hi,

    I see now that you're using the Softdevice API sd_power_gpregret_get() to read the NRF_POWER->GPREGRET register before the softdevice has been invoked by the bootloader. Try to use nrf_power_gpregret_get() instead like in the nrf_bootloader.c:dfu_enter_check() function.

Related