S7nodave for EPICS Manual

Sebastian Marsching

aquenos GmbH

Table of Contents

1. Introduction
2. Concept
2.1. libnodave
2.2. Supported Devices
2.3. Communication between the PLC and EPICS
2.4. Integration into EPICS
3. Getting Started
3.1. Prerequisites
3.2. Compiling the Prerequisites
3.3. Compiling s7nodave
3.4. Using s7nodave in a project
4. IOC Shell Reference
4.1. s7nodaveConfigureIsoTcpPort
4.2. s7nodaveConfigurePollGroup
5. Record Reference
5.1. Device Address Format
5.2. PLC Memory Addresses
5.3. PLC Data-Types
5.4. Supported Parameters
5.4.1. PG - Specifying a Poll Group
5.4.2. DLV, DHV - Specifying Device Value Limits
5.5. Supported Records
5.5.1. aai - Array Input
5.5.2. aao - Array Output
5.5.3. ai - Analog Input
5.5.4. ao - Analog Output
5.5.5. bi - Binary Input
5.5.6. bo - Binary Output
5.5.7. longin - Long Input
5.5.8. longout - Long Output
5.5.9. mbbi, mbbiDirect - Multi-Bit Binary Input
5.5.10. mbbo, mbboDirect - Multi-Bit Binary Output
5.5.11. stringin - String Input
5.5.12. stringout - String Output
5.5.13. waveform - Array Input or Output
6. Poll Groups
6.1. Creating a Poll Group
6.2. Including a Record in a Poll Group

List of Tables

5.1. PLC Memory Areas
5.2. PLC Memory Width
5.3. PLC Data Types and their Corresponding Memory Width
5.4. Mapping of PLC Types to EPICS Types
5.5. Mapping of EPICS Types to PLC Types

Chapter 1. Introduction

This manual is divided in five chapters (not counting this introduction). The first chapter introduces the concepts and features of the s7nodave device support for EPICS. The second chapter describes the few steps needed to start an IOC project making use of s7nodave. The third chapter describes the IOC shell commands supported by s7nodave. Subsequently, the fourth chapter explains the various record types supported by s7nodave. Finally, the fifth chapter explains how to use poll groups.

[Warning] Warning

When using this software to connect to a PLC, disconnect all external equipment from the PLC before trying to establish a connection.

This software can overwrite variables in the PLC memory or even parts of the program running in the PLC. Therefore outputs of the PLC might show unpredictable behavior.

There are a lot of different PLC types and depending on the type of the PLC, its configuration, the type of the host machine used for the EPICS IOC, the host machine's configuration and the EPICS IOC's configuration, this software might have very different, potentially unwanted results.

It is always the responsibility of the user using this software to ensure, that its use is safe and complies with local regulation before connecting any equipment to the PLC. Violations of this rules might result in equipment being damaged or even persons being injured by misbehaving equipment.

Chapter 2. Concept

This chapter introduces the concept of the s7nodave device support and the features offered by it.

2.1. libnodave

The s7nodave device support is based on a slightly modified version of libnodave, originally created by Thomas Hergenhahn. This library implements the communication protocol supported by many PLCs from the S7 family and thus allows software on a PC to communicate with a PLC without having to explicitly implement communication routines on the PLC side.

2.2. Supported Devices

Basically, s7nodave supports all PLCs supported by libnodave. However, as an additional constraint, the current version of libnodave only supports connections over Ethernet/PROFINET (ISO-TCP)and not over other kind of connections (e.g. special serial or USB adapters).

S7nodave has been developed using a S7-1200 PLC. However, there are reports that libnodave also works with S7-300 and S7-400 PLCs.

[Important] Important

It is the responsibility of each user to verify, that the PLC being used is compatible with this software. The author of this software does not assume any liability regarding the compatibility of this software with a certain PLC or the eligibility for a certain application.

2.3. Communication between the PLC and EPICS

