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)
{
const bool success = ((byte ^ L_DATA_CON_MASK) >> 7);
uint8_t *cemiData = _txFrame->cemiData();
CemiFrame cemiFrame(cemiData, _txFrame->cemiSize());
dataConReceived(cemiFrame, success);
free(cemiData);
delete _txFrame;
_txFrame = nullptr;
_txState = TX_IDLE;
processTxFrameComplete(success);
}
else
{
@ -436,7 +430,7 @@ void TpUartDataLinkLayer::processRxFrameByte(uint8_t byte)
if (availableInRxQueue() < (_rxFrame->size() + 3))
{
// 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);
}
@ -529,6 +523,30 @@ void TpUartDataLinkLayer::processRxFrameComplete()
_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.
*/
@ -545,6 +563,14 @@ void TpUartDataLinkLayer::pushTxFrameQueue(TpFrame *tpFrame)
_txFrameQueue.back->next = entry;
_txFrameQueue.back = entry;
}
if (_txQueueCount > 10)
{
print("_txQueueCount:");
print(_txQueueCount);
}
_txQueueCount++;
_txFrameCounter++;
}
void TpUartDataLinkLayer::setRepetitions(uint8_t nack, uint8_t busy)
@ -685,17 +711,15 @@ bool TpUartDataLinkLayer::reset()
_rxInvalidFrameCounter = 0;
_rxInvalidFrameCounter = 0;
_rxUnkownControlCounter = 0;
if (_txFrame != nullptr)
{
_txFrame = nullptr;
delete _txFrame;
}
clearTxFrame();
clearTxFrameQueue();
if (_rxFrame != nullptr)
{
_rxFrame->reset();
}
_rxState = RX_IDLE;
_txState = TX_IDLE;
_connected = false;
_stopped = false;
_monitoring = false;
@ -786,6 +810,17 @@ bool TpUartDataLinkLayer::enabled() const
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.
* 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()
{
// Diese Abfrage ist vorsorglich. Eigentlich sollte auch schon parallel gestartet werden können.
if (_rxState != RX_IDLE)
return;
if (_txState != TX_IDLE)
return;
@ -810,9 +841,9 @@ void TpUartDataLinkLayer::processTxQueue()
_txFrameQueue.back = nullptr;
}
// free old frame
if (_txFrame != nullptr)
delete _txFrame;
_txQueueCount--;
clearTxFrame();
// use frame from queue and delete queue entry
_txFrame = entry->frame;
@ -892,6 +923,7 @@ void TpUartDataLinkLayer::loop()
#endif
requestState();
clearOutdatedTxFrame();
processTxQueue();
checkConnected();
}
@ -1015,6 +1047,21 @@ uint32_t TpUartDataLinkLayer::getRxUnknownControlCounter()
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()
{
return _connected;

View File

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