Begrenzungs- / Synchronisationstechniken für serielle Protokolle

24

Da die asynchrone serielle Kommunikation auch heutzutage unter elektronischen Geräten weit verbreitet ist, sind viele von uns meiner Meinung nach von Zeit zu Zeit auf eine solche Frage gestoßen. Stellen Sie sich ein elektronisches Gerät Dund einen Computer vor, PCdie mit einer seriellen Leitung (RS-232 oder ähnlich) verbunden sind und Informationen kontinuierlich austauschen müssen . Dh PCsendet jeweils einen Befehlsrahmen X msund Dantwortet jeweils mit Statusbericht / Telemetrie-Rahmen Y ms(Der Bericht kann als Antwort auf Anforderungen oder unabhängig gesendet werden - spielt hier keine Rolle). Die Kommunikationsrahmen können beliebige Binärdaten enthalten . Angenommen, die Kommunikationsrahmen sind Pakete fester Länge.

Das Problem:

Da das Protokoll fortlaufend ist, verliert die empfangende Seite möglicherweise die Synchronisation oder "verbindet" sich einfach mitten in einem laufenden gesendeten Frame, sodass sie einfach nicht weiß, wo der Start des Frames (SOF) ist. Wenn die Daten aufgrund ihrer Position relativ zum SOF eine andere Bedeutung haben, werden die empfangenen Daten möglicherweise für immer verfälscht.

Die gewünschte Lösung

Zuverlässiges Begrenzungs- / Synchronisationsschema zur Erkennung der SOF mit kurzer Wiederherstellungszeit (dh die Neusynchronisation sollte nicht länger als 1 Frame dauern).

Mir sind die vorhandenen Techniken bekannt (und ich verwende einige):

1) Header / Checksumme - SOF als vordefinierter Bytewert. Prüfsumme am Ende des Frames.

  • Vorteile: Einfach.
  • Nachteile: Nicht zuverlässig. Unbekannte Wiederherstellungszeit.

2) Bytefüllung:

  • Vorteile: Zuverlässige, schnelle Wiederherstellung, kann mit jeder Hardware verwendet werden
  • Nachteile: Nicht so geeignet für rahmenbasierte Kommunikation mit fester Größe

3) 9. Bitmarkierung - stellen Sie jedem Byte ein zusätzliches Bit voran, während SOF mit 1und die Datenbytes mit gekennzeichnet sind 0:

  • Vorteile: Zuverlässige, schnelle Wiederherstellung
  • Nachteile: Benötigt Hardware-Unterstützung. Wird von den meisten PCHard- und Softwarekomponenten nicht direkt unterstützt .

4) Markierung des achten Bits - Art der Emulation des oben genannten, wobei das achte anstelle des neunten Bits verwendet wird, wodurch für jedes Datenwort nur 7 Bit übrig bleiben.

  • Vorteile: Zuverlässige, schnelle Wiederherstellung, kann mit jeder Hardware verwendet werden.
  • Nachteile: Erfordert ein Kodierungs- / Dekodierungsschema von / zur herkömmlichen 8-Bit-Darstellung bis / von 7-Bit-Darstellung. Etwas verschwenderisch.

5) Timeout-basiert - Nehmen Sie an, dass das SOF das erste Byte ist, das nach einer definierten Leerlaufzeit kommt.

  • Vorteile: Kein Datenaufwand, einfach.
  • Nachteile: Nicht so zuverlässig. Funktioniert nicht gut mit schlechten Zeitgebungssystemen wie beispielsweise Windows-PCs. Möglicher Overhead des Durchsatzes.

Frage: Welche anderen möglichen Techniken / Lösungen gibt es, um das Problem anzugehen? Können Sie auf die Nachteile in der obigen Liste verweisen, die leicht umgangen werden können, um sie zu entfernen? Wie entwerfen (oder würden) Sie Ihr Systemprotokoll?

