Snap7 Client

 

A PLC client is the most well-known object, almost all PLC communication drivers on the market are clients.

Into S7 world, LibNoDave, Prodave, SAPI-S7 (Simatic Net mn library) are clients.

The same OPC Server, despite to its name, is a client against the PLC.

Finally, Snap7Client is a Client.

It fulfills almost completely the S7 protocol, you can read/write the whole PLC memory (In/Out/DB/Merkers/Timers/Counters), perform block operations (upload/download), control the PLC (Run/Stop/Compress..), meet the security level (Set Password/Clear Password) and almost all functions that Simatic Manager or Tia Portal allows.

You certainly have a clear idea about its use, its functions and their use are explained in detail into the Client API reference of the Snap7 Manual.

What I think is important to highlight, is its advanced characteristics.

Snap7 library is designed keeping in mind large industrial time-critical data transfers involving networks with dozen of PLCs.

To meet this, Snap7Client exposes three interesting features : PDU Independence, SmartConnect and Asynchronous data transfer.


PDU independence

As said, every data packet exchanged with a PLC must fit in a PDU, whose size is fixed and varies from 240 up to 960 bytes.

All Snap7 functions completely hide this concept, the data that you can transfer in a single call depends only on the size of the available data.

If this data size exceeds the PDU size, the packet is automatically split across more subsequent transfers.

 

SmartConnect

When we try to connect to a generic server, basically two requirements must be met.

1.  The hardware must be powered on.

2.  A Server software listening for our connection must be running.

If the server is PC based, the first condition not always implies the second.
But for specialist hardware firmware-based such as the PLC, the things are different, few seconds after the power on all the services are running.

Said that, if we "can ping" a PLC we are almost sure that it can accept our connections.

The SmartConnect feature relies on this principle to avoid the TCP connection timeout when a PLC is off or the network cable is unwired.
Unlike the TCP connection timeout, The ping time is fixed and we can decide how much it should be.

 

When we call Cli_ConnectTo(), or when an active Snap7Partner needs to connect, first the PLC is “pinged”, then, if the ping result was ok, the TCP connection is performed.

 

Snap7 uses two different ways to do this, depending on the platform:

Windows

The system library iphlpapi.dll is used, but it’s is loaded dynamically because it’s not officially supported by Microsoft (even if it is present in all platforms and now it’s fully documented by MSDN).

If its load fails (very rare case), an ICMP socket is created to perform the ping. We use it as B-plan since we need administrative privileges to create RAW sockets in Vista/Windows 7/Windows 8.

Unix (Linux/BSD/Solaris)

From 1.3.0 an Async (with timeout) TCP connection is used so root rights are no more needed.

 

During the initialization, the library checks if the ping can be performed trying the above methods.

If all they fail, SmartConnect is disabled and all the clients (or Active partners) created will try to connect directly.

 

 

Now let's see how to take full advantage of this feature.

 

Let's suppose that we have a Client that cyclically exchanges data into a thread and we want a fast recovery in case of network problems or PLC power.

 

In the thread body we could write something like this:

 

 

 

C++

 

while (!TerminateCondition())

{   

    if (Client->Connected())

    {

       PerformDataExchange();

       sleep(TimeRate); // exchange time interval

    }   

    else

        if (Client->Connect()!=0)

            sleep(10); // small wait recovery time

}

 

//Supposing that TerminateCondition()is a bool function that //returns true when the thread needs to be terminated.

 

//In Unix you have to use nanosleep() instead of sleep() or copy
//SysSleep() from snap_sysutils.cpp.

 

 

 

Pascal

 

while not TerminateCondition do

begin   

    if Client.Connected then

    begin

       PerformDataExchange;

       Sleep(TimeRate); // exchange time interval

    end   

    else

        if Client.Connect<>0 then

            Sleep(10); // small wait recovery time  

end;

 

//Supposing that TerminateCondition()is a boolean function that //returns true when the thread needs to be terminated.

 

 

 

 

