Allgemeines Protokoll für die Datenübertragung von einem System zum anderen?

Was ist das allgemeine Protokoll zum Senden von Informationen von einem System zum anderen? Nehmen wir zum Beispiel an, wir haben einige Informationen, die über einen längeren Zeitraum vom Mikrocontroller gesammelt wurden, die wir an einen anderen Mikrocontroller senden möchten. Ich habe von SPI- und I2C-Schnittstellen gehört, aber ich bin mir nicht sicher, wann Sie eine Methode einer anderen vorziehen und wie Sie sie implementieren. Gibt es neben SPI und I2C noch andere Methoden, die üblich sind? Ist der Implementierungsprozess für verschiedene Mikrocontroller ähnlich? Analysiert es im Grunde Datenbytes, die ich auf dem empfangenden Mikrocontroller mache?

Was wollen Sie konkret tun?
Denken Sie nur daran, wie Sie verschiedene Teile eines Systems dazu bringen können, Daten in einer kleinen Box auszutauschen, sodass die Entfernung als sehr kurz angesehen werden kann. Der Grund dafür, verschiedene Teile in einer Schachtel zu haben, besteht darin, die Funktionen zu vereinfachen, sodass jedes Teil seine eigene Funktion hat (hoffentlich macht das Sinn …)
das ist nicht das, was die Leute normalerweise ein System nennen. Das sind eher das, was ich als Subsysteme definieren würde. Sie bilden einen Teil dessen, was Sie sich als einzelnes System vorstellen könnten, das eine einzelne Reihe von Aufgaben erfüllt. Es ist Semantik, aber ich denke, viele Ihrer Antworten sind sehr weit gefasst, weil sie keine perfekte Vorstellung davon haben, wonach Sie in der Frage suchen.
In Anlehnung an das, was Kortuk gesagt hat, hilft es, das Problem zu definieren. Eine wichtige Frage, die Sie sich stellen sollten, ist, ob Sie möglicherweise beabsichtigen, einzelne Subsysteme durch verschiedene Implementierungen derselben Funktion zu ersetzen, oder ob es sich um ein einmaliges Ist-Design handelt. Wenn Sie einen echten Bus verwenden und Ihrer CPU Implementierungsdetails der Subsysteme zur Verfügung stellen, erfordert eine Subsystemänderung eine As/W-Änderung für Ihren Controller, während es bei Verwendung einer Kommunikationsschnittstelle egal ist, wie Sie eine (Ersatz )-Subsystem, solange es dasselbe Nachrichtenprotokoll erfüllt.
Es ist nicht einfacher, die Funktionalität aus keinem anderen Grund als der Trennung von Aufgaben auf mehrere Geräte aufzuteilen. Kommunikation und Synchronisierung sind komplexer als zwei Prozesse im selben Mikro. Wenn diese Prozesse nun besonders inkompatible Latenzprofile haben (einer muss schnell aktualisieren, während der andere einige Zeit brauchen kann, um einen Chunk fertigzustellen), dann KÖNNTE es einen triftigen Grund geben, sie aufzuteilen. Selbst dann besteht die üblichere Lösung darin, Interrupts zu verwenden oder einen Weg zu finden, die längere Aufgabe weiter zu unterteilen. Mit dem, was Sie beschrieben haben, neige ich dazu zu denken, dass Sie dies überdenken sollten.
Ein nützlicher Vergleich von SPI vs. I2C: electronic.stackexchange.com/questions/29037/…

Antworten (7)

SPI und I2C sind sich insofern ähnlich, als sie eher zum Anschließen von Peripheriegeräten an einen Controller oder eine CPU verwendet werden als zum tatsächlichen Übertragen von Daten zwischen Systemen. USB ist eine weitere Schnittstelle, die die Leute anscheinend als Kommunikationssystem behandeln möchten, das in Wirklichkeit ein peripherer Anschlussbus ist.

Die Kommunikation zwischen Systemen ist nicht genau wie das Anschließen eines Geräts an einen Bus. Der Busanschluss ermöglicht es dem Prozessor, direkt auf Register in einem Gerät zu klopfen, während eine Kommunikationsschnittstelle es Ihnen ermöglicht, Datenströme zu senden/empfangen. Ein an einen Bus angeschlossenes Gerät benötigt im Allgemeinen einen Gerätetreiber, während es bei der Kommunikation wirklich egal ist, was am anderen Ende angeschlossen ist, soweit es den Host-Computer betrifft.

