Hi
I'm chnaging the Secure Bootloader to an external falsh for bank1, connected with QSPI.
In the function on_data_obj_write_request is the call for nrf_dfu_flash_store (file nrf_dfu_req_handler.c
static void on_data_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res) { NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (data)"); if (!nrf_dfu_validation_init_cmd_present()) { /* Can't accept data because DFU isn't initialized by init command. */ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED; return; } uint32_t const data_object_offset = s_dfu_settings.progress.firmware_image_offset - s_dfu_settings.progress.firmware_image_offset_last; if ((p_req->write.len + data_object_offset) > s_dfu_settings.progress.data_object_size) { /* Can't accept data because too much data has been received. */ NRF_LOG_ERROR("Write request too long"); p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER; return; } uint32_t const write_addr = m_firmware_start_addr + s_dfu_settings.write_offset; /* CRC must be calculated before handing off the data to fstorage because the data is * freed on write completion. */ uint32_t const next_crc = crc32_compute(p_req->write.p_data, p_req->write.len, &s_dfu_settings.progress.firmware_image_crc); ASSERT(p_req->callback.write); ret_code_t ret = nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write); if (ret != NRF_SUCCESS) { /* When nrf_dfu_flash_store() fails because there is no space in the queue, * stop processing the request so that the peer can detect a CRC error * and retransmit this object. Remember to manually free the buffer ! */ p_req->callback.write((void*)p_req->write.p_data); return; } /* Update the CRC of the firmware image. */ s_dfu_settings.write_offset += p_req->write.len; s_dfu_settings.progress.firmware_image_offset += p_req->write.len; s_dfu_settings.progress.firmware_image_crc = next_crc; /* This is only used when the PRN is triggered and the 'write' message * is answered with a CRC message and these field are copied into the response. */ p_res->write.crc = s_dfu_settings.progress.firmware_image_crc; p_res->write.offset = s_dfu_settings.progress.firmware_image_offset; }
There is a callback which is needed:
ret_code_t ret = nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write);
inside this function I use the QSPI function:
hal_qspi_write(&p_src, len, (dest & EXTERNAL_FLASH_ADDRESS_LOWER_BYTES), (void*)callback))
which at the end is calling the nrfx function nrfx_qspi_write.
Here I should have a callback, but I don't know what I should implement.
The original callback in the nrf_fstorage_write is implemented like this:
return (p_fs->p_api)->write(p_fs, dest, p_src, len, p_context);
ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs, uint32_t dest, void const * p_src, uint32_t len, void * p_context) { NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL); NRF_FSTORAGE_PARAM_CHECK(p_src, NRF_ERROR_NULL); NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE); NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH); /* Length must be a multiple of the program unit. */ NRF_FSTORAGE_PARAM_CHECK(!(len % p_fs->p_flash_info->program_unit), NRF_ERROR_INVALID_LENGTH); /* Source and destination addresses must be word-aligned. */ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32(dest), NRF_ERROR_INVALID_ADDR); NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32((uint32_t)p_src), NRF_ERROR_INVALID_ADDR); NRF_FSTORAGE_PARAM_CHECK(addr_is_within_bounds(p_fs, dest, len), NRF_ERROR_INVALID_ADDR); return (p_fs->p_api)->write(p_fs, dest, p_src, len, p_context); }
Now the DFU is strating on bank1 but the App is generating an error because data is missing because of this callack I guess?
I was following this topic:
https://devzone.nordicsemi.com/f/nordic-q-a/48961/dfu-with-external-qspi-memory