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

softdevice enable in Application crash if it has already initialized in bootloader

Hi,

On a system reset, we want a mechanism to stay in bootloader for a short period before jumping in application. This way, if something is wrong in application that prevent communication, we still have a way to fallback in the bootloader. Our system only have 1 input that trigger a hardware reset.

The problem arise when we allow the bootloader to enable the softdevice for the purpose to expose the ble dfu service. After a delay, we wish to jump in application. Here is the code called after a delay in bootloader to achieve this.

if(nrf_dfu_app_is_valid()) {
   //tried with and without these lines
    nrf_dfu_transports_close();
    app_uart_close();
    app_timer_stop_all();
    sd_softdevice_disable();
  ////
    nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR);
} else {
    printf("No valid App, stay in bootloader\r\n");
}

In application, it crash as a hardfault when this line is called:

err_code = softdevice_enable(&ble_enable_params);

The app is inspired by ble_app_hrs so it is the same code that call softdevice_enable in void ble_stack_init(void). I changed however SOFTDEVICE_HANDLER_INIT to SOFTDEVICE_HANDLER_APPSH_INIT since I use the scheduler and want to minimise parts of code running in interrupts. I tried both ways also.

I have a workaround for now. It to use GPREGRET to bypass bootloader. And reset instead of jumping to application. So a system reset seems to do a better job reinitializing memory/registries than sd_softdevice_disable();

if(NRF_POWER->GPREGRET) {
        NRF_POWER->GPREGRET = 0;
        if(nrf_dfu_app_is_valid()) { 
            nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR);
        }
}

I would prefer to avoid extraneous system resets if possible.

Thanks

Parents Reply Children
No Data
Related