帮我写一个ESP32 OTA升级的程序,不要用Arduino
时间: 2023-05-18 15:06:27 浏览: 202
非常感谢您的提问。以下是一个ESP32 OTA升级的程序,使用ESP-IDF开发框架,不使用Arduino:
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_flash_partitions.h"
#include "esp_partition.h"
static const char *TAG = "ota_example";
/* Constants that aren't configurable in menuconfig */
#define BUFFSIZE 1024
#define HASH_LEN 32 /* SHA-256 digest length */
/*an ota data write buffer ready to write to the flash*/
static char ota_write_data[BUFFSIZE + 1] = { 0 };
/*an ota example read buffer to read http response*/
char ota_read_data[BUFFSIZE + 1] = { 0 };
/*an ota hash context*/
static esp_sha256_context_t sha256_ctx;
/*an ota digest buffer*/
static uint8_t sha256_digest[HASH_LEN] = { 0 };
/*static function for updating progress bar*/
static void print_sha256 (const uint8_t *sha256_digest)
{
int i;
ESP_LOGI(TAG, "SHA-256 digest:");
for (i = 0; i < HASH_LEN; ++i) {
ESP_LOGI(TAG, "%02x", sha256_digest[i]);
}
ESP_LOGI(TAG, "\n");
}
/*callback function handling http events*/
static esp_err_t _http_event_handler(esp_http_client_event_t *evt)
{
switch(evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
if (!esp_http_client_is_chunked_response(evt->client)) {
// Write out data
memcpy(ota_read_data, evt->data, evt->data_len);
ota_read_data[evt->data_len] = '\0';
}
esp_sha256_update(&sha256_ctx, (const uint8_t *)evt->data, evt->data_len);
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
}
void ota_task(void *pvParameter)
{
ESP_LOGI(TAG, "Starting OTA example...");
const esp_partition_t *update_partition = NULL;
/*connect to http server*/
esp_http_client_config_t config = {
.url = "http://192.168.1.100:8070/hello-world.bin",
.event_handler = _http_event_handler,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_open(client, 0);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
goto end;
}
/*get header info*/
esp_http_client_fetch_headers(client);
/*check content length*/
int content_length = esp_http_client_fetch_content_length(client);
if (content_length <= 0) {
ESP_LOGE(TAG, "Invalid content length");
goto end;
}
/*check if partition has enough space for update*/
update_partition = esp_ota_get_next_update_partition(NULL);
if (update_partition == NULL) {
ESP_LOGE(TAG, "Failed to get update partition");
goto end;
}
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
update_partition->subtype, update_partition->address);
assert(update_partition->size > content_length);
/*create OTA hash context*/
esp_sha256_init(&sha256_ctx);
/*read OTA data and write to partition*/
int binary_file_length = 0;
while (1) {
int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);
if (data_read == 0) {
ESP_LOGI(TAG, "Connection closed,all data received");
break;
}
// Write OTA data to partition
err = esp_partition_write(update_partition, binary_file_length, (const void *)ota_write_data, data_read);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Error: esp_partition_write failed (%s)", esp_err_to_name(err));
goto end;
}
binary_file_length += data_read;
esp_sha256_update(&sha256_ctx, (const uint8_t *)ota_write_data, data_read);
ESP_LOGI(TAG, "Written image length %d", binary_file_length);
}
ESP_LOGI(TAG, "Total binary data length writen: %d", binary_file_length);
/*OTA update finished, deinit http session*/
esp_http_client_close(client);
esp_http_client_cleanup(client);
client = NULL;
/*calculate OTA hash*/
esp_sha256_finish(&sha256_ctx, sha256_digest);
/*print OTA hash for comparison with server*/
print_sha256(sha256_digest);
/*set boot partition*/
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
goto end;
}
ESP_LOGI(TAG, "Prepare to restart system!");
esp_restart();
end:
if (client) {
esp_http_client_close(client);
esp_http_client_cleanup(client);
}
vTaskDelete(NULL);
}
void app_main()
{
ESP_LOGI(TAG, "OTA example");
xTaskCreate(&ota_task, "ota_task", 8192, NULL, 5, NULL);
}
希望这个程序对您有所帮助!
阅读全文