ESP32S系列芯片通过EC20完成OTA统一流程

2023-11-05

    uint32_t end_size = 0;            // 最后一包的大小
    uint16_t page_number = 0;         // 总包数
    uint16_t now_number = 0;          // 当前写入页数
    uint32_t bin_addr = 0;            // 文件地址指针偏移量
    uint16_t read_size = ENCRYT_SIZE; // 每次读3088 最后一页需要计算
    uint8_t bin_handle_s[100];
    uint16_t bin_handle_d = 0;
    esp_err_t err;
    uint16_t i = 0;
    uint8_t percent = 0;

    static char bar[102];
    memset(bar, 0, sizeof(bar));
    const char *lable = "|/-\\";

    updating_flag = 1;

    ESP_LOGI(TAG, "Starting OTA example...\n");
    const esp_partition_t *configured = esp_ota_get_boot_partition();
    const esp_partition_t *running = esp_ota_get_running_partition();
    if (configured != running)
    {
        ESP_LOGI(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x\n(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)\n", configured->address, running->address);
    }
    ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)\n", running->type, running->subtype, running->address);
    update_partition = esp_ota_get_next_update_partition(NULL);
    assert(update_partition != NULL);
    ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x\n", update_partition->subtype, update_partition->address);
    err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "esp_ota_begin failed, error=%d\n", err);
        vTaskDelay(5000);
        esp_restart();
    }
    ESP_LOGI(TAG, "esp_ota_begin succeeded\n");

    end_size = LTE_EC20.BIN_len % max_read_size; // 最后一包大小
    if (end_size == 0)                           // 恰巧是完整包
    {
        page_number = LTE_EC20.BIN_len / max_read_size;
    }
    else
        page_number = LTE_EC20.BIN_len / max_read_size + 1;
    ESP_LOGI(TAG, "总长:%d 总包:%d 末包:%d\r\n", LTE_EC20.BIN_len, page_number, end_size);


    while (1)
    {
        if (percent % 10 == 0 && percent != 0)
        {
            User_Reply_Progress(percent);//上报OTA进度百分比
        }
        if (stop_update_flag == 1)//收到停止升级指令
        {
            stop_update_flag = 0;

            Log_Write(TAG, "OTA aborted by cloud mqtt server!\r");
            esp_ota_abort(update_handle); // 暂停OTA
            ESP_LOGE(TAG, "Stop Update!! Restart!\n");
           
            vTaskDelay(5000);
            esp_restart();
        }
        // 打开UFS 文件系统
        if (bin_addr == 0) // 首次读取
        {
            // 打开文件
            ucExecRes = LTE_AT_SR("AT+QFOPEN=\"ota.bin\",0\r\n", "+QFOPEN: ", "ERROR", 5000 / portTICK_PERIOD_MS); // 返回值为文件句柄 当操作文件比较多时有可能是变量
            if (ucExecRes == ExecFail)
            {
                ESP_LOGE(TAG, "Open file system failed ,stop ota");
                ucExecRes = LTE_AT_SR("AT+QFCLOSE=0", "OK", "ERROR", 1000 / portTICK_PERIOD_MS); //
                goto err_res;
            }
            Find_string((char *)Get_AT_Rev_Buffer(), "+QFOPEN: ", "\n", (char *)bin_handle_s); // 获取文件句柄
            bin_handle_d = atoi((char *)bin_handle_s);
            ESP_LOGI(TAG, "Bin handle:%d\r\n", bin_handle_d);
        }
        // 设置文件指针位置
        memset(AT_send, 0x00, sizeof(AT_send));
        snprintf((char *)AT_send, sizeof(AT_send), "AT+QFSEEK=%d,%d,0\r\n", bin_handle_d, bin_addr);
        ucExecRes = LTE_AT_SR((char *)AT_send, "OK", "ERROR", 5000 / portTICK_PERIOD_MS); //

        if (ucExecRes == Normal)
        {
            (void)0;
        }
        if (bin_addr == 0) // 第一次seek需要点时间才能到最开头的位置
            vTaskDelay(1000);
        else
            vTaskDelay(20);
        // 读文件
        memset(AT_send, 0x00, sizeof(AT_send));
        snprintf((char *)AT_send, sizeof(AT_send), "AT+QFREAD=%d,%d\r\n", bin_handle_d, read_size);
        ucExecRes = LTE_AT_SR((char *)AT_send, "OK", "ERROR", 2000 / portTICK_PERIOD_MS); //
        if (ucExecRes == Normal)
        {
            // ESP_LOGE(TAG, "CNT:%d  NUM:%d LAST:%d LEN:%d ", now_number,  page_number, end_size,LTE_EC20.BIN_len);
            percent = ((now_number * 1.0) / (page_number * 1.0)) * 100.0;
            printf("\n\033[1;32m[%-100s]\033[0m [%d%%][%c]\r\n", bar, percent, lable[percent % 4]); // 显示进度条
            fflush(stdout);                                                                         // 刷新缓冲区
            bar[percent] = '#';

            memset(ota_write_data, 0, max_read_size);
            // 根据读取的位数来判断从哪个字符开始复制
            if (read_size >= 1000 && read_size < 10000) // CONNECT 999
                memcpy(ota_write_data, Get_AT_Rev_Buffer() + 16, read_size);
            else if (read_size < 1000 && read_size >= 100) // CONNECT 999
                memcpy(ota_write_data, Get_AT_Rev_Buffer() + 15, read_size);
            else if (read_size < 100 && read_size >= 10) // CONNECT 99
                memcpy(ota_write_data, Get_AT_Rev_Buffer() + 14, read_size);
            else if (read_size < 10 && read_size >= 1) // CONNECT 9
                memcpy(ota_write_data, Get_AT_Rev_Buffer() + 13, read_size);

            err = esp_ota_write(update_handle, (const void *)ota_write_data, UNENCRYT_SIZE); // 写入数据
            if (err != ESP_OK)
            {
                ESP_LOGE(TAG, "OTA:esp_ota_write failed! err=0x%x\n", err);
                printf("Firmware write failed! restart");
                goto err_res;
            }
            now_number += 1;
            if ((now_number == page_number - 1) && (end_size != 0)) // 存在最后不整包,并且到达了最后一包
            {
                bin_addr += max_read_size; // 把读过的地址加上
                read_size = end_size;
            }
            else if (now_number == page_number) // 下载完成
            {
                ESP_LOGI(TAG, "read packet over...\r");
                snprintf((char *)AT_send, sizeof(AT_send), "AT+QFCLOSE=%d\r", bin_handle_d);
                ucExecRes = LTE_AT_SR((char *)AT_send, "OK", "ERROR", 1000 / portTICK_PERIOD_MS); //
                printf("Firmware reception completed....\nVerifying...coming soon to restart\n");
                if (esp_ota_end(update_handle) != ESP_OK || esp_ota_set_boot_partition(update_partition) != ESP_OK)
                {
                    ESP_LOGE(TAG, "esp_ota_end failed!");
                    printf("OTA end failed and set boot partition failed!\n");
                }
                else
                {
                    ESP_LOGI(TAG, "esp_ota_end succeed!");
                    printf("OTA end succeed and set boot partition succeed!\n");
                }
                ESP_LOGI(TAG, "Prepare to restart system!");
                printf("OTA finished.Prepare to restart system!\n");
            err_res:
                vTaskDelay(3000);
                updating_flag = 0;
                esp_restart();
                break;
            }
            else
            {
                bin_addr += max_read_size;
                read_size = max_read_size;
            }
        }
    }

