Add Serial buffer overrun detection

Add Serial buffer overrun detection and fix serial corruption by increasing uart serial buffer to 520
This commit is contained in:
Theo Arends 2020-05-11 15:27:29 +02:00
parent 24e72ad1cb
commit 125ee62ff3
4 changed files with 37 additions and 7 deletions

View File

@ -1227,6 +1227,17 @@ void SerialInput(void)
delay(0);
serial_in_byte = Serial.read();
if (0 == serial_in_byte_counter) {
serial_buffer_overrun = false;
}
else if ((serial_in_byte_counter == INPUT_BUFFER_SIZE)
#ifdef ESP8266
// || Serial.hasOverrun() // Default ESP8266 Serial buffer size is 256. Tasmota increases to INPUT_BUFFER_SIZE
#endif
) {
serial_buffer_overrun = true;
}
#ifdef ESP8266
/*-------------------------------------------------------------------------------------------*\
* Sonoff dual and ch4 19200 baud serial interface
@ -1255,7 +1266,7 @@ void SerialInput(void)
if (serial_in_byte_counter < INPUT_BUFFER_SIZE -1) { // Add char to string if it still fits
serial_in_buffer[serial_in_byte_counter++] = serial_in_byte;
} else {
serial_in_byte_counter = 0;
serial_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
}
}
} else {
@ -1292,8 +1303,12 @@ void SerialInput(void)
if (!Settings.flag.mqtt_serial && (serial_in_byte == '\n')) { // CMND_SERIALSEND and CMND_SERIALLOG
serial_in_buffer[serial_in_byte_counter] = 0; // Serial data completed
seriallog_level = (Settings.seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings.seriallog_level;
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), serial_in_buffer);
ExecuteCommand(serial_in_buffer, SRC_SERIAL);
if (serial_buffer_overrun) {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Serial buffer overrun"));
} else {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), serial_in_buffer);
ExecuteCommand(serial_in_buffer, SRC_SERIAL);
}
serial_in_byte_counter = 0;
serial_polling_window = 0;
Serial.flush();

View File

@ -124,7 +124,7 @@ const uint16_t SYSLOG_TIMER = 600; // Seconds to restore syslog_level
const uint16_t SERIALLOG_TIMER = 600; // Seconds to disable SerialLog
const uint8_t OTA_ATTEMPTS = 5; // Number of times to try fetching the new firmware
const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in (serial and http) command buffer
const uint16_t INPUT_BUFFER_SIZE = 520; // Max number of characters in serial command buffer
const uint16_t FLOATSZ = 16; // Max number of characters in float result from dtostrfd (max 32)
const uint16_t CMDSZ = 24; // Max number of characters in command
const uint16_t TOPSZ = 151; // Max number of characters in topic string

View File

@ -156,7 +156,8 @@ uint8_t last_source = 0; // Last command source
uint8_t shutters_present = 0; // Number of actual define shutters
uint8_t prepped_loglevel = 0; // Delayed log level message
//uint8_t mdns_delayed_start = 0; // mDNS delayed start
bool serial_local = false; // Handle serial locally;
bool serial_local = false; // Handle serial locally
bool serial_buffer_overrun = false; // Serial buffer overrun
bool fallback_topic_flag = false; // Use Topic or FallbackTopic
bool backlog_mutex = false; // Command backlog pending
bool interlock_mutex = false; // Interlock power command pending
@ -215,6 +216,7 @@ void setup(void)
RtcRebootSave();
Serial.begin(APP_BAUDRATE);
Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded
snprintf_P(my_version, sizeof(my_version), PSTR("%d.%d.%d"), VERSION >> 24 & 0xff, VERSION >> 16 & 0xff, VERSION >> 8 & 0xff); // Release version 6.3.0

View File

@ -59,13 +59,14 @@
#define D_CMND_I2CREAD "I2CRead"
#define D_CMND_I2CSTRETCH "I2CStretch"
#define D_CMND_I2CCLOCK "I2CClock"
#define D_CMND_SERBUFF "SerBufSize"
const char kDebugCommands[] PROGMEM = "|" // No prefix
D_CMND_CFGDUMP "|" D_CMND_CFGPEEK "|" D_CMND_CFGPOKE "|"
#ifdef USE_WEBSERVER
D_CMND_CFGXOR "|"
#endif
D_CMND_CPUCHECK "|"
D_CMND_CPUCHECK "|" D_CMND_SERBUFF "|"
#ifdef DEBUG_THEO
D_CMND_EXCEPTION "|"
#endif
@ -80,7 +81,7 @@ void (* const DebugCommand[])(void) PROGMEM = {
#ifdef USE_WEBSERVER
&CmndCfgXor,
#endif
&CmndCpuCheck,
&CmndCpuCheck, &CmndSerBufSize,
#ifdef DEBUG_THEO
&CmndException,
#endif
@ -479,6 +480,18 @@ void CmndCpuCheck(void)
ResponseCmndNumber(CPU_load_check);
}
void CmndSerBufSize(void)
{
if (XdrvMailbox.data_len > 0) {
Serial.setRxBufferSize(XdrvMailbox.payload);
}
#ifdef ESP8266
ResponseCmndNumber(Serial.getRxBufferSize());
#else
ResponseCmndDone();
#endif
}
void CmndFreemem(void)
{
if (XdrvMailbox.data_len > 0) {