TwinCat ADS Kommunikation: Bytes verschoben?

LMDaniel999

Level-1
Beiträge
57
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe eine Frage, bei der wir aktuell nicht weiter kommen.
Wir haben zwar eine Idee, wissen aber nicht ob das richtig ist und wie wir das lösen können.

Wir möchten mit TwinCAT 2 eine ADS Kommunikation zwischen einer CX5020 (Intel Celeron X86) und einem CP66 (ARM) aufbauen.
Prinzipiell funktioniert das auch: Ein Struct mit verschiedenen Variablen und fester Adresse im Speicher auf der einen CPU, ein ADSRead Befehl auf der anderen CPU.

Das Problem ist, dass das gleiche Struct auf der Ziel CPU anders beschrieben wird. Die Werte stimmen nicht!
Wir haben uns die übertragenen Daten Byte für Byte in Hex angesehen und festgestellt, dass die Bytes korrekt übertragen werden.
Das Problem ist aber, dass es von der einen CPU zur anderen eine Verschiebung der Variablen gibt.

Beispiel: Erstes Teil im Struct ist ein String der Länge 32. Die ersten 32Bytes sind Chars, Byte 33 ist der Abschluss vom String.
Die nächste Variable ist eine Real. Die eine CPU fängt mit der Real in Byte 34 an, die andere in Byte 37.

Unsere Theorie:
Die CX5020 nutzt jedes Byte ohne Lücke, das CP66 lässt teilweise Lücken und nutzt "eine Art Viererpack".....
Ich hoffe, das war jetzt verständlich.... :D

Nun zu den Fragen:
Warum ist das so?
Gibt es hierfür unterschiedliche Arten für eine Speicherbelegung? Wenn ja, wo steht das?
Wie setze ich eine ADS Kommunikation dann vernünftig um? Passende Reihenfolge der Variablen?

Danke!
 
Hallo beschreibung.
Die Frage ist ob du per Compiler das Alingment ausschalten kannst.
Wenn nicht , müsstest du die Structur so aufbauen, dass kein Alingment benötigt wird. (Ausfüllen mit ReserveBytes)

http://de.wikipedia.org/wiki/Speicherausrichtung

Sind die Operanden im Speicher nicht ausgerichtet, so ist eine lückenlose Nutzung des Speichers auch bei beliebiger Mischung der Datenformate möglich. Allerdings müssen abhängig von der zufälligen Anordnung ggf. mehr Speicherzugriffe erfolgen, als eigentlich für ein solches Datenelement minimal nötig wären. Durch zusätzliche Shiftoperationen müssen die Operandenteile danach erst wieder zusammengesetzt werden. (Genau genommen sind bei n größer m auch Shift-Operationen nötig, die aber bei vorgegebener Datenbusbreite unvermeidlich sind und somit kein "data misalignment" sind.)
Je nach benutzter Prozessorarchitektur wird ein Zugriff auf nicht ausgerichtete Daten hardwareseitig gar nicht unterstützt. In diesem Falle müsste eine spezielle Programmroutine, welche die Daten softwareseitig zusammensetzt, implementiert und für jeden Zugriff ausgeführt werden. Der Mehraufwand geht weit über bloße zusätzliche Speicherzugriffe hinaus.
 
Wahrscheinlich hat der ARM Prozessor eine andere Bytereihenfolge (Endianess). Zumindest bei den PLC-Bausteinen für ADS-Funktionen ist angemerkt, dass bei der Übertragung von Gleitkommavariablen die Endianess beachtet werden muss.
http://infosys.beckhoff.com/index.p...TcPlcLibDataExchange_WriteRealOnDelta.htm&id=

Wie du das Problem lösen kannst weiß ich allerdings auch nicht. Spricht nicht gerade für das ADS-Protokoll, dass die Daten nicht in einer festgelegten einheitlichen Bytereihenfolge übertragen werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi.
Danke für die Antwort. Die Übertragung ist 1 zu 1. Das passt.
Es ist definitiv so, dass die Variablen der Steuerungen unterschiedlich auf den Speicher zugreifen.
Wenn die Real Variable am Anfang vom Struct steht, wird sie übertragen. Es ist kein Endianess Problem.
Das Problem tritt dann auf, wenn ich eine Variable mit weniger als 4 Byte Länge vor z.B. einem Real habe.
Weil dann die Real an unterschiedlichen Stellen in beiden Steuerungen beginnt.
 
Das hört sich dann nach Padding bzw. Alignement an. D.h. die Variablen werden so im Speicher abgelegt, dass der Prozessor optimal darauf zugreifen kann. Wenn es für ein Prozessortyp effektiver ist alle Werte an 4 Byte Grenzen auszurichten, und davor kommt nur eine 2 Byte-Variable, dann werden dazwischen 2 Null-Bytes eingefügt die nicht verwendet werden.

