My twist on the accessor function is to cache the previously-read 32bits of flash data in a STATIC, so as to avoid repeated reads when accessing consecutive bytes of e.g. strings.
A slight 'gotcha' to be aware of is that since GCC3.0, the compiler won't let you mix const and non-const symbols in the same linker section. This means, for example, that if you define an array of strings it has to be declared as type 'const char * const strArray[]' (const pointer to const data) otherwise you'll get a section conflict error.
#include <stdint.h>
#include <ets_sys.h>
#include <osapi.h>
#include <user_interface.h>
//--------------------
// user data in flash
//--------------------
const uint8_t myString[] __attribute__((section(".irom.text"))) = "The quick brown fox jumps over the lazy dog";
// NB: you CAN use section(".irom.text") if you are also using -DUSE_OPTIMIZED_PRINTF
// but if you do so, you MUST ensure that ALL elements of your data are declared const.
//------------
// prototypes
//------------
uint8_t readByte(uint8_t *);
void initDoneCB(void);
//-----------
// functions
//-----------
// access byte stored in flash
//
uint8_t ICACHE_FLASH_ATTR readByte(uint8_t *pByte) {
static uint8_t *prevPtr = NULL;
static uint32_t longVal = 0;
uint8_t offset;
offset = (uint8_t)(*((uint8_t *)&pByte) & 0x3); // get lowest 2 bits
*((uint8_t *)&pByte) &= (uint8_t)(~ 0x3); // align address (clear lowest 2 bits)
if (pByte != prevPtr) { // optimise consecutive reads by caching
prevPtr = pByte;
longVal = *((uint32_t *)pByte); // read aligned 32bit value
}
return *((uint8_t *)(&longVal) + offset); // extract required byte
}
// entry point
//
void ICACHE_FLASH_ATTR user_init() {
system_init_done_cb(&initDoneCB);
}
// called when initialisation is complete
//
void ICACHE_FLASH_ATTR initDoneCB(void) {
uint8_t *pByte;
uint8_t byte;
os_printf("\n");
pByte = myString; // use accessor function to print string characters
do {
byte = readByte(pByte);
pByte += 1;
if (byte != 0) {
os_printf("%c", byte);
}
} while (byte != 0);
os_printf("\nDone\n");
}