Trying out transparent decompression using heatshrink... doesn't completely work on the esp8166 itself yet.

pull/30/head
Jeroen Domburg 10 years ago
parent f400fc2bb3
commit 0cd1984fb7
  1. 6
      include/httpdconfig.h
  2. 102
      user/espfs.c
  3. 2
      user/espfs.h

@ -0,0 +1,6 @@
//Define this if you want to be able to use Heatshrink-compressed espfs images.
#define EFS_HEATSHRINK
//Pos of esp fs in flash
#define ESPFS_POS 0x12000

@ -4,14 +4,37 @@ mkespfsimg tool, and can use that block to do abstracted operations on the files
It's written for use with httpd, but doesn't need to be used as such. It's written for use with httpd, but doesn't need to be used as such.
*/ */
#ifdef __ets__
//esp build
#include "driver/uart.h" #include "driver/uart.h"
#include "c_types.h" #include "c_types.h"
#include "user_interface.h" #include "user_interface.h"
#include "espconn.h" #include "espconn.h"
#include "mem.h" #include "mem.h"
#include "osapi.h" #include "osapi.h"
#else
//Test build
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define os_malloc malloc
#define os_free free
#define os_memcpy memcpy
#define os_strncmp strncmp
#define os_strcmp strcmp
#define os_strcpy strcpy
#define os_printf printf
#define ICACHE_FLASH_ATTR
extern char* espFsData;
#endif
#include "../mkespfsimage/espfsformat.h" #include "../mkespfsimage/espfsformat.h"
#include "espfs.h" #include "espfs.h"
#include "httpdconfig.h"
#ifdef EFS_HEATSHRINK
#include "heatshrink_decoder.h"
#endif
struct EspFsFile { struct EspFsFile {
EspFsHeader *header; EspFsHeader *header;
@ -25,7 +48,8 @@ struct EspFsFile {
/* /*
Available locations, at least in my flash, with boundaries partially guessed: Available locations, at least in my flash, with boundaries partially guessed:
0x00000 (0x10000): Code/data (RAM data?) 0x00000 (0x10000): Code/data (RAM data?)
0x10000 (0x30000): Free (filled with zeroes) (parts used by ESPCloud and maybe SSL) 0x10000 (0x02000): Gets erased by something?
0x12000 (0x2E000): Free (filled with zeroes) (parts used by ESPCloud and maybe SSL)
0x40000 (0x20000): Code/data (ROM data?) 0x40000 (0x20000): Code/data (ROM data?)
0x60000 (0x1C000): Free 0x60000 (0x1C000): Free
0x7c000 (0x04000): Param store 0x7c000 (0x04000): Param store
@ -56,7 +80,11 @@ void ICACHE_FLASH_ATTR memcpyAligned(char *dst, char *src, int len) {
EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) { EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
#ifdef __ets__
char *p=(char *)(ESPFS_POS+0x40200000); char *p=(char *)(ESPFS_POS+0x40200000);
#else
char *p=espFsData;
#endif
char *hpos; char *hpos;
char namebuf[256]; char namebuf[256];
EspFsHeader h; EspFsHeader h;
@ -67,14 +95,17 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
while(1) { while(1) {
hpos=p; hpos=p;
os_memcpy(&h, p, sizeof(EspFsHeader)); os_memcpy(&h, p, sizeof(EspFsHeader));
//ToDo: check magic if (h.magic!=0x73665345) {
os_printf("Magic mismatch. EspFS image broken.\n");
return NULL;
}
if (h.flags&FLAG_LASTFILE) { if (h.flags&FLAG_LASTFILE) {
// os_printf("End of archive.\n"); os_printf("End of image.\n");
return NULL; return NULL;
} }
p+=sizeof(EspFsHeader); p+=sizeof(EspFsHeader);
os_memcpy(namebuf, p, sizeof(namebuf)); os_memcpy(namebuf, p, sizeof(namebuf));
// os_printf("Found file %s . Namelen=%x fileLen=%x\n", namebuf, h.nameLen,h.fileLenComp); os_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n", namebuf, h.nameLen,h.fileLenComp,h.compression,h.flags);
if (os_strcmp(namebuf, fileName)==0) { if (os_strcmp(namebuf, fileName)==0) {
p+=h.nameLen; p+=h.nameLen;
r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); r=(EspFsFile *)os_malloc(sizeof(EspFsFile));
@ -84,8 +115,22 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
r->posComp=p; r->posComp=p;
r->posStart=p; r->posStart=p;
r->posDecomp=0; r->posDecomp=0;
r->decompData=NULL; if (h.compression==COMPRESS_NONE) {
//ToDo: Init any decompressor r->decompData=NULL;
#ifdef EFS_HEATSHRINK
} else if (h.compression==COMPRESS_HEATSHRINK) {
char parm;
//Decoder params are stored in 1st byte.
memcpyAligned(&parm, r->posComp, 1);
r->posComp++;
os_printf("Heatshrink compressed file; decode parms = %x\n", parm);
r->decompData=(heatshrink_decoder *)heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf);
os_printf("Decompressor allocated.\n");
#endif
} else {
os_printf("Invalid compression: %d\n", h.compression);
return NULL;
}
return r; return r;
} }
//Skip name and file //Skip name and file
@ -97,22 +142,63 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) { int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
int flen;
if (fh==NULL) return 0; if (fh==NULL) return 0;
memcpyAligned((char*)&flen, (char*)&fh->header->fileLenComp, 4);
if (fh->decompressor==COMPRESS_NONE) { if (fh->decompressor==COMPRESS_NONE) {
int toRead; int toRead;
toRead=fh->header->fileLenComp-(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, fh->posComp); os_printf("Reading %d bytes from %x\n", len, fh->posComp);
memcpyAligned(buff, fh->posComp, len); memcpyAligned(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);
return len; return len;
#ifdef EFS_HEATSHRINK
} else if (fh->decompressor==COMPRESS_HEATSHRINK) {
int decoded=0;
int elen, rlen, r;
char ebuff[16];
os_printf("heatshrink: reading\n");
heatshrink_decoder *dec=(heatshrink_decoder *)fh->decompData;
while(decoded<len) {
//Feed data into the decompressor
elen=flen-(fh->posComp - fh->posStart);
if (elen==0) return decoded; //file is read
if (elen>0) {
os_printf("heatshrink: feeding decoder (%d comp bytes left)\n", elen);
memcpyAligned(ebuff, fh->posComp, 16);
for (r=0; r<16; r++) os_printf("%02hhx ", ebuff[r]);
os_printf("\n");
r=heatshrink_decoder_sink(dec, ebuff, (elen>16)?16:elen, &rlen);
os_printf("heatshrink: decoder ate %d bytes (code %d)\n", rlen, r);
fh->posComp+=rlen;
if (rlen==elen) {
os_printf("heatshrink: finish\n");
heatshrink_decoder_finish(dec);
}
}
//Grab decompressed data and put into buff
r=heatshrink_decoder_poll(dec, buff, len-decoded, &rlen);
os_printf("heatshrink: decoder emitted %d bytes (code %d)\n", rlen, r);
fh->posDecomp+=rlen;
buff+=rlen;
decoded+=rlen;
}
return len;
#endif
} }
return 0;
} }
void ICACHE_FLASH_ATTR espFsClose(EspFsFile *fh) { void ICACHE_FLASH_ATTR espFsClose(EspFsFile *fh) {
if (fh==NULL) return; if (fh==NULL) return;
#ifdef EFS_HEATSHRINK
if (fh->decompressor==COMPRESS_HEATSHRINK) {
heatshrink_decoder_free((heatshrink_decoder*)fh->decompData);
}
#endif
os_free(fh); os_free(fh);
} }

@ -1,8 +1,6 @@
#ifndef ESPFS_H #ifndef ESPFS_H
#define ESPFS_H #define ESPFS_H
//Pos of esp fs in flash
#define ESPFS_POS 0x20000
typedef struct EspFsFile EspFsFile; typedef struct EspFsFile EspFsFile;

Loading…
Cancel
Save