我的 ESP32-S2 在发送大型 Websocket 时有时会(看似随机?)崩溃。
串口输出的崩溃日志:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x40087297 PS : 0x00060830 A0 : 0x80087bc9 A1 : 0x3ffd2560
A2 : 0x3ffc655c A3 : 0x3ffe3610 A4 : 0x3ffcbd54 A5 : 0x3ffc65d8
A6 : 0x3f4c0058 A7 : 0x00000001 A8 : 0xa941d536 A9 : 0x3ffd2540
A10 : 0x3ffe3610 A11 : 0x3ffe3610 A12 : 0x3ffe35f0 A13 : 0x00000000
A14 : 0x3ffcd288 A15 : 0x3ffcd23c SAR : 0x00000013 EXCCAUSE: 0x0000001c
EXCVADDR: 0xa941d542 LBEG : 0x3ffe35f0 LEND : 0x00000000 LCOUNT : 0x40028358
Backtrace:0x40087294:0x3ffd25600x40087bc6:0x3ffd2590 0x40087bdf:0x3ffd25b0 0x40087bed:0x3ffd25d0 0x40083d30:0x3ffd25f0 0x40083d4f:0x3ffd2610 0x401015dd:0x3ffd2630 0x4008dc95:0x3ffd2650 0x40083366:0x3ffd2670 0x400918a1:0x3ffd2690
#0 0x40087294:0x3ffd2560 in AsyncWebSocket::_cleanBuffers() at .pio/libdeps/esp32-s2-saola-1/ESP Async WebServer/src/AsyncWebSocket.cpp:1224 (discriminator 3)
#1 0x40087bc6:0x3ffd2590 in AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer*) at .pio/libdeps/esp32-s2-saola-1/ESP Async WebServer/src/AsyncWebSocket.cpp:986
#2 0x40087bdf:0x3ffd25b0 in AsyncWebSocket::binaryAll(char const*, unsigned int) at .pio/libdeps/esp32-s2-saola-1/ESP Async WebServer/src/AsyncWebSocket.cpp:974
#3 0x40087bed:0x3ffd25d0 in AsyncWebSocket::binaryAll(unsigned char*, unsigned int) at .pio/libdeps/esp32-s2-saola-1/ESP Async WebServer/src/AsyncWebSocket.cpp:1133
#4 0x40083d30:0x3ffd25f0 in sendMeasurements_Bin() at src/websockets.cpp:71
#5 0x40083d4f:0x3ffd2610 in captureMeasurements() at src/websockets.cpp:49
#6 0x401015dd:0x3ffd2630 in std::_Function_handler<void (), void (*)()>::_M_invoke(std::_Any_data const&) at c:\users\vojta\.platformio\packages\toolchain-xtensa-esp32s2\xtensa-esp32s2-elf\include\c++\8.4.0\bits/std_function.h:297
#7 0x4008dc95:0x3ffd2650 in std::function<void ()>::operator()() const at c:\users\vojta\.platformio\packages\toolchain-xtensa-esp32s2\xtensa-esp32s2-elf\include\c++\8.4.0\bits/std_function.h:687
(inlined by) Ticker::update() at .pio/libdeps/esp32-s2-saola-1/Ticker/Ticker.cpp:72
#8 0x40083366:0x3ffd2670 in loop() at src/main.cpp:134
#9 0x400918a1:0x3ffd2690 in loopTask(void*) at C:/Users/vojta/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:50
ELF file SHA256: 0000000000000000
定期发送websocket的函数:
void sendMeasurements_Bin(){
Serial.print("sending----");
ws.binaryAll((uint8_t*)buffer, sizeof(buffer));
Serial.println("sent");
return ;
}
其中
buffer
是结构体数组:
struct __attribute__((packed)) Measurement {
int16_t current_L;
int16_t current_R;
int16_t current_Total;
int16_t setpoint;
int16_t error;
uint32_t encoder_L;
uint32_t encoder_R;
uint32_t timestamp; // Store the time when the measurement was taken
};
const int BUFFER_SIZE = 100;
Measurement buffer[BUFFER_SIZE];
您知道是什么原因导致此问题吗?我的猜测是它与内存相关,但这对我来说没有意义,因为没有分配新的内存,缓冲区仅初始化一次,然后重写并发送。
我尝试在每次发送数据时打印出可用堆大小,使用:
Serial.print(esp_get_free_heap_size());
空闲堆大小变化不大,这是预期的。
正如官方文档中给出的,大多数情况下,当应用程序尝试读取或写入无效的内存位置时,会发生LoadProhibited。因为我怀疑
sendMeasurements_Bin
函数会抛出错误。所以只需将缓冲区指针传递给sendMeasurements_Bin
功能并尝试使用它。