首页 > 解决方案 > MacOS High Sierra Arduino Mac 1.8.5 上的 PROGMEM 错误

问题描述

我正在使用在 MacOS High Sierra 上运行的 MacBook Pro。

每当我尝试上传包含 PROGMEM 的 Arduino 代码以将原始 HTML 字符串(Arduino Mac 1.8.5)存储到我的 ESP 板时,就会出现问题。我使用的开发板是 ESP8266 LoLin V3。

每当我在 Web 浏览器上访问 ESP 的 IP 地址时,串行监视器中就会引发异常 (3) 。我还尝试使用适用于 Windows 的Arduino 的Windows 版本(1.8.5)上传相同的确切代码,并且网页可以完美显示。

代码:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char *ssid = "ssid";
const char *password = "password";

ESP8266WebServer server ( 80 );

const char homepage[] PROGMEM = R"(
  <!DOCTYPE html>
  <html>
  <body>
  <h1>Mac can't compile PROGMEM properly!</h1>
  <h3>try to upload this code to any ESP8266 on a Mac and see the error!</h3>
  <h3>Exception (3)
  LoadStoreErrorCause
  Processor internal physical address or data error during load or store!</h3>
  <h3>Windows can easily compile this and read the file perfectly on ESP8266!</h3>
  </body>
  </html>
)";

void handleRoot() {
  String page = homepage;
  server.send(200, "text/html", page); //Send web page
}

void setup ( void ) {
    Serial.begin ( 115200 );
    WiFi.mode ( WIFI_STA );
    WiFi.begin ( ssid, password );
    Serial.println ( "" );
    // Wait for connection
    while ( WiFi.status() != WL_CONNECTED ) {
        delay ( 500 );
        Serial.print ( "." );
    }
    Serial.println ( "" );
    Serial.print ( "Connected to " );
    Serial.println ( ssid );
    Serial.print ( "IP address: " );
    Serial.println ( WiFi.localIP() );

    if ( MDNS.begin ( "esp8266" ) ) {
        Serial.println ( "MDNS responder started" );
    }
    server.on ( "/", handleRoot );
    server.begin();
    Serial.println ( "HTTP server started" );
}

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

引发的错误如下:

Exception (3):
epc1=0x40209d64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4023ad32 depc=0x00000000

ctx: cont
sp: 3ffefb20 end: 3ffefe10 offset: 01a0

>>>stack>>>
3ffefcc0:  3ffe8b02 3ffeea80 3ffefd00 40207729
3ffefcd0:  00000001 00000001 3ffefd00 40207776
3ffefce0:  4023ad32 3ffefd40 3ffefd40 402076ab
3ffefcf0:  3fff10d4 00000001 3fff1044 4020206e
3ffefd00:  3fff118c 0000018f 00000182 4010020c
3ffefd10:  00000001 00000001 3ffefd40 4020836e
3ffefd20:  00000000 00000000 3fff1044 40204406
3ffefd30:  3fff1044 3ffeea9c 3fff1044 40204442
3ffefd40:  00000000 00000000 00000000 40207858
3ffefd50:  3fff1044 3ffeea9c 3ffeea58 402044c9
3ffefd60:  3fff10d4 0000000f 00000001 00000000
3ffefd70:  00000000 00000013 3ffeea5c 40203058
3ffefd80:  3ffeea9c 00000001 3ffeedf0 3ffeea80
3ffefd90:  00000001 00000000 40203964 0000000a
3ffefda0:  00000000 3fff0e5c 3ffeea58 3ffeeddc
3ffefdb0:  00000001 3ffeea80 3ffeea58 402046c0
3ffefdc0:  40107058 00000000 00001388 40208364
3ffefdd0:  00000000 3fff0e5c 00000000 feefeffe
3ffefde0:  3fffdad0 00000000 3ffeedd4 402021d0
3ffefdf0:  3fffdad0 00000000 3ffeedd4 402080e4
3ffefe00:  feefeffe feefeffe 3ffeedf0 40100710
<<<stack<<<

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

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v614f7c32
~ld

这里的任何人都可以使用 Mac 尝试将代码上传到您的 ESP8266 上,看看您是否遇到与我相同的错误?任何对 PROGMEM 和 ESP8266 有深入了解的人都可以帮我解决这个问题吗?

标签: arduinoesp8266esp32progmem

解决方案


在您的程序中,您有

void handleRoot() {
  String page = homepage;
  server.send(200, "text/html", page); //Send web page
}

这应该是

void handleRoot() {
  String page = FPSTR(homepage);
  server.send(200, "text/html", page); //Send web page
}

添加FPSTR()它,它将正常工作。没有它,您的程序将无法正确取消引用您存储在 Flash 中的字符串。

您可以在https://arduino-esp8266.readthedocs.io/en/latest/PROGMEM.html找到更多相关信息


推荐阅读