STM32 UART-Zuverlässigkeit mit hoher Baudrate

Ich verwende STM32F4 (Bare Metal mit HAL-Bibliothek) als HTTP-Server. Ich implementiere keine TCP-Schicht, da dies vom WiFi232 D2-Modul für mich erledigt wird - alles, was ich im uC über UART erhalte, ist eine Zeichenfolge mit reiner HTML-Anforderung (und alles, was ich sende, ist eine Zeichenfolge mit reiner HTML-Antwort). Die Anforderung der Anwendung besteht darin, eine große Antwort mit SPA-Webseite (fast 300.000 Zeichen) und mehrere kleine Antworten als AJAX (~ 200 Zeichen) zu senden. Mit 57600 bps funktioniert alles gut, aber die große Antwort dauert 50 Sekunden, um auf dem Client geladen zu werden, also muss ich natürlich die Baudrate erhöhen.

Das war die Kulisseneinführung, jetzt das Hauptspiel, wo das Problem beginnt: Bei allem über 57600bps verliere ich Nachrichtenzeichen auf dem Weg zum Browser. Ich verliere sie nach dem Zufallsprinzip - es ist normalerweise eine Reihe zusammenhängender Zeichen; manchmal mehrere, manchmal über hundert von ihnen. Anfangs habe ich mit dem Blockieren von UART-Transceiving gespielt. Als ich das Problem bemerkte, wechselte ich zu DMA und es änderte sich absolut nichts. Ich habe beide Fälle getestet, indem ich über UART an FTDA -> USB -> Termite-Terminal anstelle des WiFi-Moduls gesendet habe, und habe die gleichen Symptome gesehen. Da jede einzelne Simulation zu den Folgen von Datenverlusten führte, ging ich so weit, dass ich sogar STM Tx mit Rx kreuzte und überprüfte, ob auf den kürzestmöglichen Schaltungen alles in Ordnung ist, und ... es funktionierte natürlich perfekt :) Also der uC wird von den Verdächtigen ausgeschlossen.

Ist eine zuverlässige UART-Übertragung also überhaupt möglich? Haben Sie eine Ahnung, wie Sie HTTP-Nachrichten per UART mit hohen Baudraten senden können? Ich habe das Gefühl, dass ich alle Möglichkeiten ausgeschöpft habe, aber es scheint unwahrscheinlich, dass 115 kbps zu viel sind, ganz zu schweigen von Mbps ... Vielleicht übersehe ich etwas Einfaches? Die Anwendung der Hardware-Flusskontrolle korrigiert die Übertragung nur geringfügig, ich bekomme immer noch Fehler bei 115 kbps (wenn auch seltener als ohne).

*Beachten Sie, dass ich aufgrund ihrer besonderen Natur immer wieder über HTTP-Nachrichten spreche - ich kann weder Framing- noch Software-Flusskontrollalgorithmen implementieren, da ich auf der Browserseite dieser Kommunikationskette keine Macht habe.


EDIT: Einige weitere Beobachtungen:

  • Mit der RST/CST-Flusskontrolle kann ich ein Muster in der Übertragung erkennen (@230kbps): fortlaufende ~45056 ODER ~28672 Zeichen werden korrekt gesendet, dann verliere ich ein paar Zeichen und dann wieder - ~45056 ODER ~28672, dann ein loses Paar Zeichen usw. Beachten Sie, dass die Anzahl der zusammenhängenden korrekten Zeichen immer eine der beiden genannten (+/- ein paar) ist.
  • Ohne Flusskontrolle erhalte ich (wie erwartet) das folgende Muster: Übertrage GENAU 8191 @ 115 kbps oder 4095 @ 230 kbps zusammenhängende korrekte Zeichen und verliere dann ungefähr 90 @ 115 kbps oder 110 @ 230 kbps Zeichen. Seltsam ist jedoch, dass ich an keiner anderen Stelle Charaktere verliere ...

In Übereinstimmung mit diesen Beobachtungen verwende ich lieber kein hwfc und füge einfach etwas Verzögerung an den bekannten Stellen hinzu (je nach Baudrate nach jedem 8191. oder 4095. Zeichen). Dies ist jedoch sehr hackisch , ich hasse diese Lösung und hoffe, dass es immer noch einen besseren Weg gibt, dieses Problem zu lösen.

Schauen Sie sich Tabelle 133 des Referenzhandbuchs an und versuchen Sie es mit einer UART-Baudrate, die einen geringen Prozentsatz an Fehlern aufweist. Haben Sie auch überprüft, ob das UART-Modul auf dem uC Fehlerbedingungen wie einen Überlauf- oder Framing-Fehler eintritt?
Ein UART erfordert, dass Sender und Empfänger übereinstimmende Uhren verwenden. Bei höheren Baudraten werden die Uhren ungenauer, da der relative Fehler höher ist. Welche Taktquelle verwendest du?
Ich habe es nicht mit dem F401 versucht, den ich derzeit verwende, aber der F051 lief gut mit bis zu 512 kbps (habe nicht mehr versucht, da er schnell genug war). Obwohl sich der UART ein wenig unterscheidet, würde ich sagen, dass es durchaus möglich sein sollte, hohe Baudraten zuverlässig zu erreichen.
Adam , je höher die Baudrate, desto größer der Prozentsatz, also kämpft die Auswahl des niedrigeren relativen Fehlers mit meinem anfänglichen Ziel, bps zu erhöhen :) Was ORE und FE betrifft, passieren sie nicht wirklich in tx, oder? @CL. Ich teste es auf dem Discovery-Board, also sind es externe 8 MHz mit PLL, die es auf 168 anheben. Arsenal UART auf der uC-Seite funktioniert gut - wie ich geschrieben habe, habe ich es getestet, indem ich Tx mit Rx gekreuzt habe. Es ist das WiFi-Modul, das Zeichen verliert.

