# Libnodave Verbindungen zu mehrereren S7-CPUs



## Machtnix (12 Mai 2008)

Für Linux habe ich mir ein Hintergrundprogramm geschrieben, das bestimmte DBs per Libnodave (0.84 TCP) in  Gerätedateien  wiederspiegelt,  auf die  andere Programme dann wiederum zugreifen können.  Ich  hatte es gleich für mehrere Verbindungen zu verschiedenen CPUs konzipiert, die jeweils in einem Thread laufen. Mit einer Verbindung zu einer CPU läuft alles ganz wunderbar.

Nun hatte ich neulich mal die Möglichkeit, es in einem Netz mit mehreren (3) CPUs zu testen, und holte von jeder CPU jeweils einen DB. Da ergab sich der Effekt, daß sich die Daten  munter  vermischten,  dh wenn ich einen  DB beobachtete, kamen da nacheinander die  Daten von allen dreien an. 

Hab ich nun etwas falsch gemacht oder ist Libnodave garnicht für mehrere Verbindungen konzipiert? Ich vermute, daß Libnodave intern jeweils dieselben Verbindungsnummern benutzt und bei den eingehenden Päckchen die Absender-Adresse nicht überprüft.


----------



## afk (13 Mai 2008)

Machtnix schrieb:


> Hab ich nun etwas falsch gemacht oder ist Libnodave garnicht für mehrere Verbindungen konzipiert?


Da libnodave nach meinen Erfahrungen völlig problemlos mit mehreren Verbindungen funktioniert, mußt Du wohl was falsch gemacht haben.  

Ich vermute mal, daß Dein Problem darin liegt, daß die Funktionen von libnodave nicht threadsafe sind, und Du Deine Threads nicht synchronisiert hast. Wenn Du die Aufrufe der Funktionen von libnodave (vor allem daveReadBytes und daveWriteBytes) mit Semaphoren verriegelst, dann müßte es korrekt funktionieren.  


Gruß Axel


----------



## Machtnix (13 Mai 2008)

Vielen Dank, dann werde ich es wohl mal so versuchen. Mit den Threads war es zwar gerade meine Absicht, die einzelnen Verbindungen voneinander unabhängig zu halten und nicht mit allen warten zu müssen, wenn eine gestört ist, aber wenn es nicht anders geht, muß ich halt meine Erwartungen erstmal wieder zurückschrauben.


----------



## Ralle (13 Mai 2008)

Ich arbeite das Lesen/Schreiben von Daten zwar auch in einem extra Thread ab, aber für alle SPS in einem, nacheinander weg.


----------



## afk (13 Mai 2008)

Machtnix schrieb:


> Mit den Threads war es zwar gerade meine Absicht, die einzelnen Verbindungen voneinander unabhängig zu halten und nicht mit allen warten zu müssen, wenn eine gestört ist, aber wenn es nicht anders geht, muß ich halt meine Erwartungen erstmal wieder zurückschrauben.


Von warten auf "gestörte" Verbindungen war keine Rede. Bei ISO-over-TCP kannst Du unabhängig von der Semaphore den Socket zur SPS öffnen, und wenn sich der öffnen läßt, ist die Verbindung nicht mehr "gestört". Aber die Aufrufe der Kommunikationsfunktionen (z.B. daveReadBytes, daveWriteBytes, daveConnectPLC, usw.) müssen über Semaphore abgesichert werden.


Gruß Axel


----------



## Machtnix (13 Mai 2008)

Der Socket wird ja nur beim Programmstart geöffnet. Dann läuft das Programm im Idealfall dauerhaft. Wenn nun eine CPU oder ein Switch oder sonstwas im Netz mal ausfällt,  wird mit Semaphoren auch das Datenholen von den  ungestörten Verbindungen verzögert, weil zumindest das Timeout der gestörten Verbindung abgewartet werden muß. Solche Abhängigkeiten wollte ich eigentlich vermeiden, aber wenns so nicht geht,  muß  ich mich eben damit abfinden.


----------



## afk (13 Mai 2008)

Machtnix schrieb:


