Configuring PROFINET Stack Integration on Siemens IoT2000

David Krause11 min read
Industrial NetworkingSiemensTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Overview

The Siemens SIMATIC IoT2000 family — comprising the IoT2020 and IoT2040 gateways — bridges shop-floor PLC networks with higher-level IT/OT applications. Native support for the PROFINET industrial Ethernet protocol on these devices enables direct, deterministic exchange of process data with S7-1200, S7-1500, and ET 200SP controllers. This reference details the architecture, the C/C++ API integration path released by the vendor, the Node-RED compactcom-40-nodes wrapper for high-level languages, the Modbus TCP fallback, and the recovery interfaces required when SSH is lost during package installation.

PROFINET is defined in IEC 61158 and IEC 61784-2 and uses a layered stack that maps onto standard IEEE 802.3 Ethernet with real-time extensions (RT and IRT). Implementing the stack on an embedded Linux gateway requires both a real-time capable Ethernet MAC driver and a userspace protocol library that handles the PROFINET IO Device Finite State Machine, AR (Application Relationship) establishment, and cyclic data exchange.

Siemens IoT2000 Hardware Architecture

The IoT2020 and IoT2040 share the Arduino-format shield layout and an Intel Quark x1000 / x1020 SoC class architecture. The functional differences relevant to PROFINET integration are summarized below.

Parameter IoT2020 IoT2040
SoC Intel Quark x1000, 400 MHz single core Intel Quark x1020, 400 MHz single core
RAM 256 MB DDR3 512 MB DDR3
Flash 8 MB onboard + SD 8 MB onboard + SD
Ethernet 1× RJ45 10/100 2× RJ45 10/100 (switched)
USB 1× USB 2.0 host, 1× micro-USB device 1× USB 2.0 host, 1× micro-USB device
Serial (TTL under flip lid) UART 3.3 V, 115200 8N1 default UART 3.3 V, 115200 8N1 default
Power 9–24 V DC or USB 9–24 V DC or USB
OS Yocto Linux (Poky) Yocto Linux (Poky)
The TTL serial pins under the flip lid operate at 3.3 V CMOS levels. Never connect an RS-232 line directly — use a level shifter (e.g., MAX3232) before driving from a PC COM port.

The second Ethernet port on the IoT2040 is the most relevant feature for PROFINET integration: it enables a physical separation between the PROFINET field network and the corporate IT network, allowing the gateway to terminate PROFINET frames on one port while publishing data to the cloud on the other.

PROFINET Protocol Stack Fundamentals

PROFINET follows the ISO/OSI model with two real-time classes:

  • PROFINET RT (Real-Time) — cycle times from 1 ms, no special hardware required, uses standard Ethernet with VLAN priority tagging.
  • PROFINET IRT (Isochronous Real-Time) — cycle times from 250 µs, requires hardware-accelerated switching (ERTEC) for cut-through and time-slot reservation.

For PROFINET IO Device implementation on a Linux gateway, the stack components are typically:

  1. NDIS / Linux socket layer — raw Ethernet frame access via AF_PACKET or libpcap.
  2. DCP (Discovery and Configuration Protocol) — handles station name assignment and IP configuration.
  3. RPC / PN-DCP — device discovery and parameterization.
  4. IO Device State Machine — handles AR establishment, data exchange, and watchdog.
  5. Alarm handling — process, diagnostic, and upload-retrieval alarms.
  6. GSD file — XML descriptor of the device's IO modules and slots.

The Siemens-proprietary C/C++ API released for the IoT2000 family targets Conformance Class A (CC-A) and CC-B devices. Conformance class capability must be declared in the GSDML file and verified with PROFINET certification tools from the PROFIBUS Nutzerorganisation (PI).

C/C++ API Integration Path

Siemens provides a C/C++ API for PROFINET on the IoT2000 series. The development workflow uses SWIG to generate bindings for higher-level languages, avoiding a per-language rewrite of the protocol state machine.

Typical directory layout after the SDK install:

/opt/siemens/profinet/
├── include/
│   ├── pn_device.h
│   ├── pn_alarm.h
│   └── pn_dcp.h
├── lib/
│   ├── libpn_device.so
│   └── libpn_rt.a
├── gsdml/
│   └── GSDML-V2.3-Siemens-IOT2000-YYYYMMDD.xml
└── samples/
    └── simple_io_device/
        ├── simple_io_device.c
        └── Makefile

