This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Secure Serial DFU, app with UART stuck at bootloader

Hello,

I'm working on an UART application which uses experimental_bootloader_secure_serial bootloader. I've done a similar thing before with SDK-11 (though not a secure DFU) and after getting through building a secure bootloader, signing, etc. I was able to test updating BL over UART. But now I was trying to take this a step further and switching to DFU from the application and later proceeding with DFU as usual. I'm working with nrf52 DK, SDK 13.1.0, nrfutil 3.2.0, GCC 4.9.3 on Linux.

After few days of debugging I still can't make it work and started to wonder if it is not somehow caused by both BL and APP sharing resources, UART especially.

My symptoms in a simple case are the following (all observed by RTT):

  • I flash BL(with settings)+SD+APP
  • My application start
  • I call nrfjprog --reset -f nRF52
  • BL starts

The output from BL is below:

:DEBUG:In nrf_bootloader_init
:DEBUG:In real nrf_dfu_init
:DEBUG:running nrf_dfu_settings_init
:DEBUG:Enter nrf_dfu_continue
:DEBUG:Valid App
:DEBUG:Enter nrf_dfu_app_is_valid
:DEBUG:Return true. App was valid
:DEBUG:Enter nrf_dfu_app_is_valid
:DEBUG:Return true. App was valid
:DEBUG:Jumping to: 0x0001f000
:DEBUG:Running nrf_bootloader_app_start with address: 0x0001f000
:DEBUG:Disabling interrupts
:DEBUG:Setting SD vector table base: 0x0001f000
//Gets stuck where my app should start showing some RTT output
  • I call nrfjprog --reset -f nRF52 again
  • My app starts
  • .. and so on

I've also observed that when I call a "switch to dfu" command in my app it freezes and BL doesn't start. Ths code for this function is below:

void handle_dfu_start()
{
    uint32_t err_code;

    err_code = sd_power_gpregret_clr(0, 0xffffffff);
    APP_ERROR_CHECK(err_code);

    err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
    APP_ERROR_CHECK(err_code);

    NVIC_SystemReset();

}

Checked err_code values but they return 0 so no issue there.

I've started looking into BLE DFU and sources of libraries/bootloader/dfu/* and noticed for UART the function nrf_dfu_transports_close() from nrf_dfu_transport.c never gets called and this could theoretically cause some issues, especially that BL starts the application by nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR); call and not a reset which would restore the default states of peripherals and memory. I'm thinking of nrf_dfu.c, function nrf_dfu_init lines 177-195 where wait_for_event() is the last function called but no nrf_dfu_transports_close() after previous nrf_dfu_transports_init().

I've disabled UART init in my app but experience similar issues so probably my assumption is wrong but maybe it could be something else? I've also tried switching BL final call from nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR); to NVIC_SystemReset() but still no changes there.

Does someone have an idea where to look further for solving this?

Code for my BL main function is a reduced version of the example:

int main(void)
{
    uint32_t ret_val;

    (void) NRF_LOG_INIT(NULL);

    NRF_LOG_INFO("Inside BL main\r\n");
    buttons_init();  //This is required since nrf_dfu library checks button states internally
    
    ret_val = nrf_bootloader_init();
    APP_ERROR_CHECK(ret_val);

    // Boot the main application.
    nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR);
}

And my application's main function

int main(void)
{
    uint32_t err_code;

    NRF_LOG_INIT(NULL);
    NRF_LOG_INFO("Firmware: main\r\n");

    // Initialize.
    err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);

    uart_init();

    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
    // Initialize SoftDevice.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);


    // Enter main loop.
    for (;;)
    {
        power_manage();
    }
}
  • Could you post the code where you uninitializing the UART peripheral in the application before you jump to the bootloader? Also,is teh SoftDevice enabled when you call handle_dfu_start()?

  • I've tried a few things, for example the code below:

    void handle_dfu_start()
    {
        uint32_t err_code;
        app_uart_flush();
        app_uart_close();
    
        softdevice_handler_sd_disable();
        err_code = sd_softdevice_disable();
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_power_gpregret_clr(0, 0xffffffff);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
        APP_ERROR_CHECK(err_code);
    
        NVIC_SystemReset();
    
    }
    
  • Had to split my response into parts

    But the results are the same. The thing which I don't also understand is why the bootloader doen't go into the app even though it finds it valid. My apps .ld is FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000- tried reducing it but no luck. I've also reduced my firmware to total minimum and it still doesn't start from BL:

    int main(void)
    {
        uint32_t err_code;
        bool     erase_bonds;
        err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
        log_init();
        buttons_leds_init(&erase_bonds);
        nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;
        SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);
        NRF_LOG_INFO("Firmware: reset_to_dfu\r\n");
        for (;;)
        {
            power_manage();
        }
    }
    
  • output from RTT is

    :DEBUG:In nrf_bootloader_init
    :DEBUG:In real nrf_dfu_init
    :DEBUG:running nrf_dfu_settings_init
    :DEBUG:Enter nrf_dfu_continue
    :DEBUG:Valid App
    :DEBUG:Enter nrf_dfu_app_is_valid
    :DEBUG:Return true. App was valid
    :DEBUG:Enter nrf_dfu_app_is_valid
    :DEBUG:Return true. App was valid
    :DEBUG:Jumping to: 0x0001f000
    :DEBUG:Running nrf_bootloader_app_start with address: 0x0001f000
    :DEBUG:Disabling interrupts
    :DEBUG:Setting SD vector table base: 0x0001f000
    
  • The length of the application Flash section should be 0x59000 since the Secure Serial Bootloader starts at 0x78000.

Related