Skip to content

Commit d09c6dc

Browse files
authored
Merge pull request #256 from arduino-libraries/rp2040_ota
INITIAL: support OTA on Nano RP2040 Connect
2 parents 516ad1b + a212ef8 commit d09c6dc

File tree

8 files changed

+337
-15
lines changed

8 files changed

+337
-15
lines changed

extras/tools/bin2ota.py

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
magic_number = 0x23418057.to_bytes(4,byteorder='little')
2525
elif board == "PORTENTA_H7_M7":
2626
magic_number = 0x2341025B.to_bytes(4,byteorder='little')
27+
elif board == "NANO_RP2040_CONNECT":
28+
magic_number = 0x2341005E.to_bytes(4,byteorder='little')
2729
else:
2830
print ("Error,", board, "is not a supported board type")
2931
sys.exit()

src/AIoTC_Config.h

+9-4
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
* USER CONFIGURABLE DEFINES
2323
******************************************************************************/
2424

25-
#ifndef OTA_STORAGE_SFU
26-
#define OTA_STORAGE_SFU (0)
27-
#endif
28-
2925
#ifndef NTP_USE_RANDOM_PORT
3026
#define NTP_USE_RANDOM_PORT (1)
3127
#endif
@@ -94,6 +90,12 @@
9490
#define OTA_STORAGE_SNU (0)
9591
#endif
9692

93+
#if defined(ARDUINO_NANO_RP2040_CONNECT)
94+
#define OTA_STORAGE_SFU (1)
95+
#else
96+
#define OTA_STORAGE_SFU (0)
97+
#endif
98+
9799
#ifdef ARDUINO_SAMD_MKRGSM1400
98100
#define OTA_STORAGE_SSU (1)
99101
#else
@@ -143,4 +145,7 @@
143145
#define AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms (30000UL)
144146
#define AIOT_CONFIG_LASTVALUES_SYNC_MAX_RETRY_CNT (10UL)
145147

148+
#define AIOT_CONFIG_RP2040_OTA_HTTP_HEADER_RECEIVE_TIMEOUT_ms (10*1000UL)
149+
#define AIOT_CONFIG_RP2040_OTA_HTTP_DATA_RECEIVE_TIMEOUT_ms (4*60*1000UL)
150+
146151
#endif /* ARDUINO_AIOTC_CONFIG_H_ */

src/ArduinoIoTCloudTCP.cpp

+28-2
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,13 @@ 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+
/* The maximum size of a RP2040 OTA update image is 1 MByte (that is 1024 *
177+
* 1024 bytes or 0x100'000 bytes).
178+
*/
179+
String const sha256_str = FlashSHA256::calc(XIP_BASE, 0x100000);
180+
#else
181+
# error "No method for SHA256 checksum calculation over application image defined for this architecture."
175182
#endif
176183
DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(sha256_str.c_str()), sha256_str.c_str());
177184
_ota_img_sha256 = sha256_str;
@@ -259,6 +266,10 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
259266
}
260267
#endif /* OTA_STORAGE_SNU */
261268

269+
#if defined(ARDUINO_NANO_RP2040_CONNECT)
270+
_ota_cap = true;
271+
#endif
272+
262273
#ifdef BOARD_HAS_OFFLOADED_ECCX08
263274
if (String(WiFi.firmwareVersion()) < String("1.4.4")) {
264275
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());
@@ -309,6 +320,16 @@ void ArduinoIoTCloudTCP::update()
309320
}
310321
_state = next_state;
311322

323+
/* This watchdog feed is actually needed only by the RP2040 CONNECT cause its
324+
* maximum watchdog window is 8388ms; despite this we feed it for all
325+
* supported ARCH to keep code aligned.
326+
*/
327+
#ifdef ARDUINO_ARCH_SAMD
328+
samd_watchdog_reset();
329+
#elif defined(ARDUINO_ARCH_MBED)
330+
mbed_watchdog_reset();
331+
#endif
332+
312333
/* Check for new data from the MQTT client. */
313334
if (_mqttClient.connected())
314335
_mqttClient.poll();
@@ -491,6 +512,7 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
491512
/* Request a OTA download if the hidden property
492513
* OTA request has been set.
493514
*/
515+
494516
if (_ota_req)
495517
{
496518
/* Clear the error flag. */
@@ -581,12 +603,16 @@ int ArduinoIoTCloudTCP::write(String const topic, byte const data[], int const l
581603
#if OTA_ENABLED
582604
void ArduinoIoTCloudTCP::onOTARequest()
583605
{
584-
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s _ota_url = %s", __FUNCTION__, _ota_url.c_str());
606+
DEBUG_INFO("ArduinoIoTCloudTCP::%s _ota_url = %s", __FUNCTION__, _ota_url.c_str());
585607

586608
#ifdef ARDUINO_ARCH_SAMD
587609
_ota_error = samd_onOTARequest(_ota_url.c_str());
588610
#endif
589611

612+
#ifdef ARDUINO_NANO_RP2040_CONNECT
613+
_ota_error = rp2040_connect_onOTARequest(_ota_url.c_str());
614+
#endif
615+
590616
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
591617
_ota_error = portenta_h7_onOTARequest(_ota_url.c_str());
592618
#endif

src/utility/ota/FlashSHA256.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ String FlashSHA256::calc(uint32_t const start_addr, uint32_t const max_flash_siz
4545
sha256.begin();
4646

4747
/* Read the first two chunks of flash. */
48-
uint32_t flash_addr = start_addr;
48+
uint32_t flash_addr = start_addr;
49+
uint32_t bytes_read = 0;
4950
memcpy(chunk, reinterpret_cast<const void *>(flash_addr), FLASH_READ_CHUNK_SIZE);
5051
flash_addr += FLASH_READ_CHUNK_SIZE;
5152

52-
for(; flash_addr < max_flash_size; flash_addr += FLASH_READ_CHUNK_SIZE)
53+
for(; bytes_read < max_flash_size; flash_addr += FLASH_READ_CHUNK_SIZE)
5354
{
5455
/* Read the next chunk of memory. */
5556
memcpy(next_chunk, reinterpret_cast<const void *>(flash_addr), FLASH_READ_CHUNK_SIZE);
@@ -75,13 +76,15 @@ String FlashSHA256::calc(uint32_t const start_addr, uint32_t const max_flash_siz
7576
}
7677
/* Update with the remaining bytes. */
7778
sha256.update(chunk, valid_bytes_in_chunk);
79+
bytes_read += valid_bytes_in_chunk;
7880
break;
7981
}
8082

8183
/* We've read a normal segment with the next segment not containing
8284
* any erased elements, just update the SHA256 hash calcultion.
8385
*/
8486
sha256.update(chunk, FLASH_READ_CHUNK_SIZE);
87+
bytes_read += FLASH_READ_CHUNK_SIZE;
8588

8689
/* Copy next_chunk to chunk. */
8790
memcpy(chunk, next_chunk, FLASH_READ_CHUNK_SIZE);
@@ -100,7 +103,7 @@ String FlashSHA256::calc(uint32_t const start_addr, uint32_t const max_flash_siz
100103
sha256_str += buf;
101104
});
102105
/* Do some debug printout. */
103-
DEBUG_VERBOSE("SHA256: %d bytes read", flash_addr);
106+
DEBUG_VERBOSE("SHA256: %d bytes read", bytes_read);
104107
return sha256_str;
105108
}
106109

0 commit comments

Comments
 (0)