ESP32编译和双OTA分区问题
1.同一份代码,上次编译过了,重新删除build, 再次编译就会出错
这个问题也是奇葩,是因为我的电脑C盘满了,次数底层调用python编译的时候,一些数据写不到C盘,导致编译失败。
2.双OTA问题
参考文献:
分区表 - ESP32 - — ESP-IDF 编程指南 latest 文档
2.1.修改使用自己定义的paritions-16MiB.csv
在使用分区表时,最简单的方法就是打开项目配置菜单 (idf.py menuconfig
),并在 CONFIG_PARTITION_TABLE_TYPE 下选择一个预定义的分区表:
-
Single factory app, no OTA
-
Factory app, two OTA definitions
-
Custom partition table CSV
选择自己的CSV, 需要选择Custom partition table CSV
2.2.配置双OTA
最开始我的CSV文件并没有添加双OTA的数据,后面开发增加OTA, CONFIG_PARTIION_TABLE_TWO_OTA没设置,程序编译成功, 下载进去无法运行,将这个设置后,程序可以运行。
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flagsnvs, data, nvs, 0x9000, 0x4000, ,otadata, data, ota, 0xd000, 0x2000, ,phy_init, data, phy, 0xf000, 0x1000, ,factory, app, factory, 0x10000, 0x280000, ,ota_0, app, ota_0, , 0x280000, ,ota_1, app, ota_1, , 0x280000, ,storage, data, littlefs, , 0x300000, ,
3.http升级
官网提供的例程是https的升级例程,这个时候需要提供证书,目前公司走的都是http并不支持ssl.
我使用的是simple_ota_example.c
配置修改如下:
代码修改如下
/* OTA exampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied.
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_log.h"
// #include "esp_ota_ops.h"
#include "esp_http_client.h"
#include "esp_https_ota.h"
// #include "protocol_examples_common.h"
#include "string.h"
#ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
#include "esp_crt_bundle.h"
#endif
#include "esp_tls.h"
#include "nvs.h"
#include "nvs_flash.h"
// #include "protocol_examples_common.h"
#include <sys/socket.h>
#if CONFIG_EXAMPLE_CONNECT_WIFI
#include "esp_wifi.h"
#endif#define HASH_LEN 32#ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
/* The interface name value can refer to if_desc in esp_netif_defaults.h */
#if CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_ETH
static const char *bind_interface_name = EXAMPLE_NETIF_DESC_ETH;
#elif CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_STA
static const char *bind_interface_name = EXAMPLE_NETIF_DESC_STA;
#endif
#endifstatic const char *TAG = "simple_ota_example";
extern const uint8_t server_cert_pem_start[] asm("_binary_ca_cert_pem_start");
extern const uint8_t server_cert_pem_end[] asm("_binary_ca_cert_pem_end");#define OTA_URL_SIZE 256static 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);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;case HTTP_EVENT_REDIRECT:ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT");break;}return ESP_OK;
}void simple_ota_example_task(void *pvParameter)
{ESP_LOGI(TAG, "Starting OTA example task");vTaskDelay(20000 / portTICK_PERIOD_MS);ESP_LOGI(TAG, "Starting OTA example task..");ESP_LOGI(TAG, "Starting OTA example task...");ESP_LOGI(TAG, "Starting OTA example task.....");// esp_tls_cfg_t tls_cfg ={0};// tls_cfg.transport_type = ESP_TRANSPORT_SECURE_TCP;// tls_cfg.skip_server_cert_verify = false;// #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
// esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name);
// if (netif == NULL) {
// ESP_LOGE(TAG, "Can't find netif from interface description");
// abort();
// }
// struct ifreq ifr;
// esp_netif_get_netif_impl_name(netif, ifr.ifr_name);
// ESP_LOGI(TAG, "Bind interface name is %s", ifr.ifr_name);
// #endifesp_http_client_config_t config = {.url = "https://plus.your_url.com/witbee/2025/01/08/10c779fb9a8f4805b1ab259b4e9a4476.bin",
// #ifdef CONFIG_EXAMPLE_USE_CERT_BUNDLE
// .crt_bundle_attach = esp_crt_bundle_attach,
// #else
// .cert_pem = (char *)server_cert_pem_start,
// #endif /* CONFIG_EXAMPLE_USE_CERT_BUNDLE */.event_handler = _http_event_handler,.keep_alive_enable = true,
// #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF
// .if_name = &ifr,
// #endif};// #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL_FROM_STDIN
// char url_buf[OTA_URL_SIZE];
// if (strcmp(config.url, "FROM_STDIN") == 0) {
// example_configure_stdin_stdout();
// fgets(url_buf, OTA_URL_SIZE, stdin);
// int len = strlen(url_buf);
// url_buf[len - 1] = '\0';
// config.url = url_buf;
// } else {
// ESP_LOGE(TAG, "Configuration mismatch: wrong firmware upgrade image url");
// abort();
// }
// #endif
// #ifdef CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK// config.skip_cert_common_name_check = true;
// #endif
// esp_tls_init(config.url, tls_cfg);esp_https_ota_config_t ota_config = {.http_config = &config,};ESP_LOGI(TAG, "Attempting to download update from %s", config.url);esp_err_t ret = esp_https_ota(&ota_config);if (ret == ESP_OK) {ESP_LOGI(TAG, "OTA Succeed, Rebooting...");esp_restart();} else {ESP_LOGE(TAG, "Firmware upgrade failed");}while (1) {vTaskDelay(1000 / portTICK_PERIOD_MS);}
}// static void print_sha256(const uint8_t *image_hash, const char *label)
// {
// char hash_print[HASH_LEN * 2 + 1];
// hash_print[HASH_LEN * 2] = 0;
// for (int i = 0; i < HASH_LEN; ++i) {
// sprintf(&hash_print[i * 2], "%02x", image_hash[i]);
// }
// ESP_LOGI(TAG, "%s %s", label, hash_print);
// }// static void get_sha256_of_partitions(void)
// {
// uint8_t sha_256[HASH_LEN] = { 0 };
// esp_partition_t partition;// // get sha256 digest for bootloader
// partition.address = ESP_BOOTLOADER_OFFSET;
// partition.size = ESP_PARTITION_TABLE_OFFSET;
// partition.type = ESP_PARTITION_TYPE_APP;
// esp_partition_get_sha256(&partition, sha_256);
// print_sha256(sha_256, "SHA-256 for bootloader: ");// // get sha256 digest for running partition
// esp_partition_get_sha256(esp_ota_get_running_partition(), sha_256);
// print_sha256(sha_256, "SHA-256 for current firmware: ");
// }void http_ota_init(void)
{// get_sha256_of_partitions();// ESP_ERROR_CHECK(esp_netif_init());// ESP_ERROR_CHECK(esp_event_loop_create_default());/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.* Read "Establishing Wi-Fi or Ethernet Connection" section in* examples/protocols/README.md for more information about this function.*/// ESP_ERROR_CHECK(example_connect());#if CONFIG_EXAMPLE_CONNECT_WIFI/* Ensure to disable any WiFi power save mode, this allows best throughput* and hence timings for overall OTA operation.*/// esp_wifi_set_ps(WIFI_PS_NONE);
#endif // CONFIG_EXAMPLE_CONNECT_WIFIxTaskCreate(&simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL);
}
最终所有的操作将在esp_err_t ret = esp_https_ota(&ota_config);这个函数下执行