fixes some problems with txqueue

This commit is contained in:
Marco Scholl 2024-04-08 21:21:30 +02:00
parent e65afebd3a
commit 1754e5387b
No known key found for this signature in database
2 changed files with 77 additions and 22 deletions

View File

@ -306,13 +306,7 @@ void TpUartDataLinkLayer::processRxByte()
if (_txState == TX_FRAME) if (_txState == TX_FRAME)
{ {
const bool success = ((byte ^ L_DATA_CON_MASK) >> 7); const bool success = ((byte ^ L_DATA_CON_MASK) >> 7);
uint8_t *cemiData = _txFrame->cemiData(); processTxFrameComplete(success);
CemiFrame cemiFrame(cemiData, _txFrame->cemiSize());
dataConReceived(cemiFrame, success);
free(cemiData);
delete _txFrame;
_txFrame = nullptr;
_txState = TX_IDLE;
} }
else else
{ {
@ -436,7 +430,7 @@ void TpUartDataLinkLayer::processRxFrameByte(uint8_t byte)
if (availableInRxQueue() < (_rxFrame->size() + 3)) if (availableInRxQueue() < (_rxFrame->size() + 3))
{ {
// Nur wenn ich nicht selber sende // Nur wenn ich nicht selber sende
if (_txState == RX_IDLE) if (_txState == TX_IDLE)
{ {
_platform.writeUart(U_ACK_REQ | U_ACK_REQ_ADRESSED | U_ACK_REQ_BUSY); _platform.writeUart(U_ACK_REQ | U_ACK_REQ_ADRESSED | U_ACK_REQ_BUSY);
} }
@ -529,6 +523,30 @@ void TpUartDataLinkLayer::processRxFrameComplete()
_rxFrame->reset(); _rxFrame->reset();
} }
void TpUartDataLinkLayer::clearTxFrame()
{
if (_txFrame != nullptr)
{
delete _txFrame;
_txFrame = nullptr;
}
}
void TpUartDataLinkLayer::clearTxFrameQueue()
{
}
void TpUartDataLinkLayer::processTxFrameComplete(bool success)
{
uint8_t *cemiData = _txFrame->cemiData();
CemiFrame cemiFrame(cemiData, _txFrame->cemiSize());
dataConReceived(cemiFrame, success);
free(cemiData);
clearTxFrame();
_txProcessdFrameCounter++;
_txState = TX_IDLE;
}
/* /*
* Steckt das zu sendende Frame in eine Queue, da der TpUart vielleicht gerade noch nicht sende bereit ist. * Steckt das zu sendende Frame in eine Queue, da der TpUart vielleicht gerade noch nicht sende bereit ist.
*/ */
@ -545,6 +563,14 @@ void TpUartDataLinkLayer::pushTxFrameQueue(TpFrame *tpFrame)
_txFrameQueue.back->next = entry; _txFrameQueue.back->next = entry;
_txFrameQueue.back = entry; _txFrameQueue.back = entry;
} }
if (_txQueueCount > 10)
{
print("_txQueueCount:");
print(_txQueueCount);
}
_txQueueCount++;
_txFrameCounter++;
} }
void TpUartDataLinkLayer::setRepetitions(uint8_t nack, uint8_t busy) void TpUartDataLinkLayer::setRepetitions(uint8_t nack, uint8_t busy)
@ -685,17 +711,15 @@ bool TpUartDataLinkLayer::reset()
_rxInvalidFrameCounter = 0; _rxInvalidFrameCounter = 0;
_rxInvalidFrameCounter = 0; _rxInvalidFrameCounter = 0;
_rxUnkownControlCounter = 0; _rxUnkownControlCounter = 0;
if (_txFrame != nullptr)
{ clearTxFrame();
_txFrame = nullptr; clearTxFrameQueue();
delete _txFrame;
}
if (_rxFrame != nullptr) if (_rxFrame != nullptr)
{ {
_rxFrame->reset(); _rxFrame->reset();
} }
_rxState = RX_IDLE; _rxState = RX_IDLE;
_txState = TX_IDLE;
_connected = false; _connected = false;
_stopped = false; _stopped = false;
_monitoring = false; _monitoring = false;
@ -786,6 +810,17 @@ bool TpUartDataLinkLayer::enabled() const
return _initialized && _connected; return _initialized && _connected;
} }
/*
* Wenn ein TxFrame gesendet wurde, wird eine Bestätigung für den Versand erwartet.
* Kam es aber zu einem ungültigen Frame oder Busdisconnect, bleibt die Bestätigung aus und der STack hängt im TX_FRAME fest.
* Daher muss nach einer kurzen Wartezeit das Warten beendet werden.
*/
void TpUartDataLinkLayer::clearOutdatedTxFrame()
{
if (_txState == TX_FRAME && (millis() - _txLastTime) > 1000)
processTxFrameComplete(false);
}
/* /*
* Hier werden die ausgehenden Frames aus der Warteschlange genomnmen und versendet. * Hier werden die ausgehenden Frames aus der Warteschlange genomnmen und versendet.
* Das passiert immer nur einzelnd, da nach jedem Frame, gewartet werden muss bis das Frame wieder reingekommen ist und das L_DATA_CON rein kommt. * Das passiert immer nur einzelnd, da nach jedem Frame, gewartet werden muss bis das Frame wieder reingekommen ist und das L_DATA_CON rein kommt.
@ -793,10 +828,6 @@ bool TpUartDataLinkLayer::enabled() const
*/ */
void TpUartDataLinkLayer::processTxQueue() void TpUartDataLinkLayer::processTxQueue()
{ {
// Diese Abfrage ist vorsorglich. Eigentlich sollte auch schon parallel gestartet werden können.
if (_rxState != RX_IDLE)
return;
if (_txState != TX_IDLE) if (_txState != TX_IDLE)
return; return;
@ -810,9 +841,9 @@ void TpUartDataLinkLayer::processTxQueue()
_txFrameQueue.back = nullptr; _txFrameQueue.back = nullptr;
} }
// free old frame _txQueueCount--;
if (_txFrame != nullptr)
delete _txFrame; clearTxFrame();
// use frame from queue and delete queue entry // use frame from queue and delete queue entry
_txFrame = entry->frame; _txFrame = entry->frame;
@ -892,6 +923,7 @@ void TpUartDataLinkLayer::loop()
#endif #endif
requestState(); requestState();
clearOutdatedTxFrame();
processTxQueue(); processTxQueue();
checkConnected(); checkConnected();
} }
@ -1015,6 +1047,21 @@ uint32_t TpUartDataLinkLayer::getRxUnknownControlCounter()
return _rxUnkownControlCounter; return _rxUnkownControlCounter;
} }
/*
* Liefert die Anzahl der zusendenden Frames
*/
uint32_t TpUartDataLinkLayer::getTxFrameCounter()
{
return _txFrameCounter;
}
/*
* Liefert die Anzahl der versendeten Frames
*/
uint32_t TpUartDataLinkLayer::getTxProcessedFrameCounter()
{
return _txProcessdFrameCounter;
}
bool TpUartDataLinkLayer::isConnected() bool TpUartDataLinkLayer::isConnected()
{ {
return _connected; return _connected;

View File

@ -64,6 +64,8 @@ class TpUartDataLinkLayer : public DataLinkLayer
uint32_t getRxProcessdFrameCounter(); uint32_t getRxProcessdFrameCounter();
uint32_t getRxIgnoredFrameCounter(); uint32_t getRxIgnoredFrameCounter();
uint32_t getRxUnknownControlCounter(); uint32_t getRxUnknownControlCounter();
uint32_t getTxFrameCounter();
uint32_t getTxProcessedFrameCounter();
uint8_t getMode(); uint8_t getMode();
private: private:
@ -95,19 +97,21 @@ class TpUartDataLinkLayer : public DataLinkLayer
volatile bool _busy = false; volatile bool _busy = false;
volatile bool _initialized = false; volatile bool _initialized = false;
volatile uint32_t _stateTime = 0;
volatile uint8_t _rxState = 0; volatile uint8_t _rxState = 0;
volatile uint8_t _txState = 0; volatile uint8_t _txState = 0;
volatile uint32_t _rxProcessdFrameCounter = 0; volatile uint32_t _rxProcessdFrameCounter = 0;
volatile uint32_t _rxInvalidFrameCounter = 0; volatile uint32_t _rxInvalidFrameCounter = 0;
volatile uint32_t _rxIgnoredFrameCounter = 0; volatile uint32_t _rxIgnoredFrameCounter = 0;
volatile uint32_t _rxUnkownControlCounter = 0; volatile uint32_t _rxUnkownControlCounter = 0;
volatile uint32_t _txFrameCounter = 0;
volatile uint32_t _txProcessdFrameCounter = 0;
volatile bool _rxMarker = false; volatile bool _rxMarker = false;
volatile bool _rxOverflow = false; volatile bool _rxOverflow = false;
volatile uint8_t _tpState = 0x0; volatile uint8_t _tpState = 0x0;
volatile uint32_t _txLastTime = 0; volatile uint32_t _txLastTime = 0;
volatile uint32_t _rxLastTime = 0; volatile uint32_t _rxLastTime = 0;
volatile bool _forceAck = false; volatile bool _forceAck = false;
uint8_t _txQueueCount = 0;
inline bool markerMode(); inline bool markerMode();
@ -134,6 +138,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
void checkConnected(); void checkConnected();
void processRxByte(); void processRxByte();
void processTxQueue(); void processTxQueue();
void clearTxFrameQueue();
void processRxFrameComplete(); void processRxFrameComplete();
inline void processRxFrame(TpFrame* tpFrame); inline void processRxFrame(TpFrame* tpFrame);
void pushTxFrameQueue(TpFrame* tpFrame); void pushTxFrameQueue(TpFrame* tpFrame);
@ -159,6 +164,9 @@ class TpUartDataLinkLayer : public DataLinkLayer
inline void isrUnlock(); inline void isrUnlock();
inline void clearUartBuffer(); inline void clearUartBuffer();
inline void connected(bool state = true); inline void connected(bool state = true);
void clearTxFrame();
void clearOutdatedTxFrame();
void processTxFrameComplete(bool success);
ITpUartCallBacks& _cb; ITpUartCallBacks& _cb;
DataLinkLayerCallbacks* _dllcb; DataLinkLayerCallbacks* _dllcb;