Hallo Leute
Bin gerade mit einer Ansteuerung eines Atmega168 per Laptop beschäftigt.
Die Kommunikation realisiere ich per USB. Diese funktioniert soweit
problemlos.
Nun möchte ich ein eigenes Kommunikationsprotokoll zwischen Laptop und
Mikrocontroller definieren. Es werden Steuerbefehle sowie Daten
bidirektional zwischen den beiden Teilnehmern ausgetauscht. Da ich noch
nie ein eigenes Protokoll implementiert habe, frage ich hier mal nach ob
meine Ideen der Praxis entsprechen.
Ich hab mir vorgestellt, dass die Datenpakete wie folgt aussehen:
STX | Data Length | Data | CRC
Dabei habe ich folgendes definiert:
STX = 0x02
ACK = 0x06
NACK = 0x15
diverse Befehle = 0x10 bis 0x14
Meine Überlegungen waren folgende:
1. Die Kommunikation soll mit einem definierten Zeichen beginnen, wird
ein anderes Zeichen empfangen, bevor ein STX angekommen ist, wird das
empfangene verworfen.
2. Da ein Datenwert gleich dem STX Wert sein kann, gebe ich die Länge
der folgenden Daten an. Somit kann ein Datenwert nicht als Startwert
missverstanden werden
3. Die Daten bestehen entweder aus einem einzelnen der definierten
Befehle, bzw Antworten oder aus Messwerten, welche der uC dem PC
überträgt
4. Als CRC habe ich einfachheitshalber eine XOR Verknüpfung über die
Daten vorgesehen. Ist dies sicher genug oder sollte zwingend ein CRC-8
oder CRC-16 verwendet werden?
5. Jedes empfangene Datenpaket wird entweder mit einem ACK oder NACK
beantwortet. ACK signalisiert eine korrekte Übertragung und NACK
signalisiert ein nicht verstandener Befehl und der Kommunikationspartner
wird gezwungen, das Frame erneut zu senden.
Wie findet ihr meine Grundüberlegungen? Eigentlich handelt es sich um
eine überschaubare Menge von Befehlen und Datenaustauschen. Ist mein
Protokoll trotzdem geeignet oder ist es für mein Vorhaben schon zu
aufwändig? Die Länge des USB Kabels beträgt rund 5m. Die Umgebung, in
welcher das Ganze zum Einsatz kommt, verzeichnet nicht viele
Störsignale. Ist daher ein CRC Check nötig?
Ich hoffe ihr könnt mir auf den richtigen Pfad helfen und meine Fragen
beantworten. Für Verbesserungsvorschläge bin ich natürlich sehr dankbar.
Grüsse stefan
Stefan schrieb:> Ich hab mir vorgestellt, dass die Datenpakete wie folgt aussehen:>> STX | Data Length | Data | CRC>> Dabei habe ich folgendes definiert:>> STX = 0x02> ACK = 0x06> NACK = 0x15> diverse Befehle = 0x10 bis 0x14
Ist schon in Ordnung und macht Sinn. Denke aber bitte daran, wie du die
Kommunikation debuggen willst bzw. ob der Aufwand gerechtfertigt ist.
Willst du nur eine handvoll Befehle vom Laptop zum Controller senden,
fände ich das Overhead. Die USB-Verbindung ist nicht so störanfällig,
dass du unbedingt CRC oder STX bräuchtest (unter der Annahme, dass der
USB/232-Wandler nahe dem Controller sitzt!).
> Wie findet ihr meine Grundüberlegungen? Eigentlich handelt es sich um> eine überschaubare Menge von Befehlen und Datenaustauschen. Ist mein> Protokoll trotzdem geeignet oder ist es für mein Vorhaben schon zu> aufwändig? Die Länge des USB Kabels beträgt rund 5m. Die Umgebung, in> welcher das Ganze zum Einsatz kommt, verzeichnet nicht viele> Störsignale. Ist daher ein CRC Check nötig?
Grundsätzlich ist deine Idee gut. Aber denke mal praktisch: musst du
unbedingt ein Binärprotokoll verwenden? ASCII-Daten sind leichter zu
debuggen und eine BCD-Wandlung ist nicht übermäßig teuer. 'Ne
Statemachine musst du dir eh bauen für den Receiver und so haste die
Möglichkeit, auch ohne PC-Software deinen Controller nur über's
Hyperterminal zu steuern. Und gerade bei Synchronisierungsfragen hilft
dir das mehr als selbstgeschriebene Software.
Falls es unbedingt ein binäres Protokoll sein muss, würde ich dir
empfehlen, dir ein gescheites Terminalprogramm zu organisieren - sowas
wie Docklight (http://www.docklight.de). Macht die Sache deutlich
einfacher.
Falls du USB-CDC nutzt -- wenn du nur einfache Texte (ein Komando eine
Zeile) nimmst, kannst du ein Terminal-Programm zum testen nehmen.
Verlorenen Zeichen sind eigentlich kein Problem. Normalerweise geht da
eher die ganze USB-Verbindung verloren und das Betriebssystem
initialisiert das Gerät neu.
Stefan schrieb:> 2. Da ein Datenwert gleich dem STX Wert sein kann, gebe ich die Länge> der folgenden Daten an. Somit kann ein Datenwert nicht als Startwert> missverstanden werden
Das funktioniert nicht.
1. Kannst du auch Datenwert + nächstes Byte als STX + Länge
fehlinterpretieren.
2. Kannst du das zum Zeitpunkt des Empfangs des ersten Zeichens nicht
entscheiden.
Es hilft alleine auszuschliessen, dass die Mengen an Steuer- und
Datenzeichen disjunkt sind.
Dies kann man a) durch eine eindeutige Anordung erreichen (die du ja
eben nicht hast und durch das Steuerzeichen erst herstellen willst) oder
b) durch eine Codierung der Datenzeichen, die eine Überdeckung mit den
Steuerzeichen ausschließt. (z.B. 4B5B bei 100BASE-TX)
Stefan schrieb:> STX | Data Length | Data | CRC
Sowas ist noch kein Protokoll.
Frag dich lieber zu allererst, was du da eigentlich übertragen willst.
Dateien? Texte? Kommandos? Screenshots und anderes binäres?
Dann frag dich, wer hier mit wem kommunizieren will, der PC mit dem µC
oder beide miteinander? Als nächstes: was ist mit Daten, Kommandos usw.
die der jeweilige Empfänger nicht versteht, weil z.B. noch nicht
implementiert?
Und noch eins zum Schluß, falls du Kommandos geben willst:
Mache wenn möglich atomare Kommandos, also solche, die nur eine einzige
Wirkung haben und anderen kommandos nichtin die Quere kommen.
Obendrein ist es besser, grundsätzlich den einzigen Parameter eines
Kommandos VOR dem Kommando zu schicken. Das macht die Dekodierung und
Ausführung klarer und einfacher.
W.S.
Wie sicher muss die Übertragung sein? Da der verwendete µC nicht direkt
USB spricht, sondern offenbar über UART arbeitet, besteht die
Möglichkeit, dass er sich in eine laufende Übertragung in den Bitstrom
mittendrin aufschaltet.
Wenn es dann aufgrund der Zufälle der Daten passieren kann, dass er
diesen als gültig ansieht, dann hast du evtl. ein Problem. Das wird
nicht oft geschehen, kann aber in seltenen Fällen passieren. Eine CRC16
sichert dieses ziemlich gut ab, CRC8 oder XOR weniger gut.
Eine gezielte Pause vor dem Start eines Frames stellt auch sicher, dass
die Bytesynchronisation der UART korrekt aufsetzt. Krasser Fall: Bei
einem pausenlosen Bitstrom aus 0x55 ist eine Bytesynchronisation
unmöglich.
Wenn Du das über USB machst brauchst Du kein Protokoll. USB garantiert
die sichere Datenübertragung sicher.
Du schickst einfach immer (z.B.) 64 Bytes raus. Das wars.
Potter schrieb:> Wenn Du das über USB machst brauchst Du kein Protokoll. USB garantiert> die sichere Datenübertragung sicher.
Nur hat der ATmega168 kein natives USB.
Soll an dem Bus nur ein Teilnehmer sein also 1 PC und ein MC oder sollem
da mehrere Teilnehmer Beteiligt sein? Soll es Master - Slave Struktur
sein oder nicht?