mirror of
https://github.com/thelsing/knx.git
synced 2025-06-17 01:17:18 +02:00
Handling buffer overrun (#184)
This commit is contained in:
parent
1f079147c0
commit
f4d7f604be
@ -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;
|
{
|
||||||
_lastByteRxTime = millis();
|
_platform.readUart();
|
||||||
rxByte = _platform.readUart();
|
_lastByteRxTime = millis();
|
||||||
#ifdef DBG_TRACE
|
}
|
||||||
print(rxByte, HEX);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user