Skip to content

INITIAL: support OTA on Nano RP2040 Connect #256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
90f3bed
INITIAL: support OTA on Nano RP2040 COnnect
facchinm May 20, 2021
b27e30b
TEMP: add proper download via WiFi/WiFiSSL client
facchinm May 25, 2021
cc1aeba
tools/bin2ota: add nano rp2040 asupport
facchinm May 26, 2021
26d989f
Add comments and TODO
facchinm May 27, 2021
6359f8a
squashme: don't automatically trigger an OTA
facchinm May 27, 2021
08142e7
Revert initialisation of _ota_url to empty string.
aentinger May 31, 2021
171ac6d
Cleaning up SHA256 calculation logic for better maintainability.
aentinger May 31, 2021
48e3405
Signal unconditionally that the RP2040 supports OTA to the cloud.
aentinger May 31, 2021
e14a781
Fix parameters for flash checksum calculation (used parameters were f…
aentinger May 31, 2021
1c783f5
Bugfix: Ensure that the watchdog timer thread does not run forever.
aentinger May 31, 2021
1aafd84
Remove manually definition of SFU.
aentinger May 31, 2021
0dc6c4c
Provide more meaningful (and distinct for RP2040) OTA error codes.
aentinger May 31, 2021
5db1b97
Ensure initialisation with relevant default parameters.
aentinger May 31, 2021
163f84c
Replace local variable with direct access to class member string.
aentinger May 31, 2021
0a60df5
Split HTTPS-GET in 3 parts - receive header -> extract content length…
aentinger May 31, 2021
81d68e4
Move watchdog feeding within the if(client->available()) check ... ot…
aentinger May 31, 2021
364319d
Remove SSU (2nd stage bootloader for MKR GSM 1400) as OTA for MKR GSM…
aentinger May 31, 2021
48afe74
Bugfix: Function was not working correctly when start of flash was != 0.
aentinger Jun 1, 2021
cdadeff
Cleaning up.
aentinger Jun 1, 2021
fc64b0a
Simplify extraction logic for HTTP header content length.
aentinger Jun 1, 2021
421eb9d
Disable verbose debug output in production.
aentinger Jun 1, 2021
6b1e802
Replace verification if connected() with a time-out check. Otherwise …
aentinger Jun 2, 2021
756a64a
After the implementation of a time-out logic in the previous commit i…
aentinger Jun 2, 2021
b13a560
Replace magic RP2040 OTA timeout values with sensibly named constants.
aentinger Jun 2, 2021
867a6ac
Replace magic RP2040 OTA timeout values with sensibly named constants.
aentinger Jun 2, 2021
c65bd2b
Move opening of update file to the very beginning of the OTA function…
aentinger Jun 2, 2021
6672d0e
Cleanup error handling to follow the same format in the whole functio…
aentinger Jun 2, 2021
4a3ff5e
Increase timeout values for HTTPS-GET data download to flash.
aentinger Jun 2, 2021
92168d0
Removing irrelevant debug output.
aentinger Jun 2, 2021
0e386a1
Temp - Remove later - erase flash within OTA handler.
aentinger Jun 2, 2021
4f89f35
Trigger a watchdog reset to start SFU
pennam Jun 3, 2021
fc5dd4f
Cleaning up missing comments.
aentinger Jun 4, 2021
06267fb
Unmount before performing a reset.
aentinger Jun 4, 2021
94ff897
Replace mount() with reformat() which results in a reformatted and mo…
aentinger Jun 4, 2021
679118c
Avoid infinite loop if we fail to enable/reconfigure watchdog
pennam Jun 4, 2021
5ee73f7
Add watchdog reset after each step of CloudTCP state machine to avoid…
pennam Jun 7, 2021
a212ef8
Disable verbose debug output in production.
aentinger Jun 7, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions extras/tools/bin2ota.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
magic_number = 0x23418057.to_bytes(4,byteorder='little')
elif board == "PORTENTA_H7_M7":
magic_number = 0x2341025B.to_bytes(4,byteorder='little')
elif board == "NANO_RP2040_CONNECT":
magic_number = 0x2341005E.to_bytes(4,byteorder='little')
else:
print ("Error,", board, "is not a supported board type")
sys.exit()
Expand Down
13 changes: 9 additions & 4 deletions src/AIoTC_Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@
* USER CONFIGURABLE DEFINES
******************************************************************************/

#ifndef OTA_STORAGE_SFU
#define OTA_STORAGE_SFU (0)
#endif

#ifndef NTP_USE_RANDOM_PORT
#define NTP_USE_RANDOM_PORT (1)
#endif
Expand Down Expand Up @@ -94,6 +90,12 @@
#define OTA_STORAGE_SNU (0)
#endif

#if defined(ARDUINO_NANO_RP2040_CONNECT)
#define OTA_STORAGE_SFU (1)
#else
#define OTA_STORAGE_SFU (0)
#endif

#ifdef ARDUINO_SAMD_MKRGSM1400
#define OTA_STORAGE_SSU (1)
#else
Expand Down Expand Up @@ -143,4 +145,7 @@
#define AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms (30000UL)
#define AIOT_CONFIG_LASTVALUES_SYNC_MAX_RETRY_CNT (10UL)

#define AIOT_CONFIG_RP2040_OTA_HTTP_HEADER_RECEIVE_TIMEOUT_ms (10*1000UL)
#define AIOT_CONFIG_RP2040_OTA_HTTP_DATA_RECEIVE_TIMEOUT_ms (4*60*1000UL)

#endif /* ARDUINO_AIOTC_CONFIG_H_ */
30 changes: 28 additions & 2 deletions src/ArduinoIoTCloudTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
sha256_str += buf;
});
DEBUG_VERBOSE("SHA256: %d bytes (of %d) read", bytes_read, app_size);
#else
#elif defined(ARDUINO_ARCH_SAMD)
/* Calculate the SHA256 checksum over the firmware stored in the flash of the
* MCU. Note: As we don't know the length per-se we read chunks of the flash
* until we detect one containing only 0xFF (= flash erased). This only works
Expand All @@ -172,6 +172,13 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
* range 0 to 0x2000, total flash size of 0x40000 bytes (256 kByte).
*/
String const sha256_str = FlashSHA256::calc(0x2000, 0x40000 - 0x2000);
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
/* The maximum size of a RP2040 OTA update image is 1 MByte (that is 1024 *
* 1024 bytes or 0x100'000 bytes).
*/
String const sha256_str = FlashSHA256::calc(XIP_BASE, 0x100000);
#else
# error "No method for SHA256 checksum calculation over application image defined for this architecture."
#endif
DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(sha256_str.c_str()), sha256_str.c_str());
_ota_img_sha256 = sha256_str;
Expand Down Expand Up @@ -259,6 +266,10 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
}
#endif /* OTA_STORAGE_SNU */