Eugene Sh.
quelle
4 ist nur 1/8 mehr Verschwendung als 3.
Nick Johnson
@NickJohnson Ich stimme zu, aber es schlägt nur vor, dass ich das "Wasteful" -Ding auch in (3) hinzufüge :)
Eugene Sh.
Ich glaube, Sie haben Ihre Vermutungen zu Kommunikationsfehlern nicht vollständig erklärt. Gehen Sie davon aus, dass die Kommunikation "perfekt", dh fehlerfrei oder "ausreichend perfekt" ist, damit alle Fehler von der Kommunikationshardware erkannt und identifiziert werden (z. B. verwendet Comms Parity und es handelt sich nur um Einzelbitfehler)?
gbulmer
Beceiver kann sich in der Mitte eines Bytes verbinden und Bit 8 beispielsweise als Bit 4 interpretieren. 9. Bitmarkierung ist daher unzuverlässig.
Timothy Baldwin
@gbulmer Die ursprüngliche Annahme ist, dass der Kanal perfekt ist und das Problem nur aufgrund eines anfänglichen Synchronisationsfehlers auftreten kann. Unter diesen Voraussetzungen bezieht sich die "Zuverlässigkeit", auf die ich mich bezog, nur auf die Resynchronisation. In der obigen Liste garantieren alle diese Techniken mit Ausnahme der ersten einen 100% igen Erfolg. Aber wahrscheinlich sollte das Fehlerprüfschema und das Framing nicht so getrennt werden.
Eugene Sh.

Antworten:

15

Wie entwerfen (oder würden) Sie Ihr Systemprotokoll?

Meiner Erfahrung nach verbringt jeder viel mehr Zeit mit dem Debuggen von Kommunikationssystemen als jemals erwartet. Daher empfehle ich dringend, dass Sie immer dann, wenn Sie eine Auswahl für ein Kommunikationsprotokoll treffen müssen, die Option auswählen, die das Debuggen des Systems erleichtert, wenn dies überhaupt möglich ist.

Ich empfehle Ihnen, ein paar benutzerdefinierte Protokolle zu entwerfen - es macht Spaß und ist sehr lehrreich. Ich empfehle Ihnen jedoch auch, sich die vorhandenen Protokolle anzuschauen. Wenn ich Daten von einem Ort zum anderen übertragen müsste, würde ich mich sehr bemühen, ein bereits vorhandenes Protokoll zu verwenden, für das bereits ein großer Teil der Zeit für das Debuggen aufgewendet wurde.

Wenn Sie Ihr eigenes Kommunikationsprotokoll von Grund auf neu schreiben, stoßen Sie mit hoher Wahrscheinlichkeit auf viele der gleichen Probleme, die jeder hat, wenn er ein neues Protokoll schreibt.

Bei Good RS232-basierten Protokollen für die Embedded-to-Computer-Kommunikation sind ein Dutzend Protokolle für eingebettete Systeme aufgeführt. Welche entsprechen Ihren Anforderungen am ehesten?

Selbst wenn es ein Umstand unmöglich machte, ein bereits vorhandenes Protokoll genau zu verwenden, ist es wahrscheinlicher, dass ich etwas schneller zum Laufen bringe, indem ich mit einem Protokoll beginne, das fast den Anforderungen entspricht, und es dann optimiere.

schlechte Nachrichten

Wie ich schon sagte :

Leider kann kein Kommunikationsprotokoll all diese nützlichen Funktionen bieten:

  • Transparenz: Die Datenkommunikation ist transparent und "8 Bit sauber" - (a) jede mögliche Datendatei kann übertragen werden, (b) Byte-Sequenzen in der Datei werden immer als Daten behandelt und niemals als etwas anderes falsch interpretiert, und (c ) Das Ziel empfängt die gesamte Datendatei ohne Fehler, ohne Hinzufügungen oder Löschungen.
  • Einfache Kopie: Die Erstellung von Paketen ist am einfachsten, wenn wir einfach blind Daten von der Quelle in das Datenfeld des Pakets kopieren, ohne sie zu ändern.
  • eindeutiger Start: Das Symbol für den Start des Pakets ist leicht zu erkennen, da es sich um ein bekanntes konstantes Byte handelt, das an keiner anderen Stelle in den Headern, der Header-CRC, der Datennutzlast oder der Daten-CRC vorkommt.
  • 8-Bit: Verwendet nur 8-Bit-Bytes.

