3333#include " tls/utility/CryptoUtil.h"
3434#endif
3535
36+ #if defined(ARDUINO_PORTENTA_H7_M7)
37+ # include " tls/utility/SHA256.h"
38+ # include < stm32h7xx_hal_rtc_ex.h>
39+ #endif
40+
3641#include " utility/ota/OTA.h"
3742#include " utility/ota/FlashSHA256.h"
3843
3944#include " cbor/CBOREncoder.h"
4045
46+ /* *****************************************************************************
47+ * EXTERN
48+ ******************************************************************************/
49+
50+ #if defined(ARDUINO_PORTENTA_H7_M7)
51+ extern RTC_HandleTypeDef RTCHandle;
52+ #endif
53+
4154/* *****************************************************************************
4255 GLOBAL CONSTANTS
4356 ******************************************************************************/
@@ -113,6 +126,40 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort)
113126#endif /* AVR */
114127
115128#if OTA_ENABLED && !defined(__AVR__)
129+ #if defined(ARDUINO_PORTENTA_H7_M7)
130+ /* The length of the application can be retrieved the same way it was
131+ * communicated to the bootloader, that is by writing to the non-volatile
132+ * storage registers of the RTC.
133+ */
134+ SHA256 sha256;
135+ uint32_t const app_start = 0x8040000 ;
136+ uint32_t const app_size = HAL_RTCEx_BKUPRead (&RTCHandle, RTC_BKP_DR3);
137+
138+ sha256.begin ();
139+ uint32_t b = 0 ;
140+ uint32_t bytes_read = 0 ; for (uint32_t a = app_start;
141+ bytes_read < app_size;
142+ bytes_read += sizeof (b), a += sizeof (b))
143+ {
144+ /* Read the next chunk of memory. */
145+ memcpy (&b, reinterpret_cast <const void *>(a), sizeof (b));
146+ /* Feed it to SHA256. */
147+ sha256.update (reinterpret_cast <uint8_t *>(&b), sizeof (b));
148+ }
149+ /* Retrieve the final hash string. */
150+ uint8_t sha256_hash[SHA256::HASH_SIZE] = {0 };
151+ sha256.finalize (sha256_hash);
152+ String sha256_str;
153+ std::for_each (sha256_hash,
154+ sha256_hash + SHA256::HASH_SIZE,
155+ [&sha256_str](uint8_t const elem)
156+ {
157+ char buf[4 ];
158+ snprintf (buf, 4 , " %02X" , elem);
159+ sha256_str += buf;
160+ });
161+ DEBUG_VERBOSE (" SHA256: %d bytes (of %d) read" , bytes_read, app_size);
162+ #else
116163 /* Calculate the SHA256 checksum over the firmware stored in the flash of the
117164 * MCU. Note: As we don't know the length per-se we read chunks of the flash
118165 * until we detect one containing only 0xFF (= flash erased). This only works
@@ -123,12 +170,10 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort)
123170 * The bootloader is excluded from the calculation and occupies flash address
124171 * range 0 to 0x2000, total flash size of 0x40000 bytes (256 kByte).
125172 */
126- #if defined(ARDUINO_PORTENTA_H7_M7)
127- // TODO: check if we need to checksum the whole flash or just the first megabyte
128- _ota_img_sha256 = FlashSHA256::calc (0x8040000 , 0x200000 - 0x40000 );
129- #else
130- _ota_img_sha256 = FlashSHA256::calc (0x2000 , 0x40000 - 0x2000 );
173+ String const sha256_str = FlashSHA256::calc (0x2000 , 0x40000 - 0x2000 );
131174#endif
175+ DEBUG_VERBOSE (" SHA256: HASH(%d) = %s" , strlen (sha256_str.c_str ()), sha256_str.c_str ());
176+ _ota_img_sha256 = sha256_str;
132177#endif /* OTA_ENABLED */
133178
134179 #ifdef BOARD_HAS_OFFLOADED_ECCX08
0 commit comments