Was verursacht UART-Fehler?


8

Ich würde gerne wissen, warum UART-Fehler auftreten und wann man nach solchen Fehlern suchen sollte. Hier gibt es einen Beitrag, in dem nach der Behandlung einzelner Fehler wie Überlauf, Parität usw. gefragt wird. Mir ist klar, warum Datenüberlauf auftritt, warum Paritätsfehler auftreten, aber ich möchte wissen, was die Hauptursache ist. Meine Frage konzentriert sich mehr darauf, warum diese Fehler auftreten können (physikalische Gründe) und wann man die Fehlerprüfung zu einem Faktor für ihre Anwendung machen sollte.

Bisher scheint mein Programm großartig zu funktionieren (ohne Fehlerprüfung), aber ich weiß, dass Rauschen die Dinge durcheinander bringen kann. Wie kann ich Bedingungen simulieren, die dazu führen können, dass die UART Rx / Tx-Ports ausfallen?

Antworten:


8

In jedem Stromkreis gibt es mehrere mögliche Rauschquellen . Einige der häufigsten sind:

  • Schlecht geregelte Netzteile;
  • Schaltnetzteile;
  • Unzureichende kapazitive Entkopplung der Stromschienen in der Nähe der MCU;
  • Induktive Kopplung von elektromagnetischen Quellen in der Nähe (einschließlich 50 oder 60 Hz vom Stromnetz; selbst wenn der Stromkreis batteriebetrieben ist, tritt diese Störung auf, wenn er nahe genug an einer Netzquelle liegt).
  • HF-Quellen in der Nähe der Resonanzfrequenz einer Spur auf der Leiterplatte oder einer ihrer Harmonischen;
  • Routing von Hochstromspuren auf der Leiterplatte in der Nähe von Signalleitungen;
  • Usw.

Darüber hinaus ist (wie bei @jippie erwähnt) der Taktversatz eine sehr häufige Fehlerursache bei jeder Art von serieller Kommunikation, bei der eine vorgegebene Datenrate verwendet wird. Wenn Sie einen externen Kristall verwenden und eine Schnittstelle zu einem anderen System herstellen, von dem vernünftigerweise erwartet werden kann, dass es genau ist, ist es weniger wahrscheinlich, dass Probleme auftreten. Interne Oszillatoren können jedoch Toleranzen aufweisen, die mehrere Größenordnungen schlechter sind als Kristalle und über Temperaturbereiche tendenziell stärker variieren.

Es gibt mehrere grundlegende Tests, die auf einem laufenden System durchgeführt werden können, um die grundlegende Störfestigkeit (und Schrägstellung) Ihrer Schnittstelle zu bestimmen, darunter:

  • Einfrieren (den Kreislauf auf die Mindestleistung seiner Komponenten abkühlen lassen);
  • Backen (Hitze bis zur maximalen Bewertung);
  • Exposition gegenüber EMI :
    • Legen Sie die Platine auf das Netzkabel einer laufenden Raumheizung.
    • Geben Sie ein CB-Radio in der Nähe der Platine ein.
    • Stellen Sie die Karte neben Ihren WLAN-Router.
    • Verwenden Sie für die UART-Verbindung ein langes Anschlusskabel (anstelle eines ordnungsgemäß konstruierten seriellen Kabels).

Es gibt viele andere - tatsächlich gibt es große Testlabors, die sich der EMV- Qualifizierung widmen .

Im Allgemeinen ist es immer ratsam, eine Art Fehlerprüfung in Ihren Kommunikationscode aufzunehmen, es sei denn, ein minimaler Datenverlust ist akzeptabel. Selbst eine einfache Prüfsumme ist besser als nichts.


6

Eine häufige Fehlerquelle bei UART neben der Signalpegelqualität (Rauschen, Anstiegs- / Abfallzeiten) ist der Taktversatz. Wenn der Sendertakt und der Empfängertakt nicht von derselben Quelle abgeleitet sind (was meistens der Fall ist), läuft einer schneller als der andere. Wenn der Timing-Fehler zu groß ist, können Sie gelegentlich ein falsches Bit lesen.


Was würde dazu führen, dass die Uhr schief läuft, wenn der Mikrocontroller in einer Blackbox allein gelassen würde, mitten in wem weiß wo?
user791953

1
Freilaufende lokale Uhren. Jeder Oszillator hat seine eigene Genauigkeit. Der MCU-Takt kann auf eine für UART verwendbare Frequenz heruntergeteilt werden, manchmal ist er jedoch um einen kleinen Prozentsatz ausgeschaltet. Dies wird wiederum durch die Tatsache verursacht, dass der Divisor eine Ganzzahl ist.
Jippie

Z.B. MCU-Takt = 16 MHz, UART-Baudrate = 9600 Bd. Dann wird der UART üblicherweise mit 153600 Hz getaktet. 16000000/153600 ist jedoch keine Ganzzahl, daher ist die Baudrate deaktiviert.
Jippie