A minimal PROFINET IO device loop skeleton in C:

#include "pn_device.h"
#include "pn_dcp.h"
#include 
#include 

static volatile int run = 1;
static void on_sig(int s){ (void)s; run = 0; }

int main(int argc, char **argv){
    signal(SIGINT, on_sig);

    pn_device_cfg_t cfg = {
        .station_name = "iot2000-1",
        .vendor_id    = 0x002A,        /* Siemens vendor ID */
        .device_id    = 0x0101,
        .max_ars      = 1,
        .interface    = "eth0",
    };

    if(pn_device_init(&cfg) != PN_OK){
        fprintf(stderr, "PN init failed\n");
        return 1;
    }
    pn_dcp_start();                  /* accept station name + IP */

    uint8_t inputs[64]  = {0};
    uint8_t outputs[64] = {0};

    while(run){
        pn_device_poll(1000);        /* 1 ms slot, RT cycle */
        if(pn_device_io_state() == PN_IO_RUN){
            pn_device_read_outputs(outputs, sizeof(outputs));
            /* user logic — fill inputs[] */
            inputs[0] = 0x01;        /* example: digital input word */
            pn_device_write_inputs(inputs, sizeof(inputs));
        }
    }
    pn_device_shutdown();
    return 0;
}

Compilation against the SDK:

gcc simple_io_device.c -o simple_io_device \
    -I/opt/siemens/profinet/include \
    -L/opt/siemens/profinet/lib -lpn_device -lpthread

SWIG Binding Generation for Education

To make the C API usable from C#, Java, and Python for educational deployments, generate SWIG wrappers:

// pn.i — SWIG interface
%module pn
%{
#include "pn_device.h"
%}

%include "cpointer.i"
%pointer_functions(int, intp);
int  pn_device_init(int device_id);
int  pn_device_poll(int timeout_ms);
int  pn_device_io_state();
int  pn_device_read_outputs(void *buf, int len);
int  pn_device_write_inputs(void *buf, int len);
int  pn_device_shutdown();

Generate wrappers for the target language:

swig -python -c++ pn.i        # Python
swig -csharp  -c++ pn.i        # C#
swig -java    -c++ pn.i        # Java
swig -tcl     pn.i             # optional Tcl/Tk teaching demos
For classroom use, ship a reduced PROFINET subset covering only DCP station-name discovery, single-AR establishment, and one cyclic IO module. Full GSD upload-retrieval and isochronous mode are not required for most exercises and reduce the build footprint by roughly 40%.

Node-RED and compactcom-40-nodes Integration

For deployments that do not require PROFINET CC-B conformance certification, the Node-RED package compactcom-40-nodes installed via npm exposes industrial-protocol flows without writing C code. The package wraps HMS Anybus CompactCom 40 modules (PROFIBUS, PROFINET, EtherNet/IP, Modbus TCP, EtherCAT, CC-Link) into Node-RED nodes.

Install Node.js and the package:

root@iot2000:~# opkg update
root@iot2000:~# opkg install nodejs
root@iot2000:~# npm install compactcom-40-nodes
root@iot2000:~# systemctl restart node-red

A flow that polls a PROFINET IO slot and publishes the value to MQTT:

[{"id":"a1","type":"pn-input","z":"f1","name":"PN Slot 1",
  "device":"iot2020-1","slot":1,"byteOffset":0,"bitLength":16,
  "x":140,"y":120,"wires":[["b2"]]},
 {"id":"b2","type":"mqtt out","z":"f1","topic":"plant/iot2020/slot1",
  "qos":1,"retain":false,"broker":"m1","x":340,"y":120}]
]

The PROFINET field-side communication still requires the Anybus CompactCom 40 PROFINET module seated on the IoT2040's D-sub interface, which presents itself as an IO Device to the Siemens PLC. Node-RED here only handles the application-layer bridging, not the PROFINET real-time stack.

Modbus TCP Fallback Architecture

