Refactored espfs to handle Flash source

pull/193/head
Karai Csaba 9 years ago committed by Thorsten von Eicken
parent 8c4c4928b1
commit a85244d6fb
  1. 2
      esp-link/main.c
  2. 64
      espfs/espfs.c
  3. 13
      espfs/espfs.h
  4. 2
      httpd/httpdespfs.c

@ -149,7 +149,7 @@ void user_init(void) {
// Wifi // Wifi
wifiInit(); wifiInit();
// init the flash filesystem with the html stuff // 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); //EspFsInitResult res = espFsInit(&_binary_espfs_img_start);
//os_printf("espFsInit %s\n", res?"ERR":"ok"); //os_printf("espFsInit %s\n", res?"ERR":"ok");
// mount the http handlers // mount the http handlers

@ -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_malloc malloc
#define os_free free #define os_free free
#define os_memcpy memcpy #define os_memcpy memcpy
#define os_memset memset
#define os_strncmp strncmp #define os_strncmp strncmp
#define os_strcmp strcmp #define os_strcmp strcmp
#define os_strcpy strcpy #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 "espfsformat.h"
#include "espfs.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 { struct EspFsFile {
EspFsContext *ctx;
EspFsHeader *header; EspFsHeader *header;
char decompressor; char decompressor;
int32_t posDecomp; 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. 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 // base address must be aligned to 4 bytes
if (((int)flashAddress & 3) != 0) { if (((int)flashAddress & 3) != 0) {
return ESPFS_INIT_RESULT_BAD_ALIGN; 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 // check if there is valid header at address
EspFsHeader testHeader; EspFsHeader testHeader;
os_memcpy(&testHeader, flashAddress, sizeof(EspFsHeader)); espfs_memcpy(ctx, &testHeader, flashAddress, sizeof(EspFsHeader));
if (testHeader.magic != ESPFS_MAGIC) { if (testHeader.magic != ESPFS_MAGIC) {
return ESPFS_INIT_RESULT_NO_IMAGE; return ESPFS_INIT_RESULT_NO_IMAGE;
} }
espFsData = (char *)flashAddress; ctx->data = (char *)flashAddress;
ctx->valid = 1;
return ESPFS_INIT_RESULT_OK; return ESPFS_INIT_RESULT_OK;
} }
@ -89,7 +116,7 @@ EspFsInitResult ICACHE_FLASH_ATTR espFsInit(void *flashAddress) {
//ToDo: perhaps os_memcpy also does unaligned accesses? //ToDo: perhaps os_memcpy also does unaligned accesses?
#ifdef __ets__ #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 x;
int w, b; int w, b;
for (x=0; x<len; x++) { for (x=0; x<len; x++) {
@ -106,6 +133,14 @@ void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) {
#define memcpyAligned memcpy #define memcpyAligned memcpy
#endif #endif
void espfs_memcpyAligned( EspFsContext * ctx, void * dest, const void * src, int count )
{
if( ctx->source == ESPFS_MEMORY )
memcpyAligned(dest, src, count);
else
espfs_memcpy(ctx, dest, src, count);
}
// Returns flags of opened file. // Returns flags of opened file.
int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) { int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) {
if (fh == NULL) { if (fh == NULL) {
@ -116,19 +151,19 @@ int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) {
} }
int8_t flags; 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; return (int)flags;
} }
//Open a file and return a pointer to the file desc struct. //Open a file and return a pointer to the file desc struct.
EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) {
if (espFsData == NULL) { if (ctx->data == NULL) {
#ifdef ESPFS_DBG #ifdef ESPFS_DBG
os_printf("Call espFsInit first!\n"); os_printf("Call espFsInit first!\n");
#endif #endif
return NULL; return NULL;
} }
char *p=espFsData; char *p=ctx->data;
char *hpos; char *hpos;
char namebuf[256]; char namebuf[256];
EspFsHeader h; EspFsHeader h;
@ -139,7 +174,7 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
while(1) { while(1) {
hpos=p; hpos=p;
//Grab the next file header. //Grab the next file header.
os_memcpy(&h, p, sizeof(EspFsHeader)); espfs_memcpy(ctx, &h, p, sizeof(EspFsHeader));
if (h.magic!=ESPFS_MAGIC) { if (h.magic!=ESPFS_MAGIC) {
#ifdef ESPFS_DBG #ifdef ESPFS_DBG
os_printf("Magic mismatch. EspFS image broken.\n"); 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. //Grab the name of the file.
p+=sizeof(EspFsHeader); 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", // 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); // namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags);
if (os_strcmp(namebuf, fileName)==0) { 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 r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem
//os_printf("Alloc %p[%d]\n", r, sizeof(EspFsFile)); //os_printf("Alloc %p[%d]\n", r, sizeof(EspFsFile));
if (r==NULL) return NULL; if (r==NULL) return NULL;
r->ctx = ctx;
r->header=(EspFsHeader *)hpos; r->header=(EspFsHeader *)hpos;
r->decompressor=h.compression; r->decompressor=h.compression;
r->posComp=p; r->posComp=p;
@ -187,15 +223,15 @@ int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
int flen, fdlen; int flen, fdlen;
if (fh==NULL) return 0; if (fh==NULL) return 0;
//Cache file length. //Cache file length.
memcpyAligned((char*)&flen, (char*)&fh->header->fileLenComp, 4); espfs_memcpyAligned(fh->ctx, (char*)&flen, (char*)&fh->header->fileLenComp, 4);
memcpyAligned((char*)&fdlen, (char*)&fh->header->fileLenDecomp, 4); espfs_memcpyAligned(fh->ctx, (char*)&fdlen, (char*)&fh->header->fileLenDecomp, 4);
//Do stuff depending on the way the file is compressed. //Do stuff depending on the way the file is compressed.
if (fh->decompressor==COMPRESS_NONE) { if (fh->decompressor==COMPRESS_NONE) {
int toRead; int toRead;
toRead=flen-(fh->posComp-fh->posStart); toRead=flen-(fh->posComp-fh->posStart);
if (len>toRead) len=toRead; if (len>toRead) len=toRead;
// os_printf("Reading %d bytes from %x\n", len, (unsigned int)fh->posComp); // 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->posDecomp+=len;
fh->posComp+=len; fh->posComp+=len;
// os_printf("Done reading %d bytes, pos=%x\n", len, fh->posComp); // os_printf("Done reading %d bytes, pos=%x\n", len, fh->posComp);

@ -7,10 +7,19 @@ typedef enum {
ESPFS_INIT_RESULT_BAD_ALIGN, ESPFS_INIT_RESULT_BAD_ALIGN,
} EspFsInitResult; } EspFsInitResult;
typedef enum {
ESPFS_MEMORY,
ESPFS_FLASH,
} EspFsSource;
typedef struct EspFsFile EspFsFile; typedef struct EspFsFile EspFsFile;
typedef struct EspFsContext EspFsContext;
extern EspFsContext * espLinkCtx;
extern EspFsContext * userCtx;
EspFsInitResult espFsInit(void *flashAddress); EspFsInitResult espFsInit(EspFsContext *ctx, void *flashAddress, EspFsSource source);
EspFsFile *espFsOpen(char *fileName); EspFsFile *espFsOpen(EspFsContext *ctx, char *fileName);
int espFsFlags(EspFsFile *fh); int espFsFlags(EspFsFile *fh);
int espFsRead(EspFsFile *fh, char *buff, int len); int espFsRead(EspFsFile *fh, char *buff, int len);
void espFsClose(EspFsFile *fh); void espFsClose(EspFsFile *fh);

@ -40,7 +40,7 @@ cgiEspFsHook(HttpdConnData *connData) {
if (file==NULL) { if (file==NULL) {
//First call to this cgi. Open the file so we can read it. //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) { if (file==NULL) {
return HTTPD_CGI_NOTFOUND; return HTTPD_CGI_NOTFOUND;
} }

Loading…
Cancel
Save