Document Title

| ALPHA-VISION® SoftPlc7

# S7Sync.dll-Plugin

## 1. Allgemeines

Die Anbindung dieser DLL an die SoftPlc7 ermöglicht es, mehrere SoftPlc7-Instanzen in einem Netzwerk mit einer Kontrollapplikation zu synchronisieren. Die Synchronisation erfolgt über Tokens, die zyklisch weitergereicht werden. Dadurch wird gewährleistet, dass zu jedem Zeitpunkt höchstens eine SoftPlc7 ihr Step7-Programm abarbeitet. Erhält eine SoftPlc7 das Token, werden alle anstehenden OB-Zyklen ausgeführt und anschließend das Token an die nächste SoftPlc7 weitergereicht. Alle anderen Instanzen befinden sich währenddessen in einem Wartezustand. Wenn das Token bei der Kontrollapplikation angekommen ist, kann diese für jede S7-Instanz je ein Kommando absetzen, das vor dem nächsten OB-Zyklus einer SoftPlc7 ausgeführt wird. Die Kommunikation erfolgt dabei über einen Shared-Memory-Bereich für jede Instanz mit festen Strukturen für Kommando-Parameter und Nutzdaten-Bereich.
Momentan exisieren folgende Kommandos:

## 2. Kommandos

Kommando | Beschreibung | erforderliche CPU-Zustände
--- | --- | ---
CMD_STOP | Stoppt die CPU. | RUN, UNFREEZE
CMD_START | Führt einen Neustart (OB100) aus. Es werden die initiellen DBs geladen. nichtremanente Merker-Bits, Zähler und Timer werden zurückgesetzt. | STOP, UNFREEZE
CMD_RESUME | Führt einen Wiederanlauf (OB101) aus. Die im Speicher befindlichen DBs und Merker-Block werden weiter verwendet. Zähler und Timer bleiben unverändert. | STOP, UNFREEZE
CMD_COLDSTART | Führt einen Kaltstart (OB102) aus. Es werden die initiellen DBs geladen. Merker-Block, Zähler und Timer werden vollständig zurückgesetzt. | STOP, UNFREEZE
CMD_FREEZE | Die Programmabarbeitung wird angehalten, einschließlich Timer und IEC-Timer. | keine
CMD_UNFREEZE | Die Programmabarbeitung wird fortgeführt; Timer und IEC-Timer werden intern korrigiert und laufen mit dem Status zum Zeitpunkt des FREEZE weiter. | keine
CMD_LOADPROGRAM | Die CPU wird vollständig zurückgesetzt und das im übergebenen Ordner befindliche S7-Programm geladen. Die Maschine befindet sich danach im Zustand STOP. | STOP, UNFREEZE
CMD_SAVEPERSISTENT | Alle veränderlichen Daten, d.h. DBs, Merker-Block, Zähler und Timer, werden im Persistent-Ordner gespeichert. | STOP, UNFREEZE
CMD_WRITESNAPSHOT | Ein vollständiges Abbild der veränderlichen Daten der CPU wird in den Nutzdaten-Bereich des Shared-Memory geschrieben. Die Daten umfassen: sämtliche Datenbausteine, Merker, (Peripherie-) Ein-/Ausgänge, Zähler, Timer, IEC-Timer, S7-Thread-spezifische Daten und der CPU-Zustand. | FREEZE
CMD_RESTORESNAPSHOT | Die CPU wird bis auf die Programmbausteine zurückgesetzt und der Zustand beim Schreiben des Snapshots restauriert. Die Maschine befindet sich danach weiterhin im Zustand FREEZE. | FREEZE

## 3. Konfiguration

Die Weitergabe des Tokens wird durch benamte Semaphore realisiert, deren Namen über Einträge in der jeweiligen SoftPlc7.ini-Datei festgelegt werden.

