Hi,
I am working on Eddystone project, after I successfully tested the Buttonless DFU example, I added DFU service to Eddystone example (nRF5_SDK_17.0.0_9d13099\examples\ble_peripheral\ble_app_eddystone\pca10040\s132\ses) , I can scan and connect to the beacon via andriod mobile, there are Secure DFU Service, I enabled indications, then write value to reset the device to bootloader, the following error occurred,
<info> app: Booting....
<info> app: Setting vector table to bootloader: 0x00078000
<info> app: Setting vector table to main app: 0x00026000
<info> app_timer: RTC: initialized.
<info> app: DFU service init.
<info> app: Eddystone Application started.
<info> app: sent non connectable_advertising.
<info> app: sent non connectable_advertising.
<error> app: ERROR 5 [NRF_ERROR_NOT_FOUND] at E:\Example\nRF5_SDK_17.0.0_9d13099\components\ble\ble_services\eddystone\nrf_ble_es.c:395
PC at: 0x0002FE0F
<error> app: End of error report.
I just add one file related to DFU service and modified main.c , set NRF_SDH_BLE_VS_UUID_COUNT to 1, Enable DUF in sdk_congfig.h, no other changes, attached please find the code, please help me find the problem, thank you very much.
/** * @brief Function for application main entry. */ int main(void) { // Initialize. log_init(); NRF_LOG_INFO("Booting...."); // Initialize the async SVCI interface to bootloader before any interrupts are enabled. uint32_t err_code; err_code = ble_dfu_buttonless_async_svci_init(); //add for DFU APP_ERROR_CHECK(err_code); timers_init(); leds_init(); button_init(); scheduler_init(); power_management_init(); ble_stack_init(); gap_params_init(); gatt_init(); dfu_services_init(); // add for DFU NRF_LOG_INFO("DFU service init."); conn_params_init(); nrf_ble_es_init(on_es_evt); NRF_LOG_INFO("Eddystone Application started."); // Enter main loop. for (;;) { if (!NRF_LOG_PROCESS()) { idle_state_handle(); } } }
#include <stdbool.h> #include <stdint.h> #include <string.h> #include "sdk_config.h" #include "bsp.h" #include "nrf_dfu_ble_svci_bond_sharing.h" #include "nrf_svci_async_function.h" #include "nrf_svci_async_handler.h" #include "nordic_common.h" #include "nrf.h" #include "app_error.h" #include "ble.h" #include "ble_hci.h" #include "ble_srv_common.h" #include "ble_advdata.h" #include "ble_advertising.h" #include "ble_conn_params.h" #include "nrf_sdh.h" #include "nrf_sdh_soc.h" #include "nrf_sdh_ble.h" #include "app_timer.h" #include "peer_manager.h" #include "peer_manager_handler.h" #include "bsp_btn_ble.h" #include "ble_hci.h" #include "ble_conn_state.h" #include "ble_dfu.h" #include "nrf_ble_qwr.h" #include "fds.h" #include "nrf_pwr_mgmt.h" #include "nrf_drv_clock.h" #include "nrf_power.h" #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_bootloader_info.h" #include "nrf_log.h" /* Private defines */ BLE_ADVERTISING_DEF(m_advertising); /* Private function implementations */ /**@brief Handler for shutdown preparation. * * @details During shutdown procedures, this function will be called at a 1 second interval * untill the function returns true. When the function returns true, it means that the * app is ready to reset to DFU mode. * * @param[in] event Power manager event. * * @retval True if shutdown is allowed by this power manager handler, otherwise false. */ static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event) { switch (event) { case NRF_PWR_MGMT_EVT_PREPARE_DFU: NRF_LOG_INFO("Power management wants to reset to DFU mode."); // YOUR_JOB: Get ready to reset into DFU mode // // If you aren't finished with any ongoing tasks, return "false" to // signal to the system that reset is impossible at this stage. // // Here is an example using a variable to delay resetting the device. // // if (!m_ready_for_reset) // { // return false; // } // else //{ // // // Device ready to enter // uint32_t err_code; // err_code = sd_softdevice_disable(); // APP_ERROR_CHECK(err_code); // err_code = app_timer_stop_all(); // APP_ERROR_CHECK(err_code); //} break; default: // YOUR_JOB: Implement any of the other events available from the power management module: // -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF // -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP // -NRF_PWR_MGMT_EVT_PREPARE_RESET return true; } NRF_LOG_INFO("Power management allowed to reset to DFU mode."); return true; } //lint -esym(528, m_app_shutdown_handler) /**@brief Register application shutdown handler with priority 0. */ NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0); static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context) { if (state == NRF_SDH_EVT_STATE_DISABLED) { // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot. nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC); //Go to system off. nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF); } } /* nrf_sdh state observer. */ NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) = { .handler = buttonless_dfu_sdh_state_observer, }; static void disconnect(uint16_t conn_handle, void * p_context) { UNUSED_PARAMETER(p_context); ret_code_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); if (err_code != NRF_SUCCESS) { NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", conn_handle, err_code); } else { NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle); } } #define APP_ADV_INTERVAL 300 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */ #define APP_ADV_DURATION 18000 /**< The advertising duration (180 seconds) in units of 10 milliseconds. */ static void advertising_config_get(ble_adv_modes_config_t * p_config) { memset(p_config, 0, sizeof(ble_adv_modes_config_t)); p_config->ble_adv_fast_enabled = true; p_config->ble_adv_fast_interval = APP_ADV_INTERVAL; p_config->ble_adv_fast_timeout = APP_ADV_DURATION; } // YOUR_JOB: Update this code if you want to do anything given a DFU event (optional). /**@brief Function for handling dfu events from the Buttonless Secure DFU service * * @param[in] event Event from the Buttonless Secure DFU service. */ static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event) { switch (event) { case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE: NRF_LOG_INFO("Device is preparing to enter bootloader mode."); // YOUR_JOB: Disconnect all bonded devices that currently are connected. // This is required to receive a service changed indication // on bootup after a successful (or aborted) Device Firmware Update. // Prevent device from advertising on disconnect. ble_adv_modes_config_t config; advertising_config_get(&config); config.ble_adv_on_disconnect_disabled = true; ble_advertising_modes_config_set(&m_advertising, &config); // Disconnect all other bonded devices that currently are connected. // This is required to receive a service changed indication // on bootup after a successful (or aborted) Device Firmware Update. uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL); NRF_LOG_INFO("Disconnected %d links.", conn_count); break; case BLE_DFU_EVT_BOOTLOADER_ENTER: // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this // by delaying reset by reporting false in app_shutdown_handler NRF_LOG_INFO("Device will enter bootloader mode."); break; case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED: NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously."); // YOUR_JOB: Take corrective measures to resolve the issue // like calling APP_ERROR_CHECK to reset the device. break; case BLE_DFU_EVT_RESPONSE_SEND_ERROR: NRF_LOG_ERROR("Request to send a response to client failed."); // YOUR_JOB: Take corrective measures to resolve the issue // like calling APP_ERROR_CHECK to reset the device. APP_ERROR_CHECK(false); break; default: NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless."); break; } } /**@brief Function for initializing services that will be used by the application. */ void dfu_services_init(void) { uint32_t err_code; ble_dfu_buttonless_init_t dfus_init = { .evt_handler = ble_dfu_evt_handler }; err_code = ble_dfu_buttonless_init(&dfus_init); APP_ERROR_CHECK(err_code); }