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
0 commit comments