2017-12-21 16 views
1

Ich möchte eine Struktur mit vielen Strukturen in einem anderen Controller senden (nicht die gleiche Marke des Controllers, mit einer anderen Architektur). Ich benötige eine Art Serialisierung, um Daten ohne Verwendung der erfundenen Serialisierungsmethoden zu übertragen. Wie finde ich heraus, wo aufgefüllte Bytes hinzugefügt werden, damit ich sie entfernen kann, bevor ich sie an den anderen Controller sende? Wie kann ich Metadaten implementieren, so dass der andere Controller jedes Mitglied der Struktur aus den übertragenen Datenbytes rekonstruieren kann? Alle anderen Punkte, die auch erforderlich sein können, wären willkommen.Übertragen von Strukturen zwischen den Controllern

Antwort

0

Verwenden Sie TLV-Typ des Codierungsschemas. Es wird normalerweise als Typ Length Value bezeichnet.

Normalerweise sieht ein Element wie

#pragma pack(1) 
    typedef struct _tlv_node { 
      uint8_t type; 
      uint16_t length; 
      uint8_t value[0]; 
    }tlv_node; 

Diese für viele Codierung und Decodierung Ströme ist ziemlich Standard und man kann es auf alle Arten von Struktur erstrecken. Eine Menge Open-Source-Code hat dies implementiert, daher gibt es keinen Mangel an Beispiel-Implementierungen.

+1

Und der Code ist b0rken und ungültig. Insbesondere das Überschreiten des einen Elements im Wert hat ein undefiniertes Verhalten, und "pack" ist ein Hack, der sehr teuer sein könnte. –

+0

Willkommen im Jahr 1999, wir brauchen den unsicheren "struct hack" nicht mehr zu benutzen. – Lundin

+0

@lundin Sie sprechen hier für sich, Pragma Pack ist kein Hack, es wird von allen populären Toolchains für die meisten populären Prozessoren unterstützt, und es ist aus einem Grund da, um sicherzustellen, dass der Speicher auf ein bestimmtes Layout, Hardware-Register zeigt oder Netzwerkpakete. Auch wenn man sich über das Packen lustig macht, ist es ziemlich verrückt, wenn eine ganze Reihe von Prozessoren immer noch sig- busisch agieren. Auch wenn man im Internet streiten wird, wird es nie alt werden. Aber ich mag deine Antwort. – amritanshu

3

Voll tragbare Serialisierung/De-Serialisierung ist ziemlich manuell. Sie gehen einfach durch jedes Mitglied der Struktur und kopieren es. Sie könnten offsetof verwenden, um Padding zu erkennen, aber das ist meistens sinnlos, da es bedeutet, dass Sie sowieso ein "manuelles Codieren" pro Strukturelement durchführen müssten.

#pragma pack(1) und ähnliches ist nicht ideal. Structs sind aus einem bestimmten Grund gepackt, und es gibt keine tragbaren Mittel, um das Padding zu deaktivieren. Es kann auf einigen kleineren CPUs wie 8 oder 16 Bit machbar sein, aber nicht für vollständig tragbaren Code.

Wichtig ist ein gut definiertes Netzwerkprotokoll, das angibt, wie Daten gespeichert werden, einschließlich Endianess. Das heißt, der Sender, das Protokoll und der Empfänger haben alle Endlichkeit und sie sind nicht notwendigerweise dieselben.

(Traditionell verwenden Datenprotokolle oft Big-Endian, da dies die einzige Sache ist, die für die Implementierung von Hardware-CRC-Prüfungen mit XOR-Gattern sinnvoll ist, aber das ist heutzutage meistens kein Problem. Einige MCUs haben sogar eingebaute CRC-Prüfhardware .)

+0

Je nach Anforderung könnte das "wohldefinierte Netzwerkprotokoll" sogar ASCII-basiert sein. Eine solche Übertragung ist viel sicherer und einfacher zu implementieren und zu überwachen/zu debuggen als jedes Binärprotokoll. – tofro

+1

@tofro Nicht wirklich, ASCII-Protokolle bedeuten Daten aufblähen und langsamer Codierung/Decodierung. Der einzige Grund, warum Sie sie verwenden würden, ist, wenn die Überwachung von Nicht-Programmierern durchgeführt werden sollte. Ich würde vermeiden, alten Mist wie "AT-Befehle" zu implementieren. – Lundin

+0

Das meiste, wenn nicht alles der Sache, die Internet genannt wird, basiert auf solch "altem Mist". Kann nicht so schlimm sein? – tofro

Verwandte Themen