The S7plc driver from PSI is based on a whole data-block being exchanged between the PLC and the EPICS IOC. This means, that it is not possible to write single records to the PLC. Instead, all values must be sent at once. The same applies to read requests. Besides, the structure of the data-block is coded into a PLC program. If a value is added or removed from the block, the addresses in the PLC logic as well as in the EPICS record configuration have to be updated.

The s7nodave device support on the other hand, directly reads from and writes to memory addresses in the PLC. The addresses configured in the EPICS records use the same notation that is used for programming the PLC logic. When an output record is process, on the value of this record is sent to the PLC. For input records, different records can be processed at different rates and only the values in the same poll group are transferred together.

2.4. Integration into EPICS

S7nodave is implemented as an asynchronous device support based on asynDriver. While the asynDriver is used for configuration management, logging and asynchronous processing, neither the device support nor the low-level I/O routines supported by the asynDriver are used.

Chapter 3. Getting Started

This chapter describes the steps needed to setup a simple project using s7nodave. First, the prerequisites for using s7nodave are described. Subsequently, the installation and compilation of the s7nodave device support is explained. Finally, the steps needed to include the s7nodave device support in a project are shown.

3.1. Prerequisites

S7nodave has three prerequisites: First, EPICS base R3.14.12 or higher is needed. Older versions of EPICS base might work but in this case support for the aai and aao record types must be disabled, because these record types were broken in earlier versions of EPICS base.

In addition to that, the asynDriver is needed. S7nodave has been developed against version 4.13 of asyn, however most likely it also works with newer versions.

Finally, the Boost C++ library is needed (for compilation only, not at runtime). S7nodave has been developed using version 1.47.0 of Boost, but it should also work with newer versions, as long as the data structures of the optional, shared_ptr and string_algo libraries are not changed.

A modified version of libnodave is bundled with s7nodave and automatically compiled when s7nodave is compiled. Thus, you do not need to download or compile libnodave.

S7nodave has been developed under Linux, but should work on most POSIX-compliant operating systems. On Microsoft Windows, you will have to use a compatibility layer like Cygwin or change the network code in s7nodave to use the respective functions from the Windows API.

3.2. Compiling the Prerequisites

For compiling EPICS base and the asynDriver, refer to the respective manuals. Boost does not have to be compiled but can just be extracted to some directory on your disk.

3.3. Compiling s7nodave

After downloading s7nodave from the project website, extract it to the directory you want it to install in. A good place might be the /opt/epics/modules directory.

Subsequently, you have edit the configure/RELEASE file in order to configure the locations where EPICS base, the asynDriver and the Boost library are installed. Change the definitions of ASYN, RELEASE_INCLUDES and EPICS_BASE to point to the right directories.

After editing this paths, you can run make to build s7nodave.

3.4. Using s7nodave in a project

In the configure/RELEASE file of your project, you have to add a line like S/NODAVE=/opt/epics/modules/s7nodave. In the Makefile of the src directory of you application (e.g. myApp/src/Makefile) you have to add something like

my_DBD += s7nodave.dbd
my_LIBS += s7nodave

in order to use the s7nodave device support in your record definition files.

Finally, you have to configure at least one PLC connection in the startup file of your IOC. See Section 4.1, “s7nodaveConfigureIsoTcpPort” for the syntax of the corresponding command. Optionally, you also might want to configure poll groups. For defining records that read from or write to the PLC, please refer to the record reference.

Chapter 4. IOC Shell Reference

S7nodave supports IOC shell commands for configuring a PLC connection and for adding poll groups. In addition to that, the asyn commands for configuring the trace mask and trace I/O mask are supported. However, you have to add asyn.dbd to the list of DBDs used by your project in order to enable these commands in the IOC shell.

4.1. s7nodaveConfigureIsoTcpPort

The s7nodaveConfigureIsoTcpPort command is used to setup a connection to a PLC and command has the following syntax:

s7nodaveConfigureIsoTcpPort(PLC name, PLC hostname or IP address, thread priority)

The PLC name is an arbitrary string, that is used to refer to this PLC in the device address field of records and when configuring poll groups for the PLC. However, the PLC name may not contain whitespace or parentheses.