Es würde mich überraschen und freuen, wenn ein Kommunikationsprotokoll all diese Merkmale aufweisen könnte.

gute Nachrichten

Welche anderen möglichen Techniken / Lösungen gibt es, um das Problem anzugehen?

Oft macht es das Debuggen sehr viel einfacher, wenn ein Mensch an einem Textterminal eines der Kommunikationsgeräte ersetzen kann. Dies erfordert, dass das Protokoll relativ zeitunabhängig gestaltet wird (kein Timeout während der relativ langen Pausen zwischen von einem Menschen eingegebenen Tastenanschlägen). Außerdem sind solche Protokolle auf die Arten von Bytes beschränkt, die für einen Menschen leicht einzugeben und dann auf dem Bildschirm zu lesen sind.

Einige Protokolle erlauben das Senden von Nachrichten entweder im "Text" - oder "Binär" -Modus (und erfordern, dass alle möglichen Binärnachrichten eine "äquivalente" Textnachricht enthalten, die dasselbe bedeutet). Dies kann das Debuggen erheblich vereinfachen.

Einige Leute scheinen der Meinung zu sein, dass die Beschränkung eines Protokolls auf die Verwendung nur der druckbaren Zeichen "verschwenderisch" ist, aber die Einsparungen bei der Debugging-Zeit machen es oftmals lohnenswert.

Wie Sie bereits erwähnt haben, ist es wahrscheinlich, dass der Empfänger beim ersten Einschalten eines Empfängers falsch synchronisiert wird, wenn Sie zulassen, dass das Datenfeld ein beliebiges Byte enthält, einschließlich des Anfangs- und Endbytes des Headers Was wie ein Start-of-Header-Byte (SOH) im Datenfeld in der Mitte eines Pakets aussieht. Normalerweise erhält der Empfänger eine nicht übereinstimmende Prüfsumme am Ende dieses Pseudopakets (das normalerweise in der Mitte eines zweiten realen Pakets liegt). Es ist sehr verlockend, einfach die gesamte Pseudonachricht (einschließlich der ersten Hälfte dieses zweiten Pakets) zu verwerfen, bevor nach dem nächsten SOH gesucht wird - mit der Folge, dass der Empfänger für viele Nachrichten nicht synchronisiert werden kann.

Wie alex.forencich betonte, ist es für den Empfänger viel besser, Bytes am Anfang des Puffers bis zum nächsten SOH zu verwerfen. Dadurch kann der Empfänger (nachdem er möglicherweise mehrere SOH-Bytes in diesem Datenpaket durchgearbeitet hat) das zweite Paket sofort synchronisieren.

Können Sie auf die Nachteile in der obigen Liste verweisen, die leicht umgangen werden können, um sie zu entfernen?

Wie Nicholas Clark hervorhob, hat das Consistent-Overhead-Byte-Stuffing (COBS) einen festen Overhead, der sich gut für Frames mit fester Größe eignet.

Eine Technik, die oft übersehen wird, ist ein dediziertes Byte für die Frame-Ende-Markierung. Wenn der Empfänger während einer Übertragung eingeschaltet wird, kann der Empfänger mithilfe eines speziellen Frame-Ende-Markierungsbytes schneller synchronisieren.

Wenn ein Empfänger in der Mitte eines Pakets eingeschaltet wird und das Datenfeld eines Pakets zufällig Bytes enthält, die als Paketanfang erscheinen (der Beginn eines Pseudopakets), kann der Sender eine Reihe einfügen Die Anzahl der Markierungsbytes für das Ende des Frames nach diesem Paket, damit solche Pseudo-Start-of-Packet-Bytes im Datenfeld die sofortige Synchronisierung und korrekte Dekodierung des nächsten Pakets nicht beeinträchtigen - selbst wenn Sie extrem unglücklich sind und die Prüfsumme von diesem Pseudopaket erscheint richtig.

Viel Glück.

Davidcary
quelle
Diese Antwort ist es wert, die zuvor akzeptierte Antwort (sorry, @DaveTweed) zu überdenken, und der verknüpfte Artikel ist mit Sicherheit ein Muss zu diesem Thema. Vielen Dank, dass Sie sich die Zeit genommen und es geschrieben haben.
Eugene Sh.
1
schön, dass du auf COBS hinweist, damit ich keine Antwort schreiben muss :-)
Nils Pipenbrinck
11

