add faster overwrite alternate flashing method
This commit is contained in:
parent
8f31c8a740
commit
5c0e27b9e2
|
@ -87,6 +87,9 @@ void usb_device_task(void* param);
|
||||||
// used to download image onto OTA partition
|
// used to download image onto OTA partition
|
||||||
esp_ota_handle_t ota_handle = 0;
|
esp_ota_handle_t ota_handle = 0;
|
||||||
|
|
||||||
|
// how to program the downloaded data (0 = using OTA tools, 1 = using partition tools)
|
||||||
|
static uint8_t dl_method = 0;
|
||||||
|
|
||||||
// download blocks to program
|
// download blocks to program
|
||||||
static uint8_t dl_block[CFG_TUD_DFU_XFER_BUFSIZE] = {0};
|
static uint8_t dl_block[CFG_TUD_DFU_XFER_BUFSIZE] = {0};
|
||||||
static uint16_t dl_block_len = 0;
|
static uint16_t dl_block_len = 0;
|
||||||
|
@ -99,36 +102,71 @@ static void dl_task(void* arg)
|
||||||
esp_err_t rc;
|
esp_err_t rc;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (dl_block_len) { // we received a new block
|
if (dl_block_len) { // we received a new block
|
||||||
// get handle for OTA update
|
const esp_partition_t *ota_part = esp_ota_get_next_update_partition(NULL);
|
||||||
if (0 == ota_handle) {
|
if (NULL == ota_part) {
|
||||||
const esp_partition_t *ota_part = esp_ota_get_next_update_partition(NULL);
|
ESP_LOGE(TAG, "OTA not found");
|
||||||
if (NULL == ota_part) {
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_PROG);
|
||||||
ESP_LOGE(TAG, "OTA not found");
|
continue;
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_ERR_PROG);
|
}
|
||||||
return;
|
if (0 == dl_method) { // using OTA tools
|
||||||
|
// get handle for OTA update
|
||||||
|
if (0 == ota_handle) {
|
||||||
|
rc = esp_ota_begin(ota_part, OTA_SIZE_UNKNOWN, &ota_handle);
|
||||||
|
if (ESP_OK != rc) {
|
||||||
|
ESP_LOGE(TAG, "init OTA failed");
|
||||||
|
esp_ota_abort(ota_handle);
|
||||||
|
ota_handle = 0;
|
||||||
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_ERASE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rc = esp_ota_begin(ota_part, OTA_SIZE_UNKNOWN, &ota_handle);
|
|
||||||
|
// write data to partition
|
||||||
|
rc = esp_ota_write_with_offset(ota_handle, dl_block, dl_block_len, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE);
|
||||||
if (ESP_OK != rc) {
|
if (ESP_OK != rc) {
|
||||||
ESP_LOGE(TAG, "init OTA failed");
|
ESP_LOGE(TAG, "writing OTA failed");
|
||||||
esp_ota_abort(ota_handle);
|
esp_ota_abort(ota_handle);
|
||||||
ota_handle = 0;
|
ota_handle = 0;
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_ERR_ERASE);
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE);
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// write data to partition
|
tud_dfu_finish_flashing(DFU_STATUS_OK); // flashing op for download complete without error
|
||||||
rc = esp_ota_write_with_offset(ota_handle, dl_block, dl_block_len, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE);
|
} else if (1 == dl_method) { // using partition tools
|
||||||
if (ESP_OK != rc) {
|
// read current data
|
||||||
ESP_LOGE(TAG, "writing OTA failed");
|
uint8_t flash_block[CFG_TUD_DFU_XFER_BUFSIZE];
|
||||||
esp_ota_abort(ota_handle);
|
rc = esp_partition_read(ota_part, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE, flash_block, dl_block_len);
|
||||||
ota_handle = 0;
|
if (ESP_OK != rc) {
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_ERR_WRITE);
|
ESP_LOGE(TAG, "reading range failed");
|
||||||
return;
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_CHECK_ERASED);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (0 == memcmp(dl_block, flash_block, dl_block_len)) { // data is the same
|
||||||
|
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
|
||||||
|
if (ESP_OK != rc) {
|
||||||
|
ESP_LOGE(TAG, "erase range failed");
|
||||||
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_ERASE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = esp_partition_write(ota_part, dl_block_num * CFG_TUD_DFU_XFER_BUFSIZE, flash_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);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "writing range OK");
|
||||||
|
dl_block_len = 0; // ready for next block
|
||||||
|
tud_dfu_finish_flashing(DFU_STATUS_OK); // flashing op for download complete without error
|
||||||
|
} else { // unknown method
|
||||||
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_TARGET);
|
||||||
}
|
}
|
||||||
|
|
||||||
dl_block_len = 0; // ready for next block
|
dl_block_len = 0; // ready for next block
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_OK); // flashing op for download complete without error
|
|
||||||
} else { // no new block
|
} else { // no new block
|
||||||
vTaskDelay(1); // allow other tasks to run (and watchdog reset)
|
vTaskDelay(1); // allow other tasks to run (and watchdog reset)
|
||||||
}
|
}
|
||||||
|
@ -285,13 +323,13 @@ void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, u
|
||||||
|
|
||||||
ESP_LOGD(TAG, "download, alt=%u block=%u", alt, block_num);
|
ESP_LOGD(TAG, "download, alt=%u block=%u", alt, block_num);
|
||||||
|
|
||||||
if (alt > 0) {
|
if (alt > 1) {
|
||||||
ESP_LOGW(TAG, "download to invalid alt %u", alt);
|
ESP_LOGW(TAG, "download to invalid alt %u", alt);
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_ERR_ADDRESS);
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_ADDRESS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == length) { // there is nothing to programm
|
if (0 == length) { // there is nothing to program
|
||||||
// finish flashing
|
// finish flashing
|
||||||
if (ota_handle) {
|
if (ota_handle) {
|
||||||
rc = esp_ota_end(ota_handle);
|
rc = esp_ota_end(ota_handle);
|
||||||
|
@ -306,16 +344,17 @@ void tud_dfu_download_cb(uint8_t alt, uint16_t block_num, uint8_t const* data, u
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_OK); // flashing op for download complete without error
|
tud_dfu_finish_flashing(DFU_STATUS_OK); // flashing op for download complete without error
|
||||||
} else if (length > CFG_TUD_DFU_XFER_BUFSIZE) { // more data than we can handle
|
} else if (length > CFG_TUD_DFU_XFER_BUFSIZE) { // more data than we can handle
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_ERR_PROG);
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_PROG);
|
||||||
} else if (dl_block_len) { // there is already a block to programm
|
} else if (dl_block_len) { // there is already a block to program
|
||||||
tud_dfu_finish_flashing(DFU_STATUS_ERR_STALLEDPKT);
|
tud_dfu_finish_flashing(DFU_STATUS_ERR_STALLEDPKT);
|
||||||
} else { // all is fine to programm
|
} else { // all is fine to program
|
||||||
if (!dl_started) {
|
if (!dl_started) {
|
||||||
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_DOWNLOAD), 0);
|
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_DOWNLOAD), 0);
|
||||||
dl_started = true;
|
dl_started = true;
|
||||||
}
|
}
|
||||||
memcpy(dl_block, data, length); // copy data for dl_task
|
memcpy(dl_block, data, length); // copy data for dl_task
|
||||||
|
dl_method = alt; // remember how to flash
|
||||||
dl_block_num = block_num; // remember offset
|
dl_block_num = block_num; // remember offset
|
||||||
dl_block_len = length; // notitfy dl_task block is ready
|
dl_block_len = length; // notify dl_task block is ready
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue