当前位置: 首页 > news >正文

ESP8285 RTOS SDK OTA

一、官方资源说明

官方指南:空中升级 (OTA) - ESP32 - — ESP-IDF 编程指南 v4.3.6 文档,虽然是正对ESP32的,但是原理是一样的。

官方参考例程:esp-idf\ESP8266_RTOS_SDK\examples\system\ota\,其中包含两个例程,一个是simple_ota_example,另一个是native_ota。simple_ota_example例程调用的是封装之后函数,只需要将固件的下载地址传入函数即可自动完成升级,而native_ota调用的是原生的函数,有更多的过程,详细展示了OTA的下载、存储过程以及校验。这里以simple_ota_example为例进行讲解。

二、修改配置文件

1、修改Partition Table

使用带ota分区的Partition Table,在flash区域中划出两块app存储空间,一块区域是当前运行的app区,另一块区域是新下载的app存放的区域。进入到工程目录中,执行make menuconfig,然后选择

Partition Table  --->

        Partition Table (Single factory app, no OTA)  --->  

                        (X) Factory app, two OTA definitions

2、允许http方式进行ota

此方式不需要证书,更简单。

 Component config  ---> 

        ESP HTTPS OTA  --->

                 [*] Allow HTTP for OTA (WARNING: ONLY FOR TESTING PURPOSE, READ HELP)  

三、编写代码

1、升级流程

上电->进入app_main()->创建升级任务(simple_ota_example_task)->执行任务->等待wifi连接并获取IP地址->http请求服务器上的固件版本号->与当前运行版本号进行比较->如果服务器上的固件版本号更高->下载新的固件->下载完成之后重启设备。

2、代码

版本比较函数

/*** @brief  None.* @param  None.* @retval None.*/
int edition_compare(const char* pszStr1, const char* pszStr2)
{if (pszStr1 == NULL || pszStr2 == NULL) {return 0;}int nCurPos = 0, nCapPos=-1;const char* pszTmp1 = pszStr1;const char* pszTmp2 = pszStr2;while ((*pszTmp1 != '\0') && (*pszTmp2 != '\0') && (*pszTmp1 == *pszTmp2)) {	nCurPos++;									//找到第一个处不相同出现的位置pszTmp1++;pszTmp2++;if (*pszTmp1 == '.') {nCapPos = nCurPos;						//记录最近的‘.’的位置}}if (*pszTmp1 == '\0' && *pszTmp2 == '\0') { // 两个字符串相等return 0;} else if(*pszTmp1 == '\0'){return -1;} else if(*pszTmp2 == '\0'){return 1;}else{ // 两个字符串不相等,比较大小pszTmp1 = pszStr1 + nCapPos + 1;pszTmp2 = pszStr2 + nCapPos + 1;int pszNub1=strtol(pszTmp1,NULL,10);int pszNub2=strtol(pszTmp2,NULL,10);return (pszNub1 - pszNub2);}
}

创建设备事件,用于等待网络连接

const int CONNECTED_BIT = BIT0;s_device_event_group = xEventGroupCreate();

 event_handler()函数中加入s_device_event_group的设置

/*** @brief  event_handler.* @param  None.* @retval None.*/
static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect();}else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {	xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);xEventGroupClearBits(s_device_event_group, WIFI_CONNECTED_BIT);esp_wifi_connect();}else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);xEventGroupSetBits(s_device_event_group, WIFI_CONNECTED_BIT);}else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {ESP_LOGI(TAG, "Scan done");}else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {ESP_LOGI(TAG, "Found channel");} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {ESP_LOGI(TAG, "Got SSID and password");smartconfig_event_got_ssid_pswd_t* evt = (smartconfig_event_got_ssid_pswd_t*)event_data;wifi_config_t wifi_config;uint8_t ssid[33] = { 0 };uint8_t password[65] = { 0 };uint8_t rvd_data[33] = { 0 };bzero(&wifi_config, sizeof(wifi_config_t));memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));wifi_config.sta.bssid_set = evt->bssid_set;if (wifi_config.sta.bssid_set == true) {memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));}memcpy(ssid, evt->ssid, sizeof(evt->ssid));memcpy(password, evt->password, sizeof(evt->password));ESP_LOGI(TAG, "SSID:%s", ssid);ESP_LOGI(TAG, "PASSWORD:%s", password);if (evt->type == SC_TYPE_ESPTOUCH_V2) {ESP_ERROR_CHECK( esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)) );ESP_LOGI(TAG, "RVD_DATA:%s", rvd_data);}ESP_ERROR_CHECK(esp_wifi_disconnect());ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));ESP_ERROR_CHECK(esp_wifi_connect());} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);}
}

任务函数

