We are attempting to replicate the background DFU process presented in the example DFU over TFTP.
Reference SDK that we are using is 15.2
What we do:
- We are trying to update only application code (no bootloader, no SD)
- Our application retrieves the firmware and stores it in a free area of the FLASH
- After storing the firwmare, we start the DFU procedure in the application, which looks like:
APP_SCHED_INIT(IPRO_COMM_BACKGROUND_DFU_SCHED_MAX_EVENT_DATA_SIZE, IPRO_COMM_BACKGROUND_DFU_SCHED_QUEUE_SIZE); nrf_dfu_settings_init(true); nrf_dfu_req_handler_init(dfu_observer); background_dfu_state_init(&dfu_context); background_dfu_handle_event(&dfu_context, BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE); // PARSE config JSON file and retrieve triggers, not shown memset(&trigger, 0, sizeof(trigger)); trigger.init_length = uint32_big_decode((const uint8_t*) &init_length); trigger.init_crc = uint32_big_decode((const uint8_t*) &init_crc); trigger.image_length = uint32_big_decode((const uint8_t*) &image_length); trigger.image_crc = uint32_big_decode((const uint8_t*) &image_crc); if (background_dfu_validate_trigger(&dfu_context, (uint8_t *)&trigger, sizeof(trigger))) { if (!background_dfu_process_trigger(&dfu_context, (uint8_t *)&trigger, sizeof(trigger))) { // ERROR } if (dfu_context.dfu_state == BACKGROUND_DFU_IDLE) { return; } } else { // ERROR } while (! // RECEIVED BACKGROUND_DFU_DOWNLOAD_INIT_CMD event){ app_sched_execute(); } // Read flash and send 1 init block background_dfu_process_block(&dfu_context, &block); while (! // RECEIVED BACKGROUND_DFU_DOWNLOAD_FIRMWARE event){ app_sched_execute(); } // Read flash and send N firmware blocks while (...) { background_dfu_process_block(&dfu_context, &block); } while (! // RECEIVED NRF_DFU_EVT_DFU_COMPLETED event){ app_sched_execute(); } // RESET and enter bootloader
The main issue is that, if we don't comment out the following lines in the NRF SDK, the process does not end, and a DFU_STATE_FAILED is raised almost immediately after reading the init triggers. File nrf_dfu_settings.c, lines approximately 297-302.
if (NRF_DFU_SETTINGS_IN_APP && !settings_forbidden_parts_equal_to_backup((uint8_t *)&s_dfu_settings)) { NRF_LOG_WARNING("Settings write aborted since it tries writing to forbidden settings."); // Assuming NRF_DFU_SETTINGS_ALLOW_UPDATE_FROM_APP is configured the same as in bootloader. return NRF_ERROR_FORBIDDEN; } }
I am not really sure why our code is not working without commenting the above.
I'd like to understand whether this is an issue with the SDK, or (most probably) with our implementation?