Sektion/Schlüssel | Default-Wert | Beschreibung
--- | --- | ---
[Plugin-Functions]
Func1= S7Sync,S7SyncControl | "" | Diese Funktion wird in einem festen Takt, mit dem auch die OB-Zyklen synchronisiert werden, aufgerufen. Sie wartet auf das Token, übergibt die Kontrolle den S7-Threads und sendet nach Zyklusende das Token weiter.
[IPC-SYNC]
SNAPBUFSIZE=<long> | 0 | Größe des Nutzdaten-Bereichs für Kommandos. Ist der Wert 0 eingestellt, wird die Größe 1024 * 1024, also 1 MB, angenommen.
OWNSEM=<String> | "" | Name der Semaphore, auf die die SoftPlc7 wartet.
NEXTSEM=<String> | "" | Name der Semaphore, die die SoftPlc7 setzt, wenn die anstehenden OB-Zyklen abgearbeitet sind.
SHMNAME=<String> | "" | Name des Shared-Memory-Bereichs, über den die Kommunikation stattfindet.
INSTNR=<long> | -1 | Nummer der SoftPlc7 für die Tokenweitergabe, nicht zu verwechseln mit der Instanznummer. Der Wert 1 ist der Kontrollapplikation vorbehalten.

## 4. Datenaustausch über SHM (Shared Memory)

Zusätzlich zur synchronisierten Kommunikation über ein Shared Memory gibt es auch die Möglichkeit, je SoftPlc7 zwei Datenbausteinbereiche zu definieren, von denen ein Bereich als Empfangs- und der andere als Sendepuffer benutzt wird. Die Definition erfolgt über Einstellungen in der SoftPlc7.ini-Datei:

Sektion/Schlüssel | Default-Wert | Beschreibung
--- | --- | ---
[HLL-Functions]
PY0,0=S7Sync,DoDBExchangeSHM | "" | Bewirkt, dass die Funktion DoDBExchangeSHM aus der S7Sync.dll aufgerufen zyklisch wird.
[DBExchangeSHM]
DBNumIn | 0 | Datenbausteinnummer des Empfangs-DB. 0 bedeutet Peripherieeingang PE.
DBNumOut | 0 | Datenbausteinnummer des Sende-DB. 0 bedeutet Peripherieausgang PA.
LengthIn | 0 | Länge des Empfangspuffers.
LengthOut | 0 | Länge des Sendepuffers.
OffsetIn | 0 | Offset innerhalb des Empfangs-DB (bzw. PE) für den Pufferbeginn.
OffsetOut | 0 | Offset innerhalb des Sende-DB (bzw. PA) für den Pufferbeginn.
SHMNameIn | "" | Name des Shared-Memory-Bereichs für den Empfangspuffer.
SHMNameOut | "" | Name des Shared-Memory-Bereichs für den Sendepuffer.

Der Eintrag in der Sektion [HLL-Functions] bewirkt, dass zwischen je zwei OB1-Zyklen die Funktion DoDBExchangeSHM aufgerufen wird. Beim ersten Mal werden lediglich die benötigten Shared-Memory-Bereiche angelegt. Ab dem zweiten Mal werden Daten aus dem Shared Memory für den Empfang in den Datenbaustein mit der Nummer DBNumIn (bzw. PE) geschrieben und Daten vom Datenbaustein mit der Nummer DBNumOut (bzw. PA) in das Shared Memory für das Senden geschrieben. Eine andere SoftPlc7, die dieselben SHM-Namen verwendet, kann auf diese Weise geschriebene Daten empfangen oder Daten bereitstellen, die von der ersten SoftPlc7 wiederum gelesen werden. Auch ein Ringschluss mit mehreren SoftPlc7 ist denkbar.
Falls nicht nur Datenbausteine, sondern auch der Peripherieeingangsbereich ausgetauscht werden soll, muss dafür gesorgt werden, dass von der SoftPlc7 für diesen Bereich der Abgleich zwischen PE und E vorgenommen wird: Der Eintrag in der Sektion [HLL-Functions] ändert sich dann zu "PY<Offset>,<Length>=S7Sync,DoDBExchangeSHM", wobei <Offset> und <Length> den PE-Bereich definieren. Wird lediglich der Peripherieausgang angesprochen, d.h. kein PE, ist keine Änderung nötig.
Die Kommunikation erfolgt ohne Synchronisation; wenn nach einem OB1-Zyklus das Shared Memory noch beschrieben wird, wird nicht gewartet, sondern versucht, nach dem nächsten OB1-Zyklus zu lesen.