In the examples are used the C++ and Pascal classes that you find into the wrappers.


 

Asynchronous data transfer

A synchronous function, is executed in the same thread of the caller, i.e. it exits only when its job is complete. Synchronous functions are often called blocking functions because they block the execution of the caller program.

An asynchronous function as opposite, consists of two parts, the first, executed in the same thread of the caller, which prepares the data (if any), triggers the second part and exits immediately.
The second one is executed in a separate thread and performs the body of the job requested, simultaneously to the execution of the caller program.

This function is also called nonblocking.

The choice of using one or the other model, essentially depends on two factors:

1.   How much the parallel job is granular than the activity of the CPU.

2.   How much, the job execution time, is greater than the overhead introduced by the synchronization.

A S7 protocol job consists of:

·         Data preparation.

·         Data transmission.

·         Waiting for the response.

·         Decoding of the reply telegram.

Each block transmitted is called PDU (protocol data unit) which is the greatest block that can be handled per transmission.

The “max pdu size” concept belongs to the IsoTCP protocol and it’s negotiated during the S7 connection.

So, if our data size (plus headers size) is greater than the max pdu size, we need to split our packets and repeat the tasks of transmission and waiting.

“Waiting for the response” is the worst of them since it’s the longest and the CPU is unused in the meantime.

So, a S7 Job is definitely granular and could benefit from asynchronous execution.

“It could” because the advantage is zeroed by the synchronization overhead if the job consists of a single pdu.

The Snap7 Client supports both data flow models via two different set of functions that can be mixed in the same session:

 
Cli_<function name>
and Cli_As<function name>.

The example in figure shows a call of Cli_DBRead that extends for more PDUs; during its execution the caller is blocked.

 

End of Job Completion

The asynchronous model in computer communications, however, has a great Achilles heel : the completion.

To understand:

The function is called, the job thread is triggered, the function exits and the caller work simultaneously to the thread.
At the end, we need to join the two execution flows, and to do this we need of a sort of synchronization.

An inappropriate completion model can completely nullify the advantage of asynchronous execution.

Basically there are three completion models:

·         Polling

·         Idle wait

·         Callback

There is no better than the others, it depends on the context.

 

Snap7 Client supports all three models, or a combination of them, if wanted.

The polling is the simplest : after starting the process, we check the Client until the job is finished.

To do this we use the function Cli_CheckAsCompletion(); when called it quits immediately and returns the status of the job : finished or in progress.

We can use it to avoid that our program becomes unresponsive during large data transfer.

 


 

The idle wait completion waits until the job is completed or a Timeout expired. During this time our program is blocked but the CPU is free to perform other tasks.

To accomplish this are used specific OS primitives (events, semaphores..).

The function delegated to this is Cli_WaitAsCompletion()

 

 

 


 

The Callback method is the more complex one:

When the job is terminated a user function (the so named callback) is invoked.

To use it, we must instruct the client about the callback (using Cli_SetAsCallback()) and we need to write the synchronization code inside it.

If it is used properly, this method can solve problems that cannot be solved with other libraries (as we will see speaking about the Snap7Partner).

In the picture we have several PLC and we need to make a "type changeover" in a production line.
And to do this we need to transfer a new large set of working parameters to each PLC.

 

Though the callback resides into the user’s program, it’s called into the Client thread, so be aware that calling another Client function inside the callback could lead to stack overflow.

 

Note

InterlockedDecrement is a synchronization primitive present in Windows/Unix that performs an atomic decrement by one on a variable.

 

Target Compatibility

As said, the S7 Protocol, is the backbone of the Siemens communications.

Many hardware components equipped with an Ethernet port can communicate via the S7 protocol, obviously not the whole protocol is fulfilled by them (would seem strange to download an FC into a CP343).

 

S7 300/400/WinAC CPU

They fully support the S7 Protocol.

S7 1200/1500 CPU