The PLC hostname or IP address is the DNS hostname or IP address of the PLC, optionally followed by the TCP port number (separated from the hostname or IP address by a colon). If no port number is specified, the default port (102) is used.

The thread priority is the priority used for the communication thread (port thread in asyn nomenclature). If a priority of 0 is specified, the priority epicsThreadPriorityMedium is used.

An example line configuring a connection to a PLC might look like this:

s7nodaveConfigureIsoTcpPort("myPLC", "myplc.example.com", 0)

You can have multiple instances of s7nodaveConfigureIsoTcpPort in your IOC startup configuration, however the PLC name used must be unique for each instance.

4.2. s7nodaveConfigurePollGroup

The s7nodaveConfigurePollGroup command is used for configuring poll groups and has the following syntax:

s7nodaveConfigurePollGroup(PLC name, poll-group name, poll interval, thread priority)

The PLC name must be the name of a PLC previously used in an instance of s7nodaveConfigureIsoTcpPort.

The poll-group name is an arbitrary string that identifies the poll-group and must be unique for the PLC. However, the same poll-group name may be used for two different PLCs. The poll-group name must no contain whitespace, parentheses, the equal sign or commas.

The poll interval is a floating point number that specifies the interval in which the memory addresses belonging to the poll group are read. The units of the poll interval are seconds.

The thread priority specifies the priority of the thread, that periodically processes the poll group. If a priority of 0 is specified, the priority epicsThreadPriorityMedium is used.

An example line configuring a poll group that is processed once a second might look like this:

s7nodaveConfigurePollGroup("myPLC", "1s", 1.0, 0)

You can have multiple instances of s7nodaveConfigurePollGroup per PLC, however the poll-group name used must be unique for each instance referring to the same PLC.

Chapter 5. Record Reference

In this chapter, first the format of the device addresses used for the s7nodave device support is explained. Subsequently the various PLC data-types supported by s7nodave are described. Finally, details about the records, supported by s7nodave, are given.

5.1. Device Address Format

In order to use the s7nodave device address support for a record, the record's device type field (DTYP) has to specify s7nodave. This device type is used for all records supported by s7nodave except the waveform record.

The record's device address field (usually INP for input and OUT for output records) must specify a device address recognized by the s7nodave.

In general, a device address for s7nodave has the following format:

@PLC-name[(param1=value1,param2=value2,...)] PLC-address [PLC-data-type]

The exact supported options may vary depending on the record type.

Every device address start with the @-sign, followed by the PLC name. The PLC name must be the name of a PLC configured using the s7nodaveConfigureIsoTcpPort statement in the IOC startup file.

The PLC name is followed by list of optional parameters wrapped in parentheses. If no parameters are given, the parentheses can be ommitted. The supported parameters depend on the record type. Please see Section 5.4, “Supported Parameters” and Section 5.5, “Supported Records” for details. If multiple parameters are specified, they are separated by commas.

The PLC memory address is separated from the PLC name (or the optional parameter list) by whitespace. Please refer to Section 5.2, “PLC Memory Addresses” for the the format of the PLC memory address.

Finally, an optional PLC data-type, which is separated from the PLC memory address by whitespace, can be specified. If no PLC data-type is specified, the data-type is guessed based on the record-type and PLC memory address. Please refer to Section 5.3, “PLC Data-Types” and Section 5.4, “Supported Parameters” for details about the supported PLC data-types.

Examples for valid device addresses:

  • @myPLC(DLV=0,DHV=27648) IW64

  • @myPLC(DLV=0,DHV=27648) IW66 int16

  • @myPLC IB0

  • @myPLC QB0

5.2. PLC Memory Addresses

S7nodave uses the same format for PLC memory addresses, that is also usually used for programming the PLCs (e.g. using Step7 or WinPLC). The English and the German notation are both supported and equivalent to each other.

This format combines the specification of the start-byte of a variable in the PLC memory with specification of the variable's width.

The PLC address starts with the memory area. The following memory areas are supported:

Table 5.1. PLC Memory Areas

