small optimizes

This commit is contained in:
Marco Scholl 2024-04-04 20:51:45 +02:00
parent 9d7e29d705
commit 7b910eba59
No known key found for this signature in database
2 changed files with 28 additions and 30 deletions

View File

@ -67,7 +67,7 @@ class TpFrame
TpFrame(uint16_t maxSize = 263) TpFrame(uint16_t maxSize = 263)
: _maxSize(maxSize) : _maxSize(maxSize)
{ {
_data = new uint8_t[_maxSize]; _data = (uint8_t *)malloc(_maxSize);
_size = 0; _size = 0;
} }

View File

@ -123,13 +123,10 @@ enum
// In diesem Zustand werden alle Bytes als Bytes für ein Frame betrachtet. // In diesem Zustand werden alle Bytes als Bytes für ein Frame betrachtet.
RX_FRAME, RX_FRAME,
/* // In diesem Zustand werdem alle Bytes verworfen
* Dieser Zustand ist speziell und soll verhindern dass Framebytes als Steuerbytes betrachet werden.
* Das Ganze ist leider nötig, weil die verarbeitung nicht syncron verläuft und teilweise durch externe interrupt.
* Dadurch kann die 2,6ms ruhe nicht ermittelt werden um sicher zu sagen das ab jetzt alles wieder Steuercodes sind.
*/
RX_INVALID, RX_INVALID,
// Im Monitoring wird noch auf ein ACk gewartet
RX_AWAITING_ACK RX_AWAITING_ACK
}; };
@ -189,9 +186,9 @@ void TpUartDataLinkLayer::processRxByte()
return; return;
/* /*
* Wenn ich im RX_INVALID state bin * Wenn ich im RX_INVALID Modus bin
* und das letzte Byte vor mehr als 2ms verarbeitet wurde (also pause >2ms) * und das letzte Byte vor mehr als 2ms verarbeitet wurde (also pause >2ms)
* und keine weiteren Bytes vorliegen, * und keine weiteren Bytes in der Buffer vorliegen,
* dann kann ich den INVALID State verwerfen. * dann kann ich den INVALID State verwerfen.
*/ */
if (_rxState == RX_INVALID && (millis() - _rxLastTime) > 2 && !_platform.uartAvailable()) if (_rxState == RX_INVALID && (millis() - _rxLastTime) > 2 && !_platform.uartAvailable())
@ -208,10 +205,10 @@ void TpUartDataLinkLayer::processRxByte()
* Ab jetzt muss ich davon ausgehen, dass einen Übertragungsfehler gegeben hat und die aktuellen Bytes ungültig sind. * Ab jetzt muss ich davon ausgehen, dass einen Übertragungsfehler gegeben hat und die aktuellen Bytes ungültig sind.
* Gleiches gilt auch wenn ein HW Overflow erkannt wurde. * Gleiches gilt auch wenn ein HW Overflow erkannt wurde.
* *
* - Die Zeit des letzten Frames 3ms vorbei ist (kann aber nicht garantiert werden, wegen möglichem ISR & DMA. Hier sollte es das Problem aber nicht geben) * - Die Zeit des letzten Frames 3ms vorbei ist und keine Daten mehr im Buffer sind. (Wird übermir geprüft)
* - Wenn der Markermodus aktiv ist und ein U_FRAME_END_IND sauber erkannt wurde. (Wird hier geprüft) * - Wenn der Markermodus aktiv ist und ein U_FRAME_END_IND sauber erkannt wurde. (Wird hier geprüft)
* *
* Ansonsten macht dieser Abschnitt nichts und verwirrft die ungültigen Bytes * Ansonsten macht dieser Abschnitt nichts und verwirrft damit die ungültigen Bytes
*/ */
if (markerMode()) if (markerMode())
{ {
@ -252,12 +249,12 @@ void TpUartDataLinkLayer::processRxByte()
_rxState = RX_FRAME; _rxState = RX_FRAME;
/* /*
* Hier wird inital ein Ack ohne Addressed gesetzt. Das dient dazu falls noch ein Ack vom vorherigen Frame gesetzt wurde, * Hier wird inital ein Ack ohne Addressed gesetzt. Das dient dazu, falls noch ein Ack vom vorherigen Frame gesetzt ist,
* welches aber ggf nicht rechtzeitig verarbeitet (also nach der Übertragung gesendet wurde) sich nicht auf das neue Frame auswirkt. * zurück gesetzt wird. Das passiert wenn die Verarbeitung zu stark verzögert ist (z.B. weil kein DMA/IRQ genutzt wird).
* Der Zustand kann beliebig oft gesendet werden. Sobald der Moment gekommen ist, dass ein Ack gesendet wird, schaut TPUart im Buffer * Das ACK kann beliebig oft gesendet werden, weil es in der BCU nur gespeichert wird und erst bei bedarf genutzt / gesendet wird.
* was der letzte Ackstatus war und sendet diesen.
* *
* Das darf man natürlich nur wenn ich nicht gerade selber sende, da man eigene Frames nicht ACKt * Das darf man natürlich nur wenn ich nicht gerade selber sende, da man eigene Frames nicht ACKt. Ggf ignoriert die BCU dies,
* aber ich wollte hier auf sicher gehen.
*/ */
if (_txState == TX_IDLE) if (_txState == TX_IDLE)
{ {
@ -266,6 +263,8 @@ void TpUartDataLinkLayer::processRxByte()
} }
else else
{ {
// Hier werden die Commands ausgewertet, falls das noch schon passiert ist.
if (byte == U_RESET_IND) if (byte == U_RESET_IND)
{ {
// println("U_RESET_IND"); // println("U_RESET_IND");
@ -276,7 +275,7 @@ void TpUartDataLinkLayer::processRxByte()
#ifndef NCN5120 #ifndef NCN5120
/* /*
* Filtere "Protocol errors" weil auf anderen BCU wie der Siements dies gesetzt, when das timing nicht stimmt. * Filtere "Protocol errors" weil auf anderen BCU wie der Siements dies gesetzt, when das timing nicht stimmt.
* Leider ist kein perfektes Timing möglich so dass dieser Fehler ignoriert wird. Hat auch keine bekannte Auswirkungen. * Leider ist kein perfektes Timing möglich, so dass dieser Fehler ignoriert werden muss. Hat auch keine bekannte Auswirkungen.
*/ */
_tpState &= 0b11101000; _tpState &= 0b11101000;
#endif #endif
@ -350,7 +349,7 @@ void TpUartDataLinkLayer::processRxFrameByte(uint8_t byte)
{ {
/* /*
* Bei aktivem Maker muss das erste U_FRAME_END_IND ignoriert und auf ein Folgebyte gewartet werden. * Bei aktivem Maker muss das erste U_FRAME_END_IND ignoriert und auf ein Folgebyte gewartet werden.
* Das Folgebyte ist also ausschlaggebend wie dieses Byte zo bewerten ist. * Das Folgebyte ist also ausschlaggebend wie dieses Byte zu bewerten ist.
*/ */
if (markerMode() && (byte == U_FRAME_END_IND && !_rxMarker)) if (markerMode() && (byte == U_FRAME_END_IND && !_rxMarker))
{ {
@ -377,9 +376,7 @@ void TpUartDataLinkLayer::processRxFrameByte(uint8_t byte)
/* /*
* Dies ist ein hypotetischer Fall, dass die Frames ohne Marker kommen, obwohl der MarkerModus aktiv ist. * Dies ist ein hypotetischer Fall, dass die Frames ohne Marker kommen, obwohl der MarkerModus aktiv ist.
* Hier wird der aktuelle Frame abgearbeitet und RX_INVALID gesetzt, da das aktuelle Byte hierbei nicht bearbeitet wird. * Hier wird der aktuelle Frame abgearbeitet und RX_INVALID gesetzt, da das aktuelle Byte hierbei nicht bearbeitet wird.
* Dieser Fall kann eintreffen wenn der Marker Modus von der TPUart nicht unterstützt wird (NCN51xx Feature). * Dieser Fall kann eintreffen wenn der Marker Modus von der TPUart nicht unterstützt wird (NCN51xx Feature) aber aktiviert wurde.
* TODO vergleiche auf maxSize oder falls vorhanden auf länge aus telegramm -> full()
* TODO Beschriebung anpassen weil es auch bei Byteverlusten auftreten kann
*/ */
else if (markerMode() && _rxFrame->isFull()) else if (markerMode() && _rxFrame->isFull())
{ {
@ -469,8 +466,8 @@ void TpUartDataLinkLayer::processRxFrameByte(uint8_t byte)
*/ */
void TpUartDataLinkLayer::processRxFrameComplete() void TpUartDataLinkLayer::processRxFrameComplete()
{ {
// Sollte aktuell kein Frame in der Bearbeitung (size == 0) sein, dann breche ab // Sollte aktuell kein Frame in der Bearbeitung sein, dann breche ab
if (_rxFrame->size() == 0) if (!_rxFrame->size())
return; return;
// Ist das Frame vollständig und gültig // Ist das Frame vollständig und gültig
@ -860,6 +857,10 @@ void TpUartDataLinkLayer::loop()
if (!_initialized) if (!_initialized)
return; return;
/*
* Sollte ein overflow erkannt worden sein, so wechsle in RX_INVALID.
* Das greift aber nur im loop und nicht im ISR. Aber bei Nutzung von ISR und DMA sollte dieser Fall nie passieren.
*/
if (_rxOverflow) if (_rxOverflow)
{ {
println("TPUart overflow detected!"); println("TPUart overflow detected!");
@ -874,7 +875,7 @@ void TpUartDataLinkLayer::loop()
_tpState = 0; _tpState = 0;
} }
processRx(); // processRx();
#ifdef USE_TP_RX_QUEUE #ifdef USE_TP_RX_QUEUE
processRxQueue(); processRxQueue();
#endif #endif
@ -1112,16 +1113,13 @@ void TpUartDataLinkLayer::processRxQueue()
while (_rxBufferCount) while (_rxBufferCount)
{ {
const uint16_t size = pullByteFromRxQueue() + (pullByteFromRxQueue() << 8); const uint16_t size = pullByteFromRxQueue() + (pullByteFromRxQueue() << 8);
TpFrame *tpFrame = new TpFrame(size); TpFrame tpFrame = TpFrame(size);
tpFrame->addFlags(pullByteFromRxQueue()); tpFrame.addFlags(pullByteFromRxQueue());
for (uint16_t i = 0; i < size; i++) for (uint16_t i = 0; i < size; i++)
{ tpFrame.addByte(pullByteFromRxQueue());
tpFrame->addByte(pullByteFromRxQueue());
}
processRxFrame(tpFrame); processRxFrame(&tpFrame);
delete tpFrame;
asm volatile("" ::: "memory"); asm volatile("" ::: "memory");
_rxBufferCount--; _rxBufferCount--;
} }