PackMode bzw. Padding Bytes bei Siemens / Wago / Beckhoff

spsTec

Level-1
Beiträge
9
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

wir empfangen auf einem serverseitigen System TCP-IP-Nachrichten von SPS-Steuerungen.
Im Rahmen einer Weiterentwicklung haben wir beschlossen, künftig auch Wago bzw. Beckhoff Steuerungen an unserem Konnektor zu betreiben.
Problematisch ist an dieser Stelle, dass sich die Telegramme trotz dem identischen Inhalt von Nutzdaten, je nach Steuerungstyp unterscheiden.
Siemens verwendet ein PackMode 2, Beckhoff lässt sich einstellen und Wago kann nur PackMode 4.

Bei der Analyse des empfangen Bytestreams ist es somit unterschiedlich, an welchem Byteoffset die nächste Variable beginnt, da je nach PackMode sogenannte Padding-Bytes vom PLC-Controller eingefügt werden. --> http://infosys.beckhoff.de/index.ph...cPlcLibSys_F_GetStructMemberAlignment.htm&id=

Behoben wäre das Problem innerhalb unserer Applikation (C#) durch die Abbildung eines Telegramms in Form von Strukturen. Diesen Strukturen könnte je nach Steuerung ein spezifisches LayoutAttribute vorangestellt werden. --> [StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack=4)]
https://msdn.microsoft.com/de-de/li...ces.structlayoutattribute.pack(v=vs.100).aspx

Hierbei könnte über die Marshalklasse sowohl die Länge einer Variable als auch ihr Offset erfragt werden und anschließend mit dem PLC-spezifischen Converter in den entsprechenden .Net Datentyp gewandelt werden.
Da wir zum Start unserer Applikation die Vielzahl von Nachrichten nicht kennen, müssten wir zur Laufzeit mit CodeDom die Strukturen erstellen und laden. Da dies zu einem nur schwer lesbaren Quellcode führt, würde ich bei der Implementierung gerne darauf verzichten.

Jetzt zur eigentlichen Frage:
Ziel sollte es sein, dass unsere Converter-Klasse die Berechnung des nächsten Offsets selbständig übernehmen kann und somit den Algorithmus des LayoutAttributes "Pack" übernimmt.
Leider habe ich hier bei meiner bisherigen Suche im Netz noch nichts brauchbares gefunden.
Grundlage des Pack-Algorithmus ist meiner Meinung nach eine Modulo Berechnung. Allerdings bilden auch weitere Faktoren die Grundlage. Beispielsweise: Was ist mein nächster Datentyp im Stream... Je nachdem kann die Anzahl von Padding Bytes variieren.

Hatte von Euch evtl. jemand bereits vor einem ähnlichen Problem gestanden?

Vielen Dank für die Mithilfe!

Grüße,
spsTec
 
Statt Strukturen könnte man einfach alles ganz unwissenschaftlich selber in ein Array Of Byte packen und hätte dann keine Probleme mit Padding Bytes. Nebenbei würde man da auch gleich die Endianness eindeutig festlegen.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Harald,

der grobe Aufbau unseres Telegramms ist folgendermaßen:

L5 Header
L6 Header
L7 Nutzdaten

Empfangen auf Serverseite wird ein Byte[]. Über eine Konfigurationsdatenbank wissen wir, welche Datentypfolge innerhalb der Nutzdaten kommt.
Um auf den .net Zieldatentyp zu parsen, fehlt uns zur Laufzeit, auf Grund der unterschiedlichen Pack_modi, leider der Offset innerhalb des Byte[] wo der aktuelle Nutzdatenwert steht.
Auf der SPS alles in ein Byte[] zu verpacken wird schwierig, da wir hierbei an Dynamik verlieren würden.

Viele Grüße,
spsTec
 
Hallo zusammen,

ich habe einen Weg zum Umgehen des Problems gefunden. Wie bereits vermutet ist die Lösung eine Modulo-Regel.
Ist diese nicht erfüllt, so wird mit Padding-Bytes aufgefüllt, bis der neue Offset im Byte[] die festgelegte Regel erfüllt.

Hier die Lösung, falls sie auch für andere Kollegen hilfreich sein könnte:

Code:
[FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]private int[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] calculatePackOffset([/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] actOffset, [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] typeSize)[/SIZE][/FONT][/SIZE][/FONT]
[FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]{            
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#008000][FONT=Consolas][SIZE=2][COLOR=#008000][FONT=Consolas][SIZE=2][COLOR=#008000]    // this function calculate the right offset in dependence of pack mode[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]
[FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]    while[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] (actOffset % [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af]Math[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2].Min(packMode, typeSize) != 0)[/SIZE][/FONT][/SIZE][/FONT]
[FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]    {
        ++actOffset;
    }
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]
    return[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] actOffset;[/SIZE][/FONT][/SIZE][/FONT]
[FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]}
[/SIZE][/FONT][/SIZE][/FONT]


Viele Grüße,
spsTec
 
Zurück
Oben