diff --git a/esp-link/main.c b/esp-link/main.c index fe7f0ec..09d42bd 100644 --- a/esp-link/main.c +++ b/esp-link/main.c @@ -149,7 +149,7 @@ void user_init(void) { // Wifi wifiInit(); // init the flash filesystem with the html stuff - espFsInit(&_binary_espfs_img_start); + espFsInit(espLinkCtx, &_binary_espfs_img_start, ESPFS_MEMORY); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start); //os_printf("espFsInit %s\n", res?"ERR":"ok"); // mount the http handlers diff --git a/espfs/espfs.c b/espfs/espfs.c index f9942f3..6389b08 100644 --- a/espfs/espfs.c +++ b/espfs/espfs.c @@ -30,6 +30,7 @@ It's written for use with httpd, but doesn't need to be used as such. #define os_malloc malloc #define os_free free #define os_memcpy memcpy +#define os_memset memset #define os_strncmp strncmp #define os_strcmp strcmp #define os_strcpy strcpy @@ -40,9 +41,21 @@ It's written for use with httpd, but doesn't need to be used as such. #include "espfsformat.h" #include "espfs.h" -static char* espFsData = NULL; +EspFsContext espLinkCtxDef; +EspFsContext userCtxDef; + +EspFsContext * espLinkCtx = &espLinkCtxDef; +EspFsContext * userCtx = &userCtxDef; + +struct EspFsContext +{ + char* data; + EspFsSource source; + uint8_t valid; +}; struct EspFsFile { + EspFsContext *ctx; EspFsHeader *header; char decompressor; int32_t posDecomp; @@ -67,7 +80,20 @@ Accessing the flash through the mem emulation at 0x40200000 is a bit hairy: All a memory exception, crashing the program. */ -EspFsInitResult ICACHE_FLASH_ATTR espFsInit(void *flashAddress) { +void espfs_memcpy( EspFsContext * ctx, void * dest, const void * src, int count ) +{ + if( ctx->source == ESPFS_MEMORY ) + os_memcpy( dest, src, count ); + else + { + if( spi_flash_read( (int)src, dest, count ) != SPI_FLASH_RESULT_OK ) + os_memset( dest, 0, count ); // if read was not successful, reply with zeroes + } +} + +EspFsInitResult ICACHE_FLASH_ATTR espFsInit(EspFsContext *ctx, void *flashAddress, EspFsSource source) { + ctx->valid = 0; + ctx->source = source; // base address must be aligned to 4 bytes if (((int)flashAddress & 3) != 0) { return ESPFS_INIT_RESULT_BAD_ALIGN; @@ -75,12 +101,13 @@ EspFsInitResult ICACHE_FLASH_ATTR espFsInit(void *flashAddress) { // check if there is valid header at address EspFsHeader testHeader; - os_memcpy(&testHeader, flashAddress, sizeof(EspFsHeader)); + espfs_memcpy(ctx, &testHeader, flashAddress, sizeof(EspFsHeader)); if (testHeader.magic != ESPFS_MAGIC) { return ESPFS_INIT_RESULT_NO_IMAGE; } - espFsData = (char *)flashAddress; + ctx->data = (char *)flashAddress; + ctx->valid = 1; return ESPFS_INIT_RESULT_OK; } @@ -89,7 +116,7 @@ EspFsInitResult ICACHE_FLASH_ATTR espFsInit(void *flashAddress) { //ToDo: perhaps os_memcpy also does unaligned accesses? #ifdef __ets__ -void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) { +void ICACHE_FLASH_ATTR memcpyAligned(char *dst, const char *src, int len) { int x; int w, b; for (x=0; xsource == ESPFS_MEMORY ) + memcpyAligned(dest, src, count); + else + espfs_memcpy(ctx, dest, src, count); +} + // Returns flags of opened file. int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { if (fh == NULL) { @@ -116,19 +151,19 @@ int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { } int8_t flags; - memcpyAligned((char*)&flags, (char*)&fh->header->flags, 1); + espfs_memcpyAligned(fh->ctx, (char*)&flags, (char*)&fh->header->flags, 1); return (int)flags; } //Open a file and return a pointer to the file desc struct. -EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { - if (espFsData == NULL) { +EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) { + if (ctx->data == NULL) { #ifdef ESPFS_DBG os_printf("Call espFsInit first!\n"); #endif return NULL; } - char *p=espFsData; + char *p=ctx->data; char *hpos; char namebuf[256]; EspFsHeader h; @@ -139,7 +174,7 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { while(1) { hpos=p; //Grab the next file header. - os_memcpy(&h, p, sizeof(EspFsHeader)); + espfs_memcpy(ctx, &h, p, sizeof(EspFsHeader)); if (h.magic!=ESPFS_MAGIC) { #ifdef ESPFS_DBG os_printf("Magic mismatch. EspFS image broken.\n"); @@ -152,7 +187,7 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { } //Grab the name of the file. p+=sizeof(EspFsHeader); - os_memcpy(namebuf, p, sizeof(namebuf)); + espfs_memcpy(ctx, namebuf, p, sizeof(namebuf)); // os_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n", // namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags); if (os_strcmp(namebuf, fileName)==0) { @@ -161,6 +196,7 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem //os_printf("Alloc %p[%d]\n", r, sizeof(EspFsFile)); if (r==NULL) return NULL; + r->ctx = ctx; r->header=(EspFsHeader *)hpos; r->decompressor=h.compression; r->posComp=p; @@ -187,15 +223,15 @@ int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) { int flen, fdlen; if (fh==NULL) return 0; //Cache file length. - memcpyAligned((char*)&flen, (char*)&fh->header->fileLenComp, 4); - memcpyAligned((char*)&fdlen, (char*)&fh->header->fileLenDecomp, 4); + espfs_memcpyAligned(fh->ctx, (char*)&flen, (char*)&fh->header->fileLenComp, 4); + espfs_memcpyAligned(fh->ctx, (char*)&fdlen, (char*)&fh->header->fileLenDecomp, 4); //Do stuff depending on the way the file is compressed. if (fh->decompressor==COMPRESS_NONE) { int toRead; toRead=flen-(fh->posComp-fh->posStart); if (len>toRead) len=toRead; // os_printf("Reading %d bytes from %x\n", len, (unsigned int)fh->posComp); - memcpyAligned(buff, fh->posComp, len); + espfs_memcpyAligned(fh->ctx, buff, fh->posComp, len); fh->posDecomp+=len; fh->posComp+=len; // os_printf("Done reading %d bytes, pos=%x\n", len, fh->posComp); diff --git a/espfs/espfs.h b/espfs/espfs.h index c8e13e7..8e4b79f 100644 --- a/espfs/espfs.h +++ b/espfs/espfs.h @@ -7,10 +7,19 @@ typedef enum { ESPFS_INIT_RESULT_BAD_ALIGN, } EspFsInitResult; +typedef enum { + ESPFS_MEMORY, + ESPFS_FLASH, +} EspFsSource; + typedef struct EspFsFile EspFsFile; +typedef struct EspFsContext EspFsContext; + +extern EspFsContext * espLinkCtx; +extern EspFsContext * userCtx; -EspFsInitResult espFsInit(void *flashAddress); -EspFsFile *espFsOpen(char *fileName); +EspFsInitResult espFsInit(EspFsContext *ctx, void *flashAddress, EspFsSource source); +EspFsFile *espFsOpen(EspFsContext *ctx, char *fileName); int espFsFlags(EspFsFile *fh); int espFsRead(EspFsFile *fh, char *buff, int len); void espFsClose(EspFsFile *fh); diff --git a/httpd/httpdespfs.c b/httpd/httpdespfs.c index c6f2c0c..9ab2865 100644 --- a/httpd/httpdespfs.c +++ b/httpd/httpdespfs.c @@ -40,7 +40,7 @@ cgiEspFsHook(HttpdConnData *connData) { if (file==NULL) { //First call to this cgi. Open the file so we can read it. - file=espFsOpen(connData->url); + file=espFsOpen(espLinkCtx, connData->url); if (file==NULL) { return HTTPD_CGI_NOTFOUND; }