Handling buffer overrun (#184)

This commit is contained in:
mptei 2022-02-26 22:41:23 +01:00 committed by GitHub
parent 1f079147c0
commit f4d7f604be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 11 deletions

View File

@ -103,10 +103,23 @@ enum {
#define RESET_TIMEOUT 100 //milli seconds #define RESET_TIMEOUT 100 //milli seconds
#define TX_TIMEPAUSE 0 // 0 means 1 milli seconds #define TX_TIMEPAUSE 0 // 0 means 1 milli seconds
#define OVERRUN_COUNT 7 //bytes; max. allowed bytes in receive buffer (on start) to see it as overrun
// If this threshold is reached loop() goes into // If this threshold is reached loop() goes into
// "hog mode" where it stays in loop() while L2 address reception // "hog mode" where it stays in loop() while L2 address reception
#define HOGMODE_THRESHOLD 3 // milli seconds #define HOGMODE_THRESHOLD 3 // milli seconds
void TpUartDataLinkLayer::enterRxWaitEOP()
{
// Flush input
while (_platform.uartAvailable())
{
_platform.readUart();
}
_lastByteRxTime = millis();
_rxState = RX_WAIT_EOP;
}
void TpUartDataLinkLayer::loop() void TpUartDataLinkLayer::loop()
{ {
if (!_enabled) if (!_enabled)
@ -153,6 +166,12 @@ void TpUartDataLinkLayer::loop()
case RX_WAIT_START: case RX_WAIT_START:
if (_platform.uartAvailable()) if (_platform.uartAvailable())
{ {
if (_platform.uartAvailable() > OVERRUN_COUNT)
{
print("input buffer overrun: "); println(_platform.uartAvailable());
enterRxWaitEOP();
break;
}
rxByte = _platform.readUart(); rxByte = _platform.readUart();
#ifdef DBG_TRACE #ifdef DBG_TRACE
print(rxByte, HEX); print(rxByte, HEX);
@ -261,7 +280,7 @@ void TpUartDataLinkLayer::loop()
if (millis() - _lastByteRxTime > EOPR_TIMEOUT) if (millis() - _lastByteRxTime > EOPR_TIMEOUT)
{ {
_rxState = RX_WAIT_START; _rxState = RX_WAIT_START;
println("EOPR inside RX_L_ADDR"); println("EOPR @ RX_L_ADDR");
break; break;
} }
if (!_platform.uartAvailable()) if (!_platform.uartAvailable())
@ -328,8 +347,8 @@ void TpUartDataLinkLayer::loop()
#endif #endif
if (_RxByteCnt == MAX_KNX_TELEGRAM_SIZE) if (_RxByteCnt == MAX_KNX_TELEGRAM_SIZE)
{ {
_rxState = RX_WAIT_EOP;
println("invalid telegram size"); println("invalid telegram size");
enterRxWaitEOP();
} }
else else
{ {
@ -358,7 +377,18 @@ void TpUartDataLinkLayer::loop()
{ {
_receiveBuffer[0] = 0x29; _receiveBuffer[0] = 0x29;
_receiveBuffer[1] = 0; _receiveBuffer[1] = 0;
#ifdef DBG_TRACE
unsigned long runTime = millis();
#endif
frameBytesReceived(_receiveBuffer, _RxByteCnt + 2); frameBytesReceived(_receiveBuffer, _RxByteCnt + 2);
#ifdef DBG_TRACE
runTime = millis() - runTime;
if (runTime > (OVERRUN_COUNT*14)/10)
{
// complain when the runtime was long than the OVERRUN_COUNT allows
print("processing received frame took: "); print(runTime); println(" ms");
}
#endif
} }
_rxState = RX_WAIT_START; _rxState = RX_WAIT_START;
#ifdef DBG_TRACE #ifdef DBG_TRACE
@ -368,7 +398,7 @@ void TpUartDataLinkLayer::loop()
else else
{ {
println("frame with invalid crc ignored"); println("frame with invalid crc ignored");
_rxState = RX_WAIT_EOP; enterRxWaitEOP();
} }
} }
else else
@ -379,20 +409,18 @@ void TpUartDataLinkLayer::loop()
case RX_WAIT_EOP: case RX_WAIT_EOP:
if (millis() - _lastByteRxTime > EOP_TIMEOUT) if (millis() - _lastByteRxTime > EOP_TIMEOUT)
{ {
_RxByteCnt = 0; // found a gap
_rxState = RX_WAIT_START; _rxState = RX_WAIT_START;
#ifdef DBG_TRACE #ifdef DBG_TRACE
println("RX_WAIT_START"); println("RX_WAIT_START");
#endif #endif
break; break;
} }
if (!_platform.uartAvailable()) if (_platform.uartAvailable())
break; {
_platform.readUart();
_lastByteRxTime = millis(); _lastByteRxTime = millis();
rxByte = _platform.readUart(); }
#ifdef DBG_TRACE
print(rxByte, HEX);
#endif
break; break;
default: default:
break; break;

View File

@ -68,6 +68,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
bool sendFrame(CemiFrame& frame); bool sendFrame(CemiFrame& frame);
void frameBytesReceived(uint8_t* buffer, uint16_t length); void frameBytesReceived(uint8_t* buffer, uint16_t length);
void dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success); void dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success);
void enterRxWaitEOP();
bool resetChip(); bool resetChip();
void stopChip(); void stopChip();