mirror of
https://github.com/netdata-be/libnodave
synced 2025-10-13 00:42:50 +08:00
172 lines
11 KiB
Plaintext
172 lines
11 KiB
Plaintext
Questions I have been asked and answers:
|
|
|
|
Q: My VB,.NET or Delphi application doesn't work. I suppose libnodave doesn't work with my
|
|
hardware or doesn't work at all. Can you help me?
|
|
A: You can most easily find out whether Libnodave works with your hardware, PLC, adapter
|
|
etc: try the precompiled test programs. If they don't work (trying different options when
|
|
suggested), it's clearly libnodave's fault.
|
|
If they work, it's your application (or there is a little chance, the problem is in the
|
|
interface to the language you use).
|
|
|
|
Q: Can you help me?
|
|
A: Before asking me, try out the test programs as described above. When they don't work for
|
|
you, send me the output with debug option, e.g. do:
|
|
testMPI -d COM1 >debugout.txt
|
|
If they work, but your application doesn't, do:
|
|
Insert "daveSetDebug(daveDebugAll)" before calling anything else from libnodave.
|
|
Then do:
|
|
yourappliation >debugout.txt
|
|
For those people who grew up with mice and don't know the command line:
|
|
This works even with MS-Excel. Create a spreadsheet, import the VBA module,
|
|
- uncomment the "call daveSetDebug(daveDebugAll)" at the begin of sub initialize,
|
|
- save the sheet.
|
|
- then, from commandline (dos box, cmd) do:
|
|
excel testsheet >debugout.txt
|
|
All debug output (otherwise invisible) goes into debugout.txt.
|
|
When time falls short, I shall discard mails not containig debug output!
|
|
|
|
Q: What mail format do you prefer?
|
|
A: Ok, nobody asked that, but I DO prefer PLAIN TEXT.
|
|
|
|
Q: I want to read out whether my PLC is in RUN or STOP mode. Is there a function for that?
|
|
A: No, not a specialized one. For S7-300/400, use daveReadSZL to read the diagnostic lists.
|
|
This is what Step7 does. You will find information about IDs and indices in Siemens
|
|
documentation. The state of all the CPU LEDs is in ID 25 (19hex) index 0.
|
|
With S7-200, the information is somewhere in the system data.
|
|
|
|
Q: I trying to trace libnodave with a debugger. I need help?
|
|
A: There is no reason to use a debugger on libnodave unless you suspect one of the
|
|
following things:
|
|
- memory leaks
|
|
- range overflows, on numbers or array indices
|
|
- problems with passing parameters to library functions
|
|
In the latter case, better recompile libnodave after uncommenting #define DEBUG_CALLS in
|
|
nodave.c.
|
|
To find problems with PLCs and adapters, the FAR better way is to use
|
|
setDaveDebug(daveDebugAll). This will show you what is sent and received from PLC/adapter
|
|
and it will show you the relevant information instead of extracting it from memory
|
|
contents or processor registers. Thus, data exchange with the PLC is still carried out with
|
|
normal timing. With a debugger, the code might send one part of a message and then pause
|
|
longer than PLC side timeouts.
|
|
|
|
Q: Can you give documentation about S7 communication or MPI protocol?
|
|
A: No, I can't. What I know about it is from reverse engineering. This means sniffing lots of
|
|
packets, trying to make sense of them and trying to generate them with my own code.
|
|
If things are named so or so in libnodave this reflects my current hypothesis. I could
|
|
try to write documentation, but that would allways be a step behind the code: The code
|
|
is what can be proven against existing hardware, i.e. reaity. The docs cannot. And I think
|
|
the code is fairly well documented...
|
|
|
|
Q: So why do you have these complicated structures?
|
|
A: What people might have found complicated are probably the pointers to protocol dependent
|
|
functions. In fact, they make the library more simple in two ways:
|
|
- First, they separate packet forming from transport. If someone finds out how to do some
|
|
function that can be done with a Simatic S7, it is sufficient to implement the packet
|
|
forming part and it will most likely work with any transport protocol. Vice versa, if there
|
|
would be a new transport mechanism, probaly all functions will work with it as soon as the
|
|
transport functions are implemented. Version 0.8 clearly shows that by implementing a
|
|
transport vie s7online.dll.
|
|
- Commercial libraries I looked at usually have separate sets of functions for the 200
|
|
and the 300/400 family. Libnodave hasn't, so you have less to learn about the API while your
|
|
code can do more without any modification.
|
|
|
|
Q: Why do you export these structures if you say they are meaningless for applications?
|
|
A: They are not completely meaningless. There are also a lot of "intermediate step functions"
|
|
that are exported from the .dll or.so which are normally of no use to end users.
|
|
- All this is there - in the spirit of open source - for those who want to do their
|
|
own experiments. It may give you possibilities I did not think of.
|
|
- At least once, I could help a user implementing a new function (daveForce200). He only
|
|
had to add about 20 lines to his application which in turn called intermediate steps
|
|
of packet forming and analysis, like _daveAddData.
|
|
|
|
Q: Why aren't there functions like readOutputs, readInputs, readData ?
|
|
A: Other libraries usually have separate functions to read from inputs, outputs, flags,
|
|
data blocks and so on. Libnodave hasn't. Again, you have to learn less about the API.
|
|
|
|
Q: Why aren't there functions like readBytes, readIntegers, readDWords, readFloat ?
|
|
A: Other libraries often have separate functions to read integers, dwords or floats.
|
|
Libnodave hasn't. The reason is: If you have a DB (or memory area) containg mixed data
|
|
types, with those function you can only read parts of such a block. Or you use readBytes
|
|
to read the memory as raw bytes and you are left alone wit the conversion.
|
|
Libnodave generally reads an entire block of data as bytes and then provides you
|
|
with conversion functions to convert it to PLC data types and byte order.
|
|
|
|
Q: I try to compile my source code which includes nodave.h. Why do I get:
|
|
"#error Fill in what you need for your OS or API" ?
|
|
A: Libnodave has to use different functions to read byte data from serial ports or TCP/IP streams
|
|
depending on the operating system. You have to specify which OS you compile for.
|
|
Define BCCWIN for Windows and LINUX for Linux or other Unix style operating systems. I do
|
|
that using -DBCCWIN or -DLINUX when I call the compilers out of a Makefile. If you use an IDE
|
|
(integrated development environment), refer to the IDE's documentation to learn where to do
|
|
this. If you can't find out, you can help yourself putting the #define into your code (which
|
|
means your code will not be portable to other OS without modification). example:
|
|
|
|
...
|
|
#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: I try to compile libnodave from source code. There are problems.
|
|
A: - You do not need to compile libnodave yourself. You won't do it with other DLLs (windows)
|
|
or .so (Linux shared libraries). Normally, you will link such libraries dynamically with
|
|
your code.
|
|
- Nevertheless, you have the sources and you may chose to recompile it or recompile only the
|
|
parts you need, etcetera.
|
|
- You should know that S7 uses Motorola (big endian, high byte first) byte order (endianness)
|
|
while Intel processors use Intel (little endian, low byte first). On Intel and similar
|
|
machines, libnodave has to convert multibyte values. This is done in daveGetS2(), daveGetU2(),
|
|
daveGetFloat() and friends. The conversion code is only compiled in if you #define
|
|
DAVE_LITTLE_ENDIAN. Otherwise, big endian is assumed.
|
|
- Be aware that I do compile releases of libnodave using gcc (for Linux) and MSVC++
|
|
(for windows). I use the script buildall to build Linux and Windows release versions and test
|
|
programs on a Linux box. Buildall uses Linux make with MAKEFILE.VC.WINE to invoke the MSVC++
|
|
compiler for windows versions. There is also a MAKEFILE.VC which should work on a windows
|
|
system using nmake, but it may be out of date :-(. If in doubt about compiler options or
|
|
source files involved, refer to MAKEFILE.VC.WINE!
|
|
|
|
Q: I want to compile libnodave for another OS. What adaptions shall I have to make?
|
|
A: - I suppose your OS is 32 bit and your compiler treats int as 32 bit. If not, you are in
|
|
trouble!
|
|
- You need to provide functional replacements for setport.c or setportw.c and openSocket.c or
|
|
openSocketw.c
|
|
- nodave.h: You need to define a record _daveOSserialType containing members:
|
|
rfd: a data type that can refer to a serial port or a TCP socket for read access
|
|
wfd: a data type that can refer to a serial port or a TCP socket for write access
|
|
- nodave.c: You need to code functions stdread() and stdwrite() to read and write a number of
|
|
bytes from/to a serial port to/from a buffer.
|
|
|
|
Q: Is there a function to read PLC Data structure of a data block? The variables
|
|
and their data type ?
|
|
A: No. The structure information is only available to Step7 BEFORE compilation. It is NOT stored
|
|
in the PLC itself. Same situation if you open a new project and load the code from PLC into
|
|
programmer: Your DBs will be nothing more than arrays of bytes.
|
|
|
|
Q: I have problems writing inputs. Can you help me?
|
|
A: Well, there are 2 types of inputs: 1. Peripheral adresses. This is what you read with daveP
|
|
or, in a PLC program, with L PIW <address>. Accesses to these addresses are real hardware
|
|
read or write accesses and there is no way to write to input hardware.
|
|
2. Input/Output image memory. This is how programmers normally access Siemens I/O like in:
|
|
L IW <address>
|
|
or
|
|
A I 2.5
|
|
Accesses to these addresses do NO access the hardware but a special memory area. The
|
|
inputs are copied to this memory in each cycle before the application program is executed.
|
|
If you write to this memory area using daveInputs, the memory will be overwritten before next
|
|
cycle. Whether your PLC program or your application of Libnodave will "see" the values written
|
|
to this memory is a matter of time race.
|
|
|
|
Q: Is it possible to write a number of bits (up to 3) simultaneously to the PLC?
|
|
I want to avoid using "read-modify-write" techniques and make the write as "atomic"
|
|
as possible.
|
|
A: daveWriteBits() does provide an "atomic" write function, but only for a single bit.
|
|
The length parameter to daveWriteBits() has to be one, other values produce errors with
|
|
CPUs that I know of. So why is this parameter there? It corresponds to a field in the message
|
|
which contains the number of bits to read or write.
|
|
|
|
Q: Can this (an atomic read to 3 bits) be done using daveWriteBits() or do I have to use multiple
|
|
write "items" within the same PDU?
|
|
A: It CANNOT be done with daveWriteBits() with the CPUs I know. Whether writing with a PDU containing
|
|
multiple items is "atomic" or not I don't know. If you can modify the PLC program, I think the best
|
|
solution would be locating the 3 bits into a byte the rest of which remains unused.
|
|
|