They use a modified S7 protocol with an extended telegram, 1500 series has advanced security functions (such as encrypted telegrams), however they can work in 300/400 compatibility mode and some functions can be executed, see also S71200/1500 Notes.

S7 200/LOGO 0BA7

Supported from Snap7 1.1.0
These PLC have a different approach. See S7 200 and LOGO 0BA7 chapters for a detailed description about their use with Snap7.

SINAMICS Drives

It’ possible to communicate with the internal CPU and change drive parameters, for some models (G120 for example) is also possible to change drive parameters.

A way to know what is possible to do with a given model, is to search what is possible to do with an HMI panel/Scada, since Snap7 can do the same things.

CP (Communication processor)

It’s possible to communicate with them, and see their internal SDBs, although it's not such a useful thing, or you can use SZL information for debug purpose.

 

S7 Protocol partial compatibility list (See also § LOGO and S7200)

 

CPU

CP

DRIVE

 

300

400

WinAC

Snap7S

1200

1500

343/443/IE

SINAMICS

DB Read/Write

O

O

O

O

O

O(3)

-

O

EB Read/Write

O

O

O

O

O

O

-

O

AB Read/Write

O

O

O

O

O

O

-

O

MK Read/Write

O

O

O

O

O

O

-

-

TM Read/Write

O

O

O

O

-

-

-

-

CT Read/Write

O

O

O

O

-

-

-

-

Read SZL

O

O

O

O

O

O

O

O

Multi Read/Write

O

O

O

O

O

O

-

O

Directory

O

O

O

O

-

-

O

(2)

Date and Time

O

O

O

O

-

-

-

O

Control Run/Stop

O

O

O

O

-

-

(1)

O

Security

O

O

O

O

-

-

-

-

Block Upload/Down/Delete

O

O

O

-

-

-

O

O

 

Snap7S = Snap7Server

 

(1)   After the “Stop” command, the connection is lost, Stop/Run CPU sequence is needed.

(2)   Tough DB are present and accessible, directory shows only SDBs.

(3)   See S71200/1500 notes.


 S7 1200/1500 Notes

An external equipment can access to S71200/1500 CPU using the S7 “base” protocol, only working as an HMI, i.e. only basic data transfer are allowed.

All other PG operations (control/directory/etc..) must follow the extended protocol, not (yet) covered by Snap7.

Particularly to access a DB in S71500 some additional setting plc-side are needed.

1.    Only global DBs can be accessed.

2.    The optimized block access must be turned off.

3.    The access level must be “full” and the “connection mechanism” must allow GET/PUT.

Let’s see these settings in TIA Portal V12

DB property

Select the DB in the left pane under “Program blocks” and press Alt-Enter (or in the contextual menu select “Properties…”)

Uncheck Optimized block access, by default it’s checked.

Protection

Select the CPU project in the left pane and press Alt-Enter (or in the contextual menu select “Properties…”)

In the item Protection, select “Full access” and Check “Permit access with PUT/GET ….” as in figure.

 

 

Snap7 MicroClient

In the Snap7 project, TSnap7MicroClient is the ancestor of TSnap7Client class.

It’s not exported, i.e. you cannot reference it from outside the library, and the only way to use it is to embed it in your C++ source code.

TSnap7MicroClient implements the body of all S7 Client jobs and the synchronous interface functions.

The exported TSnap7Client, only adds the remaining asynchronous functions but does not introduce any new S7 behavior.

Why we are speaking about an internal object ?

The micro client is thread independent and only relies on the sockets layer, i.e. you would embed it in your source code if:

·         Your application will run in a micro-OS that has no threads layer.

·         Your application will run in a realtime-OS (such as QNX) or in an OS that has not a standard threads layer (neither Windows nor posix). In this case you may create a native thread and use the micro client inside of it.

 

Micro client “extrapolation” is provided by design, there is a well-defined group of independent files to use.

See the chapter Embedding Snap7 Microclient for further information.