Byte-Stopfschemata haben im Laufe der Jahre für mich großartig funktioniert. Sie sind nett, weil sie einfach in Software oder Hardware zu implementieren sind, Sie können ein Standard-USB-zu-UART-Kabel zum Senden von Datenpaketen verwenden und Sie erhalten garantiert eine gute Bildqualität, ohne sich Sorgen machen zu müssen Auszeiten, Hot-Swapping oder ähnliches.

Ich würde für eine Byte-Füllmethode in Kombination mit einem Längenbyte (Packet Length Modulo 256) und einer CRC auf Paketebene eintreten und dann UART mit einem Paritätsbit verwenden. Das Längenbyte stellt die Erkennung von fehlgeschlagenen Bytes sicher, was mit dem Paritätsbit gut funktioniert (da die meisten UARTs alle Bytes löschen, die die Parität nicht erfüllen). Dann gibt Ihnen die CRC auf Paketebene zusätzliche Sicherheit.

Haben Sie sich das COBS-Protokoll angesehen? Es ist ein genialer Weg, Byte-Stuffing mit einem festen Overhead von 1 Byte pro 254 übertragenen Bytes durchzuführen (plus Framing, CRC, LEN usw.).

https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing

Nicholas Clark
quelle
Dies ist eine hervorragende Möglichkeit, um im schlimmsten Fall zu vermeiden, dass die Byte-Menge doppelt so hoch wie die Daten ist. Ich habe ähnliche, aber anwendungsspezifischere Schemata verwendet, aber es ist großartig, diese auf standardmäßige Weise zu beschreiben. Ich werde ab sofort
COBS verwenden
1
Vielen Dank auch von mir für den Hinweis auf COBS - ein sehr ordentlicher kleiner Algorithmus.
Nick Johnson
6

Ihre Option Nr. 1, SOH plus Prüfsumme, ist zuverlässig und stellt sich beim nächsten unbeschädigten Frame wieder her.

Ich gehe davon aus, dass Sie entweder die Länge einer Nachricht bereits kennen oder die Länge in den Bytes unmittelbar nach SOH codiert ist. Die Prüfbytes werden am Ende der Nachricht angezeigt. Sie benötigen außerdem einen empfangsseitigen Puffer für die Daten, der mindestens so lang ist wie Ihre längste Nachricht.

Jedes Mal, wenn Sie ein SOH-Byte am Anfang des Puffers sehen, ist dies möglicherweise der Beginn einer Nachricht. Sie durchsuchen den Puffer, um den Prüfwert für diese Nachricht zu berechnen und festzustellen, ob er mit den Prüfbytes im Puffer übereinstimmt. Wenn ja, sind Sie fertig; Andernfalls verwerfen Sie Daten aus dem Puffer, bis Sie zum nächsten SOH-Byte gelangen.

Beachten Sie, dass eine Meldung, die tatsächlich Datenfehler aufweist, von diesem Algorithmus verworfen wird - aber Sie würden das wahrscheinlich trotzdem tun. Wenn Ihr Überprüfungsalgorithmus eine Vorwärtsfehlerkorrektur enthält, können Sie jede potenzielle Nachrichtenausrichtung auf korrigierbare Fehler überprüfen.

Wenn die Nachrichten eine feste Länge haben, können Sie ganz auf das SOH-Byte verzichten - testen Sie einfach JEDE mögliche Startposition auf einen gültigen Prüfwert.

Sie können auch auf den Prüfalgorithmus verzichten und nur das SOH-Byte beibehalten. Dadurch wird der Algorithmus jedoch weniger deterministisch. Die Idee ist, dass für gültige Nachrichtenausrichtungen der SOH immer am Anfang einer Nachricht angezeigt wird. Wenn Sie eine falsche Ausrichtung haben, ist es unwahrscheinlich , dass das nächste Byte im Datenstrom ein anderes SOH ist (abhängig davon, wie oft SOH in den Nachrichtendaten angezeigt wird). Sie können die gültigen SOH-Bytes nur auf dieser Basis auswählen. (So ​​funktioniert das Framing bei synchronen Telekommunikationsdiensten wie T1 und E1.)

