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 > 0) {
ESP.flashRead(addr, data, SPI_FLASH_SEC_SIZE);
int sz = SPI_FLASH_SEC_SIZE * sizeof(uint32_t);
if (rem < sz)
sz = rem;
f.write(reinterpret_cast<uint8_t *>(&data[addr]), sz);
addr += SPI_FLASH_SEC_SIZE;
rem -= sz;
yield();
Serial.println(rem);
}
f.flush();
f.close();
spi_flash_read
-which is defined intools/sdk/include/spi_flash.h
- now I think the firmware would be loaded starting at address0
- and perhaps this python code (obviously converted to c++) may help in determining the exact size of the loaded firmwareESP.getSketchSize()
to get the size of the sketch :p - so, in theory, it's just a matter of usingspi_flash_read
to read the sketch (in chunks, obviously, since the sketch is larger than RAM) and write it out to SPIFFSdata
would be 4 x SPI_FLASH_SEC_SIZEaddr += SPI_FLASH_SEC_SIZE * 4;
?