提问人:Darren Morrison 提问时间:8/10/2023 最后编辑:mpromonetDarren Morrison 更新时间:11/19/2023 访问量:259
如何对 ESP32s3 Wifi Mesh 节点/子节点进行 OTA 更新?
How to OTA update ESP32s3 Wifi Mesh nodes/children?
问:
ESP-IDF v5.1+。固定网关(root)。
我找不到有关仅使用 ESP-IDF 的 OTA 更新 WIFI MESH 节点的示例或文档。我无意使用 ESP-MDF 或 MESH-LITE,因为它们已经过时,并且对较新版本的 IDF 的支持很差。
我的网关能够使用和功能。是否有解决方案可以让节点使用相同的包装器并通过网关转发 GET 请求和响应?esp_https_ota()
esp_http_client_perform()
网关和节点的固件版本不同,因此我无法直接从网关的APP分区读取固件。 .bin 文件托管在 EC2 服务器上,在使用 HTTPS 包装器更新根时按预期工作。
答:
要使用 ESP32-S3 节点在 Wifi Mesh 网络上执行 OTA 更新,请按照以下步骤操作。该方法利用网关上的自定义 OTA 代理转发请求,并在节点上使用 ESP-IDF OTA 包装器来更新固件。
步骤 1:在网关上创建自定义 OTA 代理
在网关上将 OTA 代理实现为 HTTP 服务器。此服务器侦听 OTA 请求并将其转发到节点。然后,代理将节点的响应中继回客户端。
下面是网关 OTA 代理的代码:
#include <esp_http_server.h>
static httpd_handle_t server = NULL;
// OTA Handler which receives update requests and forwards to the node
static esp_err_t ota_handler(httpd_req_t *req) {
// Extract node IP from the request headers
char *node_ip = httpd_req_get_hdr_value_str(req, "X-Node-IP");
if (node_ip == NULL) {
// Respond with an error if the header is missing
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Node IP header is missing");
return ESP_FAIL;
}
// Configure the HTTP client to forward the request
esp_http_client_config_t client_cfg = {
.url = node_ip, // URL is the node's IP address obtained from header
.port = req->uri_port // Use the same port as the server
};
esp_http_client_handle_t client = esp_http_client_init(&client_cfg);
// Forward the request to the node and fetch the response
esp_err_t err = esp_http_client_perform(client);
if (err != ESP_OK) {
// Handle errors in forwarding
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Forwarding failed");
esp_http_client_cleanup(client);
return err;
}
// Allocate buffer for the response
char *buffer = malloc(MAX_HTTP_OUTPUT_BUFFER);
int content_len = esp_http_client_fetch_headers(client);
esp_http_client_read(client, buffer, content_len);
// Send the response back to the original requester
httpd_resp_send(req, buffer, content_len);
// Clean up and free allocated resources
free(buffer);
esp_http_client_cleanup(client);
return ESP_OK;
}
// Function to start the OTA agent server
void start_ota_agent() {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
// Start the server
if (httpd_start(&server, &config) == ESP_OK) {
// Register OTA handler
httpd_uri_t ota_uri = {
.uri = "/ota",
.method = HTTP_GET,
.handler = ota_handler
};
httpd_register_uri_handler(server, &ota_uri);
} else {
ESP_LOGE("OTA", "Server start failed");
}
}
调用以开始侦听网关上的 OTA 请求。start_ota_agent()
第 2 步:更新节点上的固件
节点使用 OTA 包装器从网关代理请求更新。
节点固件更新代码:
#include <esp_https_ota.h>
void update_firmware() {
// HTTPS client configuration for the OTA update
esp_http_client_config_t ota_client_cfg = {
.url = "http://gateway_ip/ota", // URL to the gateway OTA agent
.cert_pem = gateway_server_cert_pem_start // SSL certificate for the server
};
// Perform the OTA update
if (esp_https_ota(&ota_client_cfg) != ESP_OK) {
ESP_LOGE("OTA Update", "Firmware update failed");
return;
}
// Reboot after successful update
esp_restart();
}
确保替换为网关的实际 IP 地址,并在需要时提供正确的 SSL 证书。gateway_ip
总结
网关 OTA 代理:
网关作为 HTTP 服务器,用于接收来自节点的 OTA 请求。
OTA 处理程序函数从请求标头中提取节点 IP 地址。
它将请求转发到相应节点的 IP 地址和端口。
它接收节点的响应并将其发送回原始请求者。
节点固件更新:
节点使用 ESP-IDF OTA 封装器发起 OTA 更新。
节点固件更新代码为 OTA 配置 HTTPS 客户端 请求。
它指定网关 OTA 代理和 SSL 证书的 URL 如有必要。
它使用 esp_https_ota() 触发 OTA 更新过程。
成功更新后,它会重新启动设备以应用新的 固件。
评论