Antworten (1)

Klingt für mich nach einem Problem mit der Flusskontrolle. Ein WLAN-Modul benötigt dies bei höheren Baudraten, da es Pakete nicht mit voller Geschwindigkeit versenden kann – die internen Puffer laufen voll. Wenn Ihre MCU dies unterstützt, sollten Sie einen UART mit Hardware-Flusssteuerungssignalen (normalerweise als RTS und CTS bezeichnet) verwenden.

Ich habe in meinem Beitrag erwähnt, dass ich das leider nicht kann (weil die Pins auf der Platine belegt sind).
RTS/CTS-Flusskontrolle kann mit GPIO-Interrupts implementiert werden. Wenn Sie keine Pins frei haben, müssen Sie Ihr Board neu gestalten.
Ich befürchte, dass in diesem Fall eine Neugestaltung erforderlich ist, obwohl dies ein kostspieliges Manöver ist. Diese GPIO-HFC-Implementierung ist jedoch eine interessante Idee, auf die ich selbst nicht gekommen bin. Dank dafür!
Ich verwende die in STM32F4 eingebaute hw-Flusskontrolle, aber nach vielen Experimenten stieg die Zuverlässigkeit nur geringfügig (ich kann jetzt 115200 bps senden, aber selbst dann habe ich bei jeder ~ 5. Nachricht einige Zeichen verloren). Sollte RTS/CTS Charakterverluste nicht praktisch ausschließen? Ich bin gerade echt verwirrt... Ich habe huart3.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTSeingestellt, ich überprüfe TC & TXE Flags vor jedem Sendestart, ich warte immer in einer Schleife wenn HAL_BUSY, ich bekomme keine Fehler beim Senden und das Empfangsmodul soll funktionieren sogar mit 460800... Sollte da noch was gemacht werden?
Haben Sie daran gedacht, das WLAN-Modul auch für die Verwendung von RTS/CTS-Flusskontrolle zu konfigurieren? Dies ist normalerweise nicht die Standardkonfiguration.
Ja, habe ich. Bitte beachten Sie, dass die Kommunikation für niedrigere Baudraten funktioniert (ich denke, es würde nicht funktionieren, wenn das Modul nicht für die Hardware-Flusskontrolle konfiguriert wäre).
Nein, das Modul würde mit niedrigeren Baudraten arbeiten und Daten verlieren, wenn eine höhere Datenrate seine Puffer erschöpft, so wie Sie es beobachtet haben.
Bist du dir sicher? Ich dachte, dass: wenn es auf der Empfängerseite kein HWFC gibt, wenn der Transceiver ein RTS-Signal sendet, dann würde der Empfänger nicht mit CTS antworten, also würden die Daten überhaupt nicht gesendet. Die Konfiguration ist jedenfalls die gleiche auf beiden Seiten, das ist also nicht der Fall. Ich habe auch beobachtet, dass ich bei hohen bps Framing Error direkt mit dem ersten Zeichen bekomme. Also zusammenfassend: funktioniert gut für bps<115k; funktioniert, verliert aber Bytes in 115k & 230k; Framing Error sofort mit dem ersten Zeichen bei Baudrate bei 460k. Dies scheint mir eine Inkonsistenz der Baudrate oder ein Signalrauschen zu sein, aber könnte es einen anderen Grund geben?
Es gibt eine potenziell interessante Beobachtung, die ich gemacht habe: Wenn ich keine Flusskontrolle verwende, erhalte ich Daten in einer Art "Frames" von genau: (für 115k bps): 8191 Zeichen korrekt, und dann etwa 90 Zeichen verloren; (für 230k bps): 4095 korrekte Zeichen und ~110 verlorene Zeichen [in beiden Fällen ist das erste Bild immer zweimal kürzer]. Dies hat offensichtlich mit Pufferung zu tun. Ich verliere KEINE Zeichen an zufälligen Stellen. Mit hwfc bekomme ich jedoch nicht so genaue Daten, aber es gibt auch ein Muster - die korrekten zusammenhängenden Zeichenketten haben entweder eine Länge von ~45056 oder ~28672 ...
Eine sehr offensichtliche Frage, aber Sie verwenden einen Kristall auf Ihrem STM32F4 (mit NP0-Kondensatoren ) und haben bestätigt, dass die Sende- und Empfangsbaudraten innerhalb von 1% voneinander liegen, selbst wenn sich die Platine durch die WiFi-Zeichnung> 50 mA erwärmt, richtig? Überprüfen Sie auch noch einmal, was Adam zu Tabelle 133 gesagt hat.