#if defined(ARDUINO_NANO_RP2040_CONNECT)
_ota_cap = true;
#endif

#ifdef BOARD_HAS_OFFLOADED_ECCX08
if (String(WiFi.firmwareVersion()) < String("1.4.4")) {
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());
Expand Down Expand Up @@ -309,6 +320,16 @@ void ArduinoIoTCloudTCP::update()
}
_state = next_state;

/* This watchdog feed is actually needed only by the RP2040 CONNECT cause its
* maximum watchdog window is 8388ms; despite this we feed it for all
* supported ARCH to keep code aligned.
*/
#ifdef ARDUINO_ARCH_SAMD
samd_watchdog_reset();
#elif defined(ARDUINO_ARCH_MBED)
mbed_watchdog_reset();
#endif

/* Check for new data from the MQTT client. */
if (_mqttClient.connected())
_mqttClient.poll();
Expand Down Expand Up @@ -491,6 +512,7 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
/* Request a OTA download if the hidden property
* OTA request has been set.
*/

if (_ota_req)
{
/* Clear the error flag. */
Expand Down Expand Up @@ -581,12 +603,16 @@ int ArduinoIoTCloudTCP::write(String const topic, byte const data[], int const l
#if OTA_ENABLED
void ArduinoIoTCloudTCP::onOTARequest()
{
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s _ota_url = %s", __FUNCTION__, _ota_url.c_str());
DEBUG_INFO("ArduinoIoTCloudTCP::%s _ota_url = %s", __FUNCTION__, _ota_url.c_str());

#ifdef ARDUINO_ARCH_SAMD
_ota_error = samd_onOTARequest(_ota_url.c_str());
#endif

#ifdef ARDUINO_NANO_RP2040_CONNECT
_ota_error = rp2040_connect_onOTARequest(_ota_url.c_str());
#endif

#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
_ota_error = portenta_h7_onOTARequest(_ota_url.c_str());
#endif
Expand Down
9 changes: 6 additions & 3 deletions src/utility/ota/FlashSHA256.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ String FlashSHA256::calc(uint32_t const start_addr, uint32_t const max_flash_siz
sha256.begin();

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

for(; flash_addr < max_flash_size; flash_addr += FLASH_READ_CHUNK_SIZE)
for(; bytes_read < max_flash_size; flash_addr += FLASH_READ_CHUNK_SIZE)
{
/* Read the next chunk of memory. */
memcpy(next_chunk, reinterpret_cast<const void *>(flash_addr), FLASH_READ_CHUNK_SIZE);
Expand All @@ -75,13 +76,15 @@ String FlashSHA256::calc(uint32_t const start_addr, uint32_t const max_flash_siz
}
/* Update with the remaining bytes. */
sha256.update(chunk, valid_bytes_in_chunk);
bytes_read += valid_bytes_in_chunk;
break;
}

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

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

Expand Down
Loading