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