diff --git a/examples/device/dfu_freertos/src/main.c b/examples/device/dfu_freertos/src/main.c index 3918a9ead..b4414a793 100644 --- a/examples/device/dfu_freertos/src/main.c +++ b/examples/device/dfu_freertos/src/main.c @@ -142,20 +142,48 @@ static void dl_task(void* arg) tud_dfu_finish_flashing(DFU_STATUS_ERR_CHECK_ERASED); continue; } + // check if the data is different and we need to write it if (0 == memcmp(dl_block, flash_block, dl_block_len)) { // data is the same + ESP_LOGD(TAG, "data already flashed"); dl_block_len = 0; // ready for next block tud_dfu_finish_flashing(DFU_STATUS_OK); // flashing op for download complete without error continue; } - if (0 == (dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE) % 4096) { // new page - rc = esp_partition_erase_range(ota_part, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE, 4096); // erase page (block is smaller than page + // check if the area to be written is already erased + bool erased = true; + for (uint16_t i = 0; i < dl_block_len && erased; i++) { + if (0xff != flash_block[i]) { + erased = false; + } + } + // get range when some of it is not erased + if (!erased) { +#define RANGE_SIZE 4096U // range/page size for the flash + // get range data + const uint32_t range_start = (dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE) - ((dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE) % RANGE_SIZE); + uint8_t range_data[RANGE_SIZE]; + rc = esp_partition_read(ota_part, range_start, range_data, RANGE_SIZE); + if (ESP_OK != rc) { + ESP_LOGE(TAG, "reading range failed"); + tud_dfu_finish_flashing(DFU_STATUS_ERR_CHECK_ERASED); + continue; + } + // erase range + rc = esp_partition_erase_range(ota_part, range_start, RANGE_SIZE); // erase page (block is smaller than page) if (ESP_OK != rc) { ESP_LOGE(TAG, "erase range failed"); tud_dfu_finish_flashing(DFU_STATUS_ERR_ERASE); continue; } + // write range data before downloaded block + rc = esp_partition_write(ota_part, range_start, range_data, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE - range_start); // write old + if (ESP_OK != rc) { + ESP_LOGE(TAG, "writing existing range failed"); + tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE); + continue; + } } - rc = esp_partition_write(ota_part, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE, flash_block, dl_block_len); // write new data + rc = esp_partition_write(ota_part, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE, dl_block, dl_block_len); // write new data if (ESP_OK != rc) { ESP_LOGE(TAG, "writing range failed"); tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE); @@ -239,7 +267,7 @@ int main(void) #endif // create task to handle download progress - xTaskCreate(dl_task, "dl_task", 2 * 1024, NULL, 8, NULL); + xTaskCreate(dl_task, "dl_task", 7 * 1024, NULL, 8, NULL); ESP_LOGI(TAG, "DFU mode");