基于ESP-IDF4.1
1 #include <string.h> 2 #include "freertos/FreeRTOS.h" 3 #include "freertos/task.h" 4 #include "esp_system.h" 5 #include "esp_event.h" 6 #include "esp_log.h" 7 #include "esp_ota_ops.h" 8 #include "esp_http_client.h" 9 #include "esp_flash_partitions.h" 10 #include "esp_partition.h" 11 #include "nvs.h" 12 #include "nvs_flash.h" 13 #include "driver/gpio.h" 14 #include "protocol_examples_common.h" 15 #include "errno.h" 16 17 #if CONFIG_EXAMPLE_CONNECT_WIFI 18 #include "esp_wifi.h" 19 #endif 20 21 #define BUFFSIZE 1024 22 #define HASH_LEN 32 //sha256摘要长度 23 24 static const char *TAG = "native_ota_example"; 25 //准备写入闪存的OTA数据写入缓冲区 26 static char ota_write_data[BUFFSIZE + 1] = { 0 }; 27 extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start"); 28 extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end"); 29 30 #define OTA_URL_SIZE 256 31 32 static void http_cleanup(esp_http_client_handle_t client) 33 { 34 esp_http_client_close(client); 35 esp_http_client_cleanup(client); 36 } 37 38 //__attribute__((noreturn)) 这个属性告诉编译器函数不会返回,这可以用来抑制关于未达到代码路径的错误。 39 static void __attribute__((noreturn)) task_fatal_error(void) 40 { 41 ESP_LOGE(TAG, "Exiting task due to fatal error..."); 42 (void)vTaskDelete(NULL); 43 44 while (1) { 45 ; 46 } 47 } 48 49 static void print_sha256 (const uint8_t *image_hash, const char *label) 50 { 51 char hash_print[HASH_LEN * 2 + 1]; 52 hash_print[HASH_LEN * 2] = 0; 53 for (int i = 0; i < HASH_LEN; ++i) { 54 sprintf(&hash_print[i * 2], "%02x", image_hash[i]); 55 } 56 ESP_LOGI(TAG, "%s: %s", label, hash_print); 57 } 58 59 static void infinite_loop(void) 60 { 61 int i = 0; 62 ESP_LOGI(TAG, "When a new firmware is available on the server, press the reset button to download it"); 63 while(1) { 64 ESP_LOGI(TAG, "Waiting for a new firmware ... %d", ++i); 65 vTaskDelay(2000 / portTICK_PERIOD_MS); 66 } 67 } 68 69 //OTA升级任务 70 static void ota_example_task(void *pvParameter) 71 { 72 esp_err_t err; 73 //更新处理程序,通过esp_ota_begin()设置,必须通过esp_ota_end()释放 74 esp_ota_handle_t update_handle = 0 ; 75 const esp_partition_t *update_partition = NULL; 76 77 ESP_LOGI(TAG, "Starting OTA example"); 78 79 const esp_partition_t *configured = esp_ota_get_boot_partition(); 80 const esp_partition_t *running = esp_ota_get_running_partition(); 81 82 if (configured != running) { 83 ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x", 84 configured->address, running->address); 85 ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)"); 86 } 87 ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)", 88 running->type, running->subtype, running->address); 89 90 esp_http_client_config_t config = { 91 .url = CONFIG_EXAMPLE_FIRMWARE_UPG_URL, 92 .cert_pem = (char *)server_cert_pem_start, 93 .timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT, 94 }; 95 96 #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN 97 char url_buf[OTA_URL_SIZE]; 98 if (strcmp(config.url, "FROM_STDIN") == 0) { 99 example_configure_stdin_stdout(); 100 fgets(url_buf, OTA_URL_SIZE, stdin); 101 int len = strlen(url_buf); 102 url_buf[len - 1] = '