其实简化下来就是获取数据、写入数据、完成OTA重启三个步骤

简化代码为:


    ESP_LOGI(TAG, "Starting OTA example...\n");
    const esp_partition_t *configured = esp_ota_get_boot_partition();
    const esp_partition_t *running = esp_ota_get_running_partition();
    if (configured != running)
    {
        ESP_LOGI(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x\n(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)\n", configured->address, running->address);
    }
    ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)\n", running->type, running->subtype, running->address);
    update_partition = esp_ota_get_next_update_partition(NULL);
    assert(update_partition != NULL);
    ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x\n", update_partition->subtype, update_partition->address);
    err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
    if (err != ESP_OK)
    {
        esp_restart();
    }

    err = esp_ota_write(update_handle, (const void *)ota_write_data, UNENCRYT_SIZE); // 写入数据
            if (err != ESP_OK)
            {
                ESP_LOGE(TAG, "OTA:esp_ota_write failed! err=0x%x\n", err);
                goto err_res;
            }
           
                if (esp_ota_end(update_handle) != ESP_OK || esp_ota_set_boot_partition(update_partition) != ESP_OK)
                {
                    ESP_LOGE(TAG, "esp_ota_end failed!");
                }
                else
                {
                    ESP_LOGI(TAG, "esp_ota_end succeed!");
                }
                ESP_LOGI(TAG, "Prepare to restart system!");

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ESP32S系列芯片通过EC20完成OTA统一流程 的相关文章

  • aosp/ota/incremental update package/安卓 7aosp代码增量升级包

    make otapackage out target product aosp aosp ota eng lake zip 61 61 61 gt full update NOT used for incremental package B
  • ESP8266/ESP32+OLED12864简单WiFi扫描器 支持OTA

    功能描述 OLED显示SSID 全中文界面 支持中文SSID Arduino OTA支持 硬件准备 ESP8266 NodeMCU WiFi ESP32 WIFI 43 BLE 43 OLED开发板 OLED控制芯片 SSD1315兼容SS
  • EC20模块AT指令MQTT连接阿里云IoT,HTTP接口来实现一型一密动态注册的流程。

    EC20模块AT指令MQTT连接阿里云过程 推荐 xff1a 使用移远BC28 模组对接阿里云 MQTT 嵌入式 lx121451的博客 CSDN博客 https blog csdn net lx121451 article details
  • Android OTA升级

    1 xff0c Build otapackage后system img没有打包进去 xff1f Ota包里面缺失system img xff0c 原因是客户修改了prop里面的 ro product device value值 尝试以下两种
  • 汽车OTA是个什么鬼?

    OTA xff1a Over the Air Technology 这描述的是手机吧 xff01 不过一开始的手机也是不可以直接OTA的 1997年之前所有汽车都是一个独立的机械个体 xff0c 一个方向盘 xff0c 一组踏板 xff0c
  • An Ota Package Tool

    文章目录 OtaPackageToolInstallationBinary InstallationInstalling Tool from Source UsagePreparationExamplesFull UpdatesIncrem
  • Hi3798移植4G模块(移远EC20)

    Hi3798移植4G模块 xff08 移远EC20 xff09 一 前言二 USB驱动修改2 1 添加VID和PID信息2 2 添加空包处理机制2 3 添加复位重连机制2 4 修改内核配置 三 GoBiNet测试程序 一 前言 本次系统采用
  • 移远EC20设置RNDIS模式拨号上网

    背景 4G模块原本使用QMI方式拨号上网 xff0c 客户反馈某种定制卡不能上网 xff0c 切换下拨号模式看下设备能不能正常上网 xff1b 过程 openwrt中如果使用RNDIS模式上网需要在kernel配置中使能以下项 xff1a
  • EC20 GPS RMC格式数据转化

    文章目录 目录 前言 一 RMC是什么 xff1f 二 EC20 输出的RMC解析 1 EC20返回的RMC报文 2 RMC报文解析 3 NMEA数据ddmm mmmm转换成dd ddddd 4 RMC UTC时间转化成北京时间 总结 前言
  • 浅谈一下汽车行业中的OTA/FOTA/SOTA

    首先来一个背景知识铺垫 xff1a 被誉为汽车界 苹果 的特斯拉 xff0c 从它的第一款ModelS上市开始 xff0c 截止到2017年3月份的5年时间里 xff0c 总计对车辆推送了25次远程升级 特斯拉每次发布新系统新功能就可以通过
  • stm32 esp8266 ota升级-hex合并-烧录-bin生成

    stm32 esp8266 ota系列文章 xff1a stm32 esp8266 ota 快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级 tcp模拟http stm32 esp8266 o
  • stm32 esp8266 ota升级-tcp模拟http

    stm32 esp8266 ota系列文章 xff1a stm32 esp8266 ota 快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级 tcp模拟http stm32 esp8266 o
  • stm32 esp8266 ota升级-自建mqtt和文件服务器全量升级

    stm32 esp8266 ota系列文章 xff1a stm32 esp8266 ota 快速搭建web服务器之docker安装openresty stm32 esp8266 ota升级 tcp模拟http stm32 esp8266 o
  • 4.3寸串口屏在智能炒菜机上应用分享

    现代人追求高效品质生活的美好愿望以及社会科技的不断发展持续推动着一种新兴经济形态的出现 即懒人经济 懒人经济的崛起也成为智能家电行业新的增长引擎 自动炒菜机便是这一经济形态下的产物 对于很多居住于快节奏生活的一二线城市人来说 在辛苦工作一整
  • QCC300x笔记(6) -- QCC3007的OTA流程梳理

    哈喽大家好 这是该系列博文的第六篇 篇 lt lt 系列博文索引 快速通道 gt gt 写在前面 QCC300x支持OTA功能 官方提供了详细的文档说明 按照文档即可升级成功 下面是对流程的简单梳理 可参考 文档和APP下载 1 生产APP
  • stm32 IAP APP 相互跳转实验 (keil4 jlink STM32F407ZE)

    1 实验目标 STM32 IAP学习时 希望有一个快捷的方式去实验IAP与APP之间的相互跳转 1 验证IAP跳转至APP 2 验证APP通过软件reset跳转至IAP 避免再一开始就实验完整的IAP过程 编写BootLoader 编写 A
  • OTA测试方法解析

    目前 标准的OTA测试系统是SISO 单输入 单输出 如主流的2G 3G和WLAN的802 11a b g等设备 其主要的测试指标是TRP 总辐射功率 和TIS 总全向灵敏度 现代无线技术如LTE HSPA WI FI和WiMAX为了提高数
  • 经纬恒润OTA仿真测试解决方案为汽车智能化发展保驾护航

    OTA技术是汽车实现完整网联化 智能化体验的基础 自被引用汽车以来 广受研发人员 市场用户的关注 近来 国家有关部门也陆续出台了相应政策 对汽车企业OTA技术的应用进行了约束和规范 因此 OTA技术在量产车型的应用落地 离不开完整的测试验证
  • NRF52832学习笔记(2)—— 添加DFU功能(基于SDK15.3)

    前言 SDK版本15 3 评估板 pca10040 在 uart 的例程中添加 DFU 功能 使用 s132 的协议栈 因为官方的 BootLoader 工程用的是s132的协议栈 一 准备工作 在开始实验之前必须先准备以下软件 gcc a
  • 【自用】无法通过ESP32创建HomeAssistant实体问题解决(MQTT对ESP32创建实体请求无应答)

    一 问题描述 1 使用 MQTTX 测试客户端能够创建实体 当通过 MQTTX 发送注册实体请求的时候 实体能够在 MQTT 服务器中注册成功 2 使用 ESP32 无法创建实体 在ESP32中通过 publish 函数发送注册请求的时候

