[Solved] esp_partition_write for OTA
Posted: Mon Mar 07, 2022 2:59 pm
Hello,
I want to implement OTA programming for the ESP32. But I dont want to use a webserver but through direct file transfer on an html page. So I wrote this handler which triggers on a HTTP post request. The function works and I can select a binary file and program the esp32. However the esp_partition_write function keeps adding whitespace to my partition if I dont use vTaskDelay(). (checked it by reading the flash and comparing it to my orignal binary)
With vTaskDelay(8) it works but the only way I got it to work is by experimenting a bit with the delay value. I would like to know why this happens. My guess is that the esp_partition_write function is still doing something in the background and I need to first wait for it to finish. The uploading is also very slow due to the delay and I would like to improve that to similar speeds as the regular esp_https_ota function. Is there maybe some kind of flag I can read out before calling the function again?
I want to implement OTA programming for the ESP32. But I dont want to use a webserver but through direct file transfer on an html page. So I wrote this handler which triggers on a HTTP post request. The function works and I can select a binary file and program the esp32. However the esp_partition_write function keeps adding whitespace to my partition if I dont use vTaskDelay(). (checked it by reading the flash and comparing it to my orignal binary)
With vTaskDelay(8) it works but the only way I got it to work is by experimenting a bit with the delay value. I would like to know why this happens. My guess is that the esp_partition_write function is still doing something in the background and I need to first wait for it to finish. The uploading is also very slow due to the delay and I would like to improve that to similar speeds as the regular esp_https_ota function. Is there maybe some kind of flag I can read out before calling the function again?
- // Handler for esp32 ota programming
- esp_err_t program_esp32_handler(httpd_req_t* req)
- {
- esp_err_t error = 0;
- printf("esp32_handler\n\r");
- extern const unsigned char cacert_pem_start [] asm("_binary_cacert_pem_start");
- extern const unsigned char cacert_pem_end [] asm("_binary_cacert_pem_end");
- ESP_LOGI(TAG, "ESP32 programming starting");
- char url[1024];
- char buf[512] = {0};
- int received;
- int remaining = req->content_len;
- int iterator = 0;
- // Find the partition map in the partition table
- const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "ota_1");
- assert(partition != NULL);
- ESP_ERROR_CHECK(esp_partition_erase_range(partition, 0, partition->size));
- printf("content length %d\n\r", req->content_len);
- while (remaining > 0)
- {
- //ESP_LOGI(TAG, "Remaining size : %d", remaining);
- /* Receive the file part by part into a buffer */
- memset(buf, 0, 512);
- if ((received = httpd_req_recv(req, buf, MIN(remaining, 512))) <= 0)
- {
- if (received == HTTPD_SOCK_ERR_TIMEOUT) continue;
- ESP_LOGE(TAG, "File reception failed!");
- httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file");
- return ESP_FAIL;
- }
- //ESP_LOGI(TAG, "Received size : %d", received);
- ESP_ERROR_CHECK(esp_partition_write(partition, 0 + (iterator * 512), buf, MIN(remaining, 512)));
- vTaskDelay(8); // Note required otherwise esp_partition_write adds whitespace
- remaining -= received;
- iterator++;
- }
- ESP_LOGI(TAG, "File reception complete");
- // Redirect onto root to see the updated file list
- httpd_resp_set_status(req, "303 See Other");
- httpd_resp_set_hdr (req, "Location", "/");
- #ifdef CONFIG_EXAMPLE_HTTPD_CONN_CLOSE_HEADER
- httpd_resp_set_hdr(req, "Connection", "close");
- #endif
- httpd_resp_sendstr(req, "File uploaded successfully");
- partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_ANY, "ota_1");
- esp_ota_set_boot_partition(partition);
- vTaskDelay(200);
- esp_restart();
- return error;
- }