mirror of
https://github.com/netdata-be/libnodave
synced 2025-10-13 00:42:50 +08:00
190 lines
13 KiB
Plaintext
190 lines
13 KiB
Plaintext
Fragen, die mir schon oefter gestellt wurden und die Antworten:
|
|
|
|
Q: Meine VB,.NET oder Delphi-Anwendung funktioniert nicht. Ich vermute, Libnodave funktioniert
|
|
nicht mit meiner Hardware oder funktioniert gar nicht. Kannst du mir helfen?
|
|
A: Du kannst ganz einfach herausfinden, ob Libnodave mit deiner Hardware, SPS, Adapter
|
|
usw. arbeitet: Probierer es mit den vorkompilierten Testprogrammen. Wenn die nicht funktionieren
|
|
(auch die vorgeschlagenen Optionen probieren, wenn welche vorgeschlagen werden), ist es ganz
|
|
klar ein Fehler in Libnodave.
|
|
Wenn sie funktionieren, liegt es an deiner Anwendung (oder, selten, koennte das Problem in
|
|
der Schnittstelle zu der verwendeten Programmiersprache liegen).
|
|
|
|
Q: Kannst du mir helfen?
|
|
A: Bevor du fragst, probiere die Testprogramme wie oben beschrieben. Wenn die bei dir nicht
|
|
funktionieren, schicke mir die Ausgabe mit der Debug-Option, z.B.:
|
|
testMPI -d COM1 >debugout.txt
|
|
Wenn sie funktionieren, deine Anwendung aber nicht, probier mal:
|
|
Fuege die Zeile "daveSetDebug(daveDebugAll)" vor allen anderen Aufrufen von Libnodave in
|
|
deinen Code ein.
|
|
Dann versuche:
|
|
deineAnwendung >debugout.txt
|
|
Fuer die Leute, die mit Maeusen gross wurden und die Kommandozeile nicht mehr kennen:
|
|
Das funktioniert sogar mit MS-Excel. Erzeuge eine neue Tabelle, importiere das VBA_Modul,
|
|
- nimm das "rem" weg vor "call daveSetDebug(daveDebugAll)" am Anfang von sub initialize,
|
|
- Speichere das Arbeitsblatt.
|
|
- Starte dann von der Kommandozeile (Dos-Box, Ausfuehren/cmd):
|
|
excel testsheet >debugout.txt
|
|
Alle Debug-Ausgaben gelangen in die Datei debugout.txt.
|
|
Wenn meine Zeit knapp wird, schmeisse ich Mails ohne Debug-Ausgabe weg!
|
|
|
|
Q: Welches E-mail Format bevorzugst du?
|
|
A: Na ja, niemand hat danach gefragt, aber ich ziehe PUREN TEXT vor.
|
|
|
|
Q: Ich moechte auslesen, ob meine CPU in RUN oder STOP ist. Gibt es dafuer eine Funktion?
|
|
A: Nein, keine spezialisierte. Verwende bei S7-300/400 daveReadSZL, um die SZL Systemzustandslisten
|
|
zu lesen. Step7 macht das auch so. Informationen ueber IDs und Indizes findest du in der Siemens
|
|
Dokumentation. Der Zustand aller CPU-LEDs ist in ID 25 (19hex), index 0.
|
|
Bei der S7-200 befindet sich diese Information irgendwo in den Systemdaten.
|
|
|
|
Q: Ich versuche, Libnodave mit einem Debugger nachzuvollziehen. Ich brauche Hilfe?
|
|
A: Es gibt kaum einen Grund, Libnodave mit einem Debugger zu untersuchen, ausser du vermutest eine
|
|
der fogenden Sachen:
|
|
- Speicherprobleme (memory leaks)
|
|
- Bereichsueberschreitungen (range overflows) bei Zahlen oder Array-Indizes.
|
|
- Probleme bei der Uebergabe von Parametern an Bibliotheksfunktionen
|
|
Im letzteren Fall uebersetze besser Libnodave neu, nachdem du das Kommentarzeichen vor
|
|
#define DEBUG_CALLS in nodave.c entfernt hast.
|
|
Um Probleme mit SPS und Adaptern zu finden, ist die Debug-Ausgabe der weit bessere Weg.
|
|
Sie zeigt dir alles, was von und zu SPS/Adapter gesendet und empfangen wird und sie
|
|
zeigt dir das, was wichtig ist, anstatt es aus Speicher und Registern herauszufinden.
|
|
|
|
Q: Kannst du mir eine Dokumentation ueber die S7-Kommunikation oder das MPI-Protokoll geben?
|
|
A: Nein, kann ich nicht. Was ich darueber weiss, stammt aus "reverse engineering". Das
|
|
bedeutet, eine Menge Pakete mitzuschreiben, versuchen, einen Sinn hineinzuinterpretieren
|
|
und sie mit eigenem Code nachzubilden. Wenn in Libnodave Dinge Namen haben, so geben diese
|
|
meine gegenwaertige Hypothese wieder. Ich koennte versuchen, Dokumentation zu schreiben, aber
|
|
die wuerde immer einen Schritt hinter dem Code hinterherhinken: Der Code kann an der gegebenen
|
|
Hardware, also an der Realitaet, getestet werden, die Dokumentation nicht. Und der Code ist
|
|
recht gut dokumentiert...
|
|
|
|
Q: Also, warum gibt es diese komplizierten Strukturen (structs)?
|
|
A: Was kompliziert erscheint, sind wahrscheinlich zunaechst die Zeiger auf protokollspezifische
|
|
Funktionen. In Wahrheit machen sie die Bibliothek einfacher in zweierlei Hinsicht:
|
|
- Erstens trennen sie die Bildung der Pakete vom Transport. Wenn jemand herausfindet, wie man
|
|
mit der S7 etwas neues machen kann, reicht es, die Paketbildung zu implementieren und schon
|
|
wird es hoechstwahrscheinlich mit jedem Transportprotokoll funktionieren. Wenn andererseits
|
|
ein neuer Transportmechanismus hinzukommt, werden wahrscheinlich alle Functionen damit
|
|
funktionieren, sobald der Transport an sich funktioniert.
|
|
Version 0.8 zeigt das klar anhand der Implementierung des Transports ueber s7online.dll.
|
|
- Kommerzielle Bibliotheken, die ich gesehen habe, haben meist getrennte Saetze von Funktionen
|
|
fuer die 200 und die 300/400 Familie. Libnodave hat das nicht. So musst du weniger ueber das
|
|
API der Bibliothek lernen waehrend deine Anwendung ohne Veraenderung des Codes mehr kann.
|
|
|
|
Q: Warum exportierst du alle diese Strukturen, wenn du sagst, man braucht sie fuer keinerlei
|
|
Anwendung?
|
|
A: Sie sind nicht ganz bedeutungslos. Es sind auch eine Menge Funktionen dabei, die
|
|
"Zwischenschritte" duechfhren un normalerweise fr den Endanwender von keinem Nutzen sind.
|
|
Dennoch werden sie aus der .dll exportiert.
|
|
- Das ist alles verfuegbar - im Sinne von Open Source - fueer diejenigen, die eigene
|
|
Experimente machen wollen. Es mag ja Moeglichkeiten gebn, an die ich nicht gedacht habe.
|
|
- Wenigstens einmal konnte ich einem Benutzer helfen, eine neue Funktion (daveForce200) zu
|
|
implementiern. Er mute nur ca. 20 Zeilen in sein Programm einfuegen, die zum groessten Teil
|
|
solche Zwischenschritte beim Zusammenstellen eines Pakets und zur Analyse der Antwort
|
|
aufriefen, wie z.B. _daveAddData.
|
|
|
|
Q: Warum gibts keine Funktionen wie readOutputs, readInputs, readData ?
|
|
A: Andere Bibliotheken haben ueblicherweise separate Functionen um Eingaenge, Ausgaenge,
|
|
Merker, Datenbausteine zu lesen. Libnodave hat das nicht. Schon wieder musst du weniger
|
|
ueber das API lernen.
|
|
Q: Warum gibt es keine Funktionen wie readBytes, readIntegers, readDWords, readFloat ?
|
|
A: Andere Bibliotheken haben oft separate Funktionen um Integers, Worte oder Fliesskomma-
|
|
zahlen zu lesen. Libnodave hat das nicht. Der Grund ist: Wenn du einen DB (oder einen
|
|
anderen Speicherbereich in der SPS) hast, der Daten verschiedener Types enthaelt, koenntest
|
|
du mit solchen Functionen nur Teile davon lesen. Oder du benutzt readBytes um den Speicher
|
|
als eine Reihe von Bytes zu lesen und bist bei der Umwandlung auf dich allein gestellt.
|
|
Libnodave liest generell den ganzen Block als Bytes und stellt dir dann Funktionen zur
|
|
Umwandlung von/in SPS-Datentypen und Byte-Anordnung zur Verfuegung.
|
|
|
|
Q: Ich versuche, meinen Quellcode zu kompilieren, der nodave.h einbindet. Warum erhalte ich:
|
|
"#error Fill in what you need for your OS or API" ?
|
|
A: Libnodave mu unter verschiedenen Betriebssystemen verschiedene Funktionen nutzen,
|
|
um Daten byteweise von seriellen Schnittstellen oder TCP/IP streams zu lesen.
|
|
Diese Funktionen sind betriebssystemspezifisch. Du mut spezifizieren fr welches BS du
|
|
kompilierst. Definiere BCCWIN fuer Windows und LINUX fuer Linux oder andere Unix-artige
|
|
BS. Ich benutze -DBCCWIN oder -DLINUX beim Aufruf der Compiler aus einem Makefile. Wenn du
|
|
eine IDE (integrierte Entwicklungsumgebung) nutzt, entnimm der Dokumentation der IDE wie das
|
|
dort geht. Wenn du es nicht herausfinden kannst, kannst du dir auch helfen indem du die
|
|
#defines in deinen Quellcode schreibst (was bedeutet, dass dein Quellcode nicht mehr
|
|
ohne Aenderungen auf ein anderes System portiert werden kann). Beispiel:
|
|
|
|
...
|
|
#define BCCWIN // if you work on windows
|
|
#include nodave.h // or nodavesimple.h, but NEVER both
|
|
#include setport.h // if your code works with serial connections
|
|
#include openSocket.h // if your code works with TCP/IP
|
|
...
|
|
Q: Ich versuche, libnodave aus dem Quellcode zu kompilieren. Es gibt Probleme.
|
|
A: - Du brauchst Libnodave nicht selbst zu kompilieren. Du wrdest das mit anderen DLLs (Windows)
|
|
oderr .sos (gemeinsam genutzte Bibliotheken unter Linux) auch nicht machen. Normalerweise
|
|
linkt man solche Bibliotheken dynamisch zum eigenen Code.
|
|
- Nichtsdestotrotz steht dir der Quellcode zur Verfuegunge und du moechtes ihn oder nur die
|
|
benoetigten Teile rekompilieren usw..
|
|
- Du solltest wissen, dass die S7 die Motorola- (big endian, hchstwertiges byte zuerst)
|
|
Byteanordnung (endianness) verwendet, waehrend Intel-Prozessoren Intel-Byteanordnung
|
|
(little endian, niederwertigstes Byte zuerst). Auf Intel- und aehnlichen Maschinen
|
|
muss Libnodave Mehbyte-Werte umsortieren. Dies geschieht mittels der Funktionen daveGetS2(),
|
|
daveGetU2(), daveGetFloat() usw.. Der Code zur Konvertierung wird nur mitkompiliert
|
|
wenn du DAVE_LITTLE_ENDIAN definierst. Ansonsten wird "big endian" vorausgesetzt.
|
|
- Beachte, dass ich die publizierten Versionen von Libnodave mit gcc (fuer Linux) und MSVC++
|
|
(fuer windows) kompiliere. Dazu verwende ich das Skript buildall um Linux und Windows
|
|
Release-Versionen und Testprogramme auf einem Linux-Rechner zu erzeugen. Buildall benutzt
|
|
seinerseits das make von Linux mit MAKEFILE.VC.WINE um den MSVC++-Compiler fuer die
|
|
Windows-Versionen aufzurufen. Es gibt auch ein MAKEFILE.VC das auf einem Windows-System
|
|
mittels nmake dasselbe leisten sollte, aber es koennte nicht auf dem neuesten Stand sein :-(
|
|
Wenn du Zweifel hast, welche Compileroptionen oder Quelldateien noetig sind, schau in
|
|
MAKEFILE.VC.WINE nach!
|
|
|
|
Q: Ich moechte Libnodave fuer ein anderes Betriebssystem kompilieren. Welche Anpassungen
|
|
muss ich vornehmen?
|
|
A: - Ich nehme mal an, dass dein Betriebssystem ein 32-Bit-System ist und der zugehoerige
|
|
Compiler int als 32-Bit-Zahl behandelt. Wenn nicht, wird es schwierig!
|
|
- Du brauchst funktionsgleichen Ersatz fuer setport.c oder setportw.c und openSocket.c oder
|
|
openSocketw.c
|
|
- nodave.h: Du musst ein struct _daveOSserialType definieren, dass folgende Elemente beinhaltet:
|
|
rfd: Ein Datentyp, der eine serielle Schnittstelle oder ein TCP socket bei einem Lesezugriff
|
|
indentifiziert.
|
|
wfd: Ein Datentyp, der eine serielle Schnittstelle oder ein TCP socket bei einem Schreibzugriff
|
|
indentifiziert.
|
|
- nodave.c: Du musst die Funktionen stdread() und stdwrite() implementieren, die Bytes
|
|
von/an eine serielle Schnittstelle in/aus einem Puffer lesen/schreiben.
|
|
|
|
Q: Gibt es eine Funktion um die Struktur eines Datenbausteins zu lesen? Variablen und ihre
|
|
Datentypen ?
|
|
A: Nein. Die Strukturinformation steht nur in Step7 und nur vor der Compilierung verfuegbar.
|
|
Sie wird nicht in die SPS selbst uebertragen. Es ist dasselbe, wenn du ein neues Projekt
|
|
anlegst und den Programmcode aus der SPS laedtst: Von den Datenbausteinen bleiben nur
|
|
Byte-Arrays.
|
|
|
|
Q: Ich habe Probleme, auf Eingaenge zu schreiben. Koennen Sie mir hefen?
|
|
A: Zunaechst gibt es zwei Typen von "Eingaengen": 1. Periphere Adressen. Das ist das, was Sie
|
|
mit daveP ansprechen, oder, in einen SPS-Programm, mittels L PEW <adresse>. Zugriffe auf
|
|
diese Adressen sind echte Schreib- oder Lesezugriffe auf die Hardware und es gibt keine
|
|
Moeglichkeit, die Hardware von Eingaengen zu schreiben.
|
|
2. Prozessabbild der Ein- und Ausgaenge. Das ist was Programmierer von Siemens-SPS
|
|
normalerweise als Ein- und Ausgaenge ansprechen, wie bei:
|
|
L EW <Adresse>
|
|
or
|
|
U E 2.5
|
|
Zugriffe auf diese Adressen sprechen NICHT die Hardware sondern einen speziellen Speicherbereich
|
|
an. Der Zustand der Eingaenge wird in jedem Zyklus in diesen Speicherbereich kopiert, bevor
|
|
das Anwenderprogramm ausgefhrt wird. Wenn Sie mittels daveInputs dorthin schreiben, werden die
|
|
Werte vor dem naechsten Zyklus ueberschrieben.
|
|
Ob Ihr SPS-Programm oder Ihre Libnodave-Anwendung die geschriebenen Werte "sehen" wird, ist
|
|
ein zeitlicher Wettlauf.
|
|
|
|
Q: Ist es moeglich, mehrere (bis zu 3) Bits gleichzeitig in die SPS zu schreiben?
|
|
Ich moechte "Read-modify-write"-Techniken vermeiden und das Schreiben so "atomar" wie moeglich
|
|
halten.
|
|
A: daveWriteBits() stellt eine "atomare" Schreibfunktion bereit, aber nur fr ein einzelnes Bit.
|
|
Der Parameter "length" bei daveWriteBits() muss 1 sein, andere Werte liefern Fehler bei den
|
|
CPUs die ich kenne. Warum also ist der Parameter vorhanden? Es gibt ein entsprechendes Feld
|
|
in der Nachricht, das in anderen Faellen die Zahl der Bits angibt.
|
|
|
|
Q: Kann das ("atomares" Schreiben auf 3 Bits) mit daveWriteBits() erreicht werden oder muss
|
|
ich mehrere Variablen mit einer PDU schreiben?
|
|
A: Es kann NICHT mit daveWriteBits() erreicht werden, jedenfalls mit den CPUs die ich kenne. Ob
|
|
das I know. Whether Schreiben mehrerer Variablen mit einer PDU atomar ist, weiss ich nicht.
|
|
Wenn Sie das SPS-Programm verndern koennen, denke ich das Beste waere, die 3 Bits in ein Byte
|
|
zu packen, dessen andere Bits nicht gebraucht werden.
|
|
|