Hi Nordic team,
Due to critical real time constraints, I have to temporarily disable the softdevice, perform data acquisition from sensors, then enable it again.
I'm using softdevice s130 v5.0.0 on nRF52832 and SDK 14.2.0 for both application and bootloader
Currently I'm doing the following:
// In main.c int main(void) { // Some hardware initialization... nrf_drv_clock_init(); nrf_drv_clock_hfclk_request(NULL); sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE); sd_power_mode_set(NRF_POWER_MODE_LOWPWR); ble_stack_init(); gap_params_init(); gatt_init(); services_init(); advertising_init(); conn_params_init(); advertising_start(); //.... }
In services_init function, I added Device Information service, Battery service, one custom service and the buttonless DFU service:
void services_init(void) { // Add DIS // Add BAS // Add custom service memset(&dfus_init, 0, sizeof(dfus_init)); dfus_init.evt_handler = ble_dfu_evt_handler; // Initialize the async SVCI interface to bootloader. err_code = ble_dfu_buttonless_async_svci_init(); APP_ERROR_CHECK(err_code); err_code = ble_dfu_buttonless_init(&dfus_init); APP_ERROR_CHECK(err_code); }
I have added softdevice state observer using NRF_SDH_STATE_OBSERVER macro to track softdevice state when disabling/enabling it:
NRF_SDH_STATE_OBSERVER(m_sd_state_observer, 0) = { .handler = sd_state_evt_handler, .p_context = NULL, }; static void sd_state_evt_handler(nrf_sdh_state_evt_t state, void *p_context) { switch (state) { case NRF_SDH_EVT_STATE_ENABLE_PREPARE: break; case NRF_SDH_EVT_STATE_ENABLED: sd_enabled = true; break; case NRF_SDH_EVT_STATE_DISABLED: sd_disabled = true; break; default: break; } }
In my application code, I disable the softdevice by calling nrf_sdh_disable_request:
sd_ble_gap_adv_stop(); sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); err_code = nrf_sdh_disable_request(); APP_ERROR_CHECK(err_code); while(!sd_disabled){} // Perform critical timing work...
And then I re-enable the softdevice by calling nrf_sdh_enable_request:
err_code = nrf_sdh_enable_request(); APP_ERROR_CHECK(err_code); // Configure the BLE stack using the default settings. // Fetch the start address of the application RAM. uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start); APP_ERROR_CHECK(err_code); // Overwrite some of the default configurations for the BLE stack. ble_cfg_t ble_cfg; memset(&ble_cfg, 0, sizeof(ble_cfg)); // Three vendor-specific UUIDs: our own, Nordic's DFU service and Nordic's // UART service. ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = 2; err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, ram_start); APP_ERROR_CHECK(err_code); // Enable BLE stack. err_code = nrf_sdh_ble_enable(&ram_start); APP_ERROR_CHECK(err_code);
And when I receive softdevice enabled notification (NRF_SDH_EVT_STATE_ENABLED) I reconfigure gap, gatt, adv, conn, and all services and restart advertisement:
gap_params_init();
gatt_init();
services_init();
advertising_init();
conn_params_init();
advertising_start();
Every thing is working as expected, except adding the DFU buttonless service after disabling the softdevice and enabling it again, the application crashes when calling nrf_dfu_set_adv_name_init function (ble_dfu_unbonbed.c) which is called inside ble_dfu_buttonless_async_svci_init function!
uint32_t ble_dfu_buttonless_async_svci_init(void) { uint32_t ret_val; ret_val = nrf_dfu_svci_vector_table_set(); VERIFY_SUCCESS(ret_val); ret_val = nrf_dfu_set_adv_name_init(); VERIFY_SUCCESS(ret_val); ret_val = nrf_dfu_svci_vector_table_unset(); return ret_val; }
The only workaround that I did for the moment is to call ble_dfu_buttonless_async_svci_init only once during the first call to services_init at device power-up, and do not call it (ble_dfu_buttonless_async_svci_init) when adding services after disabling and re-enabling softdevice, After doing this the DFU is still working without problem.
So I would like to know if this workaround is safe?
And I would be grateful if someone could check why nrf_dfu_set_adv_name_init function crashes when it is called after disabling then enabling the softdevice.
thank you in advance,
Best Regards.