Richtig, das ergibt einen kleinen Fehleranteil. Ich schätze, ich hatte das Glück, keine Fehler festgestellt zu haben, aber wenn es sich um kritische Daten handelt, sollten Überprüfungen immer durchgeführt werden.
user791953

Niedrigere Baudrate, höhere Taktrate (erhöht die Abtastauflösung und die Timing-Genauigkeit).
Jippie

1

Die meisten Fehler sind auf drei Ursachen zurückzuführen: (1) Das vom Sender erzeugte Signal stellte keine gültigen Daten dar. (2) das Signal des Senders wurde nicht wie erzeugt empfangen, oder (3) der Empfänger war nicht bereit, die Daten zu verarbeiten, als sie empfangen wurden. Die häufigste Ursache für Problem Nr. 1 ist ein Sender, der während der Datenübertragung neu konfiguriert oder heruntergefahren wird. Problem Nr. 2 kann leicht bei Signalen auftreten, die aufgrund von Funkstörungen durch die "Außenwelt" übertragen werden (Mobiltelefone können überraschend unangenehm sein!), Sollte jedoch im Allgemeinen nicht bei Signalen auftreten, die auf eine einzelne Karte beschränkt sind. Problem Nr. 3 kann entweder auftreten, weil zu viele Bytes schneller ankommen als verarbeitet werden können, oder weil der Empfänger während einer Übertragung neu konfiguriert, heruntergefahren oder gestartet wird.

In vielen Fällen ist es schwierig, alle diese Probleme vollständig zu beseitigen. Das Ziel sollte es sein, sicherzustellen, dass der von ihnen verursachte "Gesamtschaden" (Eintrittswahrscheinlichkeit, mal Schaden pro Auftreten) akzeptabel gering ist. Dies kann am einfachsten erreicht werden, indem eine pessimistische Schätzung der Zuverlässigkeit ausgewählt und anschließend ein Protokoll entworfen wird, sodass die Auswirkungen selbst der schlimmsten Fehler, die mit den Schätzungen übereinstimmen, auf die Systemleistung innerhalb akzeptabler Grenzen liegen.


0

Rahmenfehler können durch das verursacht werden, was @jippie erwähnt - der Empfänger hat das Startbit erkannt und wo er das Stoppbit erwartet, werden die Daten invertiert. Dies kann auch auf eine Datenbeschädigung zurückzuführen sein, die durch eine auf das Stoppbit auftreffende Leitungsstörung verursacht wird. Sie müssen dies immer für jedes empfangene Byte überprüfen.

Paritätsfehler treten auf, wenn Parität auf der Datenverbindung implementiert ist und eine Beschädigung vorliegt, die eine Paritätsfehlanpassung in den empfangenen Daten verursacht. Sie müssen dies immer für jedes empfangene Byte überprüfen.

Eine Empfangspause wird ebenfalls als Fehler angesehen, obwohl dies tatsächlich ein Hinweis darauf ist, dass die eingehenden Daten länger als 1 Datenbyte auf die logische Null gefallen sind. Normalerweise ist logisch 1 der "Umgebungs" -Zustand zwischen aufeinanderfolgenden Datenbytes und bleibt dies auch. Es ist ein Rückfall in alte Telegraphiesysteme, denke ich. Ich würde dies nicht überprüfen, wenn Sie diese "Funktion" nicht verwenden würden, um dem Empfänger einen Rücksetzbefehl anzuzeigen (z. B.).

Ein Überlauffehler liegt vor, wenn ein neues Byte empfangen wird, bevor das vorherige Byte von einer CPU gelesen wurde. Etwas anders, wenn ein FIFO beteiligt ist, aber dasselbe ist - gültige empfangene Daten gehen aufgrund der Langsamkeit der CPU verloren. Überprüfen Sie dies immer, bevor Sie ein Byte lesen. Wenn das Byte Teil einer längeren Nachricht (oder eines längeren Befehls) ist, werfen Sie die gesamte Nachricht / den gesamten Befehl weg und fordern Sie den Sender auf, die gesamte Nachricht / den gesamten Befehl erneut zu senden.

Unter Ausführen ist kein wirklicher Fehler, sondern zeigt dem sendenden UART an, dass sein Sendepuffer leer ist, dh er fordert ein neues Byte zum Senden an. Sie müssen dies nicht überprüfen.


Ich verstehe, was diese Fehler sind und warum sie auftreten. Meine Frage ist eher, wann man eine Fehlerprüfung für sie durchführen sollte.
user791953

@ user791953 - fertig
Andy aka