Natürlich wird dies die ganze Zeit eine unschärfere Grenze. Dinge wie PCI und ISA sind unbestreitbar Busse; I2C, SPI, USB sind wohl Busse; wobei RS232, RS485 und Ethernet definitiv Kommunikationsschnittstellen sind. Aber dann gibt es Dinge wie CAN-Bus und 1553, bei denen es definitiv darum geht, Daten zu bewegen, aber auf eine sehr komplizierte Art und Weise.

CANbus ist sehr involviert und Ethernet nicht? CAN ist sehr einfach für einfaches Hin- und Her-Messaging zum Laufen zu bringen. Sie sind dedizierte Chips und die meisten Familien unterstützen interne Mikrocontroller.
@Kortuk - insofern so etwas wie 232 eine Art Peer-to-Peer-Symmetrie hat, während 1553 oder CAN eine Master / Slave-Beziehung auferlegen, ja. Ich glaube nicht, dass ich gesagt habe, dass Ethernet einfach ist, nur dass es den Endpunkten keine Unterscheidung zwischen Buscontroller und Busgerät auferlegt.
auch vollständige Offenlegung - meine Meinung zu CAN beruht ausschließlich auf tangentialer Exposition; Es war ein ungenutztes optionales Peripheriegerät auf mehreren Systemen, an denen ich gearbeitet habe, aber nach Hunderten von Durchgängen durch die Dokumentation nehmen Sie ein wenig über die ungenutzten Optionen nur durch Osmose auf. Ich arbeite also unter der Annahme, dass CAN eine Architektur vom Typ Controller / Controlled Device ist.
Ich denke, Bus hat in verschiedenen Kontexten unterschiedliche Bedeutungen. Auf schematischer Ebene kann jede Schnittstelle mit mehreren Signalen als Bus betrachtet werden. Wenn Sie sich zu höheren Ebenen mit mehr Abstraktion bewegen, ändert Bus seine Bedeutung. Etwas höher bedeutet Bus normalerweise, dass mehrere Geräte beteiligt sind oder sein können. RS485 Multipoint ist zum Beispiel definitiv ein Bus. Viel weiter oben, aus der Sicht eines Linux-Geräts, wird RS485 wieder zu einer Kommunikationsschnittstelle und wird von einem Bus herabgestuft ... bis Sie Ihre eigene Protokollschicht darüber hinzufügen und sie wieder in einen Bus verwandeln. Auf jeder Ebene hat es unterschiedliche Bedeutungen.

Es gibt nicht die eine Art, Daten zu senden, es gibt viele verschiedene Arten zu kommunizieren, abhängig von der Entfernung, der Datenrate, der Umgebung, der Anwendung ...

Die unterste Schicht ist die physikalische Schicht , die die Bits tatsächlich bewegt.

  • SPI und I²C sind für kurze Distanzen in einem Gerät, wo es nicht viel Rauschen gibt, das die Übertragung stören könnte.

  • Für eine nicht zu schnelle Kommunikation über Entfernungen bis zu einigen zehn Metern ist die serielle Kommunikation über RS-232 eine gute Wahl.

  • Wenn es mehr Rauschen oder größere Entfernungen gibt, werden differentielle Signale verwendet, zum Beispiel in RS-485. Für eine schnellere Datenübertragung gibt es Ethernet, das sich immer mehr durchsetzt.

  • Dann gibt es noch diverse WLAN-Standards.

Auf der physikalischen Schicht gibt es weitere Schichten, die organisieren, wie die Daten gesendet werden, um Fehler bei der Übertragung, dem Routing in einem Netzwerk und vielen anderen Dingen zu erkennen und zu korrigieren. Beispielsweise ist das Internetprotokoll ein ziemlich komplexer Stapel aus mehreren Schichten, typischerweise über dem Ethernet-Protokoll.

Ein einfacher serieller UART kann verwendet werden (eine Tx- und eine Rx-Leitung ohne diskreten Takt) und kann leicht angepasst werden, um mit Optoisolatoren oder magnetischen Isolatoren zwischen verschiedenen Potentialen (sogar Primär- und Sekundärkreisen) zu kreuzen .

Soweit Protokolle gehen, wird alles mit definierten Befehlsbytes und einer Art Prüfsummenschema gut funktionieren. Es gibt wirklich kein allumfassendes Standardprotokoll, das für alle Kommunikationsarten geeignet ist. I2C hat Signalisierungsstandards (definiert Adressierung, Stopps, Starts usw.), aber das Protokoll dessen, was tatsächlich kommuniziert wird, liegt ausschließlich beim Entwickler.