/*** @brief  None.* @param  None.* @retval None.*/
static void simple_ota_example_task(void * pvParameter)
{EventBits_t uxBits = xEventGroupWaitBits(s_device_event_group, WIFI_CONNECTED_BIT, pdFALSE, false, portMAX_DELAY ); if( (uxBits & WIFI_CONNECTED_BIT) == WIFI_CONNECTED_BIT ){ESP_LOGI(TAG, "Starting OTA example...");char local_response_buffer[101] = {0};esp_http_client_config_t config0 = {.url = "http://www.huochaigun.top/hello-world/version.html",.event_handler = _http_event_handler,
//	        .user_data = local_response_buffer,        // Pass address of local buffer to get response.buffer_size = 100};esp_http_client_handle_t client = esp_http_client_init(&config0);		// GETesp_err_t err = esp_http_client_perform(client);if (err == ESP_OK) {ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",esp_http_client_get_status_code(client),esp_http_client_get_content_length(client));} else {ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));}esp_http_client_read_response( client, local_response_buffer, 100 );local_response_buffer[ esp_http_client_get_content_length(client) ] = '\0';ESP_LOGI(TAG,"http response:%s\n", local_response_buffer );esp_http_client_cleanup(client);if( edition_compare(local_response_buffer, AppVer) > 0 ){esp_http_client_config_t config = {.url = "http://www.huochaigun.top/hello-world/hello-world.bin",.event_handler = _http_event_handler,};esp_err_t ret = esp_https_ota(&config);if (ret == ESP_OK) {esp_restart();} else {ESP_LOGE(TAG, "Firmware Upgrades Failed");}}else{ESP_LOGI(TAG, "The current software is the latest version");}}vTaskDelete( NULL );
}

app_main()中加入以下代码创建任务 

xTaskCreate(simple_ota_example_task, "ota_example_task", 8192, NULL, 5, NULL);

 四、编译固件

执行make之后,会新生成4个bin文件,将4个bin文件下载到设备即可。

0xd000 ota_data_initial.bin
0x0 bootloader.bin
0x10000 hello-world.bin
0x8000 partitions_two_ota.bin

可提供有偿技术支持。

相关文章:

ESP8285 RTOS SDK OTA

一、官方资源说明 官方指南:空中升级 (OTA) - ESP32 - — ESP-IDF 编程指南 v4.3.6 文档,虽然是正对ESP32的,但是原理是一样的。 官方参考例程:esp-idf\ESP8266_RTOS_SDK\examples\system\ota\,其中包含两个例程&…...

Hadoop3教程(四):HDFS的读写流程及节点距离计算

文章目录 (55)HDFS 写数据流程(56) 节点距离计算(57)机架感知(副本存储节点选择)(58)HDFS 读数据流程参考文献 (55)HDFS 写数据流程 …...

[0xGameCTF 2023] web题解

文章目录 [Week 1]signinbaby_phphello_httprepo_leakping [Week 2]ez_sqli方法一&#xff08;十六进制绕过&#xff09;方法二&#xff08;字符串拼接&#xff09; ez_upload [Week 1] signin 打开题目&#xff0c;查看下js代码 在main.js里找到flag baby_php <?php /…...

Qt之submodule编译

工作中会遇到这样一种情况&#xff1a;qt应用程序在运行时提示找不到某个qt的动态库。我遇到的是缺少libQt5Websocket.so&#xff0c;因为应用程序是在x86平台银河麒麟v10上开发&#xff0c;能够正常编译运行&#xff0c;然后移植到rk3588&#xff08;aarch64架构&#xff09;上…...

Python实现带图形界面的计算器

Python实现带图形界面的计算器 在本文中&#xff0c;我们将使用Python编写一个带有图形用户界面的计算器程序。这个程序将允许用户通过点击按钮或键盘输入数字和操作符&#xff0c;并在显示屏上显示计算结果。 开发环境准备 要运行这个计算器程序&#xff0c;您需要安装Pyth…...

$ vue -Vbash: vue: command not found

$ vue -V bash: vue: command not found报这个错&#xff0c;我们需要找到vue安装路径&#xff0c;添加在环境变量的用户变量中&#xff1a; 1、vue安装路径 2、编辑环境变量 然后重新打开命令框&#xff0c;就可以了...

专业音视频领域中,Pro AV的崛起之路

编者按&#xff1a;在技术进步的加持下&#xff0c;AV行业发展得如何了&#xff1f;本文采访了两位深耕于广播电视行业的技术人&#xff0c;为我们介绍了专业音视频的进展&#xff1a;一位冉冉升起的新星&#xff1a;Pro AV以及FPGA在其中发挥的作用。 美国&#xff0c;拉斯维加…...

vscode 右侧滚动条标记不提示,问题解决纪录

问题描述 用vscode看代码时&#xff0c;我希望在右侧提示一个变量在文件下都在那里使用&#xff0c;在那里赋值&#xff0c;之前该功能是存在的&#xff0c;当我打开一个新的文件夹时这个功能消失了。 解决办法 在setting.json文件下输入 "C_Cpp.intelliSenseEngine&…...

【Java 进阶篇】JavaScript特殊语法详解

JavaScript是一门非常灵活的编程语言&#xff0c;允许开发人员使用多种不同的语法和技巧来解决各种问题。本篇博客将深入探讨JavaScript中的一些特殊语法&#xff0c;这些语法可能不是常规的JavaScript编程知识&#xff0c;但它们对于理解语言的强大之处以及在某些情况下解决问…...

PCL点云处理之配准中的匹配对连线可视化显示 Correspondences(二百一十九)

PCL点云处理之配准中的匹配对连线可视化显示 Correspondences(二百一十九) 一、算法介绍二、算法实现1.可视化代码2.完整代码(特征匹配+可视化)最终效果一、算法介绍 关于点云配准中的匹配对,如果能够可视化将极大提高实验的准确性,还好PCL提供了这样的可视化工具,做法…...

Vue el-table全表搜索,模糊匹配-前端静态查询

后端返回的数据是全部的数据&#xff0c;没有分页&#xff0c;前端需要做的是分页全表模糊查询 代码&#xff1a; //根据关键字对表全局搜索 globalSearch() {//为了拿到对象的列名let filterList Object.keys(this.tableData[0]);if (this.searchWord) {this.tableFilterDat…...

基于html5开发的Win12网页版,抢先体验

据 MSPoweruser 报道&#xff0c;Windows 11虽然刚刚开始步入正轨&#xff0c;但最新爆料称微软已经在开启下一个计划&#xff0c;Windows 12 的开发将在 去年3 月份开始。德国科技网站 Deskmodder.de 称&#xff0c;根据内部消息&#xff0c;微软将在 2022年3 月开始开发 Wind…...

Studio One6.5中文版本下载安装步骤

在唱歌效果调试当中&#xff0c;我们经常给客户安装的几款音频工作站。第一&#xff0c;Studio One 6是PreSonus公司开发的一款功能强大的音频工作平台&#xff0c;具有丰富的音频处理功能和灵活的工作流程。以下是Studio One6的一些主要特点&#xff1a; 1.多轨录音和编辑&…...

Java架构师缓存架构设计解决方案

目录 1 缓存常见的三大问题1.1 缓存雪崩1.2 缓存穿透1.3 缓存击穿2 缓存key的生成策略3 热点数据集中失效的问题4 如何提高缓存的命中率5 缓存和数据库双写不一致的问题6 如何对缓存数据进行分片想学习架构师构建流程请跳转:Java架构师系统架构设计 1 缓存常见的三大问题 缓…...

【玩转Redhat Linux 8.0系列 | 实验—使用Bash shell执行命令】

今天继续分享一些Redhat Linux 8.0的知识&#xff0c;记得关注&#xff0c;会一直更新~ 访问命令行 任务执行清单 在本实验中&#xff0c;您将使用Bash shell来执行命令。 成果 使用Bash shell命令行成功运行简单的程序。 执行用于识别文件类型并显示文本文件部分内容的命…...

Linux系统编程详解

Linux 多线程编程 什么是线程&#xff1f; 与线程类似&#xff0c;线程是允许应用程序并发执行多个任务的一种机制 线程是轻量级的进程&#xff08;LWP&#xff1a;Light Weight Process&#xff09;&#xff0c;在 Linux 环境下线程的本 质仍是进程。 一个进程可以包含多个线…...

ios设备管理软件iMazing 2.17.11官方中文版新增功能介绍

iMazing 2.17.11官方中文版(ios设备管理软件)是一款管理苹果设备的软件&#xff0c; Windows 平台上的一款帮助用户管理 IOS 手机的应用程序&#xff0c;软件功能非常强大&#xff0c;界面简洁明晰、操作方便快捷&#xff0c;设计得非常人性化。iMazing官方版与苹果设备连接后&…...

算法通关村第18关【青铜】| 回溯

回溯算法是一种解决组合优化问题和搜索问题的算法。它通过尝试各种可能的选择来找到问题的解决方案。回溯算法通常用于问题的解空间非常大&#xff0c;而传统的穷举法会导致计算时间爆炸的情况。回溯算法可以帮助限制搜索空间&#xff0c;以提高效率。 回溯算法的核心思想是在…...

【环境搭建】linux docker-compose安装seata1.6.1,使用nacos注册、db模式

新建目录&#xff0c;挂载用 mkdir -p /data/docker/seata/resources mkdir -p /data/docker/seata/logs 给权限 chmod -R 777 /data/docker/seata 先在/data/docker/seata目录编写一个使用file启动的docker-compose.yml文件&#xff08;seata包目录的script文件夹有&#…...

20231008-20231013 读书笔记

计算机硬件 基本硬件系统&#xff1a;运算器、控制器、存储器、输入设备和输出设备中央处理单元&#xff08;CPU&#xff09;:运算器、控制器、寄存器组和内部总线等部件组成 功能&#xff1a;程序控制、操作控制、时间控制、数据处理运算器&#xff1a;ALU、AC、DR、PSW控制器…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...