随机推荐

  • 在VUE中使用ElementUI的常用组件

    Layout布局 ElementUI将一行分为24栏 通过
  • Qt之信号与槽

    目录 信号与槽的概念 实现对象与对象之间的通信 信号 槽 信号与槽的连接 1 连接方式 2 连接规则 3 连接类型 信号与槽的概念 实现对象与对象之间的通信 当一个对象发生了改变会发送一个信号通知另一个对象执行一个函数 这个函数被称为槽 信
  • img标签的onerror事件

    有时 img标签中的src图片加载失败 原来的图片位置会出现一个碎片图标 用户体验会下降 通过百度 可以给img标签加背景图片 代码如下 headLogo img display block width 270px height 60px
  • mmdetection结果可视化

    import os from mmdet apis import init detector inference detector config file home lgh Desktop ours config py checkpoint
  • 使用Nvidia Jetson TX2进行人脸检测

    环境 Jetson TX2 JetPack 3 1 构建 1 下载代码 git clone https github com AastaNV Face Recognition 2 进入Face Recognition文件夹 cd Face
  • Nginx停止服务和各种命令

    1 停止Nginx服务的四种方法 从容停止服务 这种方法较stop相比就比较温和一些了 需要进程完成当前工作后再停止 nginx s quit 立即停止服务 这种方法比较强硬 无论进程是否在工作 都直接停止进程 nginx s stop s
  • k-均值聚类简介

    k 均值聚类 将训练集分成k个靠近彼此的不同样本聚类 因此我们可以认为该算法提供了k 维的one hot编码向量h以表示输入x 当x属于聚类i时 有hi 1 h的其它项为零 k 均值聚类提供的one hot编码也是一种稀疏表示 因为每个输入
  • C编程实例

    1 任意输入 3 个整数 编程实现对这 3 个整数由小到大进行排序 实现过程 1 定义数据类型 本实例中 a b c t 均为基本整型 2 使用输入函数获得任意 3 个值赋给 a b c 3 使用 if 语句进行条件判断 如果 a 大于 b
  • python dict无需判断key存在即可追加写入

    使用dict setdefault 可设置一个默认值 如果key已存在 就不会有其他操作 借此我们可以不用在追加数据时判断key的存在 my dict 建立一个空字典 my dict setdefault key 设置默认键 print a
  • mysql实习报告总结_MYSQL实训心得

    随时光游走 阳光穿过树叶的间隙 我们重新踏入这座美丽的校园 首先迎接我们的便是为时一周的 MYSQL 实训 在这短短的一周内 我们获益匪浅 在实训的开始 我们小组分析了老师给出的两个任务 然后一致决定研究第一个任务 我们首先讨论了处理任务的
  • 【手把手教你】使用pyfinance进行证券收益分析

    pyfinance简介 在查找如何使用Python实现滚动回归时 发现一个很有用的量化金融包 pyfinance 顾名思义 pyfinance是为投资管理和证券收益分析而构建的Python分析包 主要是对面向定量金融的现有包进行补充 如py
  • 汇编语言与微机原理(1)基础知识

    前言 1 本人使用的是 王爽老师的汇编语言第四版和 学校发的微机原理教材配合学习 2 推荐视频教程 通俗易懂的汇编语言 王爽老师的书 贺老师C站账号网址 3 文章配套资料 Github仓库链接 4 本文是介绍8086汇编语言 汇编语言简介
  • 基于51单片机的心率计脉搏体温测量仪WIFI传输APP设计方案原理图

    系统的功能分析及体系结构设计 末尾附文件 系统功能分析 本系统采用STC89C52单片机 LCD1602液晶 脉搏传感器 温度传感器DS18b20 WIFI模块电路设计而成 1 LCD1602液晶第一行显示设计信息 第二行显示心率和温度 2
  • 嵌入式软件开发之程序分层(二)

    前言 该内容是工作一年来通过上网或其他方式不断搜索 实践 总结出来的嵌入式软件开发经验 本文仅适用于单片机的裸机开发 希望能帮到正在学习这方面的朋友 如有不好的地方 请多多见谅 在嵌入式软件开发过程中 在程序架构的搭建完成之后 为了提高项目
  • 深度学习速成(5)torch.nn.Module类

    nn Module 是PyTorch中的一个基础类 nn即是Neural Networks 用于构建神经网络模型 所有的神经网络模型都必须继承于nn Module类 并实现 forward 方法来定义模型的前向传播过程 nn Module类
  • nginx 配置静态网页

    nginx 配置静态网页 进入配置文件 etc nginx conf d default conf 配置的时候小伙伴们一定要记得先备份一份文件 这样方便后续出错恢复 server listen 端口号 server name IP loca
  • 解决Springboot GET请求参数过长的情况

    项目场景 使用Spring Boot进行项目开发 解决Springboot GET请求参数过长的情况 问题描述 报错信息 Springboot GET请求参数过长抛出异常 Request header is too large 的问题 现象
  • 华为OD机试 - 冠亚军排名,奖牌榜排名(Java)

    题目描述 2012伦敦奥运会即将到来 大家都非常关注奖牌榜的情况 现在我们假设奖牌榜的排名规则如下 首先gold medal数量多的排在前面 其次silver medal数量多的排在前面 然后bronze medal数量多的排在前面 若以上
  • 2022-12-27 使用lodash库实现两个非空对象的深拷贝并输出这两个对象的并集

    问题描述 遇到这样一个题 如下 const a fruits apple banana series apple C banana A B const b fruits banana orange animals pig series ba
  • ESP32S系列芯片通过EC20完成OTA统一流程

    uint32 t end size 0 最后一包的大小 uint16 t page number 0 总包数 uint16 t now number 0 当前写入页数 uint32 t bin addr 0 文件地址指针偏移量 uint16