Skip to content

Commit 08067d5

Browse files
implemented esp32 ota class
1 parent 10c0345 commit 08067d5

File tree

2 files changed

+146
-9
lines changed

2 files changed

+146
-9
lines changed

src/ota/implementation/OTAEsp32.cpp

+114
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,117 @@
1+
/*
2+
This file is part of the ArduinoIoTCloud library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
11+
#include "AIoTC_Config.h"
112
#if defined(ARDUINO_ARCH_ESP32) && OTA_ENABLED
13+
#include "OTAEsp32.h"
14+
#include <esp_ota_ops.h>
15+
#include <Update.h>
16+
17+
ESP32OTACloudProcess::ESP32OTACloudProcess(MessageStream *ms, Client* client)
18+
: OTADefaultCloudProcessInterface(ms), rom_partition(nullptr) {
19+
20+
}
21+
22+
23+
OTACloudProcessInterface::State ESP32OTACloudProcess::resume(Message* msg) {
24+
return OtaBegin;
25+
}
26+
27+
OTACloudProcessInterface::State ESP32OTACloudProcess::startOTA() {
28+
if(Update.isRunning()) {
29+
Update.abort();
30+
DEBUG_VERBOSE("%s: Aborting running update", __FUNCTION__);
31+
}
32+
33+
if(!Update.begin(UPDATE_SIZE_UNKNOWN)) {
34+
DEBUG_VERBOSE("%s: failed to initialize flash update", __FUNCTION__);
35+
return OtaStorageInitFail;
36+
}
37+
38+
return OTADefaultCloudProcessInterface::startOTA();
39+
}
40+
41+
OTACloudProcessInterface::State ESP32OTACloudProcess::flashOTA() {
42+
43+
if (!Update.end(true)) {
44+
DEBUG_VERBOSE("%s: Failure to apply OTA update", __FUNCTION__);
45+
return OtaStorageEndFail;
46+
}
47+
48+
return Reboot;
49+
}
50+
51+
OTACloudProcessInterface::State ESP32OTACloudProcess::reboot() {
52+
ESP.restart();
53+
54+
return Idle; // we won't reach this
55+
}
56+
57+
int ESP32OTACloudProcess::writeFlash(uint8_t* const buffer, size_t len) {
58+
return Update.write(buffer, len);
59+
}
60+
61+
bool ESP32OTACloudProcess::isOtaCapable() {
62+
const esp_partition_t * ota_0 = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
63+
const esp_partition_t * ota_1 = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
64+
return ((ota_0 != nullptr) && (ota_1 != nullptr));
65+
}
66+
67+
void* ESP32OTACloudProcess::appStartAddress() {
68+
return nullptr;
69+
}
70+
uint32_t ESP32OTACloudProcess::appSize() {
71+
return ESP.getSketchSize();
72+
}
73+
74+
bool ESP32OTACloudProcess::appFlashOpen() {
75+
rom_partition = esp_ota_get_running_partition();
76+
77+
if(rom_partition == nullptr) {
78+
return false;
79+
}
80+
81+
return true;
82+
}
83+
84+
void ESP32OTACloudProcess::calculateSHA256(SHA256& sha256_calc) {
85+
if(!appFlashOpen()) {
86+
return; // TODO error reporting
87+
}
88+
89+
sha256_calc.begin();
90+
91+
uint8_t b[SPI_FLASH_SEC_SIZE];
92+
if(b == nullptr) {
93+
DEBUG_VERBOSE("ESP32::SHA256 Not enough memory to allocate buffer");
94+
return; // TODO error reporting
95+
}
96+
97+
uint32_t read_bytes = 0;
98+
uint32_t const app_size = ESP.getSketchSize();
99+
for(uint32_t a = rom_partition->address; read_bytes < app_size; ) {
100+
/* Check if we are reading last sector and compute used size */
101+
uint32_t const read_size = read_bytes + SPI_FLASH_SEC_SIZE < app_size ?
102+
SPI_FLASH_SEC_SIZE : app_size - read_bytes;
103+
104+
/* Use always 4 bytes aligned reads */
105+
if (!ESP.flashRead(a, reinterpret_cast<uint32_t*>(b), (read_size + 3) & ~3)) {
106+
DEBUG_VERBOSE("ESP32::SHA256 Could not read data from flash");
107+
return;
108+
}
109+
sha256_calc.update(b, read_size);
110+
a += read_size;
111+
read_bytes += read_size;
112+
}
113+
114+
appFlashClose();
115+
}
2116

3117
#endif // defined(ARDUINO_ARCH_ESP32) && OTA_ENABLED

src/ota/implementation/OTAEsp32.h

+32-9
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,43 @@
1+
/*
2+
This file is part of the ArduinoIoTCloud library.
3+
4+
Copyright (c) 2024 Arduino SA
5+
6+
This Source Code Form is subject to the terms of the Mozilla Public
7+
License, v. 2.0. If a copy of the MPL was not distributed with this
8+
file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
111
#pragma once
212

3-
#include "src/ota/interface/OTAInterface.h"
13+
#include "ota/interface/OTAInterfaceDefault.h"
414

5-
class ESP32OTACloudProcess: public OTACloudProcessInterface {
15+
class ESP32OTACloudProcess: public OTADefaultCloudProcessInterface {
616
public:
7-
STM32H7OTACloudProcess();
17+
ESP32OTACloudProcess(MessageStream *ms, Client* client=nullptr);
18+
19+
virtual bool isOtaCapable() override;
820
protected:
9-
// we start the download and decompress process
10-
virtual State fetch(Message* msg=nullptr);
21+
virtual OTACloudProcessInterface::State resume(Message* msg=nullptr) override;
1122

12-
// when the download is completed we verify for integrity and correctness of the downloaded binary
13-
// virtual State verifyOTA(Message* msg=nullptr); // TODO this may be performed inside download
23+
// we are overriding the method of startOTA in order to download ota file on ESP32
24+
virtual OTACloudProcessInterface::State startOTA() override;
1425

1526
// whene the download is correctly finished we set the mcu to use the newly downloaded binary
16-
virtual State flashOTA(Message* msg=nullptr);
27+
virtual State flashOTA() override;
1728

1829
// we reboot the device
19-
virtual State reboot(Message* msg=nullptr);
30+
virtual State reboot() override;
31+
32+
// write the decompressed char buffer of the incoming ota
33+
virtual int writeFlash(uint8_t* const buffer, size_t len) override;
34+
35+
void* appStartAddress();
36+
uint32_t appSize();
37+
bool appFlashOpen();
38+
bool appFlashClose() { return true; };
39+
40+
void calculateSHA256(SHA256&) override;
41+
private:
42+
const esp_partition_t *rom_partition;
2043
};

0 commit comments

Comments
 (0)