2

For the past two days, I've been trying to set up an ESP8266WebServer to serve my static web app files from SPIFFS. But as soon as I make a call to serveStatic, the ESP crashes. This is the exact code I'm running:

#include <FS.h>
#include <ESP8266WebServer.h>

ESP8266WebServer s;

void setup() {

    Serial.begin(115200);

    if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
    }

    s.serveStatic("/", SPIFFS, "/static/");    
    s.begin();
}

void loop() {
  s.handleClient();
}

I know that this is example does not allow me to access the files in any way because I don't have WiFi configured, but this is enough for me to crash the ESP. This is the error that I keep seeing:

SPIFFSImpl: allocating 512+240+1400=2152 bytes
SPIFFSImpl: mounting fs @100000, size=2fa000, block=2000, page=100
SPIFFSImpl: mount rc=0

Fatal exception 28(LoadProhibitedCause):
epc1=0x4021407a, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Exception (28):
epc1=0x4021407a epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffca0 end: 3fffffc0 offset: 01a0
3ffffe40:  3ffefaf8 00000000 3ffffea0 402127b1  
3ffffe50:  00000001 ffffffff 4020a9dc 00000000  
3ffffe60:  3ffe8304 00000000 0000000a 40216e21  
3ffffe70:  402497e1 00000000 00000000 4020b414  
3ffffe80:  3ffffee0 3ffffed0 00000008 402497e3  
3ffffe90:  402497e2 3ffe8304 3ffefaf8 402171ec  
3ffffea0:  00000000 ffffffff 00000000 00000000  
3ffffeb0:  00000001 00000041 3f302073 40212d8e  
3ffffec0:  3ffffee0 3ffffed0 00000004 40209c90  
3ffffed0:  3fffff10 00000000 00000017 3fff0580  
3ffffee0:  00308658 3fffff20 3ffef85c 4020a3e9  
3ffffef0:  000018c0 3ffee6b0 00000000 40208120  
3fffff00:  3fffff60 3fffff50 00000014 00000001  
3fffff10:  00000009 00000001 00000001 40207c65  
3fffff20:  40100b04 00001000 00002000 3fff0580  
3fffff30:  3ffe8658 402497a4 3ffe8304 40212d8e  
3fffff40:  3fffff60 3fffff50 00000004 40100476  
3fffff50:  3ffe8658 3ffe8658 3ffe865f 00000000  
3fffff60:  00000000 00000000 3fff056c 4020ffa5  
3fffff70:  3fffdad0 3ffee690 3fff056c 40201325  
3fffff80:  3ffe865f feefeffe feefeffe feefeffe  
3fffff90:  feefeffe feefeffe feefeffe 3ffee610  
3fffffa0:  3fffdad0 00000000 3ffee5d0 40206aa0  
3fffffb0:  feefeffe feefeffe 3ffe84f4 40101245  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1392, room 16 
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

I have also analyzed the stack trace using ESP exception decoder, which didn't get me any further though. Here is the output of that tool:


Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
PC: 0x4021407a: pgm_read_byte_inlined at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/sys/xtensa/sys/pgmspace.h line 72
EXCVADDR: 0x00000000