Der direkte Zugriff auf Speicher ist nie eine gute Idee. Es kann auch sein dass eine andere Compiler-(Linker)-version die Variablen anders im Speicher ablegt, da kannst du dir nie sicher sein.
 
Hi.
Ok, aber wie mache ich dann eine ADS Kommunikation ohne direkten Zugriff auf den Speicher?
Das ist ja genau so beschrieben. Die Daten liest er ja auch entsprechend.
Problem ist halt nur die unterschiedliche Aufteilung.
Wir haben uns nun überlegt, einfach beim Erstellen vom Struct auf diese "Eigenschaft" zu achten und die Variablen entsprechend zu sortieren. Dann sollte es gehen....
 
Vielleicht noch kurz:
Du solltest die größte von oben nach unten anordnen. Spricht 4Byte, 2Byte, 1Byte.
Dann sollte es gehen.

Grüße
 
Du kannst auch ein Array of Byte als Sendepuffer benutzen und Deine Variablen da hineinkopieren, da kannst Du ganz genau bestimmen, an welcher Position die Variablen liegen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi.
Danke für die ganzen Antworten.
Also das Problem ist genau dieses Alignment.
Wir machen es jetzt so, dass wir ein Array of Byte erstellen, der uns zum Senden und Empfangen den Speicher reserviert, damit die Steuerung diesen Speicher nicht anderweitig nutzt.
Dann werden wir in diesen Speicherbereich unsere ganzen Variablen legen, aber fest adressiert. Dadurch können wir beidseitig entsprechend lesen und schreiben.
Wir müssen so zwar auf die korrekte Verteilung der Variablen achten, wissen aber genau, wo jede ist....

So sollte es dann gehen.
Danke für die Hinweise!
 
Den Unterschied kann man feststellen über den Befehl SIEZEOF.
Sollte eine Byte Differenz zwischen x86 und ARM existieren hilft nur schrittweise
Analyse vom Struct.
Manchmal hilft ein BOOL mehr (gerade Anzahl vom Bits) oder Erweiterung vom Byte zum Word.
Auf jeden Fall muss! die Byte Anzahl im x86 und ARM PLC gleich sein.

Das Problem liegt an den unterschiedliechen Hardwareplatformen und nicht am ADS.



Irek
 
Ja, die Länge war unterschiedlich. Da haben wir es ja dran gemerkt.
Und dann haben wir uns die HEX Werte angesehen und verglichen.
Da kam es dann zum Vorschein.

EDIT: Das ADS überträgt sauber! Das hat man ja an den HEX Werten gesehen.
Das Problem ist dann halt nur, dass die lesende Steuerung die Variablen falsch aus dem Speicher holt, wenn er die unterschiedlich positioniert...
 
Morgen,

also wie schon gesagt, wenn ihr die einzelnen Variabeln richtig anordnet, ist das Problem behoben!!!
Das wäre der sauberste und einfachste Weg.

Grüße
 
Du kannst theoretisch auch jedes einzelne "Object" lesen und entsprechend schreiben. Aber dann musst du für jede Variable einen ADS Read Befehl erstellen.
Dann geht das aber nicht mit einem Struct, weil man in einem Struct den Variablen keine feste Adresse geben kann.
Wenn du die Variablen einzeln übertragen willst, dann musst du jede Variable an einer festen Stelle im Speicher ablegen und diese Stelle übertragen.

Aber dann ist es einfacher, wenn du die Variablen alle fest im Speicher ablegst, sie entsprechend zusammenpackst und dann einen ADS Read Befehl machst.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
TC2:
- Byte-Alignment ARM Prozessor: 4
- Byte-Alignment Intel : 1

Nachzulesen:http://infosys.beckhoff.com/content...s/bt_el66xx_beckhoff_network_var_settings.htm
(bitte etwas scrollen)

Für effiziente Übertragung rate ich nur 1 ADS-Kommando abzusetzen. Wenn die Struktur entsprechend sortiert ist dann ist das Alignment kein Problem. Im Worst case eben dummy-Bytes einfügen.


Ach ja: TC3: Alle Plattformen haben eine 8 - Byte alignment. Vor vielen Jahren hat aber noch keiner an ARM und x64
gedacht. Das Alignment war deshalb eindeutig, die neuen Anforderungen waren mit der Historie nicht abgedeckt deshalb das Mischmasch. Das trifft deshalb auf ziemlich viele Systeme zu
 
Zurück
Oben