Dave Tweed
quelle
Ich denke, die Zuverlässigkeit ist etwas probabilistisch? Abhängig von der Stärke des Fehlerprüf- / Korrekturcodes können Frames auftreten, die in einem zufälligen / willkürlichen Bytestrom korrekt erscheinen.
Eugene Sh.
Sicher ist das möglich. In der Praxis ist es jedoch relativ einfach, einen Prüfalgorithmus auszuwählen, der stark genug ist.
Dave Tweed
Wenn Sie eine Fehlerrate ungleich Null haben, besteht immer die Möglichkeit, dass Sie eine ungültige Nachricht trotzdem akzeptieren.
Nick Johnson
@NickJohnson Unter der Annahme eines vollkommen sauberen Kanals wird es bei diesem Ansatz immer noch (theoretisch) Unstimmigkeiten geben. Natürlich kann ihre Wahrscheinlichkeit vernachlässigbar sein.
Eugene Sh.
1
Ich weiß, dass Sie dies bereits wissen und es bereits im Vorbeigehen erwähnt haben, aber die Version, in der Sie keine ganze Nachricht puffern oder einfach nur faul darüber sind, wie Sie dekodieren, ist weniger zuverlässig. Wenn Sie beim nächsten SOH-Byte nach der nicht übereinstimmenden Prüfsumme erneut synchronisieren, haben Sie eine sehr gute Chance, den eigentlichen Nachrichtenstart zu verwerfen und bei vielen Nachrichten oder in der SOH nicht synchron zu bleiben schlimmster Fall für immer.
Hobbs
5

Eine Option, die nicht erwähnt, aber weit verbreitet ist (insbesondere im Internet), ist die ASCII / Text-Codierung (die meisten modernen Implementierungen setzen UTF-8 voraus). Nach meiner Erfahrung hassen es Hardware-Leute, dies zu tun, aber Software-Leute bevorzugen dies eher als fast alles andere (meistens aufgrund der Unix-Tradition, alles textbasiert zu machen).

Der Vorteil der Textkodierung besteht darin, dass Sie nicht druckbare Zeichen zum Einrahmen verwenden können. Am einfachsten wäre es zum Beispiel, wenn Sie so etwas wie 0x00den Beginn eines Frames und das 0xffEnde eines Frames angeben .

Ich habe zwei Möglichkeiten gesehen, wie Daten als Text codiert werden:

  1. Wenn ein Hardware- / Montagetechniker dazu aufgefordert wird, wird dies höchstwahrscheinlich als Hex-Codierung implementiert. Dies konvertiert einfach die Bytes in ihre Hex-Werte in ASCII. Der Aufwand ist groß. Grundsätzlich übertragen Sie zwei Bytes für jedes tatsächliche Datenbyte.

  2. Wenn ein Software-Typ dazu aufgefordert wird, wird es wahrscheinlich als Base64-Codierung implementiert. Dies ist die De-facto-Codierung des Internets. Wird von E-Mail-MIME-Anhängen bis zur URL-Datencodierung verwendet. Der Overhead beträgt genau 33%. Viel besser als einfache Hex-Codierung.

Alternativ können Sie auf Binärdaten vollständig verzichten und Text übertragen. In diesem Fall besteht die gebräuchlichste Technik darin, Daten mit Zeilenvorschub abzugrenzen (entweder nur "\n"oder "\r\n"). NMEA (GPS), Modem AT-Befehle und Adventech ADAM-Sensoren sind einige der häufigsten Beispiele hierfür.

Alle diese textbasierten Protokolle / Frames haben die folgenden Vor- und Nachteile:

Profi:

  • Einfach zu debuggen
  • Einfach in einer Skriptsprache zu implementieren
  • Hardware kann einfach mit Hyperterminal / Minicom getestet werden
  • Einfach auf der Hardware zu implementieren (es sei denn, es ist ein wirklich kleines Mikro wie ein PIC)
  • Kann entweder ein Rahmen mit fester Größe oder eine unterschiedliche Größe sein.
  • Vorhersehbares Framing und schnelle Synchronisationswiederherstellungszeit (Wiederherstellung am Ende des aktuellen Frames)

