This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE DFU (SDK 14.2) - fstorage jobs queued but never executed

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

  • Hi Karl,

    The bootloader in SDK v12.x uses S132 v3.0 when the one in SDK v14 uses S132 v5.0, did you combine the softdevice and the bootloader when you do DFU ?

    Have you tried to test with the unmodified bootloader in SDK v12 and update it to the bootloader in SDK v14 ?

  • I flash the new softdevice (v5) and bootloader (from SDK14.2) by using nrfjprog. I am currently not doing a DFU from an old bootloader (SDK 12.2) + softdevice (v3).

    @echo Flashing: s132_nrf52_5.0.0_softdevice.hex
    nrfjprog --program $(NRFSDK_ROOT)/components/softdevice/s132/hex/s132_nrf52_5.0.0_softdevice.hex -f nrf52 --chiperase
    @echo Flashing: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
    nrfjprog --program $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex -f nrf52 --sectoranduicrerase
    nrfjprog --reset -f nrf52
    

    What I am trying to do is to flash a standalone bootloader + Softdevice and then do DFU with my application, which was also updated to SDK14.2

  • I've done this with SDK14, but it needed some changes to the secure ble bootloader example. First off, I would advise using the drop in upgrade for s132 (V5.1.0).

    After that, take a look at ble_dfu_enter_check. It should be somewhere within the example, the default option doesn't consider the possibility of trying to boot into DFU mode before having a valid app flashed onto the device if I remember correctly.

    I have it on my to-do list to make sure I document all of the changes I had to go through to get DFU working on a custom platform, but I hope this helps for now.

  • So you are simply using softdevice v5 and bootloader from SDK v14.2 and simply want to DFU update an application ?

    Have you tried to use a example in our SDK as the application, ble_app_hrs for example ?

    Which central device did you use to do DFU update, we suggest to use nRFConnect app on the phone to test.

    I have a blog here describe step by step on testing , it might be useful.

  • @Hung,

    If you are asking me, I did see your blog, but there are still some issues with those steps which are exposed when developing with something other than the dk.

    In addition, some built in problems with the examples in sdk 14.2. Maybe you have seen some of my suggestions. devzone.nordicsemi.com/.../ devzone.nordicsemi.com/.../

Related