Snap7

repository·main·Indexed 41 days ago

https://github.com/davenardella/snap7

A library for communication with Siemens S7 PLCs and CP units, providing capabilities to read/write data and monitor communications. It includes the TSnap7Client class for asynchronous PLC communication, TSnap7Peer for managing ISO-on-TCP socket connections, and TSnap7Server for simulating PLC behavior and managing memory areas such as Process Images and Data Blocks.

Tokens
3.4K
Snippets
10
Records
15
Agent score
51%

What's inside Snap7

  1. Overview of Snap7 repository structure

    main

    Starting from release 1.4.3, the Snap7 package has been split into multiple repositories to allow users to download only the components they need. The main repository contains the core library, while specialized components are hosted elsewhere:

    • Examples: snap7.examples
    • LabVIEW integration: snap7.LabVIEW
    • Rich Demos: snap7.rich-demos
    • Utilities: snap7.utility (Includes pre-compiled Windows binaries for HMITracer, clientdemo, serverdemo, and partnerdemo for testing PLC/CP connections or tracing HMI requests).
  2. Build Snap7 on Windows using Visual Studio

    main

    To build Snap7 on Windows, use Visual Studio (Community Edition is sufficient):

    1. Locate the Solution file in /build/windows/VSXXXX/VSXXXX.sln (where VSXXXX corresponds to your Visual Studio version).
    2. Open the .sln file with Visual Studio.
    3. Build the solution.
  3. Build Snap7 on *nix (Linux, BSD, OSX, Solaris, MIPS)

    main

    To use Snap7 on *nix systems, you must compile it to match your specific architecture and libc version. You will need a C++ toolchain installed (e.g., sudo apt install build-essential on Linux).

    Steps to build:

    1. Clone the repository: git clone https://github.com/davenardella/snap7.git
    2. Navigate to the OS-specific build folder: snap7/build/<your_OS>/
    3. Run the appropriate build command based on your OS and toolchain.
    git clone https://github.com/davenardella/snap7.git
  4. Get pre-compiled Windows binaries

    main

    If you are developing on Windows, you do not need to compile the library yourself to get started. The latest Windows DLLs and .lib files are provided in the following directories:

    • /build/bin/win32
    • /build/bin/win64
    Files available in:
    /build/bin/win32
    /build/bin/win64
  5. Build commands for *nix systems

    main

    After navigating to the correct directory in snap7/build/<your_OS>/, use the following commands. Note that using the install target requires sudo privileges.

    OS / ToolchainCommand
    Linux, MIPSmake [clean | all | install]
    OSX, BSDgmake [clean | all | install]
    Solaris 32-bit (Oracle Solaris Studio)gmake -f i386_solaris_cc.mk [clean | all | install]
    Solaris 64-bit (Oracle Solaris Studio)gmake -f x86_64_solaris_cc.mk [clean | all | install]
    Solaris 32-bit (GNU Toolchain)gmake -f i386_solaris_gcc.mk [clean | all | install]
    Solaris 64-bit (GNU Toolchain)gmake -f x86_64_solaris_gcc.mk [clean | all | install]
  6. Manage S7 peer connections with TSnap7Peer

    main

    The TSnap7Peer class is the primary interface for establishing and managing communication with an S7 peer (such as a PLC) over an ISO-on-TCP socket. It inherits from TIsoTcpSocket and provides methods to control the connection lifecycle and access PDU (Protocol Data Unit) information.

    Key Public Members

    • PeerConnect(): Establishes a connection to the S7 peer.
    • PeerDisconnect(): Terminates the connection to the S7 peer.
    • LastError: An integer representing the last error encountered during peer operations.
    • PDULength: The length of the current PDU.
    • PDURequest: The requested PDU length.

    Error Masking Constants

    When checking for errors, the following constants are used to identify the nature of the error:

    • errPeerMask: Mask used to isolate peer-related error bits.
    • errPeerBase: The base value for peer errors.
    • errNegotiatingPDU: Indicates an error occurred during the PDU length negotiation phase.
    TSnap7Peer peer;
    int result = peer.PeerConnect();
    if (result != 0) {
        // Handle error using peer.LastError
    }
    
    // ... perform operations ...
    
    peer.PeerDisconnect();
  7. Manage asynchronous job completion with WaitAsCompletion

    main

    If you prefer a synchronous-style wait for an asynchronous operation, use WaitAsCompletion. This method blocks the calling thread until the background job finishes or the specified timeout is reached.

    Signature: int WaitAsCompletion(unsigned long Timeout);

    • Timeout: The maximum time to wait in milliseconds.

    Returns an integer status code indicating success or failure.

    // Start an async operation
    client.AsReadArea(AreaDB, 1, 0, 10, WordLen, buffer);
    
    // Wait up to 5000ms for it to finish
    int status = client.WaitAsCompletion(5000);
  8. Use TSnap7Client for asynchronous PLC communication

    main

    The TSnap7Client class provides an asynchronous interface for communicating with S7 PLCs. Unlike standard synchronous calls, asynchronous methods (prefixed with As) initiate a job that runs in a background thread.

    To handle the results of an asynchronous operation, you can use one of two patterns:

    1. Callback Pattern: Register a completion callback using SetAsCallback. When a job finishes, the provided function is called with the operation code and the result.
    2. Polling/Waiting Pattern: Use CheckAsCompletion to poll for status or WaitAsCompletion to block the current thread until the job completes or a timeout occurs.

    Common asynchronous operations include reading/writing data areas (AsReadArea, AsWriteArea), DB operations (AsDBRead, AsDBWrite, AsDBGet), and block transfers (AsUpload, AsDownload).

    // Example: Using the callback pattern
    TSnap7Client client;
    
    // Define a callback function
    void MyCompletionCallback(void * usrPtr, int opCode, int opResult) {
        // Handle completion
    }
    
    // Register the callback
    client.SetAsCallback(MyCompletionCallback, nullptr);
    
    // Start an asynchronous DB read
    int result = client.AsDBRead(1, 0, 10, buffer);
  9. Set Server Event Callbacks

    main

    To handle incoming S7 protocol requests (Read/Write operations) from clients, you must register callback functions with the TSnap7Server.

    Read Events

    Use SetReadEventsCallBack to receive notifications when a client attempts to read data. This provides information about the sender, the area, and the requested data.

    Read/Write Area Callbacks

    Use SetRWAreaCallBack to implement custom logic for handling read and write operations. This is useful for intercepting data access or simulating PLC behavior.

    Callback Operation Constants:

    • OperationRead (0)
    • OperationWrite (1)
    // Callback signature for RW operations
    typedef int (S7API *pfn_RWAreaCallBack)(void *usrPtr, int Sender, int Operation, PS7Tag PTag, void *pUsrData);
    
    // Setting the callback
    server->SetRWAreaCallBack(myCallbackFunction, myUserPointer);
  10. Manage Server Memory Areas

    main

    The TSnap7Server class allows you to register and manage memory areas (like Data Blocks or Process Images) that the server will respond to.

    Register an Area

    Use RegisterArea to map a memory segment to a specific S7 area ID and index.

    Unregister an Area

    Use UnregisterArea to remove a previously registered area.

    Lock/Unlock an Area

    Use LockArea and UnlockArea to control access to specific areas or Data Blocks.

    ```cpp
    // Example registration
    server->RegisterArea(srvAreaDB, 1, pData, size);
    
    // Example locking
    server->LockArea(srvAreaDB, 1);
    
    // Example unregistering
    server->UnregisterArea(srvAreaDB, 1);
  11. Start the Snap7 Server

    main

    To begin listening for S7 connections, call StartTo with the network address and port.

    Note: Once the server is running, certain parameters cannot be changed using SetParam (indicated by errSrvCannotChangeParam).

    TSnap7Server *server = new TSnap7Server();
    server->StartTo("0.0.0.0"); // Listen on all interfaces
  12. Server Error Codes

    main

    When using the Snap7 server, the following error codes are used to indicate failures in area registration or parameter handling:

    • errSrvDBNullPointer (0x00200000): A null pointer was passed as PData.
    • errSrvAreaAlreadyExists (0x00300000): Attempted to re-register an area that already exists.
    • errSrvUnknownArea (0x00400000): An unknown area was requested.
    • errSrvInvalidParams (0x00500000): Invalid parameters were supplied.
    • errSrvTooManyDB (0x00600000): Cannot register more Data Blocks (DBs); the MaxDB limit has been reached.
    • errSrvInvalidParamNumber (0x00700000): Invalid parameter number provided to srv_get/set_param.
    • errSrvCannotChangeParam (0x00800000): Cannot change parameters because the server is currently running.