Con:

  • Sehr großer Overhead im Vergleich zur reinen Binärübertragung (dann kann die Text-E / A auch Zahlen wie das Senden eines Bytes "0"(0x30) statt vier Bytes (0x00000000) "komprimieren". )
  • Nicht so sauber auf sehr kleinen Mikros wie dem PIC zu implementieren (es sei denn, Ihre Bibliothek enthält eine sprintf()Funktion)

Persönlich überwiegen für mich die Vor- und Nachteile. Die einfache Fehlersuche allein zählt als 5 Punkte (so dass ein Punkt alleine bereits beide Nachteile überwiegt).


Dann gibt es nicht allzu sorgfältig durchdachte Lösungen, die oft von Software-Entwicklern stammen: Senden Sie verschlüsselte Daten, ohne über Frames nachzudenken.

Ich musste in der Vergangenheit mit Hardware kommunizieren, die unformatiertes XML gesendet hat. Das XML war der ganze Rahmen, den es gab. Glücklicherweise ist es ziemlich einfach, die Rahmengrenzen anhand der <xml></xml>Tags zu bestimmen. Das große Manko für mich ist, dass es mehr als ein Byte für das Framing verwendet. Außerdem kann es vorkommen, dass der Frame selbst nicht repariert wird, da das Tag möglicherweise Attribute enthält. <tag foo="bar"></tag>Sie müssten also im schlimmsten Fall puffern, um den Frame-Start zu finden.

Kürzlich habe ich Leute gesehen, die angefangen haben, JSON über serielle Schnittstellen zu senden. Bei JSON ist Framing bestenfalls eine Vermutung. Sie haben nur das "{"(oder "[") Zeichen, um einen Frame zu erkennen, aber sie sind auch in den Daten enthalten. Am Ende benötigen Sie also einen Parser für rekursive Abstammung (oder zumindest einen Klammerzähler), um den Frame zu ermitteln. Zumindest ist es trivial zu wissen, ob der aktuelle Frame vorzeitig endet "}{"oder "]["in JSON ungültig ist und somit anzeigt, dass der alte Frame beendet wurde und ein neuer Frame gestartet wurde.