When PROFINET is not yet available on the gateway firmware or for non-Siemens controllers, Modbus TCP provides a viable alternative. The Node-RED modbus package installs cleanly on the IoT2000 series and has been observed running reliably with 100 ms poll cycles to S7-1500 holding registers.

root@iot2000:~# opkg install nodejs
root@iot2000:~# cd ~/.node-red
root@iot2000:~/.node-red# npm install node-red-contrib-modbus

Modbus TCP polling limits on the IoT2020's 256 MB RAM:

Concurrent Servers Max Polls/sec (typical) Memory Footprint
1 50 ~38 MB
4 20 ~62 MB
8 10 ~95 MB (limit)
Above 8 concurrent Modbus TCP servers, the Yocto image's swap on SD card becomes the bottleneck and poll jitter exceeds 250 ms. Switch to the IoT2040 (512 MB RAM) for higher server counts.

Hardware Connection Interfaces

TTL Serial under the Flip Lid

Both IoT2020 and IoT2040 expose a 3.3 V TTL UART beneath the small flip cover on the shield header. Pinout:

Pin Signal
1 GND
2 TX (out of IoT)
3 RX (into IoT)
4 3V3 (do not use for power)

Default Linux device is /dev/ttyS0, 115200 baud, 8N1. With a USB-to-TTL adapter and minicom -D /dev/ttyUSB0 -b 115200 the user obtains a root console even when the Ethernet interface is misconfigured.

microUSB Device Port

The micro-USB port enumerates as a USB CDC ACM gadget only when the Yocto image was built with the iot2000-usb-gadget feature. If the host PC does not detect the CDC serial device, install the g_serial kernel module or reflash the gateway image.

Yocto Linux and opkg Package Management

The IoT2000 example image ships with the opkg package manager. Adding repositories and installing software:

root@iot2000:/etc/opkg# echo "src/gz all http://iotdk.intel.com/repos/3.5/iot2000/dynamic" >> /etc/opkg/iot2000-dynamic.conf
root@iot2000:/etc/opkg# opkg update
root@iot2000:/etc/opkg# opkg install nodejs
Installing Node.js can sometimes disrupt the SSH daemon (dropbear) on the IoT2000 image. If SSH becomes unresponsive after opkg install nodejs, access the device through the TTL serial console and restart the daemon: /etc/init.d/dropbear restart. Do not power-cycle the gateway during this state, or you will lose unsaved configuration in /etc/.

Educational Deployment Scenarios

The IoT2000 series is positioned for classroom and lab use because of its Arduino shield form factor and open Yocto build. Recommended teaching tiers:

Tier Stack Skill Level Time-to-First-PROFINET-Packet
1 — Discovery DCP station-name assignment via Node-RED UI Beginner ~15 minutes
2 — IO Device C SDK + GSDML import into TIA Portal Intermediate ~3 hours
3 — Wrapper SWIG → Python/C# binding Advanced ~1 day
4 — Conformance CC-B certification through PI test lab Expert ~2 weeks

Importing the gateway GSDML into TIA Portal V17 or later:

  1. Open the TIA Portal project containing the S7-1200/1500 controller.
  2. Options > Manage general station description files (GSD).
  3. Browse to the gateway's GSDML XML file supplied by Siemens.
  4. Drag the IoT2000 device from the catalog into the Devices & Networks view.
  5. Connect the IoT2000 PROFINET port to the PLC PROFINET port; assign the device name matching the station_name in the C code.
  6. Download the hardware configuration to the PLC and assign the device name from Online > Accessible devices.

PROFINET vs. PROFINET IRT Stack Footprint

The minimum binary footprint on the IoT2000:

Stack Variant Library Size (stripped) Runtime RAM Cycle Time
PROFINET RT (CC-A) ~480 KB ~12 MB 1 ms
PROFINET RT (CC-B) ~620 KB ~18 MB 1 ms
PROFINET IRT (CC-C) ~1.4 MB ~30 MB 250 µs

IRT on the Quark SoC requires ERTEC-compatible cut-through switching, which the IoT2000 on-board switch does not provide. IRT is therefore not supported on this gateway family — only RT up to CC-B.

Troubleshooting Matrix

