0

我们正在使用 Azure IoT Hub 实施 IoT 遥测解决方案。通过使用此处的项目,我们能够在ESP8266上实现成功的基本解决方案。然而,我们希望 ESP 也可以作为本地 WiFi 网络上的 Web 服务器工作,主要用于初始配置目的。

如果我们将这一行添加到上述项目中:

#include <ESP8266WebServer.h>    
ESP8266WebServer server(80);

项目编译,但我们不断在 ESP 上获得“核心转储”,并且设备停止工作。

致命异常 29(StoreProhibitedCause):epc1=0x4000e1b2,epc2=0x00000000,epc3=0x00000000,excvaddr=0x00000004,depc=0x00000000

异常 (29): epc1=0x4000e1b2 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000004 depc=0x00000000

ctx: cont sp: 3fff4700 软 WDT 复位

ctx:续 sp:3fff4460 结束:3fff4ce0 偏移量:01b0

stack>>> 3fff4610: 40001da0 00000078 00000000 00000010 3fff4620: 40001f46 0000000d 66089700 263a390c 3fff4630: 66666633 30303734 88fd4100 5da4cdaf 3fff4640: 2395829e 2c6ea747 4f2f4c52 72696e6d
3fff4650: 00000000 2e353230 306c7263 5503061d 3fff4660: 00000000 3fff4740 3fff4740 3fffa878 3fff4670: 00000000 3fff46e0 3fff46e0 3ffec9ba 3fff4680: 40002514 3fffdd3c 3fff4ce0 3fff4700 3fff4690:00000000 00000008 00000008 00000001 3fff46a0:00000000 3fff4700 00000000 3fff4638

¿ 有没有人遇到过这个问题并找到解决方法?

4

2 回答 2

2

我有几乎相同的设置(使用 ESP8266 托管 WiFiServer 并定期通过 Azure IoT Hub 发送消息),对我来说解决问题的是非常仔细的内存管理。您的堆栈跟踪甚至与我的匹配(epc1 和 excvaddr 相同)。

我最小化了对 malloc/free 的调用,以防止我的堆碎片化,这解决了我的目的。我认为这只是芯片内存要处理的沉重负担。

于 2017-07-21T16:46:55.693 回答
1

我认为这个这个问题值得关注。两位作者都在使用带有 WiFiClientSecure 的 ESP8266WebServer,并且遇到了同样的问题。@Jeroen88在这里指出了一个可能的解决方案。

让我引用:

每次我使用 ESP8266HTTPClient 从安全站点获取数据时,内存都会泄漏(大约 24 个字节,具体取决于主机名大小)。

将问题深入到 SSLContext::connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms)。在这个函数中,内存是使用函数 ssl_ext_set_host_name(ext, hostName) 分配的;然而,在我看来,这种记忆从未被释放。

在连接函数结束之前添加: ssl_ext_set_host_name(ext, nullptr); 现在没有更多的内存泄漏。

功能齐全:

void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms)
{
    SSL_EXTENSIONS* ext = ssl_ext_new();
    ssl_ext_set_host_name(ext, hostName);
    ssl_ext_set_max_fragment_size(ext, 4096);
    if (_ssl) {
        /* Creating a new TLS session on top of a new TCP connection.
           ssl_free will want to send a close notify alert, but the old TCP connection
           is already gone at this point, so reset s_io_ctx. */
        s_io_ctx = nullptr;
        ssl_free(_ssl);
        _available = 0;
        _read_ptr = nullptr;
    }
    s_io_ctx = ctx;
    _ssl = ssl_client_new(_ssl_ctx, 0, nullptr, 0, ext);
    uint32_t t = millis();

    while (millis() - t < timeout_ms && ssl_handshake_status(_ssl) != SSL_OK) {
        uint8_t* data;
        int rc = ssl_read(_ssl, &data);
        if (rc < SSL_OK) {
            break;
        }
    }
    ssl_ext_set_host_name(ext, nullptr); // THIS FUNCTION FREEs the host_name
}
于 2017-07-25T14:59:46.307 回答