Skip to content

Commit 3f46665

Browse files
committed
Initial draft for OTA via RP2040.
1 parent d585618 commit 3f46665

File tree

5 files changed

+178
-3
lines changed

5 files changed

+178
-3
lines changed

src/AIoTC_Config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
#define OTA_STORAGE_PORTENTA_QSPI (0)
107107
#endif
108108

109-
#if (OTA_STORAGE_SFU || OTA_STORAGE_SSU || OTA_STORAGE_SNU || OTA_STORAGE_PORTENTA_QSPI) && !defined(ARDUINO_AVR_UNO_WIFI_REV2)
109+
#if (OTA_STORAGE_SFU || OTA_STORAGE_SSU || OTA_STORAGE_SNU || OTA_STORAGE_PORTENTA_QSPI || ARDUINO_NANO_RP2040_CONNECT) && !defined(ARDUINO_AVR_UNO_WIFI_REV2)
110110
#define OTA_ENABLED (1)
111111
#else
112112
#define OTA_ENABLED (0)

src/ArduinoIoTCloudTCP.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
160160
sha256_str += buf;
161161
});
162162
DEBUG_VERBOSE("SHA256: %d bytes (of %d) read", bytes_read, app_size);
163-
#else
163+
#elif defined(ARDUINO_ARCH_SAMD)
164164
/* Calculate the SHA256 checksum over the firmware stored in the flash of the
165165
* MCU. Note: As we don't know the length per-se we read chunks of the flash
166166
* until we detect one containing only 0xFF (= flash erased). This only works
@@ -172,6 +172,10 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
172172
* range 0 to 0x2000, total flash size of 0x40000 bytes (256 kByte).
173173
*/
174174
String const sha256_str = FlashSHA256::calc(0x2000, 0x40000 - 0x2000);
175+
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
176+
String const sha256_str = "TODO"; /* TODO !!! */
177+
#else
178+
# error "You need to implement the SHA256 checksum calculation for this architecture"
175179
#endif
176180
DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(sha256_str.c_str()), sha256_str.c_str());
177181
_ota_img_sha256 = sha256_str;
@@ -259,6 +263,10 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
259263
}
260264
#endif /* OTA_STORAGE_SNU */
261265

266+
#ifdef ARDUINO_NANO_RP2040_CONNECT
267+
_ota_cap = true;
268+
#endif /* ARDUINO_NANO_RP2040_CONNECT */
269+
262270
#ifdef BOARD_HAS_OFFLOADED_ECCX08
263271
if (String(WiFi.firmwareVersion()) < String("1.4.4")) {
264272
DEBUG_ERROR("ArduinoIoTCloudTCP::%s In order to connect to Arduino IoT Cloud, NINA firmware needs to be >= 1.4.4, current %s", __FUNCTION__, WiFi.firmwareVersion());
@@ -590,6 +598,10 @@ void ArduinoIoTCloudTCP::onOTARequest()
590598
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
591599
_ota_error = portenta_h7_onOTARequest(_ota_url.c_str());
592600
#endif
601+
602+
#if defined(ARDUINO_NANO_RP2040_CONNECT)
603+
_ota_error = nano_rp2040_connect_onOTARequest(_ota_url.c_str());
604+
#endif
593605
}
594606
#endif
595607

src/ArduinoIoTCloudTCP.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,4 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
161161

162162
extern ArduinoIoTCloudTCP ArduinoCloud;
163163