Übrigens ist Unterlauf bei den meisten Protokollen kein Problem, aber einige Protokolle verwenden eine Leerlaufleitung, um das Ende des Pakets anzuzeigen. In solchen Fällen kann ein Unterlauf auf der Sendeseite dazu führen, dass der Empfänger fälschlicherweise denkt, dass das Paket endet, bevor es soll.
Supercat

0

Um diese Fehler zu beheben, müssen Sie ein logisches Protokoll einer höheren Ebene implementieren. etwas ähnlich wie TCP, oder überprüfen Sie den OSI-Stack auf Ideen.

Grundsätzlich sind zwei wichtige Teile zunächst Prüfsummen und Zeitüberschreitungen. Verwenden Sie einen Algorithmus, um einen redundanten Wert zu berechnen, der in kleinerer Form den Inhalt jeder Nachricht darstellt. Überprüfen Sie dies in der empfangenen Nachricht. Wenn die Summen nicht übereinstimmen, ist möglicherweise ein Rahmenfehler, ein Bitrauschen usw. usw. aufgetreten, und Sie müssen die Nachricht verwerfen und eine Art Wiederherstellung, erneutes Senden, NACK-Signal (nicht bestätigt) usw. versuchen.

Stellen Sie außerdem sicher, dass Timeouts in Ihrem Protokoll der oberen Ebene implementiert sind. Wenn Sie einen Rahmenfehler erhalten, wird Ihr UART möglicherweise nie wiederhergestellt und beginnt erneut mit der Verarbeitung. Möglicherweise wartet es auf das Stoppbit in einem Frame, von dem der Sender-UART glaubt, dass es bereits gesendet wurde, das jedoch durch Rauschen, Taktversatz usw. beschädigt wurde. Dadurch wird jeder Eingabecode in eine Endlosschleife gesendet. Stellen Sie sicher, dass Sie eine vernünftige Grenze dafür haben, wie lange Ihr Eingabewert warten soll, bis Sie sich entscheiden, diese Nachricht abzubrechen, und wiederholen Sie erneut, NACK, Abbruch usw.


Zeitüberschreitungen müssen auf mindestens einer Seite eines übergeordneten Protokolls implementiert werden. In vielen Fällen ist es am besten, sie genau auf einer Seite zu implementieren. Eine Seite für immer auf Daten warten zu lassen, die niemals eintreffen, ist nur dann ein Problem, wenn es etwas anderes Nützliches gibt, das sie stattdessen hätte tun können. Wenn X Y nach Daten fragt, muss X darauf vorbereitet sein, seine Anfrage erneut zu senden, falls Y sie nicht erhält. Y muss sich jedoch keine Sorgen machen, ob X seine Antwort erhält. Wenn X es nicht bekommt, fragt X erneut nach den Daten. Die Tatsache, dass X nicht erneut nach den Daten fragt, bedeutet, dass Y sie nicht erneut senden muss.
Supercat

@supercat richtig, das ist ein gutes Muster, aber ich ziele mehr auf die Low-Level-Line-by-Line-Codierung. Sie werden immer eine Schleife haben, die Daten liest und versucht herauszufinden, ob eine vollständige Nachricht bereit ist. Wenn eine vollständige Nachricht nie vorhanden ist, kann sie das Eingabesubsystem hängen lassen, unabhängig davon, ob nichts anderes als darauf zu warten ist erledigt. In diesem Fall muss das Eingabesubsystem zumindest erkennen, dass ein Fehler aufgetreten ist, alle Gabage-Daten löschen und für einen weiteren Versuch zurücksetzen.
Andyz Smith

Wenn jedes Paket mit einer Byte-Sequenz beginnt, die in jedem Kontext immer identifizierbar ist, und wenn der Empfänger nichts Nützliches hat, was er tun kann, bis er ein vollständiges Paket empfängt, warum sollte es ihn interessieren, wenn einige Stunden nach dem Empfang eines Teilpakets vergehen? Wenn jemand das nächste Mal versucht, ein echtes Paket zu senden, sieht der Empfänger die Paketanfangsmarkierung und gibt das Teilpaket auf.
Supercat

@supercat, weil Sie dann eine Schleife haben, die nach mehreren Dingen sucht. Es wird immer noch nach dem Ende des Teilpakets gesucht, und es wird nach dem Anfang eines frischen, unverfälschten Pakets gesucht. Dies macht die Logik in Bezug auf die praktische Codierung viel komplexer, wenn Sie dies während der Codierung tun.
Andyz Smith

Ich bin mir nicht ganz sicher, was die Schwierigkeit ist. Wenn jemand eine Empfangsbyte-Schleife verwendet, muss er aus dieser Schleife ausbrechen, wenn entweder eine Zeitüberschreitung auftritt oder ein Startbyte angezeigt wird. Beide Verhaltensweisen müssen identisch behandelt werden, außer dass die Startsequenz ein Flag setzen sollte, damit der nächste Code, der danach sucht, nicht stört.
Supercat
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.