ich verwende bei meinem STM32F767 mehrere UARTS. Bei einem nutze ich den Callback für empfangene Daten (jeweils 1 Byte). Nach dem Auswerten des Bytes wird der Empfang des nächsten Bytes gleich wieder angestoßen.
Ca. 1 Mal in der Woche bleibt das Ganze hängen (es werden ca. 600.000 Telegramme pro Woche empfangen). Den Grund habe ich nun gefunden, denn HAL_UART_Receive_IT liefert BUSY zurück. Aber warum? Was kann dazu führen, daß er busy ist? Es wurde ja zuvor nur 1 Byte empfangen und bis er das ausgewertet hat, sollte doch ein weiteres Freischalten gehen?
Kenne mich mit der HAL von ST nicht aus, aber könnte es sein dass in diesem Zustand irgendwelche Fehlerbits in den Registern gesetzt sind.
Also Parity-, Frame-, Overrunerror oder ähnliches?
/* Check that a Rx process is not already ongoing */
4
if(huart->RxState==HAL_UART_STATE_READY)
5
{
6
....//diverse Befehle
7
returnHAL_OK;
8
}
9
else
10
{
11
returnHAL_BUSY;
12
}
13
}
Also ist "huart->RxState == HAL_UART_STATE_READY" nicht erfüllt. Aber warum? Welche Register könnte ich im Fehlerfall in meinem Fehlerspeicher sichern, um den Fehler einzugrenzen?
Wie ist das eigentlich, wenn zu diesem Zeitpunkt ein Interrupt einer höher priorisierten Schnittstelle kommt? Kann das dazu führen, daß dann busy kommt?
Ich nehme an das Interrupt Flag wird in der ISR sofort
zurück gestzt? Dann würde ich die Interrupt Priorität erhöhen und
schauen ob das was bringt ...
Das dumme ist, daß sich der Fehler erst nach einigen Tagen bemerkbar macht. Kann auch mal 2-3 Wochen laufen. Daher ist die Fehlereingrenzung schwierig.
Du kannst in der IDE suchen, wo huart->RxState überall gesetzt wird.
Mit STRG+H gibst du die gesuchte Variable ein und klickst auf search.
Ich habe ein Bild angehängt.
Nach dem Empfang eines Bytes wird RxState in der Funktion UART_RxISR_8BIT wieder zurück auf STATE_READY gesetzt. Des Weiteren werden die Interruptflags dort zurückgesetzt.
[CODE]
ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); // Zeile 4400
Erst danach wird deine Callback-Funktion aufgerufen.
-> Sehr merkwürdig das ganze.
Mich hats gestern übrigens total geärgert, dass man den RX-Interrupt durch die Funktion TRANSMIT_IT jedesmal anstoßen muss.
Du schreibst ja, daß du mehrere UARTs verwendest. Kannst du sicher ausschliessen, daß du nicht an irgendeiner Stelle versehentlich das falsche UART-Handle übergibts?
Das würde zumindest dieses Verhalten erklären.
Du schreibst ja, daß du mehrere UARTs verwendest. Kannst du sicher
ausschliessen, daß du nicht an irgendeiner Stelle versehentlich das
falsche UART-Handle übergibts?
Das würde zumindest dieses Verhalten erklären.
huart7 bzw. huart_knx wird für den Empfang nur an 2 Stellen verwendet:
Du schreibst ja, daß du mehrere UARTs verwendest. Kannst du sicher
ausschliessen, daß du nicht an irgendeiner Stelle versehentlich das
falsche UART-Handle übergibts?
Das würde zumindest dieses Verhalten erklären.
huart7 bzw. huart_knx wird für den Empfang nur an 2 Stellen verwendet:
beim Initialisieren des Programms
nach dem Empfang der einzelnen Bytes
Und du bist dir ganz sicher, dass diese Instanz nicht woanders noch verwendet wird?
Kannst ja mal per STRG+H prüfen, ob du es ausversehen noch woanders verwendest :)
Und du bist dir ganz sicher, dass diese Instanz nicht woanders noch
verwendet wird?
Kannst ja mal per STRG+H prüfen, ob du es ausversehen noch woanders
verwendest :)
Anbei ein Bild, wo Interrupt-gesteuerter Empfang angestoßen wird.
Einziger Unterschied ist, daß ich einmal huart7 und huart_knx geschrieben habe. Ist aber durch defines identisch:
Hmm...
also mir gehen die Ideen aus.
Du könntest höchstens noch die Variable huart->RxState abfragen bzw. tracen, wenn ein HAL_BUSY zurückgegeben wird.
Hab mir jetzt nur den vom TE geposteten Code angeschaut. Könnte es sein, dass das Empfangen per Interrupt in der HAL nicht mehr vorgesehen ist, wenn das nächste Byte bereits angekommen ist?
In HAL_UART_Receive_IT(...) heißt es (siehe Kommentar) ja:
1
/* Check that a Rx process is not already ongoing */
2
if(huart->RxState==HAL_UART_STATE_READY)
"already ongoing" verstehe ich so, dass das nächste Byte schon da ist.
Vielleicht ist auch nur ein kurzer Zeitraum "gesperrt" zwischen Empfang in der HAL und Verarbeitung* durch die HAL. *Es scheint ja so, dass man nicht nur einzelne Byte abholen kann.
Blos wie macht die HAL das mit mehreren Bytes wenn angegeben? Wenn mit DMA, dann wird es problematisch sein, wenn bereits ein Byte im Empfangsbuffer liegt. Das Busy-Flag könnte das absichern. Meine Vermutung war eben, dass deine Verarbeitung (des Bytes) sporadisch zu lange dauert und dann das nächste schon angekommen ist, was dann ein Busy signalisiert.
Meine
Vermutung war eben, dass deine Verarbeitung (des Bytes) sporadisch zu
lange dauert und dann das nächste schon angekommen ist, was dann ein
Busy signalisiert.
Da musst du bei einem F7 aber schon ne Menge Radau machen, damit sowas passiert.
Das einschieben in einen FiFo wird dazu sicher nicht reichen.
Und wenn man sich bei der Vergabe der Interrupt-Prioritäten nicht allzu dusselig anstellt werden auch Unterbrechungen durch andere Interrupts sicher nicht zum Problem - erst recht nicht bei einem doch recht lahmen UART.
"already ongoing" verstehe ich so, dass das nächste Byte schon da ist.
Vielleicht ist auch nur ein kurzer Zeitraum "gesperrt" zwischen Empfang
in der HAL und Verarbeitung* durch die HAL. *Es scheint ja so, dass man
nicht nur einzelne Byte abholen kann.
Ich vermute, daß dann die Bytes verloren gehen, wenn man zu spät wieder freigibt. Busy kann er eigentlich nicht sein, denn wenn kein Empfang für ein neues Byte freigegeben wurde, kann er auch nicht damit beschäftigt sein.
Ich denke, bis ich das erste Byte in der Initialisierung freigebe, sind schon ein paar Byte von der Schnittstelle vom KNX gekommen. Wenn dann schon busy kommen würde, hätte ich da ja schon das Problem und er würde nie was empfangen. Wenn nicht freigeschaltet, werden alle Bytes ignoriert- so meine Vermutung. Baudrate ist übrigens 19200, sollte daher kein Problem machen.
Ich werde morgen mal schauen, daß ich die neusten STM-HAL´s drauf spiele. IDE (Segger) ist auch noch eine ältere Version (5.50d). Mal sehen, ob das Problem dann weg ist. Kurios ist, daß ich das Problem nur bei UART 7 habe. Bei einem anderen UART hängt eine Wetterstation dran, die jede Sekunde Daten sendet. Da hatte ich noch nie ein derartiges Problem. Hat ebenfalls 19200 Baud.