Hi there
I did an upgrade of the bootloader from SDK 12.2 to SDK 14.2. I am using the nrf52832 chip. It is basically the same as the secure BLE DFU example from the SDK plus a few things like LED signaling and buzzer control. Nothing really serious and these things should not cause any troubles (I guess).
I managed to get the device to advertise and I can connect through BLE and start the DFU. Prevalidation succeeds, so the application firmware packet seems to be correct too. I also printed the received data to the debugging interface and there is indeed data coming, but eventually the fstorage queue runs full and the DFU is aborted. If I increase NRF_FSTORAGE_SD_QUEUE_SIZE to 1024 the data transmission succeeds but in postvalidation I get a hash error.
Next I checked if data is actually written to flash by reading back with "nrfjprog --memrd ..." and it seems there are only FFFFFF in there, so nothing gets written. I added some calls to nrf_dfu_flash_store() in nrf_dfu_init() and it seems, that when I use NVMC as a backend the data is written and events are triggered but when SD backend is used, only the first fstorage job is executed and no event is triggered. Someone got a pointer what could be the issue here?
Here is the relevant code snippet:
uint32_t nrf_dfu_init(void)
{
Status ret_val = NRF_SUCCESS;
uint32_t enter_bootloader_mode = 0;
NRF_LOG_DEBUG("In real nrf_dfu_init");
nrf_dfu_settings_init(false); // use NVMC
NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Pat the watchdog
clock_init();
timers_init();
// no problem if I call nrf_dfu_flash_store() from here with NVMC backend active
// Continue ongoing DFU operations
// Note that this part does not rely on SoftDevice interaction
ret_val = nrf_dfu_continue(&enter_bootloader_mode);
if(ret_val != NRF_SUCCESS)
{
NRF_LOG_INFO("Could not continue DFU operation: 0x%08x");
enter_bootloader_mode = 1;
}
NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Pat the watchdog
// Check if there is a reason to enter DFU mode
// besides the effect of the continuation
if (nrf_dfu_enter_check())
{
NRF_LOG_INFO("Application sent bootloader request");
enter_bootloader_mode = 1;
}
NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Pat the watchdog
nrf_power_gpregret_set(0);
if(enter_bootloader_mode != 0 || !nrf_dfu_app_is_valid())
{
scheduler_init();
// Start the inactivity timer.
ret_val = app_timer_start(nrf_dfu_inactivity_timeout_timer_id,
APP_TIMER_TICKS(NRF_DFU_INACTIVITY_TIMEOUT_MS),
NULL);
if (ret_val != NRF_SUCCESS)
{
NRF_LOG_ERROR("Could not initialize inactivity timer");
return ret_val;
}
// Initializing transports
ret_val = nrf_dfu_transports_init();
if (ret_val != NRF_SUCCESS)
{
NRF_LOG_INFO("Could not initalize DFU transport: 0x%08x");
return ret_val;
}
NRF_WDT->RR[0] = WDT_RR_RR_Reload; // Pat the watchdog
(void)nrf_dfu_req_handler_init();
/**
* TEST
*/
{
uint32_t test = 0x01234567, test2 = 0x89ABCDEF;
NRF_LOG_INFO("TEST STORE DATA");
nrf_dfu_flash_store(0x23000, &test2, sizeof(test2), NULL); // this gets written but event handler is never triggered
nrf_dfu_flash_store(0x23004, &test, sizeof(test), NULL); // only queued but not written
}
/**
* TEST ENDE
*/
// This function will never return
NRF_LOG_INFO("Waiting for events");
wait_for_event();
NRF_LOG_INFO("After waiting for events");
}
if (nrf_dfu_app_is_valid())
{
if (g_SignalProvider != NULL) {
g_SignalProvider->Uninit();
}
NRF_LOG_INFO("Jumping to: 0x%08x", MAIN_APPLICATION_START_ADDR);
nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR);
}
// Should not be reached!
NRF_LOG_INFO("After real nrf_dfu_init");
return NRF_SUCCESS;
}
Here is the relevant NRF_LOG output
0> <info> BL_main: Inside main
0> <debug> BL_main: Starting Bootloader {VM}.{vm}{VS} (0.0.0.0): ...
0> <debug> app: In nrf_bootloader_init
0> <debug> app: in weak nrf_dfu_init_user
0> <debug> nrf_dfu: In real nrf_dfu_init
0> <debug> nrf_dfu_settings: Running nrf_dfu_settings_init(sd_irq_initialized=false).
0> <debug> nrf_dfu_flash: Calling nrf_dfu_flash_init(sd_irq_initialized=false)...
0> <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
0> <debug> nrf_dfu_settings: Resetting bootloader settings.
0> <debug> nrf_dfu_settings: Writing settings...
0> <debug> nrf_dfu_settings: Erasing old settings at: 0x0007F000
0> <debug> nrf_dfu_flash: nrf_fstorage_erase(addr=0x0x0007F000, len=1 pages), queue usage: 1
0> <debug> nrf_dfu_flash: Flash erase success: addr=0x0007F000, pending 0
0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x0007F000, len=0x1B8 bytes), queue <debug> nrf_ble_dfu: Enabling SoftDevice.
0> <debug> nrf_ble_dfu: SoftDevice enabled.
0> <debug> nrf_ble_dfu: nrf_dfu_settings_adv_name_is_valid FALSE
0> <debug> nrf_ble_dfu: Regular adv name
0> <debug> nrf_ble_dfu: #### Advertising NO BONDING ####
0> <debug> nrf_ble_dfu: Finished initializing BLE DFU transport
0> <debug> app: After nrf_dfu_transports_init
0> <debug> nrf_dfu_flash: Calling nrf_dfu_flash_init(sd_irq_initialized=true)...
0> <debug> nrf_dfu_flash: Initializing nrf_fstorage_sd backend.
0> <info> nrf_dfu: TEST STORE DATA
0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00023000, len=0x4 bytes), queue usage: 1
0> <debug> nrf_dfu_flash: nrf_fstorage_write(addr=0x00023100, len=0x4 bytes), queue usage: 2
0> <info> nrf_dfu: Waiting for events
I also believe that I configured the SDK right. Some relevant things from sdk_config.h
#define NRF_SDH_DISPATCH_MODEL 1
#define NRF_SDH_SOC_ENABLED 1
#define NRF_SDH_BLE_ENABLED 1
#define NRF_DFU_INACTIVITY_TIMEOUT_MS 120000
#define NRF_DFU_POST_SD_BL_TIMEOUT_MS 10000
#define FLASH_BUFFER_LENGTH 256
#define NRF_FSTORAGE_SD_QUEUE_SIZE 1024
#define NRF_FSTORAGE_SD_MAX_RETRIES 8
#define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 20
Why is there no event triggered and obviously no data written to flash with SD as a fstorage backend? What do I miss, please help me before I loose the rest of my hair here :)
Kind regards Karl