前言
我使用的IDF版本是V4.4,
OTA需要有一个服务器才行,
这个例程使用的是本地服务器,实现OTA升级
一、先准备一个升级包
这里我使用的是 hello_world
例程作为升级后的程序
什么也不用修改,直接编译工程,然后进入 build
cd .\build\
再执行
python -m http.server 8070
在你的电脑浏览器上输入IP地址+端口(8070)就可以进入网页
进入网页后,这里主要是复制hello_world.bin
的地址
我这里复制到的地址如下所示,这就是新固件的下载地址待会需要用到
http://192.168.0.140:8070/hello_world.bin
1.到此升级包准备工作已经完成
2.那个http服务端需要一直打开,不能关闭
3.你的电脑必须是在2.4G频段的wifi,否则ESP32无法和电脑在同一个局域网内
4.点击hello_world.bin
,看看能不能下载,如果不能下载,可能是电脑的防火墙拦截了,可以关闭防火墙试试。否则你的ESP32也是不能下载到固件的
二、OTA升级
使用的是 simple_ota_example
例程
需要修改5个地方
- 修改为4M的flash
- 修改为2_OTA分区
- WiFi账号
- WIFI密码
- 固件的下载地址
1.打开 simple_ota_example
例程进入 menuconfig
设置
修改完之后,建议打开sdkconfig
看看是否对应,我的WiFi带有中文,会出现乱码
编译烧录即可
三、效果
四、simple_ota_example
源码分析
在源码中esp_https_ota(&config)
已经将所有OTA相关的东西都处理了,如果你想获取更多OTA过程的信息,需要修改esp_https_ota()
函数
esp_err_t ret = esp_https_ota(&config); // HTTPS OTA固件升级
if (ret == ESP_OK)
{
ESP_LOGW(TAG, "固件升级成功");
vTaskDelay(5 * 1000 / portTICK_PERIOD_MS);
esp_restart();
}
else
{
ESP_LOGE(TAG, "固件升级失败");
vTaskDelete(NULL);
}
例如:在OTA的过程中,我读取固件下载的进度,固件信息。。。
1、显示下载进度
复制esp_https_ota
函数,重新命名函数
显示进度主要使用到两个函数即可
esp_https_ota_get_image_size
// 获取固件大小
esp_https_ota_get_image_len_read
// 已经下载
esp_err_t user_esp_https_ota(const esp_http_client_config_t *config)
{
int image_size, download_size;
if (!config)
{
ESP_LOGE(TAG, "esp_http_client config not found");
return ESP_ERR_INVALID_ARG;
}
esp_https_ota_config_t ota_config = {
.http_config = config,
};
esp_https_ota_handle_t https_ota_handle = NULL;
esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle);
if (https_ota_handle == NULL)
{
return ESP_FAIL;
}
image_size = esp_https_ota_get_image_size(https_ota_handle); // 获取固件大小
while (1)
{
err = esp_https_ota_perform(https_ota_handle);
if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS)
{
break;
}
download_size = esp_https_ota_get_image_len_read(https_ota_handle); // 已经下载
ESP_LOGI(TAG, "Image bytes read: %d/%d--- %0.2f%%",
download_size,
image_size,
(float)download_size * 100 / image_size);// 下载进度(百分比)
}
if (err != ESP_OK)
{
esp_https_ota_abort(https_ota_handle);
return err;
}
esp_err_t ota_finish_err = esp_https_ota_finish(https_ota_handle);
if (ota_finish_err != ESP_OK)
{
return ota_finish_err;
}
return ESP_OK;
}
注意:esp_https_ota这个函数不要直接拷贝我上面的代码,IDF4.4 / 5.3不同的版本,esp_https_ota函数有些许差异,直接拷贝编译会报错
拓展
我提供了一个Python脚本
将.bin文件和start_server.py放在同一个目录下,运行start_server.py脚本
就可以直接创建本地服务器了
start_server.py
import os
import subprocess
def start_http_server():
try:
# 获取脚本所在的目录
script_directory = os.path.dirname(os.path.abspath(__file__))
print(f"Starting HTTP server on port 8070 in directory: {script_directory}")
subprocess.run(["python", "-m", "http.server", "8070"], cwd=script_directory)
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == "__main__":
start_http_server()