Description
Describe the bug
Using ESP3D V3.0, I noticed that when a lot of serial data is generated during the startup of ESP3D then the board might lockup or restart.
I recently developed a motherboard bootloader that I put into test mode to see if everything works reliably.
During the test the bootloader repeatedly send some text like below to the ESP3D.
Bootloader started
Device mounted
Comparing firmware to flash contents.
======================================================== Equal
Firmware file and flash contents are equal, no update required
This message repeats about once a second. The ===... are send 1 character at a time like a progress bar.
I noticed that the ESP3D will not connect as a client to the wifi network if this serial data is send during its startup process. I also noticed that if I block the messages and let the ESP3D connect to the wifi network, that the serial messages are never shown on the web terminal.
Expected behavior
- Connect to the Wifi as AP even if serial data is incoming
- Show the serial data in the web terminal even if the data is send quite quickly
ESP3D Firmware:
- ESP3D FW version: 3.0.0-4b1.M2.1
- ESP3D-WebUI Version: 3.0.0.2b1
- Wifi mode: AP
- Flash method: build in PlatformIO, flashed OTA
Target Firmware:
- Name: Marlin
- Version 2.0
Board used (please complete the following information):
- MCU: ESP32-S2
- Name: Wemos ESP32-S2 mini V1.0.0
- Flash size: 4M + 2MB PSram
========================================================
I have a quick look into the code and found a potential issue in serial_service_esp32.cpp
void ESP3DSerialService::receiveCb() {
if (!started()) {
return;
}
if (xSemaphoreTake(_mutex, portMAX_DELAY)) {
uint32_t now = millis();
while ((millis() - now) < SERIAL_COMMUNICATION_TIMEOUT) {
if (Serials[_serialIndex]->available()) {
_buffer[_buffer_size] = Serials[_serialIndex]->read();
now = millis();
if (esp3d_string::isRealTimeCommand(_buffer[_buffer_size])) {
flushChar(_buffer[_buffer_size]);
_buffer[_buffer_size] = '\0'; //remove realtime command from buffer
} else {
_buffer_size++;
if (_buffer_size > ESP3D_SERIAL_BUFFER_SIZE ||
_buffer[_buffer_size - 1] == '\n') {
flushBuffer();
}
}
}
}
xSemaphoreGive(_mutex);
} else {
esp3d_log_e("Mutex not taken");
}
}
receiveCb() will never exit when serial data is send at a fast rate (faster than SERIAL_COMMUNICATION_TIMEOUT = 500 ms). I'm not sure if this will call a buffer overrun and cause the crash/restart that I'm seeing.
In normal 3D printer/CNC operation this can probably never happen.
Perhaps it's better to exit the while loop when the buffer is full (_buffer_size > ESP3D_SERIAL_BUFFER_SIZE).