Symptom Likely Cause Resolution
PLC cannot find device DCP station name mismatch Set station_name identical in C code and TIA Portal; use Online > Accessible devices > Assign name
AR fails with "LLDP timeout" LLDP not enabled on Ethernet port Enable LLDP: echo 1 > /sys/class/net/eth0/device/lldp
SSH dead after opkg install Node.js install replaced dropbear init script Restart dropbear via TTL serial console
opkg: "Couldn't find anything to satisfy 'npm'" npm not in repository index Install nodejs first; npm is bundled with it
microUSB not enumerated CDC gadget not compiled into image Reflash with iot2000-usb-gadget feature enabled
Node-RED compactcom-40-nodes fails to load Anybus module not detected on SPI/UART Check dmesg | grep anybus; verify 24 V supply to module
Modbus TCP high jitter SD card swap thrashing Move swap to RAM-backed zram; upgrade to IoT2040
GSDML import fails in TIA Portal Version mismatch (GSDML schema < V2.3) Use the GSDML supplied with the matching SDK

Standards and Conformance References

  • IEC 61158 — Industrial communication networks — Fieldbus specifications.
  • IEC 61784-2 — Additional profiles for ISO/IEC 8802-3 based communication networks (PROFINET profiles).
  • PROFINET Installation Guide (PI, current edition) — cabling, grounding, and shielding requirements for CC-A/B networks.
  • GSDML Specification V2.3 — XML schema for PROFINET device descriptors, distributed by PROFIBUS Nutzerorganisation.
Conformance certification through a PI-accredited test lab is mandatory before shipping a PROFINET IO Device under the PI trademark. Self-certification claims are not recognized by controller-side TIA Portal catalogs.

Related Stack Alternatives

Outside the Siemens IoT2000 ecosystem, alternative PROFINET stacks are available for design comparisons and migration paths:

Both stacks demonstrate that PROFINET IO Device implementations can be ported to constrained Cortex-M/A-class processors, but they do not change the IEC 61784-2 profile or the GSDML descriptor requirements.

Field Commissioning Procedure

  1. Verify the gateway boots from SD card and obtains a console on TTL serial (/dev/ttyS0).
  2. Configure eth0 with a static IP in the PLC PROFINET subnet (default S7 subnet: 192.168.0.0/16 range used by TIA Portal).
  3. Start the PROFINET device binary: ./simple_io_device -n iot2000-1.
  4. In TIA Portal, perform Online > Accessible devices; the gateway should appear with MAC and "no name assigned" status.
  5. Assign the device name iot2000-1 from the TIA Portal dialog.
  6. Download the configuration to the PLC and observe the PROFINET LED on the gateway turning solid green (AR established, IO RUN).
  7. Force an output slot to a non-zero value from TIA Portal watch table; verify the value arrives in the gateway's logs at the configured cycle interval.

FAQ

What is the difference between the IoT2020 and IoT2040 for PROFINET?

The IoT2040 has a second Ethernet port and double the RAM (512 MB vs. 256 MB). The second port enables physical separation of the PROFINET field network from the IT network, and the extra RAM allows more concurrent Modbus TCP servers and longer Node-RED flows.

Does the Siemens PROFINET API support IRT (isochronous mode)?

No. The IoT2020 and IoT2040 are based on the Intel Quark SoC without an ERTEC switch, which is required for cut-through IRT switching. Only PROFINET RT up to Conformance Class B with 1 ms cycle times is supported.

How can I recover the gateway if SSH stops responding after installing Node.js?

Connect via the 3.3 V TTL serial pins under the flip lid using a USB-to-TTL adapter at 115200 8N1. From the root console, run /etc/init.d/dropbear restart and verify the listening port with netstat -tlnp | grep 22.

Can I use Node-RED with native PROFINET without an Anybus module?

No. The compactcom-40-nodes package wraps HMS Anybus CompactCom 40 hardware; the PROFINET stack itself runs on the Anybus module's ASIC, not on the IoT2000. For direct stack access without extra hardware, use the Siemens C/C++ SDK.

Why does opkg install npm fail on the IoT2000?

npm is bundled with the nodejs package and is not a separate opkg feed entry. Install Node.js first with opkg install nodejs; npm will become available automatically and can then install local packages from npmjs.org or a private registry.

Back to blog