164-
#endif
164+
#endif
+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
This file is part of ArduinoIoTCloud.
3+
4+
Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
5+
6+
This software is released under the GNU General Public License version 3,
7+
which covers the main part of arduino-cli.
8+
The terms of this license can be found at:
9+
https://www.gnu.org/licenses/gpl-3.0.en.html
10+
11+
You can be released from the requirements of the above licenses by purchasing
12+
a commercial license. Buying such a license is mandatory if you want to modify or
13+
otherwise use the software for commercial activities involving the Arduino
14+
software without disclosing the source code of your own applications. To purchase
15+
a commercial license, send an email to [email protected].
16+
*/
17+
18+
#ifdef ARDUINO_NANO_RP2040_CONNECT
19+
20+
/******************************************************************************
21+
* INCLUDE
22+
******************************************************************************/
23+
24+
#include "OTA.h"
25+
26+
#include <Arduino_DebugUtils.h>
27+
28+
/* This library resides within the Nano RP2040 Connect Arduino Core
29+
* and provides a 2nd stage bootloader which upon booting checks
30+
* for the existence of a firmware update image and then performs
31+
* a firmware update.
32+
*/
33+
#include <SFU.h>
34+
35+
/* The Arduino Nano RP2040 Connect has a NINA-W102 WiFi module
36+
* mounted for connectivity. Therefore its library needs to be
37+
* included here in order to access the WiFi module for downloading
38+
* the firmware update image.
39+
*/
40+
#include <WiFiNINA.h>
41+
42+
#include "../watchdog/Watchdog.h"
43+
44+
45+
#include "mbed.h"
46+
#include "FlashIAPBlockDevice.h"
47+
#include "FATFileSystem.h"
48+
49+
/******************************************************************************
50+
* FUNCTION DEFINITION
51+
******************************************************************************/
52+
53+
int nano_rp2040_connect_onOTARequest(char const * ota_url)
54+
{
55+
int err = 0;
56+
57+
mbed_watchdog_reset();
58+
59+
/* As a first step prepare everything for the pending
60+
* firmware image download. Initialize the flash,
61+
* mount a filesystem and clean-up any left-overs from
62+
* previous (and possibly failed) update attempts.
63+
*/
64+
65+
FlashIAPBlockDevice sd(XIP_BASE + 0x100000, 0x100000);
66+
if ((err = sd.init()) < 0)
67+
{
68+
DEBUG_ERROR("%s: sd.init() failed with %d", __FUNCTION__, err);
69+
return err;
70+
}
71+
72+
mbed_watchdog_reset();
73+
74+
mbed::FATFileSystem fs("ota");
75+
if ((err = fs.mount(&sd)) != 0)
76+
{
77+
DEBUG_ERROR("%s: fs.mount() failed with %d", __FUNCTION__, err);
78+
return err;
79+
}
80+
81+
mbed_watchdog_reset();
82+
83+
remove("/ota/UPDATE.BIN");
84+
remove("/ota/UPDATE.BIN.LZSS");
85+
remove("/ota/UPDATE.BIN.LZSS.TMP");
86+
87+
mbed_watchdog_reset();
88+
89+
FILE * file = fopen("/ota/UPDATE.BIN.LZSS.TMP", "wb");
90+
if (!file)
91+
{
92+
DEBUG_ERROR("%s: fopen() failed", __FUNCTION__);
93+
fclose(file);
94+
return errno;
95+
}
96+
97+
/* Now its time to actually download the firmware
98+
* image from the server and store it on the filesystem.
99+
*/
100+
//WiFiSSLClient client;
101+
WiFiClient client;
102+
103+
// if (!client.connect("api2.arduino.cc", 443))
104+
if (!client.connect("107-systems.org", 80))
105+
{
106+
DEBUG_ERROR("%s: Connection failure with OTA storage server", __FUNCTION__, err);
107+
return -1; /* TODO: Implement better error codes. */
108+
}
109+
110+
mbed_watchdog_reset();
111+
112+
/*
113+
client.println("GET iot/ota/8ea3d719-0df0-4a7f-b469-896d61fe42db HTTP/1.1");
114+
client.println("Host: api2.arduino.cc");
115+
client.println("Connection: close");
116+
client.println();
117+
*/
118+
119+
client.println("GET ota/rp2040-led-red.bin HTTP/1.1");
120+
client.println("Host: 107-systems.org");
121+
client.println("Connection: close");
122+
client.println();
123+
124+
String http_header;
125+
bool is_header_complete = false;
126+
127+
while (client.available())
128+
{
129+
mbed_watchdog_reset();
130+
131+
char const c = client.read();
132+
133+
if(!is_header_complete)
134+
{
135+
http_header += c;
136+
if (http_header.endsWith("\r\n\r\n"))
137+
is_header_complete = true;
138+
}
139+
else
140+
{
141+
if (fwrite(&c, 1, sizeof(c), file) != sizeof(c))
142+
{
143+
DEBUG_ERROR("%s: Writing of firmware image to flash failed", __FUNCTION__);
144+
return -2; /* TODO: Find better error codes. */
145+
}
146+
}
147+
}
148+
149+
int const file_len = ftell(file);
150+
DEBUG_DEBUG("%s: %d bytes received", __FUNCTION__, file_len);
151+
152+
fclose(file);
153+
154+
/* TODO: Check CRC and header data and decompress. */
155+
156+
return 0;
157+
}
158+
159+
#endif /* ARDUINO_NANO_RP2040_CONNECT */

src/utility/ota/OTA.h

+4
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,8 @@ int samd_onOTARequest(char const * ota_url);
5454
int portenta_h7_onOTARequest(char const * ota_url);
5555
#endif
5656

57+
#if defined(ARDUINO_NANO_RP2040_CONNECT)
58+
int nano_rp2040_connect_onOTARequest(char const * ota_url);
59+
#endif
60+
5761
#endif /* ARDUINO_OTA_LOGIC_H_ */

0 commit comments

Comments
 (0)