> Der Socket wird ja nur beim Programmstart geöffnet. Dann läuft das Programm im Idealfall dauerhaft.


Wenn die Verbindung abreißt, dann solltest Du aber auch zur Laufzeit des Programms den Socket schließen und wieder neu öffnen, sonst mußt Du ja das Programm neu startenn, um die Verbindung wieder zum Laufen zu bringen.



Machtnix schrieb:


> Wenn nun eine CPU oder ein Switch oder sonstwas im Netz mal ausfällt,  wird mit Semaphoren auch das Datenholen von den  ungestörten Verbindungen verzögert, weil zumindest das Timeout der gestörten Verbindung abgewartet werden muß. Solche Abhängigkeiten wollte ich eigentlich vermeiden, aber wenns so nicht geht,  muß  ich mich eben damit abfinden.


Den Timeout kannst Du aber so einstellen, daß er in einem für Dich erträglichen Rahmen liegt. Wenn die Kommunikation auf das LAN beschränkt ist, kannst Du mit einer geringen Antwortzeit rechnen, die hauptsächlich von der Reaktionsgeschwindigkeit der CPU abhängig ist.


Gruß Axel


----------



## Jochen Kühner (19 Juli 2010)

*Grab mal diesen alten Thread aus....*

Hallo, ich grab mal diesen alten Thread aus um was abzuklären.

Wenn ich in meiner Connection Library für .NET mehrere Verbindungen unterstützen will was muss Ich den fürs multithreading beachten??

Ich muss dann alle libnodave funktionen gegeneinander verriegeln, welche daten über die sps Schnittstelle versenden und empfangen, oder?


----------



## dimdum (9 September 2010)

Guten Abend
müssen alle Funktionen verriegelt werden oder nur die eigentlichen Read und write funktionen? Wäre es dadurch möglich in allen Threads schon einen verbindungsaufbau zu machen und dann nur das lesen und schreiben zu verriegeln?

Mein Problem besteht darin, dass ich mit knappen 100 CPUs (200er) über Lan kommunizieren muss, jeweils ca. 20 Byte lesen und 20 Byte schreiben muss pro CPU und doch eine Zykluszeit von kleiner 2 Sekunden brauche.

Ist das realistisch oder einfach nicht zu schaffen?

Danke im voraus ich bin für alle Ideen dankbar

Gruß aus dem Sauerland
Sebastian


----------



## dimdum (26 September 2013)

Hallo Zusammen

der Vollständigkeit wollte ich hier meine Erfahrungen zu Multithreading mit der Libnodave kurz umschreiben.

Ich habe ein Csharp Programm geschrieben, dass einen Datenaustausch mit aktuell ca. 100 Siemens SPSen macht. Es sind hauptsächlich 224XP SPSen von Siemens, aber auch teilweise WinAC oder ET200 Steuerungen dabei. Innerhalb des Programms wird für jeden aktiven Teilnehmer (SPS) ein Thread berechnet und erstellt. Das Programm stellt eine Verbindung zu den jeweiligen SPSen her und hält diese Verbindung durchgehend. Es werden ca. 50 Byte Daten pro Zyklus geschrieben, gelesen, entsprechend umgewandelt und in mehrere Microsoft SQL Tabellen geschrieben.
Jeder thread hat eine aktuelle Zykluszeit von durchschnittlich ca. 700ms.

Bei der Programmierung muss berücksichtigt werden, wenn man über mehrere Threads Verbindungen zu mehreren SPSen herstellen und halten will dass Alle Befehle von Libnodave die etwas mit dem Verbindungs Aufbau und Abbau zu tun haben gegeneinander verriegelt werden müssen, da es sonst zu fehlern kommt. Die eigentlichen Read und Write Befehle musste ich nicht verriegeln, da diese anscheinend Threadsicher sind.

Zu meinem letzten Beitrag kann ich mir die Frage mittlerweile selbst beantworten, ja es funktioniert... das zu programmierende Sytem läuft mittlerweile den 2. Monat in realer Produktion.

Wenn jemand Fragen zu dem Thema hat, kann er mir gerne per PN schreiben.

Gruß
Sebastian


----------

