ESP32学习笔记(24)——OTA(空中升级)接口使用(原生API)

发布者:平凡幸福最新更新时间:2025-02-28 来源: jianshu关键字:ESP32  OTA  API 手机看文章 扫描二维码
随时随地手机看文章

一、概述

ESP32应用程序可以在运行时通过Wi-Fi以太网从特定的服务器下载新映像,然后将其闪存到某些分区中,从而进行升级。

在ESP-IDF中有两种方式可以进行空中(OTA)升级:

  • 使用 app_update 组件提供的原生API

  • 使用 esp_https_ota 组件提供的简化API,它在原生OTA API上添加了一个抽象层,以便使用HTTPS协议进行升级。

分别在 native_ota_example 和 simple_ota_example 下的OTA示例中演示了这两种方法。

1.1 OTA工作流程

1.2 OTA数据分区

ESP32 SPI Flash 内有与升级相关的(至少)四个分区:OTA data、Factory App、OTA_0、OTA_1。其中 FactoryApp 内存有出厂时的默认固件

首次进行 OTA 升级时,OTA Demo 向 OTA_0 分区烧录目标固件,并在烧录完成后,更新 OTA data 分区数据并重启。

系统重启时获取 OTA data 分区数据进行计算,决定此后加载 OTA_0 分区的固件执行(而不是默认的 Factory App 分区内的固件),从而实现升级。

同理,若某次升级后 ESP32 已经在执行 OTA_0 内的固件,此时再升级时 OTA Demo 就会向 OTA_1 分区写入目标固件。再次启动后,执行 OTA_1 分区实现升级。以此类推,升级的目标固件始终在 OTA_0、OTA_1 两个分区之间交互烧录,不会影响到出厂时的 Factory App 固件。

为了简单起见,OTA示例通过在menuconfig中启用CONFIG_PARTITION_TABLE_TWO_OTA选项来选择预定义的分区表,该选项支持三个应用程序分区:工厂分区、OTA_0分区和OTA_1分区。有关分区表的更多信息,请参阅分区表.

二、API说明

以下原生 OTA 接口位于 app_update/include/esp_ota_ops.h。

2.1 esp_ota_begin

2.2 esp_ota_write

2.3 esp_ota_end

2.4 esp_ota_set_boot_partition

2.5 esp_ota_get_boot_partition

2.6 esp_ota_get_running_partition

2.7 esp_ota_get_next_update_partition

三、编程流程

3.1 OTA详细过程逻辑

3.2 OTA分区操作流程



节选自 esp-idfexamplessystemotanative_ota_example 中的例程


