diff --git a/cores/esp32/Esp.cpp b/cores/esp32/Esp.cpp index 9e5dbc25254..60e4490d72e 100644 --- a/cores/esp32/Esp.cpp +++ b/cores/esp32/Esp.cpp @@ -30,6 +30,7 @@ extern "C" { #include } +#include /** * User-defined Literals @@ -158,9 +159,9 @@ static uint32_t sketchSize(sketchSize_t response) { data.start_addr = running_pos.offset; esp_image_verify(ESP_IMAGE_VERIFY, &running_pos, &data); if (response) { - return running_pos.size - data.image_len; + return running_pos.size - data.image_len; } else { - return data.image_len; + return data.image_len; } } @@ -168,6 +169,38 @@ uint32_t EspClass::getSketchSize () { return sketchSize(SKETCH_SIZE_TOTAL); } +String EspClass::getSketchMD5() +{ + static String result; + if (result.length()) { + return result; + } + uint32_t lengthLeft = getSketchSize(); + + const esp_partition_t *running = esp_ota_get_running_partition(); + if (!running) return String(); + const size_t bufSize = SPI_FLASH_SEC_SIZE; + std::unique_ptr buf(new uint8_t[bufSize]); + uint32_t offset = 0; + if(!buf.get()) { + return String(); + } + MD5Builder md5; + md5.begin(); + while( lengthLeft > 0) { + size_t readBytes = (lengthLeft < bufSize) ? lengthLeft : bufSize; + if (!ESP.flashRead(running->address + offset, reinterpret_cast(buf.get()), (readBytes + 3) & ~3)) { + return String(); + } + md5.add(buf.get(), readBytes); + lengthLeft -= readBytes; + offset += readBytes; + } + md5.calculate(); + result = md5.toString(); + return result; +} + uint32_t EspClass::getFreeSketchSpace () { const esp_partition_t* _partition = esp_ota_get_next_update_partition(NULL); if(!_partition){ diff --git a/cores/esp32/Esp.h b/cores/esp32/Esp.h index 385bcbb4b1f..f8e7b9cfe70 100644 --- a/cores/esp32/Esp.h +++ b/cores/esp32/Esp.h @@ -90,6 +90,7 @@ class EspClass FlashMode_t magicFlashChipMode(uint8_t byte); uint32_t getSketchSize(); + String getSketchMD5(); uint32_t getFreeSketchSpace(); bool flashEraseSector(uint32_t sector);