esp8266 writing to internal flash (basic key/value store)
The following code for the esp8266 shows how you might write to the user flash area and implement a simple key/value store. I wouldn’t use this for anything, but the example may be instructive.
The memory map of the esp8266 isn’t yet fully understood, but there appears to be a user writable area at the location identified as 0x3C00. All flash reads/writes are executed via the library functions spi_flash_xxx. I assume this region of flash is marked for user applications only, and there’s no possibility of user code overflowing into this area. I don’t know how large this region is. If you know, please comment below or send me an email.
I’ve also noticed someone here disabling UART interrupts during flash writes using ETS_UART_INTR_DISABLE() and ETS_UART_INTR_ENABLE(). I’m not doing this in the code below, but it is possibly important to do so.
#include "flash.h" ICACHE_FLASH_ATTR static char *find_key(const char *key,char *settings) { int n; for(n=0;n<1024;n+=128) { if(strcmp(key,settings+n) == 0) return settings+n; } return 0; } ICACHE_FLASH_ATTR static char *find_free(char *settings) { int n; for(n=0;n<1024;n+=128) { if(settings[n] == 0) return settings+n; } return 0; } ICACHE_FLASH_ATTR void flash_erase_all() { char settings[1024]; int n; for(n=0;n<1024;n++) settings[n]=0; spi_flash_erase_sector(0x3C); spi_flash_write(0x3C000,settings,1024); } ICACHE_FLASH_ATTR int flash_key_value_set(const char *key,const char *value) { if(strlen(key) > 64) return 1; if(strlen(value) > 64) return 1; char settings[1024]; spi_flash_read(0x3C000, (uint32 *) settings, 1024); char *location = find_key(key,settings); if(location == NULL) { location = find_free(settings); } if(location == NULL) return 0; strcpy(location,key); strcpy(location+64,value); spi_flash_erase_sector(0x3C); spi_flash_write(0x3C000,settings,1024); return 1; } ICACHE_FLASH_ATTR int flash_key_value_get(char *key,char *value) { if(strlen(key) > 64) return 0; if(strlen(value) > 64) return 0; char settings[1024]; spi_flash_read(0x3C000, (uint32 *) settings, 1024); char *location = find_key(key,settings); if(location == NULL) value[0]=0; strcpy(value,location+64); return 1; }