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);
}