English German Description
DBn.DB DBn.DB Data Blocks (n must be an integer number)
F M Flags
I E Input Memory Image
Q A Output Memory Image
T T Timers
C Z Counters

For data block addresses the data-block number has to be included in the area specification. For addresses using the data-block, flags, input-memory and output memory areas, you next have to specify the width of the memory that should be read from or written to. The notation used for specifying the width is:

Table 5.2. PLC Memory Width

Notation Description
B Byte (8 bits)
W Word (16 bits)
D Double Word (32 bits)

For addresses referring to a single bit and for addresses referring to the counter or timer areas, no width specification is given: Bit addresses are identified by specifying the bit within the byte and the counter and timer areas always use word (16-bit) values.

After specifying the memory width, the start address must be specified. The start address is always given in the number of bytes counted from the beginning of the respective area (starting with zero). For example, if at the beginning of DB1 two 32-bit numbers were stored, the two addresses for these numbers would be DB1.DBD0 and DB1.DBD4.

For addresses referring to a single bit, the start bit within the byte has to be specified, separated from the start byte by a dot. For example, in order to refer to the first bit of the first byte in the input-memory area, you would use the address I0.0. You must not specify a start bit for byte, word or double-word addresses.

PLC memory-address specifications are not case-sensitive. However, for enhanced readability the use of upper case characters is recommended.

Examples for valid memory addresses:

  • DB3.DBD4

  • FW4

  • IB2

  • Q8.3

  • T2

  • C2

5.3. PLC Data-Types

s7nodave supports eight different PLC data-types. Each of these data-types may only be used together with a memory address having the right width:

Table 5.3. PLC Data Types and their Corresponding Memory Width

Data Type Memory Width Description
bool 1 bit Boolean
int8 Byte (8 bits) Signed Integer
uint8 Byte (8 bits) Unsigned Integer
int16 Word (16 bits) Signed Integer
uint16 Word (16 bits) Unsigned Integer
int32 Double Word (32 bits) Signed Integer
uint32 Double Word (32 bits) Unsigned Integer
float Double Word (32 bits) Single Precision Floating Point Number

The available data-types are also limited by the used record-type. Please refer to Section 5.5, “Supported Records” for details.

5.4. Supported Parameters

There is a number of optional parameters that can be used to specify device-support specific options for a record. Most of these options are only valid for a specific record-type, so please refer to the description of the respective options for finding out which option can be used with which record type.

5.4.1. PG - Specifying a Poll Group

The PG parameter can be used with all input records to specify a poll group for the record. It is only valid, if the SCAN field of the record is set to I/O Intr. Example: @myPLC(PG=1s) IW64

5.4.2. DLV, DHV - Specifying Device Value Limits

The DLV and DHV parameters specify the lower and upper bounds of the raw values read from or written to the PLC. These values together with the record fields EGUL and EGUF are used for converting raw values to values in engineering units and vice-versa, when the record's LINR field is set to LINEAR.

If linear conversion is enabled, the conversion parameters are set in such a way, that a raw value of DLV corresponds to an engineering units value of EGUL and a raw value of DHV corresponds to an engineering units value of EGUF. Please refer to the description of the ai and ao records in the EPICS Record Reference Manual for details about linear conversion.

5.5. Supported Records

S7nodave supports most records from EPICS base, that have an interface for device support routines. In order to use s7nodave with a record, the record's DTYP and INP or OUT fields have to be set correctly. Please refer to Section 5.1, “Device Address Format” for details. This chapter describe the specific options for each supported record type.

This manual only describe those features of each record, which are specific to the s7nodave device support. Please refer to the EPICS Record Reference Manual for a general description of each record type and its fields.

5.5.1. aai - Array Input

The aai record is used for reading multiple elements from the PLC's memory into an array. The supported PLC data-types depend on the EPICS data-type specified in the record's FTVL field, as described in this table:

Table 5.4. Mapping of PLC Types to EPICS Types

  bool int8 uint8 int16 uint16 int32 uint32 float
