Skip to content

Commit 61f0329

Browse files
committed
feat(hosted): Implement OTA for esp-hosted co-processors
1 parent e7df08a commit 61f0329

File tree

6 files changed

+230
-12
lines changed

6 files changed

+230
-12
lines changed

cores/esp32/esp32-hal-hosted.c

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "esp32-hal-hosted.h"
1919
#include "esp32-hal-log.h"
20+
#include "esp32-hal.h"
2021
#include "pins_arduino.h"
2122

2223
#include "esp_hosted.h"
@@ -53,6 +54,9 @@ static esp_hosted_coprocessor_fwver_t host_version_struct = {
5354
.major1 = ESP_HOSTED_VERSION_MAJOR_1, .minor1 = ESP_HOSTED_VERSION_MINOR_1, .patch1 = ESP_HOSTED_VERSION_PATCH_1
5455
};
5556

57+
static bool hostedInit();
58+
static bool hostedDeinit();
59+
5660
void hostedGetHostVersion(uint32_t *major, uint32_t *minor, uint32_t *patch) {
5761
*major = host_version_struct.major1;
5862
*minor = host_version_struct.minor1;
@@ -66,6 +70,11 @@ void hostedGetSlaveVersion(uint32_t *major, uint32_t *minor, uint32_t *patch) {
6670
}
6771

6872
bool hostedHasUpdate() {
73+
if (!hosted_initialized) {
74+
log_e("ESP-Hosted is not initialized");
75+
return false;
76+
}
77+
6978
uint32_t host_version = ESP_HOSTED_VERSION_VAL(host_version_struct.major1, host_version_struct.minor1, host_version_struct.patch1);
7079
uint32_t slave_version = 0;
7180

@@ -106,6 +115,11 @@ char *hostedGetUpdateURL() {
106115
}
107116

108117
bool hostedBeginUpdate() {
118+
if (!hosted_initialized) {
119+
log_e("ESP-Hosted is not initialized");
120+
return false;
121+
}
122+
109123
esp_err_t err = esp_hosted_slave_ota_begin();
110124
if (err != ESP_OK) {
111125
log_e("Failed to begin Update: %s", esp_err_to_name(err));
@@ -114,6 +128,11 @@ bool hostedBeginUpdate() {
114128
}
115129

116130
bool hostedWriteUpdate(uint8_t *buf, uint32_t len) {
131+
if (!hosted_initialized) {
132+
log_e("ESP-Hosted is not initialized");
133+
return false;
134+
}
135+
117136
esp_err_t err = esp_hosted_slave_ota_write(buf, len);
118137
if (err != ESP_OK) {
119138
log_e("Failed to write Update: %s", esp_err_to_name(err));
@@ -122,6 +141,11 @@ bool hostedWriteUpdate(uint8_t *buf, uint32_t len) {
122141
}
123142

124143
bool hostedEndUpdate() {
144+
if (!hosted_initialized) {
145+
log_e("ESP-Hosted is not initialized");
146+
return false;
147+
}
148+
125149
esp_err_t err = esp_hosted_slave_ota_end();
126150
if (err != ESP_OK) {
127151
log_e("Failed to end Update: %s", esp_err_to_name(err));
@@ -130,16 +154,31 @@ bool hostedEndUpdate() {
130154
}
131155

132156
bool hostedActivateUpdate() {
157+
if (!hosted_initialized) {
158+
log_e("ESP-Hosted is not initialized");
159+
return false;
160+
}
161+
162+
// Activate can fail on older firmwares and that is not critical
163+
uint32_t slave_version = ESP_HOSTED_VERSION_VAL(slave_version_struct.major1, slave_version_struct.minor1, slave_version_struct.patch1);
164+
uint32_t min_version = ESP_HOSTED_VERSION_VAL(2, 6, 0);
165+
166+
if (slave_version < min_version) {
167+
// Silence messages caused by earlier versions
168+
esp_log_level_set("rpc_core", ESP_LOG_NONE);
169+
}
170+
133171
esp_err_t err = esp_hosted_slave_ota_activate();
134-
if (err != ESP_OK) {
172+
173+
// Any further communication will result in logged errors
174+
esp_log_level_set("sdmmc_io", ESP_LOG_NONE);
175+
esp_log_level_set("H_SDIO_DRV", ESP_LOG_NONE);
176+
177+
if (err != ESP_OK && slave_version >= min_version) {
135178
log_e("Failed to activate Update: %s", esp_err_to_name(err));
179+
return false;
136180
}
137-
// else {
138-
// hostedDeinit();
139-
// delay(1000);
140-
// hostedInit();
141-
// }
142-
return err == ESP_OK;
181+
return true;
143182
}
144183

145184
static bool hostedInit() {
@@ -158,15 +197,22 @@ static bool hostedInit() {
158197
conf.pin_d2.pin = sdio_pin_config.pin_d2;
159198
conf.pin_d3.pin = sdio_pin_config.pin_d3;
160199
conf.pin_reset.pin = sdio_pin_config.pin_reset;
161-
// esp_hosted_sdio_set_config() will fail on second attempt but here temporarily to not cause exception on reinit
162-
if (esp_hosted_sdio_set_config(&conf) != ESP_OK || esp_hosted_init() != ESP_OK) {
163-
log_e("esp_hosted_init failed!");
200+
esp_err_t err = esp_hosted_sdio_set_config(&conf);
201+
if (err != ESP_OK) { //&& err != ESP_ERR_NOT_ALLOWED) { // uncomment when second init is fixed
202+
log_e("esp_hosted_sdio_set_config failed: %s", esp_err_to_name(err));
203+
return false;
204+
}
205+
err = esp_hosted_init();
206+
if (err != ESP_OK) {
207+
log_e("esp_hosted_init failed: %s", esp_err_to_name(err));
164208
hosted_initialized = false;
165209
return false;
166210
}
167211
log_i("ESP-Hosted initialized!");
168-
if (esp_hosted_connect_to_slave() != ESP_OK) {
169-
log_e("Failed to connect to slave");
212+
err = esp_hosted_connect_to_slave();
213+
if (err != ESP_OK) {
214+
log_e("esp_hosted_connect_to_slave failed: %s", esp_err_to_name(err));
215+
hosted_initialized = false;
170216
return false;
171217
}
172218
hostedHasUpdate();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "WiFi.h"
2+
#include "ESP_HostedOTA.h"
3+
4+
const char *ssid = "your-ssid"; // Change this to your WiFi SSID
5+
const char *password = "your-password"; // Change this to your WiFi password
6+
7+
void setup() {
8+
Serial.begin(115200);
9+
10+
WiFi.STA.begin();
11+
12+
Serial.println();
13+
Serial.println("******************************************************");
14+
Serial.print("Connecting to ");
15+
Serial.println(ssid);
16+
17+
WiFi.STA.connect(ssid, password);
18+
19+
while (WiFi.STA.status() != WL_CONNECTED) {
20+
delay(500);
21+
Serial.print(".");
22+
}
23+
Serial.println();
24+
25+
Serial.println("WiFi connected");
26+
Serial.print("IP address: ");
27+
Serial.println(WiFi.STA.localIP());
28+
29+
if (updateEspHostedSlave()) {
30+
// Currently it's required to restart the host
31+
ESP.restart();
32+
}
33+
}
34+
35+
void loop() {
36+
delay(1000);
37+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#######################################
2+
# Syntax Coloring Map For ESP_HostedOTA
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
#######################################
10+
# Methods and Functions (KEYWORD2)
11+
#######################################
12+
13+
updateEspHostedSlave KEYWORD2
14+
15+
#######################################
16+
# Constants (LITERAL1)
17+
#######################################
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=ESP_HostedOTA
2+
version=3.3.4
3+
author=me-no-dev
4+
maintainer=me-no-dev
5+
sentence=Library for updating the ESP-Hosted co-processor
6+
paragraph=Supports ESP32 Arduino platforms.
7+
category=Communication
8+
url=https://github.com/espressif/arduino-esp32/
9+
architectures=esp32
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include "sdkconfig.h"
2+
#if CONFIG_ESP_WIFI_REMOTE_ENABLED
3+
#include "Arduino.h"
4+
#include "esp32-hal-hosted.h"
5+
#include "Network.h"
6+
#include "HTTPClient.h"
7+
#include "NetworkClientSecure.h"
8+
#endif
9+
10+
bool updateEspHostedSlave() {
11+
#if CONFIG_ESP_WIFI_REMOTE_ENABLED
12+
bool updateSuccess = false;
13+
if (!hostedIsInitialized()) {
14+
Serial.println("ERROR: esp-hosted is not initialized. Did you call WiFi.STA.begin()?");
15+
return updateSuccess;
16+
}
17+
if (!hostedHasUpdate()) {
18+
// esp-hosted is already the latest version
19+
return updateSuccess;
20+
}
21+
if (!Network.isOnline()) {
22+
Serial.println("ERROR: Network is not online! Did you call WiFi.STA.connect(ssid, password)?");
23+
return updateSuccess;
24+
}
25+
Serial.print("Updating esp-hosted co-processor from ");
26+
Serial.println(hostedGetUpdateURL());
27+
NetworkClientSecure *client = new NetworkClientSecure();
28+
if (!client) {
29+
Serial.println("ERROR: Could not allocate client!");
30+
return updateSuccess;
31+
}
32+
client->setInsecure();
33+
HTTPClient https;
34+
int httpCode = 0;
35+
if (!https.begin(*client, hostedGetUpdateURL())) {
36+
Serial.println("ERROR: HTTP begin failed!");
37+
goto finish_ota;
38+
}
39+
httpCode = https.GET();
40+
if (httpCode == HTTP_CODE_OK) {
41+
int len = https.getSize();
42+
if (len < 0) {
43+
Serial.println("ERROR: Update size not received!");
44+
https.end();
45+
goto finish_ota;
46+
}
47+
NetworkClient *stream = https.getStreamPtr();
48+
if (!hostedBeginUpdate()) {
49+
Serial.println("ERROR: esp-hosted update start failed!");
50+
https.end();
51+
goto finish_ota;
52+
}
53+
#define HOSTED_OTA_BUF_SIZE 2048
54+
uint8_t * buff = (uint8_t*)malloc(HOSTED_OTA_BUF_SIZE);
55+
if (!buff) {
56+
Serial.println("ERROR: Could not allocate OTA buffer!");
57+
https.end();
58+
goto finish_ota;
59+
}
60+
while (https.connected() && len > 0) {
61+
size_t size = stream->available();
62+
if (size > 0) {
63+
Serial.print(".");
64+
if (size > HOSTED_OTA_BUF_SIZE) {
65+
size = HOSTED_OTA_BUF_SIZE;
66+
}
67+
if (size > len) {
68+
Serial.printf("\nERROR: Update received extra bytes: %u!", size - len);
69+
break;
70+
}
71+
int readLen = stream->readBytes(buff, size);
72+
len -= readLen;
73+
if (!hostedWriteUpdate(buff, readLen)) {
74+
Serial.println("\nERROR: esp-hosted update write failed!");
75+
break;
76+
}
77+
if (len == 0) {
78+
if (!hostedEndUpdate()) {
79+
Serial.println("\nERROR: esp-hosted update end failed!");
80+
break;
81+
}
82+
if (!hostedActivateUpdate()) {
83+
Serial.println("\nERROR: esp-hosted update activate failed!");
84+
break;
85+
}
86+
updateSuccess = true;
87+
Serial.println("\nSUCCESS: esp-hosted co-processor updated!");
88+
break;
89+
}
90+
}
91+
delay(1);
92+
}
93+
free(buff);
94+
Serial.println();
95+
}
96+
97+
https.end();
98+
finish_ota:
99+
delete client;
100+
return updateSuccess;
101+
#else
102+
return false;
103+
#endif
104+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
#include <stdbool.h>
4+
5+
bool updateEspHostedSlave();

0 commit comments

Comments
 (0)