Сбой при обслуживании файлов статической ширины ESP8266WebServer

Последние два дня я пытался настроить ESP8266WebServer для обслуживания моих статических файлов веб-приложений из SPIFFS. Но как только я вызываю serveStatic, ESP падает. Это точный код, который я запускаю:

#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();
}

Я знаю, что этот пример не позволяет мне каким-либо образом получить доступ к файлам, потому что у меня не настроен WiFi, но этого достаточно для того, чтобы ESP вышел из строя. Это ошибка, которую я постоянно вижу:

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

Я также проанализировал трассировку стека с помощью декодера исключений ESP, но это не помогло мне. Вот результат работы этого инструмента:


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

Вот мои настройки в Arduino IDE:

Настройки скетча в IDE

Чтобы записать данные в ESP, я использую последнюю версию этого инструмента для Arduino-IDE: https:/ /github.com/esp8266/arduino-esp8266fs-плагин

Возможно, я совершаю глупую ошибку, но уже несколько часов ломаю голову и не могу понять, в чем может быть проблема. Мы будем очень признательны за любую помощь!

Обновление №1:

Данные определенно доступны в ESP, так как этот фрагмент работает нормально:


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

Обновление №2

Обслуживание файлов путем регистрации приведенной ниже функции в качестве обработчика (server.on("/", myHandler)работает:

#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();
}

, 👍2

Обсуждение

попробуйте отключить журналы отладки с помощью «Уровня отладки» Нет, @Juraj

уже пробовал, не помогло к сожалению, @Alexander Richter

вы уверены? у вас такая же трассировка стека? отключить отладочный порт тоже, @Juraj

Ничего себе, я только что попробовал еще раз - и вы были правы! Теперь работает! Может быть, я просто понизил уровень раньше... Но почему? Означает ли это, что я не могу просматривать свои WiFi-Debug-Messages при использовании `serveStatic()`?, @Alexander Richter

Я только что провел некоторое тестирование и выяснил, что как только я включаю CORE в меню отладки, он начинает падать. Я бы никогда не догадался, что это проблема., @Alexander Richter

должна быть какая-то ошибка с ведением журнала. printf в трассировке стека был подсказкой, @Juraj

Отличная находка! Позор, я не могу проголосовать за вас!, @Alexander Richter


2 ответа


Лучший ответ:

4

Оказывается, сбой ESP вызван настройками отладки в Arduino IDE. Как только CORE-уровень включается, возникает ошибка. Кажется, где-то в прошивке ошибка. Включение других уровней, кажется, нормально.

Огромное спасибо Юраю за помощь в обнаружении этого.

,

0

Возможно, вы не загрузили SPIFFS.
Поэтому после прошивки программы вы должны использовать ESP8266DataUpload, а в вашем каталоге, содержащем *.ino, должен быть каталог «data», в котором должен находиться файл, который вы обслуживаете, или каталог в вашем случае «/static/». существует.

EDIT Нет, файл не существует ;-) используйте

 serveStatic("/", SPIFFS, "/static");  //=> без завершающего '/'

или используйте (имейте в виду, что обслуживание статических каталогов не работает должным образом. У меня есть каждый большой файл в одном статическом выражении, включая старение

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

Не зная размера ваших статических файлов, флэш-память с 2 МБ FS / или 1 МБ FS / проблема в том, что если вам не нужен OTA, вы всегда теряете место. Я создал свои личные схемы разделов, например, 2MB Spiffs/2MB flash/No OTA для проги.
Размер вашей памяти должен быть следующим: размер программы + размер переменной (видимый в среде IDE) + размер самых больших (статических) файлов * 1,2 (запас прочности) должен заполнять «память приложения» примерно на 80%.
В качестве примера вашего использования на данный момент выглядит следующим образом:
На данный момент у вас есть максимум 400 КБ для приложения И обслуживания (статических) файлов. Вы используете

  • 3 МБ для файловой системы SPIFFS,
  • 512 для ОТА,
  • минимум 100 КБ для уровня отладки

=> как он может сохранить/загрузить, например, файл размером 300 КБ во флэш-память?
Ваш код ошибки 28 обычно связан с проблемами нехватки памяти, вторая строка сообщения об ошибке указывает на то, что что-то должно быть загружено в память и не может, мы исключили все другие причины, поэтому ...

,

Это именно то, что у меня есть. Я знаю, что файлы есть и доступны для чтения, потому что чтение файлов по отдельности из SPIFFS работает. См. мое редактирование выше., @Alexander Richter

Я только что изменил свой код, чтобы определить файл отдельно, но ошибка все еще существует :(, @Alexander Richter

Это хороший совет, я рассмотрю возможность его настройки перед развертыванием. Однако мои статические файлы (все внутри каталога данных) в настоящее время имеют размер 1,4 МБ. Это должно быть совместимо с моими текущими настройками IDE, верно?, @Alexander Richter

Нет, это не так - на данный момент у вас есть максимум 400 КБ для приложения И обслуживания статических файлов (вы используете 3 МБ для файловой системы SPIFFS, 512 для OTA, минимум 100 КБ для вашего уровня отладки) - как он может хранить/загружать, например, файл размером 300 КБ в prgmem - ваша строка сообщения об ошибке вторая указывает на то, что что-то должно быть загружено в prgmem и не может Мы исключили все другие причины, поэтому ..., @Codebreaker007

Но если это было проблемой, почему обработка статического файла читается не через `server.serveStatic()`, а через `server.on(...)` с пользовательской функцией-обработчиком, которая передает файл над работает? См. мое второе редактирование для справки., @Alexander Richter

Кроме того, не могли бы вы предоставить мне ссылку на ресурс, который показывает мне, как удалить пространство раздела OTA? Я просто некоторое время гуглил, и я не могу найти ничего полезного..., @Alexander Richter

Это был бы новый вопрос, @Codebreaker007