X = default for memory addresses of the corresponding width, o = supported, if specified explicitly
STRING   X o          
CHAR X X            
UCHAR X   X          
SHORT X X o X        
USHORT X   X   X      
LONG X X o X o X    
ULONG X   X   X   X  
FLOAT X o X o X o o X
DOUBLE X o X o X o o X
ENUM X   X   X      

For all EPICS data-types except STRING, the width of the PLC data-type has to match the width of the PLC address. In this case, the total number of bytes read is the width of the PLC data-type multiplied by the number of elements in the array. The PLC memory address specified is the start of the first element in the array.

If FTVL is set to STRING, the PLC memory-address must be a byte. This byte is regarded to be the first byte of the first string in the array. In total, fourty bytes are read for each element in the array. For example, if the array has ten elements, 400 bytes are read from the PLC memory.

If the PLC address specified refers to a bit, the number of bits read from the PLC equals the number of elements in the array. The read does not have to be aligned to byte boundaries.

5.5.2. aao - Array Output

The aao record is used for writing multiple elements from an array into the PLC's memory. The supported PLC data-types depend on the EPICS data-type specified in the record's FTVL field, as described in this table:

Table 5.5. Mapping of EPICS Types to PLC Types

  bool int8 uint8 int16 uint16 int32 uint32 float
X = default for memory addresses of the corresponding width, o = supported, if specified explicitly
STRING   X o          
CHAR X X   X   X   o
UCHAR X   X o X o X o
SHORT X     X   X   o
USHORT X       X o X o
LONG X         X   o
ULONG X           X o
FLOAT X o o o o o o X
DOUBLE X o o o o o o X
ENUM X       X o X o

For all EPICS data-types except STRING, the width of the PLC data-type has to match the width of the PLC address. In this case, the total number of bytes written is the width of the PLC data-type multiplied by the number of elements in the array. The PLC memory address specified is the start of the first element in the array.

If FTVL is set to STRING, the PLC memory-address must be a byte. This byte is regarded to be the first byte of the first string in the array. In total, fourty bytes are written for each element in the array. For example, if the array has ten elements, 400 bytes are written to the PLC memory.

If the PLC address specified refers to a bit, the number of bits written to the PLC equals the number of elements in the array. The write does not have to be aligned to byte boundaries. Every non-zero number is converted to one before being written to the corresponding bit.

Writing a DOUBLE value may be connected with loss of precision, as the PLC driver only supports single precision floating point numbers.

5.5.3. ai - Analog Input

The ai record is used for reading analog values from the PLC. For conversion from PLC raw values to engineering units, the DLV and DVH options can be used (see Section 5.4.2, “DLV, DHV - Specifying Device Value Limits”).

The PLC data-types supported by this record are bool, int8, uint8, int16, uint16, int32 and float. When using the float type, conversion from raw to engineering units is not supported. The value from the PLC memory is directly written to the record's VAL field instead.

5.5.4. ao - Analog Output

The ao record is used for writing analog values to the PLC. For conversion from engineering units to PLC raw units, the DLV and DHV options can be used (see Section 5.4.2, “DLV, DHV - Specifying Device Value Limits”).

The PLC data-types supported by this record are bool, int8, uint8, int16, uint16, int32 and float. When using the float type, conversion from engineering to raw units is not supported. The value of the record's VAL field is written to the PLC's memory instead. Please note that the conversion from engineering to raw units might be lossy, if the calculated raw value does not fit within the specificed PLC data-type.

5.5.5. bi - Binary Input

The bi record is used for reading a binary state from the PLC. The PLC data-types supported by this record are bool, int8, uint8, int16, uint16, int32, uint32 and float.

For all types except float, a value that does not equal zero is considered to be one. For floats, a value of NaN or +inf and -inf is also considered to be zero.

5.5.6. bo - Binary Output

The bo record is used to set a binary state in the PLC. The PLC data-types supported by this record are bool, int8, uint8, int16, uint16, int32, uint32 and float.

5.5.7. longin - Long Input

The longin record is used for reading an integer number from the PLC. The PLC data-types supported by this record are bool, int8, uint8, int16, uint16 and int32.

