ESP8266 перестает работать, когда я использую 2x static const char (PROGMEM)

*Версия SDK: 2.2.2-dev(5ab15d1) *Основная версия: 2_6_1

Возвращена следующая ошибка:

Exception 3: LoadStoreError: Processor internal physical address or data error during load or store PC: 0x4000bf64 EXCVADDR: 0x4024e963
Decoding stack results 
0x4020175d: HTML1(String) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/WString.h line 128 
0x40238c26: umm_info(void*, int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc/umm_info.c line 164 
0x40100278: millis() at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_wiring.cpp line 188 
0x40238c26: umm_info(void*, int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc/umm_info.c line 164 
0x4020af74: String::copy(char const*, unsigned int) at C:\Users\b.yuzo\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\WString.cpp line 214 
0x40201a3c: 

Код:

static const char HTML1[] PROGMEM = R"=====(
<!DOCTYPE HTML><html><head>
<meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
)=====";

static const char HTML2[] PROGMEM = R"=====(
<button type='button' onclick='sendData(2)'>Test2</button>
)=====";

String html_return = HTML1;
html_return += "<button type='button' onclick='sendData(1)'>Test</button>";
Serial.println("Before Second Const Char");
html_return += HTML2; //<< ESP stops working here

, 👍0

Обсуждение

Если я удалю объявление static, оно не скомпилируется в локальной функции. Я пытался объявить HTML1[] и HTML2[] вне функции без объявления static, но ошибка та же., @Bruno Yuzo

У меня еще есть память, я использую только (42%) из 81Кбайт. Итак, я работаю без PROGMEM, и это работает следующим образом: Строка HTML2 = R"=====( <button type='button' onclick='sendData(2)'>Тест2</button> )=====";, @Bruno Yuzo


1 ответ


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

1

См. Руководство по PROGMEM на ESP8266 и Arduino IDE. .

Поскольку вы помещаете массив символов в PROGMEM, необходимо использовать специальные функции для его загрузки из флэш-памяти в ОЗУ; поэтому, чтобы загрузить его в объект String, необходимо использовать класс FlashHelper. Вы можете просто использовать макрос FPSTR(programmem_ptr).

#include <Arduino.h>

void setup() {
    Serial.begin(115200);
    Serial.println("\nStart firmware");

    static const char HTML1[] PROGMEM = R"=====(
    <!DOCTYPE HTML><html><head>
    <meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
    )=====";

    static const char HTML2[] PROGMEM = R"=====(
    <button type='button' onclick='sendData(2)'>Test2</button>
    )=====";

    String html_return = HTML1;
    html_return += "<button type='button' onclick='sendData(1)'>Test</button>";
    Serial.println("Before Second Const Char");
    //html_return += HTML2; //вылетает
    html_return += FPSTR(HTML2); //работает
    Serial.println("Result");
    Serial.println(html_return);
}

void loop() {

}

Выводы

Start firmware
Before Second Const Char
Result

        <!DOCTYPE HTML><html><head>
        <meta charset='utf-8' name='viewport' content='width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0'>
        <button type='button' onclick='sendData(1)'>Test</button>
        <button type='button' onclick='sendData(2)'>Test2</button>
,

Макрос FPSTR преобразует тип и, таким образом, заставляет использовать правильный оператор + для строки PROGMEM. Это то же самое, что и html_return += F("какой-то текст хранится в памяти программы");, @Juraj

Уважаемый Максимилиан, спасибо за подробный ответ, работает очень хорошо. Спас мою память ESP!, @Bruno Yuzo