static void ota_example_task(void *pvParameter){

    esp_err_t err;

    /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */

    esp_ota_handle_t update_handle = 0 ;

    const esp_partition_t *update_partition = NULL;


    ESP_LOGI(TAG, 'Starting OTA example');

    //获取OTA app存放的位置

    const esp_partition_t *configured = esp_ota_get_boot_partition();

    //获取当前系统执行的固件所在的Flash分区

    const esp_partition_t *running = esp_ota_get_running_partition();


    if (configured != running) {

        ESP_LOGW(TAG, 'Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x',

                 configured->address, running->address);

        ESP_LOGW(TAG, '(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)');

    }

    ESP_LOGI(TAG, 'Running partition type %d subtype %d (offset 0x%08x)',

             running->type, running->subtype, running->address);


    esp_http_client_config_t config = {

        .url = CONFIG_EXAMPLE_FIRMWARE_UPG_URL,

        .cert_pem = (char *)server_cert_pem_start,

        .timeout_ms = CONFIG_EXAMPLE_OTA_RECV_TIMEOUT,

    };#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] = '';

        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_http_client_handle_t client = esp_http_client_init(&config);

    if (client == NULL) {

        ESP_LOGE(TAG, 'Failed to initialise HTTP connection');

        task_fatal_error();

    }

    //连http服务器

    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));

        esp_http_client_cleanup(client);

        task_fatal_error();

    }

    esp_http_client_fetch_headers(client);


    //获取当前系统下一个(紧邻当前使用的OTA_X分区)可用于烧录升级固件的Flash分区

    update_partition = esp_ota_get_next_update_partition(NULL);

    ESP_LOGI(TAG, 'Writing to partition subtype %d at offset 0x%x',

             update_partition->subtype, update_partition->address);

    assert(update_partition != NULL);


    int binary_file_length = 0;

    /*deal with all receive packet*/

    bool image_header_was_checked = false;

    while (1) {

        int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);

        if (data_read < 0) {

            ESP_LOGE(TAG, 'Error: SSL data read error');

            http_cleanup(client);

            task_fatal_error();

        } else if (data_read > 0) {

            if (image_header_was_checked == false) {

                esp_app_desc_t new_app_info;

                if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) {

                    // check current version with downloading

                    memcpy(&new_app_info, &ota_write_data[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));

                    ESP_LOGI(TAG, 'New firmware version: %s', new_app_info.version);


                    esp_app_desc_t running_app_info;

                    if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {

                        ESP_LOGI(TAG, 'Running firmware version: %s', running_app_info.version);

                    }


                    const esp_partition_t* last_invalid_app = esp_ota_get_last_invalid_partition();

                    esp_app_desc_t invalid_app_info;

                    if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK) {

                        ESP_LOGI(TAG, 'Last invalid firmware version: %s', invalid_app_info.version);

                    }


                    // check current version with last invalid partition

                    if (last_invalid_app != NULL) {

                        if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) {

                            ESP_LOGW(TAG, 'New version is the same as invalid version.');

                            ESP_LOGW(TAG, 'Previously, there was an attempt to launch the firmware with %s version, but it failed.', invalid_app_info.version);

                            ESP_LOGW(TAG, 'The firmware has been rolled back to the previous version.');

                            http_cleanup(client);

                            infinite_loop();

                        }

                    }#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK

                    if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {

                        ESP_LOGW(TAG, 'Current running version is the same as a new. We will not continue the update.');

                        http_cleanup(client);

                        infinite_loop();

                    }#endif


                    image_header_was_checked = true;

                     //OTA写开始

                    err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);

                    if (err != ESP_OK) {

                        ESP_LOGE(TAG, 'esp_ota_begin failed (%s)', esp_err_to_name(err));

                        http_cleanup(client);

                        task_fatal_error();

                    }

                    ESP_LOGI(TAG, 'esp_ota_begin succeeded');

                } else {

                    ESP_LOGE(TAG, 'received package is not fit len');

                    http_cleanup(client);

[1] [2]
关键字:ESP32  OTA  API 引用地址:ESP32学习笔记(24)——OTA(空中升级)接口使用(原生API)

上一篇:ThreadX移植——STM32H7+MDK-AC6平台
下一篇:ESP32学习笔记(23)——NVS(非易失性存储)接口使用

推荐阅读最新更新时间:2026-03-18 16:46

ESP32学习笔记(24)——OTA(空中升级)接口使用(原生API
一、概述 ESP32应用程序可以在运行时通过Wi-Fi或以太网从特定的服务器下载新映像,然后将其闪存到某些分区中,从而进行升级。 在ESP-IDF中有两种方式可以进行空中(OTA)升级: 使用 app_update 组件提供的原生API 使用 esp_https_ota 组件提供的简化API,它在原生OTA API上添加了一个抽象层,以便使用HTTPS协议进行升级。 分别在 native_ota_example 和 simple_ota_example 下的OTA示例中演示了这两种方法。 1.1 OTA工作流程 1.2 OTA数据分区 ESP32 SPI Flash 内有与升级相关的(至少)四个分区:OTA data
[单片机]
所有汽车厂商的研发趋势:OTA空中升级服务
随着社会发展,马路上的汽车越来越多,据最新报告预计,到2020年,世界上会有2500万辆互联汽车行驶在公路上,促进了全新的车载服务和自动驾驶功能的发展。那如何能实现智能化汽车时代,将是一个大话题。 但是,什么才是真正意义上的智能汽车?智能应该是有生命的东西,它会成长。这也是特斯拉的高明之处,它首开先河,以OTA 的方式进行软件更新。特斯拉也成为在新兴汽车制造商领域将OTA战略执行最为彻底也是从中受益最大的汽车公司。其自2014年进入中国后,通过OTA技术对ModelS系列的汽车先后进行了8次大的版本升级迭代,每次都为客户带来的新的体验。摩根士丹利分析师Adam Jonas甚至认为传统汽车会过时的主要原因就是他们无法与特斯拉的
[汽车电子]
打破汽车价值链 斑马智行启动全球最大规模汽车OTA空中升级
斑马网络正式启动 斑马智行 2.0空中升级,当日约30位 荣威RX5 智 联网汽车 车主齐聚斑马网络总部,参与了此次斑马智行2.0升级的首发式。即日起,近40万智联网汽车用户将陆续、分批次完成OTA空中升级,这也是全球汽车领域最大规模的OTA升级。斑马智行2.0的升级预示其正在打破传统汽车价值链,让汽车成为新的智能移动终端。   伴随着智能网联汽车的“风口”,汽车产业正进入重新洗牌的阶段,软件正在重新定义汽车。据赛迪研究院统计,在传统汽车价值中硬件占90%,软件占10%,在智能汽车价值中,硬件占40%,软件占40%,内容占20%。一辆智能汽车约装备50-100个ECU(电控单元),20000万行左右的源代码,代码量与空客A380客
[嵌入式]
解决方法:ESP32同时打开蓝牙、WIFI和OTA后程序过大导致无法启动
一、问题 使用 ESP32-WROOM-32E(4MB) 模组,同时使用了蓝牙模块、WIFI模块功能,编译的时候没问题,然后运行的时候报以下错误: 二、原因 ESP32 如果使同时使用了蓝牙模块、WIFI模块和OTA的话很有可能会导致程序过大(超过1M),系统无法启动的情况。这里提供一种通过修改分区表扩大程序储存空间的方法来避免这一问题。这一解决方法同样只用于因为其他问题导致的程序过大的情况。 三、解决方法 3.1 分区表 每片 ESP32 的 Flash 可以包含多个应用程序,以及多种不同类型的数据(例如校准数据、文件系统数据、参数存储器数据等)。因此,引入分区表的概念。 具体来说,ESP32 在 Flash 的 默认偏移
[单片机]
Nordic Semiconductor最新nRF5 SDK推出安全的签名空中固件升级功能
Nordic最新发布的nRF5 SDK v12.0允许通过安全签名完成空中固件升级,确保更新来自经过验证的可信任来源。此外,这款SDK现在支持基于Nordic nRF52832的 Arduino Primo 基板共用的Arduino开发套件,具有允许使用Keil进行图形配置的CMSIS配置向导,提供低功耗蓝牙连续血糖仪(CGM)规范支持,以及优化浮点单元运算 挪威奥斯陆 2016年9月5日 Nordic Semiconductor宣布其最新发布的nRF5 SDK v12.0支持安全的签名空中设备固件升级(OTA-DFU),可增强应用升级的安全性,通过使用安全的签名,在给定设备上确保使用经过验证的可信任来源进行应用更新
[安防电子]
Nordic Semiconductor最新nRF5 SDK推出安全的签名<font color='red'>空中</font>固件<font color='red'>升级</font>功能
Neuralink首例受试者:无需手术升级脑机接口 类似特斯拉OTA更新
1月19日消息,据媒体报道,全球首例Neuralink侵入式脑机接口受试者诺兰·阿博(Nolan Arbaugh)近日透露,其植入的脑机芯片已能够通过OTA(空中下载技术)方式进行远程升级,更新模式类似特斯拉汽车的OTA更新。 阿博介绍,目前Neuralink脑机接口系统主要通过三种途径进行更新:一是通过名为“心灵感应”(Telepathy)的专用应用程序进行软件更新。该应用允许患者在手机或电脑上以意念操控外部设备,并会像普通App一样定期接收云端更新。 二是植入体固件本身的无线升级。脑机芯片搭载的固件支持OTA更新,这意味着无需二次手术,即可持续提升系统在速度、精度、信号处理及可靠性等方面的表现。 阿博举例称,其植入初期曾遭遇约
[医疗电子]
STM32三方库固件升级OTA详解
一、Bootloader 1、Bootloader生成 官方网站:http://iot.rt-thread.com 官方文档:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/application-note/system/rtboot/an0028-rtboot 新建产品- 固件升级- 生成Bootloader: 将会生成bin固件发送到邮箱并下载: 2、Bootloader烧录 配置工程、Target- Production Programming(JLINK方式): 由于此时
[单片机]
STM32三方库固件<font color='red'>升级</font>与<font color='red'>OTA</font>详解
ESP32-OTA升级
基于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 #
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved