Reading contents of ESP8266 Flash from inside sketch I am aware that there is a way to create a dump of the flash via esptool, but is there a way to read the contents of the sketch (just the sketch, not the full flash or SPIFFS) memory via the sketch itself? As in, have a program on the ESP8266 able to read its own machine code from the flash to do something with? I do not need write access, just read access.

I would like to be able to create a backup of the current sketch in SPIFFS so that it is possible to revert a bad sketch so long as the reversion trigger isn't broken. (For example, if a later part of the boot process is messed up, or if a function acts slightly wrong, a button could be held, and it would restore from the saved image. The restore process is something that I've figured out from my previous question, but I would like a way to write the sketch to SPIFFS that does not require a separate manual upload or a wrapper around the OTA process.)

[edit:]
Thank you for the comments.

I have created this code that SHOULD have copied the sketch to SPIFFS. However, it does not seem to have done so properly (since the result does not have the same checksums as the original file, and attempts to write it yield a nonfunctional device). Can I have someone look over it and see if they can figure out why?

unsigned long addr = 0;
unsigned long rem = ESP.getSketchSize();
uint32_t *data = new uint32_t[SPI_FLASH_SEC_SIZE];
File f = SPIFFS.open("/fw.bin", "w");
while (rem &gt; 0) {
  ESP.flashRead(addr, data, SPI_FLASH_SEC_SIZE);
  int sz = SPI_FLASH_SEC_SIZE * sizeof(uint32_t);
  if (rem &lt; sz)
    sz = rem;
  f.write(reinterpret_cast&lt;uint8_t *&gt;(&amp;data[addr]), sz);
  addr += SPI_FLASH_SEC_SIZE;
  rem -= sz;
  yield();
  Serial.println(rem);
}
f.flush();
f.close();
I think you're reading of flash is slightly wrong

while ESP.flashRead takes a unit32_t pointer for output data, the read "count" argument is in bytes - looking at Updater.cpp code it does this

uint8_t buff[128];
for(int i = 0; i &lt; binSize; i += sizeof(buff)) {
  ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff));
  .....
}


so, the the address and count are in bytes - given that SPI_FLASH_SEC_SIZE is 0x1000 or 4096, your code is doing the following


reading 4096 bytes into a 16384 buffer
writing 16384 bytes (so the last 12288 bytes are zero, or random, not sure)
adding 4096 to the address
subtracting 16384 from size
repeat until all read


So, the written size will be correct, but the data will be three quarters wrong :p

Therefore, your code should be

unsigned long addr = 0;
unsigned long rem = ESP.getSketchSize();
uint8_t *data = new uint8_t[SPI_FLASH_SEC_SIZE];
int sz = SPI_FLASH_SEC_SIZE;
File f = SPIFFS.open("/fw.bin", "w");

while (rem &gt; 0) {
    ESP.flashRead(addr, (uint32_t *)data, SPI_FLASH_SEC_SIZE);
    if (rem &lt; sz)
        sz = rem;
    f.write(data, sz);
    addr += SPI_FLASH_SEC_SIZE;
    rem -= sz;
    yield();
    Serial.println(rem);
}

f.flush();
f.close();