Datenkonsistenz in DB's sicherstellen

SPS-Dummy

Level-1
Beiträge
2
Reaktionspunkte
0
Zuviel Werbung?
-> 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':

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
 
Schau die den Returncode mal als Hex an und suche in der Hilfe nach den Rückgabewerten des Bausteins.

-32472 --> W#16#8128

8x28 Ausrichtungsfehler beim Lesen eines Parameters.

Warum Ret_val ein Int sein muß, obwohl der Code eigentlich Hex ist, bleibt wohl ein Geheimnis der Siemens-Entwickler.

Es scheint aber, als wenn deine Pointer so nicht hinhauen.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich bin mit nicht sicher, du willst ja anscheinend 8 Boolean kopieren in deinem Beispiel (Dein Datentyp ist 1 als Boolean). Könnte sein, daß man mindestens ein Word kopieren muß, also 16 Bool, versuchs mal.
Näheres zu Any findest du im Forum in der FAQ.
 
Ohne die Hilfe von Step7 gelesen zu haben:
QuellPointer.BytePointer wird vermutlich einen Pointer benötigen. Pointer in Step7 sind so codiert, daß ein Byte die Art des Speicherbereichs (Datenbausteine, Merker, Eingänge, usw) bestimmt, ein weiteres Byte die DB Nummer und der Rest die Anfangsadresse. Ich weiß nicht, ob die durch dw#16#84000000; codierte Zahl einen korrekten Pointer darstellt, aber wenn dann steht 0x84 für den Bereich der Datenbausteine. der Rest ist Null. Damit sind Quelle und Ziel DB0 ab DBB 0.
In Step7 Läßt sich ein Pointer so schreiben: #P#DB2.DBX4.0. Das ist ein Pointer auf DBB4 (oder dessen erstes Bit, DBX4.0) im DB2
 
Datenkonsistenz

Hallo,

SPS_Dummy schrieb:
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.

Das ist richtig erkannt, die Kommunikation ist doch völlig asynchron zum SPS-Zyklus. Weiss der Teufel, wann Daten vom CP in den Datenbaustein geschrieben werden b.z.w. vom CP aus dem Datenbaustein gelesen und an den Koppelpartner übermittelt werden (vielleicht hat auch nur irgendein Depp den RJ45 Stecker gezogen ?).

Du kannst jedoch selber für Konsistenz sorgen, indem Du z.B. dafür ein zusätzliches Bit im Datenverkehr definierst. Also neue Daten in den DB erst schreiben, wenn die vorige Datenübertragung komplett abgeschlossen ist.
Nur mal so als Denkanstoss ...
Das Schreiben und Lesen in die DB's der jeweilgen Steuerungen ist wirklich absolut asychron, das ist auch nicht zu ändern. Dateninkonsistenzen kann man aber durch entsprechende Programmierung vermeiden.

Gruß

Question_mark
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen lieben Dank für die guten Antworten!

Ich hab' noch ein Statement von Siemens zu diesem Thema bekommen:

die exakte Definition der Datenkonsistenz finden Sie im folgenden Handbuch im Kapitel 3.2.9 "Datenkonsistenz" bzw. im Anhang:

"CPU 31xC und CPU 31x, Technische Daten Gerätehandbuch"
http://support.automation.siemens.com/WW/view/de/12996906

Der SFC81 "UBLKMOV" ist prinzipiell für die S7-400 Steuerungen implementiert worden und aus Kompatibilitätsgründen für die S7-300 verwendbar.

Die maximale Datenmenge, die Sie kopieren können, beträgt 512 Byte bei den S7-400 Steuerungen und maximal 64 Byte (CPU 317, CPU 319: 160 Byte) bei der S7-300 Steuerungen, wobei die Daten immer im Zykluskontrollpunkt des Betriebssystems konsistent in/aus den/dem Anwenderspeicher kopiert werden.

Ich verstehe dies nun so, dass ich mittels "UBLKMOV" bei meiner CPU eine Datenkonsistenz von 64 Bytes erzwingen kann. So fände auch der Transfer der Daten zu einem definierten Zeitpunkt statt. (Im Zykluskontrollpunkt, der offenbar dem Zeitpunkt entspicht, an dem das Prozessabbild übernommen wird, bzw. rausgeschrieben. Gibt es 2 Zykluskontrollpunkte (IN/OUT)?)

Versteht das jemand anders? :)

Wenn meine Daten jedoch mehr als 64 Bytes gross wären: Muss ich dann damit rechnen, dann 2 CPU-Zyklen für den Transfer gebraucht würden oder verwechsle ich da was?
 
Hallo,

Gibt es 2 Zykluskontrollpunkte?
Für OB1: nein. Ausnahme: ein Prozessabbild, das für einen Alarm zur Verfügung gestellt wird.

Wenn meine Daten jedoch mehr als 64 Bytes gross wären: Muss ich dann damit rechnen, dann 2 CPU-Zyklen für den Transfer gebraucht würden oder verwechsle ich da was?
Die Kommunikation erfolgt nicht unbedingt synchron zum SPS-Zyklus (das ist einstellbar - Standard ist asynchron). Was gewährleistet ist, ist die konsistente Übernahme und Übergabe der 64 Bytes im Zykluskontrollpunkt an das Anwenderprogramm (OB1). Wenn die CPU eine sehr kurze Zykluszeit hat, können durchaus mehrere OB1 Zyklen vergehen, bis der Kommunikationsprozessor die Daten übertragen hat. Der UBLKMOV hält den Zyklus für die Kommunikation nicht extra an.

Ein wenig tendiere ich persönlich zu dem Lösungsansatz von Question_mark und würde die Konsistenz mit Hilfe von Handshake-Variablen anwenderprogrammseitig sicherstellen.

Gruß
 
Zuletzt bearbeitet:
Zurück
Oben