5.5.8. longout - Long Output

The longout record is used for writing an integer number to the PLC. The PLC data-types supported by this record are bool, int8, uint8, int16, uint16 and int32.

Please note that the write operation might be lossy, if the value written does not fit within the specificed PLC data-type.

5.5.9. mbbi, mbbiDirect - Multi-Bit Binary Input

The mbbi and mbbiDirect record types are used for reading a state consisting of multiple bits from the PLC. The PLC data-types supported by this record are int8, uint8, int16, uint16, int32 and uint32.

The SHFT and NOBT fields of the record are supported by the s7nodave device support, so that bits which are not aligned to the byte boundaries can be read.

As far as the s7nodave device support is concerned, there is no difference between the mbbi and mbbiDirect record-types. Please refer to the EPICS Record Reference Manual for the differences between the two record types.

5.5.10. mbbo, mbboDirect - Multi-Bit Binary Output

The mbbo and mbboDirect record types are used for writing a state consisting of multiple bits to the PLC. The PLC data-types supported by this record are int8, uint8, int16, uint16, int32 and uint32.

The SHFT and NOBT fields of the record are supported by the s7nodave device support, so that bits which are not aligned to the byte boundaries can be written. However, the write operation is always applied to the complete byte, setting the other bits to zero. If you want to set specific bits without touching the other bits in the same byte, you should use the bo or the aao record.

As far as the s7nodave device support is concerned, there is no difference between the mbbo and mbboDirect record-types. Please refert to the EPICS Record Reference Manual for the differences between the two record types.

5.5.11. stringin - String Input

The stringin record is used for reading a string from the PLC. The PLC data-types supported by this record are bool, int8 and uint8.

If either the int8 (the default) or uint8 data-type is specified, fourty bytes are read from the PLC and interpreted as a string.

If the bool data-type is specified, a single bit is read from the PLC and the string is set to “TRUE” if the bit is one and to “FALSE” if the bit is zero.

5.5.12. stringout - String Output

The stringout record is used for writing a string to the PLC. The PLC data-types supported by this record are bool, int8 and uint8.

If either the int8 (the default) or uint8 data-type is specified, the fourty bytes of the string stored in the record's VAL field are written to the PLC.

If the bool data-type is specified, a single bit is written to the PLC. If the string is “TRUE” or “1”, one is written, otherwise zero is written.

5.5.13. waveform - Array Input or Output

The waveform record is an alternative to the aai and aao records. Unlike the other records, it can act as either an input or an output record. The device address is always stored in the record's INP field. If you want to use the record as an input record, you have to set the record's DTYP field to s7nodaveWfIn, if you want to use the record as an output record, the field has to be set to s7nodaveWfOut. Apart from that, as far as the s7nodave device support is concerned, this record acts exactly like the aai or aao records.

Chapter 6. Poll Groups

If you periodically scan multiple input records, that read data from the PLC, this is very inefficient, because each read operation sends a read request over the network and has to wait for a response from the PLC.

Thus, if multiple input records shall be processed at the same rate, you should put the in the same poll-group. The read request for all records being in the same poll group are placed in the same read request (unless the packet size is exceeded) and sent to the PLC together. Accordingly, the response from the PLC to all the read requests is also sent in a single packet, thus reducing the number of round-trips needed significantly.

Poll groups are only supported for input records, because output records typically are only processed on change anyway.

6.1. Creating a Poll Group

A poll group is created using the s7nodaveConfigurePollGroup command in the IOC's statup configuration. If you use the poll-group name “default”, this has a special meaning. This poll-group is used for all records, that are configured to use a poll group but do not explicitly specify the name of the poll group to use. For each PLC that is configured, the default poll-group must be configured separately.

6.2. Including a Record in a Poll Group

In order to make a record be processed in a poll group, the SCAN field of the record has to be set to I/O Intr. If you want to use a different poll group than the default poll-group, you can use the PG parameter to specify the poll group to use (see Section 5.4.1, “PG - Specifying a Poll Group”).