mirror of
https://github.com/thelsing/knx.git
synced 2025-01-21 00:05:43 +01:00
small optimizes
This commit is contained in:
parent
9d7e29d705
commit
7b910eba59
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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--;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user