PMBus ist beispielsweise ein Kommunikationsprotokoll für Stromversorgungen, das I2C als physikalisches Medium verwendet.

Wie @Jon feststellte, besteht ein Problem bei der Auswahl einer Kommunikationsschnittstelle darin, ob immer eine Einheit für die Initiierung der Kommunikation verantwortlich ist oder ob möglicherweise mehr als eine Einheit dafür verantwortlich ist. Eine damit zusammenhängende Frage ist, ob eine Entität immer bereit sein wird, unerbetene Mitteilungen zu empfangen. SPI wird häufig in Anwendungen verwendet, bei denen eine Seite immer bereit ist, Kommunikation zu empfangen. So etwas wie zum Beispiel ein 74HC595-Schieberegister ist niemals "besetzt". Während SPI gut für die Kommunikation zwischen einem Mikrocontroller und der Hardware ist, die der Mikrocontroller steuern soll, ist es wirklich nicht gut für die Kommunikation zwischen zwei Mikrocontrollern. Wenn zwei Prozessoren mit I2C-Hardware es zur Kommunikation verwenden, kann die Software so lange brauchen, wie sie möchte (innerhalb sehr großzügiger Einschränkungen), um mit dem fertig zu werden, was vor sich geht. ohne Datenverlust zu verursachen. Wenn ein Prozessor 100 Mikrosekunden benötigen würde, um jedes eingehende Byte zu verarbeiten, würde dies den Durchsatz stark einschränken, aber der Sender würde so langsam werden, dass der Empfänger mithalten kann. Die einzige Möglichkeit, die im Allgemeinen mit SPI passieren kann, besteht darin, einen separaten Draht für das Handshaking zu haben.

I2C ist wirklich ein wunderbares Protokoll. Die größten Einschränkungen, die es davon abhalten, das perfekteste Protokoll zu sein, das man sich vorstellen kann, sind

  1. Seine Geschwindigkeit ist etwas begrenzt; SPI kann viel schneller gehen, und sogar UARTs können manchmal etwas schneller gehen
  2. (2) Während es sehr praktisch ist, dass I2C nur zwei Drähte benötigt, müssen beide Drähte bidirektionale Open-Collector-Kommunikation ermöglichen. Dies erschwert das Senden von I2C über Repeater.

Persönlich würde ich gerne sehen, dass Controller-Anbieter eine Drei-Draht-Variante von SPI unterstützen, die Handshaking beinhaltet. Mir ist jedoch kein Controller bekannt, der dies tut.