Slebetman
quelle
Für Textkodierungen gibt es auch base85 , das statt 33% nur 25% Overhead hat.
Dave Tweed
Ich würde es als Teilmenge / Variation der 4. Methode betrachten.
Eugene Sh.
@EugeneSh .: Technisch gesehen handelt es sich um eine Teilmenge von Bytestuffing. Andererseits, da Sie es als Teilmenge der Bitmarkierung betrachten, können Sie verstehen, warum diese Mehrdeutigkeit es zu einer eigenen Kategorie macht. Außerdem können Sie die meisten Implementierungen der Textcodierung nicht als Teilmenge der Bitmarkierung betrachten, da die Markierungsbits nie verwendet werden (ich verwende zum Beispiel normalerweise <und >als Begrenzer E-Mail verwendet Zeilenumbrüche. Hinweis: Ja, E-Mail ist ein ordnungsgemäß eingerahmtes Format
Dies
4

Was Sie als "X-te Bit-Markierung" bezeichnen, kann in andere Codes verallgemeinert werden, die die Eigenschaft haben, die Daten um einen konstanten Bruchteil zu erweitern, so dass einige Codewörter als Begrenzer verwendet werden können. Oft bieten diese Codes auch andere Vorteile. CDs verwenden eine Modulation von acht bis vierzehn , die eine maximale Lauflänge von 0 Bits zwischen jeweils 1 garantiert. Andere Beispiele umfassen Vorwärtsfehlerkorrektur-Blockcodes , die zusätzliche Bits verwenden, um Fehlererkennungs- und Korrekturinformationen zu codieren.

Ein anderes System, das Sie nicht erwähnt haben, ist die Verwendung von Out-of-Band-Informationen, z. B. eine Chipauswahlleitung, um Transaktionen oder Pakete abzugrenzen.

Nick Johnson
quelle
Die Fehlerkorrekturcodes sind ein bisschen abseits der Frage. Sie sollten auf jeden Fall zu einem dieser Schemata hinzugefügt werden. Die "Out-of-Band-Information", auf die Sie sich beziehen, ist die gleiche wie "Hardware-Flusskontrolle", denke ich?
Eugene Sh.
@EugeneSh. - Tatsächlich ist die Verwendung von Fehlerprüfbits für die Rahmenbildung vollkommen gültig, obwohl sie auf der Empfangsseite rechenintensiv ist. Sie führen einfach die Fehlerberechnung für jede mögliche Datenausrichtung durch, und die erfolgreiche ist eine gültige Ausrichtung auf einem unbeschädigten Frame. Natürlich, wenn der Rahmen ist beschädigt, werden Sie es nicht finden.
Dave Tweed
@ DaveTweed Nun, es ist ziemlich genau das, was ich mit der ersten Technik gemeint habe. Oder verstehe ich dich falsch?
Eugene Sh.
Nein, du missverstehst nicht. Darüber habe ich gesprochen. Ihr "con" ist jedoch falsch - es ist zuverlässig und es kann auch in Bezug auf tatsächliche Übertragungsfehler robust gemacht werden.
Dave Tweed
@ DaveTweed Was ist mit der Erholungszeit? Haben Sie Beispiele, wie es robust gemacht werden kann?
Eugene Sh.
3

Eine weitere Option ist die sogenannte Liniencodierung . Die Leitungscodierung verleiht dem Signal bestimmte elektrische Eigenschaften, die die Übertragung erleichtern (Gleichstromausgleich und maximale Lauflänge garantiert), und sie unterstützt Steuerzeichen für die Rahmenbildung und die Taktsynchronisation. Leitungscodes werden in allen modernen seriellen Hochgeschwindigkeitsprotokollen verwendet - 10M-, 100M-, 1G- und 10G-Ethernet, Serial ATA, FireWire, USB 3, PCIe usw. Übliche Leitungscodes sind 8b / 10b , 64b / 66b und 128b / 130b. Es gibt auch einfachere Leitungscodes, die keine Rahmeninformationen liefern, sondern nur die Gleichstrombalance und die Taktsynchronisation. Beispiele hierfür sind Machester und NRZ. Sie möchten wahrscheinlich 8b / 10b verwenden, wenn Sie schnell synchronisieren möchten. Die anderen Leitungscodes sind nicht für eine schnelle Synchronisierung ausgelegt. Wenn Sie einen Leitungscode wie den oben genannten verwenden, müssen Sie zum Senden und Empfangen benutzerdefinierte Hardware verwenden.

Was Ihre Option 5 betrifft, soll die Standard-RS232-Serie das Senden und Empfangen von Unterbrechungen unterstützen, wenn die Leitung ein paar Byte lang inaktiv ist. Dies wird jedoch möglicherweise nicht auf allen Systemen unterstützt.

Im Allgemeinen ist die einfachste und zuverlässigste Framing-Methode Ihre Option 1 in Kombination mit einem Längenfeld und einer einfachen CRC- oder Prüfsummenroutine. Die Dekodierungsroutine ist einfach: Verwerfen Sie Bytes, bis Sie ein Startbyte erhalten, lesen Sie das Längenfeld, warten Sie auf den gesamten Frame, überprüfen Sie die Prüfsumme und behalten Sie sie bei, wenn sie gut ist. Wenn die Prüfsumme schlecht ist, verwerfen Sie zunächst die Bytes aus dem Puffer, bis Sie ein Startbyte erhalten, und wiederholen Sie diesen Vorgang. Das Hauptproblem bei dieser Technik besteht darin, ein Start-of-Frame-Byte zu finden, das eigentlich kein Start-of-Frame-Byte ist. Um dieses Problem zu beheben, besteht eine Technik darin, Bytes mit demselben Wert wie der Beginn des Frame-Bytes mit einem anderen Steuerzeichen zu maskieren und das maskierte Byte dann so zu ändern, dass es einen anderen Wert hat. In diesem Fall müssen Sie dasselbe auch mit dem neuen Steuerbyte tun.

alex.forencich
quelle
Dies ist die gleiche Antwort wie bei Nick Johnson.
Dave Tweed