-> Hier kostenlos registrieren
Hallo SPS'ler
Ist die Datenkonsistenz gewährleistet bei Kommunikation zwischen:
CPU315-2 DP (315-2AG10-0AB0) und CP343-1 Advanced (343-1GX21-0XE0) oder CP343-1 (343-1EX11-0XE0)
Fallbeschreibung:
- Das CP kommuniziert über Ethernet(*)
- Die CPU schreibt die Kommunikationsdaten in einen Datenbaustein (DB)
(*) Wir haben einen Treiber, der mit dem CP über Ethernet kommuniziert und seine Daten so in z.B. einen Datenbaustein (DB1) schreibt.
Andererseits liest unser SCL-Programm während des SPS-Zyklus diese Werte aus und schleust diese Werte zu den I/O's weiter.
Der Treiber garantiert uns, dass er eine Datenmenge von einem Block (216 Bytes) konsistent zum CP sendet.
Umgekehrt lesen wir die Daten per SCL von den I/O's und schreiben diese in DB2. Unser Treiber fragt dann diese Daten wiederum über das CP ab.
Nach meinen Erkundigungen scheint es nun so zu sein, dass das Schreiben in die DB's und das Lesen daraus nicht synchronisiert ist und das somit Dateninkonsistenzen auftreten können.
Ich bin mir nicht sicher, ob diese Inkonsistenz die einzelnen Variabeln betreffen kann oder nur die ganzen übertragenen Speicherblöcke. Wir könnten es uns schon leisten, dass Werte verloren (x) gehen, jedoch nicht, dass sie verändert werden.
(x) Fall: CP schreibt in DB, wird nicht fertig und CPU liest derweilen aus DB.
In der SFC Referenz hab' ich folgende, interessante Funktion gefunden:
UBLKMOV (SFC81)
Diese verspricht mir einen max. 512 Byte grossen Datenbereich atomisch zu kopieren.
Dies gelingt mir nicht. Momentan versuche ich "einfach" die BOOL's in DB1 in die BOOL-Speicherstellen in DB2 zu verschieben:
Nun ein bisschen Code, den ich abgekupfert und angepasst hab':
Kompilieren tut das schon mal, aber sonst macht es nix, wenn ich die Onlinesicht des DB2 ansehe und den E0.0 On/Off schalte.
ret ist -32472, was mir nach einem "Datenmüllwert" aussieht.
Meine Fragen:
1) Weiss jemand, warum der Code nicht läuft?
2) Gibt es andere Möglichkeiten die Schreib- Lesezugriffe auf "meine" DB's zu synchronisieren? Unter welchen Bedingungen kann ich Datenkonsistenz garantieren?
Darf ich Euch bitten, Eure Antworten möglichst "idiotensicher" zu formulieren? Ich bin, siehe mein (aktuellgültiger) Name *gg*, alles andere als ein SPS-Kenner - eigentlich Java-Programmierer.
Vielen Dank für Eure Gedanken,
Oliver
Ist die Datenkonsistenz gewährleistet bei Kommunikation zwischen:
CPU315-2 DP (315-2AG10-0AB0) und CP343-1 Advanced (343-1GX21-0XE0) oder CP343-1 (343-1EX11-0XE0)
Fallbeschreibung:
- Das CP kommuniziert über Ethernet(*)
- Die CPU schreibt die Kommunikationsdaten in einen Datenbaustein (DB)
(*) Wir haben einen Treiber, der mit dem CP über Ethernet kommuniziert und seine Daten so in z.B. einen Datenbaustein (DB1) schreibt.
Andererseits liest unser SCL-Programm während des SPS-Zyklus diese Werte aus und schleust diese Werte zu den I/O's weiter.
Der Treiber garantiert uns, dass er eine Datenmenge von einem Block (216 Bytes) konsistent zum CP sendet.
Umgekehrt lesen wir die Daten per SCL von den I/O's und schreiben diese in DB2. Unser Treiber fragt dann diese Daten wiederum über das CP ab.
Nach meinen Erkundigungen scheint es nun so zu sein, dass das Schreiben in die DB's und das Lesen daraus nicht synchronisiert ist und das somit Dateninkonsistenzen auftreten können.
Ich bin mir nicht sicher, ob diese Inkonsistenz die einzelnen Variabeln betreffen kann oder nur die ganzen übertragenen Speicherblöcke. Wir könnten es uns schon leisten, dass Werte verloren (x) gehen, jedoch nicht, dass sie verändert werden.
(x) Fall: CP schreibt in DB, wird nicht fertig und CPU liest derweilen aus DB.
In der SFC Referenz hab' ich folgende, interessante Funktion gefunden:
UBLKMOV (SFC81)
Diese verspricht mir einen max. 512 Byte grossen Datenbereich atomisch zu kopieren.
Dies gelingt mir nicht. Momentan versuche ich "einfach" die BOOL's in DB1 in die BOOL-Speicherstellen in DB2 zu verschieben:
Nun ein bisschen Code, den ich abgekupfert und angepasst hab':
VAR_TEMP
Quelle : ANY;
QuellPointer AT Quelle : STRUCT
SyntaxID : BYTE;
Datentyp : BYTE;
Laenge : INT;
db_Nummer : INT;
BytePointer : DWORD;
END_STRUCT;
Ziel : ANY;
ZielPointer AT Ziel : STRUCT
SyntaxID : BYTE;
Datentyp : BYTE;
Laenge : INT;
db_Nummer : INT;
BytePointer : DWORD;
END_STRUCT;
BEGIN
DB1.DX[0,0] := E0.0;
// Quellbereichsdefinition
Quelle := DB1.DX[0,0];
QuellPointer.SyntaxID := b#16#10;
QuellPointer.Datentyp := b#16#1; //Datentyp WORD
QuellPointer.Laenge := 8; //Zum Beispiel 10 Worte
QuellPointer.db_nummer := 1; //zum Bleistift DB100
QuellPointer.BytePointer := dw#16#84000000; // OR SHL(IN: DINT_TO_DWORD(i),N:=3);
// Zielbereichsdefinition
Quelle := DB2.DX[0,0];
ZielPointer.SyntaxID := b#16#10;
ZielPointer.Datentyp := b#16#1; //Datentyp WORD
ZielPointer.Laenge := 8; //Zum Beispiel 10 Worte
ZielPointer.db_nummer := 2; //zum Bleistift DB100
ZielPointer.BytePointer := dw#16#84000000; // OR SHL(IN: DINT_TO_DWORD(i),N:=3);
ret := UBLKMOV(SRCBLK := Quelle // IN: ANY
,DSTBLK := Ziel // OUT: ANY
); // INT
END_VAR
Kompilieren tut das schon mal, aber sonst macht es nix, wenn ich die Onlinesicht des DB2 ansehe und den E0.0 On/Off schalte.
ret ist -32472, was mir nach einem "Datenmüllwert" aussieht.
Meine Fragen:
1) Weiss jemand, warum der Code nicht läuft?
2) Gibt es andere Möglichkeiten die Schreib- Lesezugriffe auf "meine" DB's zu synchronisieren? Unter welchen Bedingungen kann ich Datenkonsistenz garantieren?
Darf ich Euch bitten, Eure Antworten möglichst "idiotensicher" zu formulieren? Ich bin, siehe mein (aktuellgültiger) Name *gg*, alles andere als ein SPS-Kenner - eigentlich Java-Programmierer.
Vielen Dank für Eure Gedanken,
Oliver