Skip to content

Commit 1623741

Browse files
implemented rp2040 ota class
1 parent 724bd7b commit 1623741

File tree

2 files changed

+166
-9
lines changed

2 files changed

+166
-9
lines changed
+129
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,133 @@
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>
12+
113
#if defined(ARDUINO_NANO_RP2040_CONNECT) && OTA_ENABLED
14+
#include <SFU.h>
215
#include "OTANanoRP2040.h"
16+
#include <Arduino_DebugUtils.h>
17+
#include "mbed.h"
18+
#include "utility/watchdog/Watchdog.h"
19+
20+
#define SD_MOUNT_PATH "ota"
21+
#define FULL_UPDATE_FILE_PATH "/ota/UPDATE.BIN"
22+
23+
const char NANO_RP2040OTACloudProcess::UPDATE_FILE_NAME[] = FULL_UPDATE_FILE_PATH;
24+
25+
26+
NANO_RP2040OTACloudProcess::NANO_RP2040OTACloudProcess(MessageStream *ms, Client* client)
27+
: OTADefaultCloudProcessInterface(ms, client)
28+
, flash((uint32_t)appStartAddress() + 0xF00000, 0x100000) // TODO make this numbers a constant
29+
, decompressed(nullptr)
30+
, fs(nullptr) {
31+
}
32+
33+
NANO_RP2040OTACloudProcess::~NANO_RP2040OTACloudProcess() {
34+
close_fs();
35+
}
36+
37+
OTACloudProcessInterface::State NANO_RP2040OTACloudProcess::resume(Message* msg) {
38+
return OtaBegin;
39+
}
40+
41+
int NANO_RP2040OTACloudProcess::writeFlash(uint8_t* const buffer, size_t len) {
42+
if(decompressed == nullptr) {
43+
DEBUG_VERBOSE("writing on a file that is not open"); // FIXME change log message
44+
return 0;
45+
}
46+
return fwrite(buffer, sizeof(uint8_t), len, decompressed);
47+
}
48+
49+
OTACloudProcessInterface::State NANO_RP2040OTACloudProcess::startOTA() {
50+
int err = -1;
51+
if ((err = flash.init()) < 0) {
52+
DEBUG_VERBOSE("%s: flash.init() failed with %d", __FUNCTION__, err);
53+
return OtaStorageInitFail;
54+
}
55+
56+
flash.erase((uint32_t)appStartAddress() + 0xF00000, 0x100000);
57+
58+
fs = new mbed::FATFileSystem(SD_MOUNT_PATH); // FIXME can this be allocated in the stack?
59+
if ((err = fs->reformat(&flash)) != 0) {
60+
DEBUG_VERBOSE("%s: fs.reformat() failed with %d", __FUNCTION__, err);
61+
return ErrorReformatFail;
62+
}
63+
64+
decompressed = fopen(UPDATE_FILE_NAME, "wb"); // TODO make this a constant
65+
if (!decompressed) {
66+
DEBUG_VERBOSE("%s: fopen() failed", __FUNCTION__);
67+
fclose(decompressed);
68+
return ErrorOpenUpdateFileFail;
69+
}
70+
71+
// we start the download here
72+
return OTADefaultCloudProcessInterface::startOTA();;
73+
}
74+
75+
76+
OTACloudProcessInterface::State NANO_RP2040OTACloudProcess::flashOTA() {
77+
int err = 0;
78+
if((err = close_fs()) != 0) {
79+
return ErrorUnmountFail;
80+
}
81+
82+
return Reboot;
83+
}
84+
85+
OTACloudProcessInterface::State NANO_RP2040OTACloudProcess::reboot() {
86+
mbed_watchdog_trigger_reset();
87+
/* If watchdog is enabled we should not reach this point */
88+
NVIC_SystemReset();
89+
90+
return Resume; // This won't ever be reached
91+
}
92+
93+
void NANO_RP2040OTACloudProcess::reset() {
94+
OTADefaultCloudProcessInterface::reset();
95+
96+
close_fs();
97+
}
98+
99+
int NANO_RP2040OTACloudProcess::close_fs() {
100+
int err = 0;
101+
102+
if(decompressed != nullptr) {
103+
fclose(decompressed);
104+
decompressed = nullptr;
105+
}
106+
107+
if (fs != nullptr && (err = fs->unmount()) != 0) {
108+
DEBUG_VERBOSE("%s: fs.unmount() failed with %d", __FUNCTION__, err);
109+
} else {
110+
delete fs;
111+
fs = nullptr;
112+
}
113+
114+
return err;
115+
}
116+
117+
bool NANO_RP2040OTACloudProcess::isOtaCapable() {
118+
return true;
119+
}
120+
121+
// extern void* __stext;
122+
extern uint32_t __flash_binary_end;
123+
124+
125+
void* NANO_RP2040OTACloudProcess::appStartAddress() {
126+
// return &__flash_binary_start;
127+
return (void*)XIP_BASE;
128+
}
129+
uint32_t NANO_RP2040OTACloudProcess::appSize() {
130+
return (&__flash_binary_end - (uint32_t*)appStartAddress())*sizeof(void*);
131+
}
3132

4133
#endif // defined(ARDUINO_NANO_RP2040_CONNECT) && OTA_ENABLED
+37-9
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,51 @@
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

515
#include "FATFileSystem.h"
616
#include "FlashIAPBlockDevice.h"
717

8-
class NANO_RP2040OTACloudProcess: public OTACloudProcessInterface {
18+
class NANO_RP2040OTACloudProcess: public OTADefaultCloudProcessInterface {
919
public:
10-
STM32H7OTACloudProcess();
20+
NANO_RP2040OTACloudProcess(MessageStream *ms, Client* client=nullptr);
21+
~NANO_RP2040OTACloudProcess();
22+
23+
virtual bool isOtaCapable() override;
1124
protected:
12-
// we start the download and decompress process
13-
virtual State fetch(Message* msg=nullptr);
25+
virtual OTACloudProcessInterface::State resume(Message* msg=nullptr) override;
1426

15-
// when the download is completed we verify for integrity and correctness of the downloaded binary
16-
// virtual State verifyOTA(Message* msg=nullptr); // TODO this may be performed inside download
27+
virtual OTACloudProcessInterface::State startOTA() override;
1728

1829
// whene the download is correctly finished we set the mcu to use the newly downloaded binary
19-
virtual State flashOTA(Message* msg=nullptr);
30+
virtual OTACloudProcessInterface::State flashOTA() override;
2031

2132
// we reboot the device
22-
virtual State reboot(Message* msg=nullptr);
33+
virtual OTACloudProcessInterface::State reboot() override;
34+
35+
// write the decompressed char buffer of the incoming ota
36+
virtual int writeFlash(uint8_t* const buffer, size_t len) override;
37+
38+
virtual void reset() override;
39+
40+
void* appStartAddress();
41+
uint32_t appSize();
42+
bool appFlashOpen() { return true; };
43+
bool appFlashClose() { return true; };
44+
private:
45+
FlashIAPBlockDevice flash;
46+
FILE* decompressed;
47+
mbed::FATFileSystem* fs;
48+
static const char UPDATE_FILE_NAME[];
49+
50+
int close_fs();
2351
};

0 commit comments

Comments
 (0)