Decoding stack results
0x402127b1: _printf_i at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/nano-vfprintf_i.c line 226
0x4020a9dc: spiffs_object_find_object_index_header_by_name_v(spiffs*, spiffs_obj_id, spiffs_block_ix, int, void const*, void*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_nucleus.cpp line 1664
0x40216e21: __sfputs_r at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/nano-vfprintf.c line 433
0x4020b414: spiffs_obj_lu_scan(spiffs*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_nucleus.cpp line 439
0x402171ec: _vfprintf_r at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/nano-vfprintf.c line 667
0x40212d8e: printf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/printf.c line 61
0x40209c90: SPIFFS_mount(spiffs*, spiffs_config*, u8_t*, u8_t*, u32_t, void*, u32_t, spiffs_check_callback) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_hydrogen.cpp line 138
0x4020a3e9: SPIFFS_stat(spiffs*, char const*, spiffs_stat*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_hydrogen.cpp line 769
0x40208120: spiffs_impl::SPIFFSImpl::_tryMount() at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs_api.h line 320
0x40207c65: spiffs_impl::SPIFFSImpl::exists(char const*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs_api.cpp line 80
0x40100b04: get_poisoned(void*, size_t) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/umm_malloc/umm_poison.c line 112
0x40212d8e: printf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/printf.c line 61
0x40100476: pvPortMalloc(size_t, char const*, int) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/heap.cpp line 267
0x4020ffa5: fs::FS::exists(char const*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/FS.cpp line 363
0x40201325: setup() at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 75
0x40206aa0: loop_wrapper() at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_main.cpp line 177

These are my settings in the Arduino IDE:

Sketch settings in IDE

To flash the data to the ESP, im using the latest version of this tool for the Arduino-IDE: https://github.com/esp8266/arduino-esp8266fs-plugin

I'm probably making a stupid mistake but I've been scratching my head for hours now and can't see where the issue could be. Any help would be greatly appreciated!

EDIT #1:

The data is definitely available on the ESP, since this snippet works fine:

#include <FS.h>
#include <ESP8266WebServer.h>

ESP8266WebServer s;

void setup() {

    Serial.begin(115200);

    if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
    }

    /*s.serveStatic("/", SPIFFS, "/static/");    
    s.begin();*/
}

void loop() {
  //s.handleClient();

    delay(5000);

    File f = SPIFFS.open("/static/index.html", "r");

    String s = f.readString();

    Serial.println(s);

    f.close();
}

EDIT #2

Serving the files by registering the function below as a handler (server.on("/", myHandler)works:

void myHandler(){

    String file = "/static/index.html";

    Serial.println("[INFO] requested file " + file);

    if(!SPIFFS.exists(file)){

        server.send(404, "text/plain", "<h1>404: Not found</h1>");         
        return;
    }

    String contentType = "text/plain";

    if(file.endsWith(".html")){
        contentType = "text/html";
    } else if(file.endsWith(".css")){
        contentType = "text/css";
    } else if(file.endsWith(".js")){
        contentType = "application/javascript";
    }

    File f = SPIFFS.open(file, "r");

    server.streamFile(f, contentType);

    f.close();
}
7
  • try to turn off the debug logs with "Debug level" None
    – Juraj
    Apr 20, 2020 at 11:43
  • tried that before, didn't help unfortunately Apr 20, 2020 at 11:53
  • are you sure? do you have the same stack trace then? turn off Debug port too
    – Juraj
    Apr 20, 2020 at 11:59
  • Wow, I just tried it again - and you were right! It's working now! Maybe I had just turned down the level before... But why? Does that mean I can't look at my WiFi-Debug-Messages while using serveStatic()? Apr 20, 2020 at 12:04
  • I've just done some testing and figured out that as soon as I include CORE in the debugging menu, it starts crashing. I would have never guessed this was the issue. Apr 20, 2020 at 12:12

2 Answers 2

4

Turns out the ESP crash is caused by the debug settings in the Arduino IDE. As soon as the CORE-level is included, the error occurs. There seems to be a bug in the firmware somewhere. Including other levels seems to be fine.

A huge thanks to Juraj for helping me spot this one.

0

Probably you have no SPIFFS uploaded.
So after flashing the program you have to use ESP8266DataUpload and in your Dir containing the *.ino there has to be a "data" directory in which the file you serve or the dir in your case "/static/" has to exist.

EDIT No the file is not existing ;-) use

 serveStatic("/", SPIFFS, "/static");  //=> no trailing '/'

or use (Be aware that serving dirs static is not working properly. I have every large file in a single static statement including the ageing

 serveStatic("/", SPIFFS, "/static/index.html"); 

Not knowing the size of your static files flash with 2MB FS / or 1MB FS / the problem is that if you don't need OTA you always waste space. I created my personal partition schemes with e.g. 2MB Spiffs/2MB flash/No OTA for the prog.
Your memory should be sized as follows prog size + var size (seen in IDE) + size of the largest (static) files * 1.2 (safety margin) should fill "App memory" around 80%.
As an example your usage is at the moment as follows:
You have at the moment max 400kb for the app AND serving (static) files. You use

  • 3 MB for SPIFFS file system,
  • 512 for OTA,
  • min 100kb for your Debug level

=> how could it keep/load e.g a 300kb file into flash?
Your error code 28 is normally connected to out of memory problems, the error message line two indicates that something should be loaded to memory and cant, We ruled out all other reasons so ...

7
  • Thats exactly what I have. I know that the files are there and are readable because reading the files individually from SPIFFS works. See my edit above. Apr 20, 2020 at 9:53
  • I just changed my code to define a file individually but the error is still there :( Apr 20, 2020 at 10:05
  • Thats a good hint, I will consider adjusting that before deploying. However, my static files (everything inside the data directory) are currently 1,4MB in size. That should be compatible with my current IDE settings, correct? Apr 20, 2020 at 10:32
  • No its not - you have at the moment max 400kb for the app AND serving static files (you use 3 MB for SPIFFS file system, 512 for OTA, min 100kb for your Debug level) - how could it keep/load e.g a 300kb file in prgmem -your error message line two indicates that something should be loaded to prgmem and cant We ruled out all other reasons so ... Apr 20, 2020 at 11:09
  • But if that was an issue, how come handling static file reads not through server.serveStatic() but through server.on(...)with a custom handler function that streams the file over works? See my second edit for reference. Apr 20, 2020 at 11:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.