Komisch, dass Sie das erwähnen sollten ... Ich muss eine SPI-Schnittstelle in eine nicht-bidirektionale I2C-ähnliche Schnittstelle verwandeln (das erste Byte ist eine Adresse), damit viel mehr Geräte am Bus teilnehmen können, als ich Chipauswahl habe . Es funktioniert, wenn Ihre Slave-Geräte alle FPGAs sind. :) Ich habe mir auch gewünscht, es gäbe etwas zwischen diesen beiden großen Synchronstandards.
Oh, ich denke, ich sollte klarstellen, dass die Ausgangsfreigaben auf den Slaves nicht aktiviert werden, bis das Adressbyte empfangen wird, und sie bleiben aktiviert, bis die Single-Chip-Auswahl deaktiviert wird ... also ist es offensichtlich etwas anders als normal SPI + High-Pegel Protokoll. Aus Sicht des Master-Geräts ist es jedoch vollständig kompatibel mit Standard-SPI. (wie ein Mikroprozessor)
@darron: Cool. Ich frage mich, was passieren müsste, damit die Industrie einen dreiadrigen Kommunikationsbus mit offenem Standard verwendet, bei dem die Drähte aktiv hoch und niedrig getrieben werden? Ich denke, es gibt einen kleinen Konflikt zwischen dem Vermeiden passiver Pull-ups und dem Zulassen, dass jedes Gerät einen Interrupt signalisiert, obwohl dies behoben werden könnte, indem ein Interrupt-Pin hinzugefügt wird, der nach Belieben der Slaves mit dem Master verbunden werden kann oder nicht (meine derzeitige Implementierung von das Protokoll hat nur einen Slave, sodass es die Datenrückleitung verwenden kann, um asynchron zu signalisieren, wann es bedient werden möchte).
@darron: Um zu vermeiden, dass ein Chip-Select-Pin verwendet werden muss, signalisiert der Master den Start des Befehls, indem er zwei steigende Flanken auf der Datenleitung sendet, während der Takt niedrig ist. Slaves können anzeigen, ob ihr letztes Datenbyte gültig war, indem sie einen Statuswert ausgeben, wenn Takt und Daten beide niedrig (idle) sind; andernfalls zeigen sie an, dass sie Aufmerksamkeit wünschen, wenn die Uhr niedrig und die Daten hoch sind. Wenn ich Master-Hardware für dieses Protokoll entwerfen würde, würde ich die Möglichkeit hinzufügen, 8-Takt-Impulse zu senden, bei denen die Datenleitung den Takt widerspiegelt, und in der Slave-Hardware eine asynchrone Zählung der Anzahl der steigenden Flanken während ...
@darron: ...ein Datenbyte. Bei fünf oder mehr würde das Byte ignoriert (der Slave würde annehmen, dass der Master daran interessiert wäre, ein Datenbyte zu empfangen, aber eigentlich nichts sagen wollte). Das wäre jedoch nicht annähernd so wichtig, als wenn der Slave den Status des letzten Bytes melden würde, wenn die Uhr niedrig war (was, wenn das Slave-Gerät ein Prozessor wäre, dem Master ermöglichen würde, zu wissen, dass der Slave nicht bereit war und hatte die letzte „Transaktionsgelegenheit“ verpasst.

Es gibt wirklich kein "allgemeines" Protokoll, was Sie letztendlich verwenden, hängt stark von der Anwendung ab. Damit wir Ihnen eine bessere Antwort geben können, müssen wir Ihre Anforderungen etwas besser verstehen. Sie erwähnen, dass Sie separate Mikrocontroller haben möchten, die als Subsysteme miteinander kommunizieren.

Einige Fragen zu dieser Anwendung:

  1. Wird es in diesem Projekt mehr als 2 Mikrocontroller geben?
  2. Was sind Ihre Geschwindigkeits- und Durchsatzanforderungen? Wie schnell kommen die benötigten Informationen dort an und wie oft senden/empfangen Sie Daten?

Wenn Sie Frage 1 mit NEIN beantwortet haben:

Wenn es in diesem Projekt nur 2 Mikrocontroller gibt, können Sie definitiv UART zwischen ihnen verwenden. Wenn beide die Kommunikation initiieren müssen, verwenden Sie die Flusskontrolle, andernfalls sollte es trivial sein, Daten in eine Richtung zu senden. In den meisten Fällen sollte es "schnell genug" sein, vorausgesetzt, Sie wählen eine der höheren Baudraten. I2C und SPI eignen sich normalerweise nur für Master/Slave-Architekturen.

Wenn Sie Frage 1 mit JA (mehr als 2 Controller) beantwortet haben:

  • Wenn Ihr Projekt mehr als 2 Mikrocontroller enthält, welcher initiiert die Kommunikation? Wird es nur ein Master-Controller sein (dh Master-Slave-Architektur)? Oder würde eines der Subsysteme jederzeit sprechen können?
  • Müssen die Subsysteme miteinander kommunizieren? zB: für die Geräte A, B und C: A kann an B und C senden, und B kann sowohl an A als auch C senden usw.

Jetzt brauchen Sie also etwas Skalierbareres, bei dem Sie adressierbare Geräte auf einen gemeinsamen Bus ziehen können. Die Antwort auf diese Folgefragen hilft Ihnen bei der Entscheidung zwischen I2C und SPI (Master-Slave) oder so etwas wie CAN (Multi-Master).

Ihr Mikrocontroller verfügt höchstwahrscheinlich über ein UART-Peripheriegerät, die anderen (insbesondere CAN) sind möglicherweise nur auf High-End-Chips verfügbar. In jedem Fall sollte es reichlich Dokumentation darüber geben, wie diese Peripheriegeräte verwendet werden, um Bytes zu verschieben.

In keiner bestimmten Reihenfolge scheinen die beliebtesten Physical-Layer-Instanzen für 2 CPUs in derselben Box zu sein:

  • Daisy-Chain-SPI (wie von JTAG verwendet)
  • Select-Wire-per-Slave-SPI
  • "RS-232 auf TTL-Ebene", auch bekannt als "asynchrone serielle Start-Stopp-Kommunikation" (direkte Verbindung des UART-TX-Pins einer CPU mit dem UART-RX-Pin einer anderen CPU)
  • I2C
  • 8-Bit-Daten + Strobe (wie z. B. der Parallelanschluss des IEEE 1284-Druckeranschlusses)
  • Shared-Memory (nur jeweils eine CPU steuert den Adress-/Daten-/Steuerbus)

Diese Instanzen der physikalischen Schicht (sowie andere Instanzen der physikalischen Schicht für 2 CPUs in getrennten Boxen) liefern typischerweise einen Strom von Bytes an die Software, die die höheren Ebenen des Kommunikationssystems implementiert.

Kluge Programmierer schreiben die Software so, dass der Hardware-Typ, wenn er beschließt, eine Instanz der physikalischen Schicht herauszureißen und durch eine völlig andere Instanz der physikalischen Schicht zu ersetzen, nur ein paar Funktionen neu schreiben muss, um ihren Ausgangsstrom von Bytes zu speisen zur Hardware und liest einen Strom von Bytes von der Hardware zurück, und alle Protokolle auf höherer Ebene arbeiten unverändert weiter.

Das Protokoll zum Senden von Informationen von einer CPU zu einer anderen CPU beinhaltet fast immer die Interpretation des Bytestroms als eine Reihe von Paketen:

  1. Präambel
  2. Header
  3. (möglicherweise maskierte) serialisierte Daten
  4. Anhänger

Einige Leute scheinen Spaß daran zu haben, völlig neue, benutzerdefinierte, inkompatible Protokolle zu erstellen, indem sie (2) eine von vielen Arten von Header-Strukturen mit (3a) einer von vielen Arten von Serialisierungsdaten mit (3b) einer von vielen Arten von mischen und abgleichen Escape dieser serialisierten Daten mit (4) einer von vielen Arten von Anhängern.

Zu den einfachsten Protokollen zum Einkapseln von Daten in ein Paket gehören:

Zu den etwas komplizierteren Protokollen zum Einkapseln von Daten in ein Paket gehören:

Es gibt eine lange Liste von Protokollen unter

Vielleicht möchten Sie „Protocol Design Folklore“ von Radia Perlman lesen , in dem beschrieben wird, wie Protokolldesign schief gehen kann.

Kein einzelnes „allgemeines“ Protokoll. Die Wahl kann (zum Beispiel) abhängen von:

  • Distanz
  • erforderlichen Durchsatz
  • Verfügbarkeit spezieller Peripheriegeräte
  • Geräuschpegel
  • Notwendigkeit einer optischen Isolierung
  • Kritikalität (tolerierbare Ausfallrate)
  • verfügbare CPU-Leistung an beiden Enden
  • verfügbare E/A-Pins an beiden Enden

In vielen Fällen müssen Sie die physikalische Schicht (Signalpegel) von der Datenverbindungsschicht unterscheiden (+/- die Art und Weise, wie Daten codiert werden) (siehe OSI-Modell, untere 2..4 Schichten). Mögliche physikalische Schichten sind zum Beispiel:

  • einfache 5V oder 3,3V oder sogar 1,8V TTL
  • eines der oben genannten, aber Open-Collector statt Push-Pull
  • symmetrische Low-Spannungssignalisierung (oft mit FPGAs verwendet)
  • ausgeglichene höhere Spannung (RS485, RS432)
  • single ended höhere Spannung (RS232)
  • symmetrisch trafogekoppelt (verschiedene Ethernet-Versionen, PDIF-Audio)
  • optisch (optisches Ethernet, Toslink)

Sie können eine Zeile verwenden, um Daten und Uhrzeitinformationen zu übertragen, oder diese in mehrere Zeilen aufteilen. Letzteres war früher beliebt, aber heutzutage neigen die meisten neuen / schnellen Protokolle dazu, eine Leitung (oder ein Paar Leitungen, die als eine fungieren) zu verwenden.

Es gibt viele Möglichkeiten, Daten zu codieren und auf einer Leitung zu takten. RS232 verwendet traditionell NRZ, es gibt Machester-Kodierung und die verschiedenen Formate, die auf Festplatten mit merkwürdigen Namen verwendet werden, Zeile 2.7 RLL.

Um es zusammenzufassen: Es gibt unzählige Möglichkeiten, zwischen Systemen zu kommunizieren. Und ich habe Konnektoren oder übergeordnete Aspekte wie Fehlererkennung und -wiederherstellung, Datenkodierung, Komprimierung und Verschlüsselung noch nicht einmal erwähnt ...