- Beiträge
- 9.191
- Reaktionspunkte
- 2.950
-> Hier kostenlos registrieren
Durch die "ruhigen Tage" und viel Spekulatius (hilft beim Spekulieren) habe ich mal etwas Zeit gefunden und versucht herauszufinden wie ein Programm für die S7-1200 übersetzt und abgearbeitet wird.
Dazu habe ich diverse kurze Programme mit einfachen Anweisungen in die SPS hochgeladenen, die übertragenen Daten am Netzwerk abgegriffen und auseinandergepflückt.
Mir ging es nicht darum alles komplett zu entschlüsseln, sondern nur einen groben Überblick über die Funktionsweise zu bekommen. Ich finde es hilft ungemein wenn man wenigstens grob weiß was da im Hintergrund abläuft, aber Siemens rückt ja keine detaillierten Beschreibungen raus.
Hinweis:
Dieses ist alles meine eigene Interpretation, kann sein dass ich in einigen Dingen falsch liege!
Ein im TIA-Portal übersetztes Programm wird in eine Art Zwischencode (oder Intermediate Language - IL) übersetzt.
Dieser Code wird in die SPS hochgeladen und dort ausgeführt. Ob der Code dort direkt interpretiert oder mittels eines dort befindlichen
Just-in-Time Compilers in Maschinencode übersetzt wird, kann nicht nachvollzogen werden, da dieser Teil in der Firmware der SPS
implementiert ist. Die Vorgehensweise mit IL und JIT ist z.B. von den .Net-Sprachen her bekannt.
Ich habe nun versucht den Aufbau dieser IL herauszufinden, und aus den Bytes eine symbolische Assemblersprache (1200-IL) zurückzuentwickeln.
Im Gegensatz zur bekannten S7-AWL-Syntax mit dem Aufbau einer Zeile "Funktion Operand", kann eine Anweisung in 1200-IL mehrere Operanden besitzen (z.B. "Funktion Ziel, Operand1, Operand2").
Beispiele:
S7-AWL:
entspräche in 1200-IL:
S7-AWL:
entspräche in 1200-IL:
Die Mnemonics wie MOVW und ADDW sind dabei meine Interpretation der 1200-IL, die Siemens-Bezeichnung sieht garantiert anders aus.
Ein paar weitere Funktionen der 1200-IL:
Da die Sprungziele in dieser Sprache noch über Labels und nicht über Codeadressen / Sprungweiten laufen,
kann es sich meiner Meinung nach nicht direkt um Maschinensprache handeln sondern eben um eine Zwischenschicht.
Die Operanden (op1, op2) und Ziel einer Operation (dst) bestehen aus einem Byte Bereichs-/Längen-Kennung und dem eigentlichen Operandenwert.
Eine Bereichs-Kennung ist z.B. Merker-, Eingangs- oder Ausgangsbereich, oder Konstantenkennung (8/16/24/32 Bit).
FUP und SCL erzeugen prinzipiell beide Code dieses Befehlssatzes.
Es existieren aber erweiterte Anweisungen um die Weitergabe von EN und ENO an gestapelte FUP-Boxen zu ermöglichen.
Ähnliche Anweisungen werden auch in SCL erzeugt wenn man das Bausteinattribut "ENO automatisch setzen" aktiviert (was die Codegröße in etwa verdoppelt).
Wobei eine ADD-Box in FUP über den EN-Eingang nicht wie bei S7-AWL in einen Sprung übersetzt wird, sondern es dafür eine extra Anweisung gibt.
(in der Art einer "ADDcc" - Add conditional - Funktion).
Ein Beispiel wie SCL in 1200-IL übersetzt wird:
SCL:
1200-IL:
Die @-Variablen sind ein Ablageplatz für Zwischenberechnungen, welche nach Größen der Datentypen sortiert sind (Bool/Int/Dint/Real/...).
Auf IL-Ebene gibt es auch keine Symbole mehr, sondern es wird direkt z.B. "Merkerbereich, Wort 6" oder "Eingang, Byte 100" angesprochen.
Bei Datenbausteinen sieht das etwas anders aus, dort scheint per Basispointer und Offset gearbeitet zu werden. Das habe ich noch nicht ganz auseinandergenommen.
Mit dem Befehlssatz dürfte auch klar sein warum bei der 1200 kein AWL möglich ist, denn demgegenüber ist die IL eine "höhere" Programmiersprache.
Da wäre interessant wie sich die 1500 verhält. D.h. ob diese prinzipiell die gleiche IL wie die 1200 spricht, erweitert um Ein-Adress-Anweisungen für AWL, oder ob das eine komplett eigenständige Entwicklungslinie ist.
Vielleicht hat ja jemand irgendwelche offiziellen Infos die das Bild komplettieren, z.B. bezüglich Unterschiede 1200/1500 und Abarbeitung in der SPS.
Ich glaube bei Siemens heißt diese Zwischensprache MC7plus wenn ich mich nicht irre.
Dazu habe ich diverse kurze Programme mit einfachen Anweisungen in die SPS hochgeladenen, die übertragenen Daten am Netzwerk abgegriffen und auseinandergepflückt.
Mir ging es nicht darum alles komplett zu entschlüsseln, sondern nur einen groben Überblick über die Funktionsweise zu bekommen. Ich finde es hilft ungemein wenn man wenigstens grob weiß was da im Hintergrund abläuft, aber Siemens rückt ja keine detaillierten Beschreibungen raus.
Hinweis:
Dieses ist alles meine eigene Interpretation, kann sein dass ich in einigen Dingen falsch liege!
Ein im TIA-Portal übersetztes Programm wird in eine Art Zwischencode (oder Intermediate Language - IL) übersetzt.
Dieser Code wird in die SPS hochgeladen und dort ausgeführt. Ob der Code dort direkt interpretiert oder mittels eines dort befindlichen
Just-in-Time Compilers in Maschinencode übersetzt wird, kann nicht nachvollzogen werden, da dieser Teil in der Firmware der SPS
implementiert ist. Die Vorgehensweise mit IL und JIT ist z.B. von den .Net-Sprachen her bekannt.
Ich habe nun versucht den Aufbau dieser IL herauszufinden, und aus den Bytes eine symbolische Assemblersprache (1200-IL) zurückzuentwickeln.
Im Gegensatz zur bekannten S7-AWL-Syntax mit dem Aufbau einer Zeile "Funktion Operand", kann eine Anweisung in 1200-IL mehrere Operanden besitzen (z.B. "Funktion Ziel, Operand1, Operand2").
Beispiele:
S7-AWL:
Code:
L 123
T MW10
entspräche in 1200-IL:
Code:
MOVW MW10, 123
S7-AWL:
Code:
L 123
L 456
+I
T MW10
entspräche in 1200-IL:
Code:
ADDW MW10, 123, 456
Die Mnemonics wie MOVW und ADDW sind dabei meine Interpretation der 1200-IL, die Siemens-Bezeichnung sieht garantiert anders aus.
Ein paar weitere Funktionen der 1200-IL:
Code:
ADDW dst, op1, op2 // Addition 2 Byte (INT) und transferiere
MULR dst, op1, op2 // Real Multiplikation und transferiere
ANDW dst, op // Bitweise AND-Verknüpfung 2 Byte (WORD)
JMP lbl // Springe unbedingt zu Label
JNvke lbl // Springe wenn VKE=false zu Label
Da die Sprungziele in dieser Sprache noch über Labels und nicht über Codeadressen / Sprungweiten laufen,
kann es sich meiner Meinung nach nicht direkt um Maschinensprache handeln sondern eben um eine Zwischenschicht.
Die Operanden (op1, op2) und Ziel einer Operation (dst) bestehen aus einem Byte Bereichs-/Längen-Kennung und dem eigentlichen Operandenwert.
Eine Bereichs-Kennung ist z.B. Merker-, Eingangs- oder Ausgangsbereich, oder Konstantenkennung (8/16/24/32 Bit).
FUP und SCL erzeugen prinzipiell beide Code dieses Befehlssatzes.
Es existieren aber erweiterte Anweisungen um die Weitergabe von EN und ENO an gestapelte FUP-Boxen zu ermöglichen.
Ähnliche Anweisungen werden auch in SCL erzeugt wenn man das Bausteinattribut "ENO automatisch setzen" aktiviert (was die Codegröße in etwa verdoppelt).
Wobei eine ADD-Box in FUP über den EN-Eingang nicht wie bei S7-AWL in einen Sprung übersetzt wird, sondern es dafür eine extra Anweisung gibt.
(in der Art einer "ADDcc" - Add conditional - Funktion).
Ein Beispiel wie SCL in 1200-IL übersetzt wird:
SCL:
Code:
"MW2" := 26214;
"MW4" := ("MW0" + "MW6") * ("MW6" - 4369);
"MW6" := 17476;
1200-IL:
Code:
MOVW MW2, 0x6666
ADDW @iTemp1, MW0, MW6
ADDW @iTemp2, MW6, 0x1111
MULW MW6, @iTemp1, @iTemp2
Die @-Variablen sind ein Ablageplatz für Zwischenberechnungen, welche nach Größen der Datentypen sortiert sind (Bool/Int/Dint/Real/...).
Auf IL-Ebene gibt es auch keine Symbole mehr, sondern es wird direkt z.B. "Merkerbereich, Wort 6" oder "Eingang, Byte 100" angesprochen.
Bei Datenbausteinen sieht das etwas anders aus, dort scheint per Basispointer und Offset gearbeitet zu werden. Das habe ich noch nicht ganz auseinandergenommen.
Mit dem Befehlssatz dürfte auch klar sein warum bei der 1200 kein AWL möglich ist, denn demgegenüber ist die IL eine "höhere" Programmiersprache.
Da wäre interessant wie sich die 1500 verhält. D.h. ob diese prinzipiell die gleiche IL wie die 1200 spricht, erweitert um Ein-Adress-Anweisungen für AWL, oder ob das eine komplett eigenständige Entwicklungslinie ist.
Vielleicht hat ja jemand irgendwelche offiziellen Infos die das Bild komplettieren, z.B. bezüglich Unterschiede 1200/1500 und Abarbeitung in der SPS.
Ich glaube bei Siemens heißt diese Zwischensprache MC7plus wenn ich mich nicht irre.