PROFINET Controller Demo Application

Overview

The PROFINET Controller Demo Application (profinet_controller_demo_app.c) demonstrates a complete working implementation of the RAPIDSEA PROFINET Controller stack. It showcases a two-device setup — an Advantech ADAM-6100PN and an RT-Labs reference device — and walks through the full lifecycle: controller initialization, device discovery, network configuration, connection establishment, cyclic IO data exchange, and graceful shutdown.

The application is structured as a finite state machine and serves as a reference starting point for integrating the RAPIDSEA PROFINET Controller stack into custom applications.

Compile-Time Feature Flags

Two feature flags control optional application behaviour at compile time:

Feature Flags

Macro

Default

Description

PN_CONSOLE_ENABLED

0

When set to 1, enables interactive console-based entry of controller network parameters (IP address, subnet mask, gateway, station name, timeout, interface name, device port) at startup instead of using hard-coded defaults.

PN_XML_CONFIG_ENABLED

0

When set to 1, loads controller and device configuration from an XML file via get_controller_config() and get_device_config() instead of using the static compile-time device configuration structures.

Device State Flag Bits

Each managed device tracks its progression through discovery and connection using a bitmask stored in device_info_t.device_state:

Device State Flags

Flag

Description

DEVICE_DISCOVERED

Set in rcb_pn_controller_dcp_identify_result when a DCP Identify response is matched to a configured device by station name.

DEVICE_STN_NAME_CHANGE_REQ

Indicates that a station name change has been requested for this device.

DEVICE_NW_RECONFIGURE_REQ

Indicates that a network reconfiguration (IP/subnet/gateway) has been requested for this device.

DEVICE_NETWORK_CONFIGURED

Set once the device’s network parameters have been successfully configured via DCP SET commands.

DEVICE_READY_FOR_CONNECT

Indicates that the device is ready to proceed to RPC connection establishment.

DEVICE_CONNECTED

Set in rcb_pn_controller_rpc_connection_result when an AR is successfully established with the device.

Application State Machine

The demo is driven by a single while(1) loop executing a switch on the current app_state_t. rs_pn_controller_process() is called unconditionally on every iteration regardless of state. The states and their transitions are described below:

The state transition flow is illustrated below:

CONTROLLER_OPEN → DISCOVERY → DISCOVERY_DELAY → CONFIGURATION
    → CONNECT_DEVICE ↔ WAIT_FOR_CONNECTION
    → RUNNING → RELEASE_DEVICE → CONNECT_DEVICE (loop)
    → CONTROLLER_CLOSE → exit

Demo Device Configurations

When PN_XML_CONFIG_ENABLED is 0, two static rs_pn_device_config_t structures are compiled in and copied into g_pn_controller_config.device_config[] before the main loop starts.

Advantech ADAM-6100PN (Device Index 0)

Station Name

adam-6100pn

Vendor ID / Device ID

0x01C6 / 0x6100

RT Class

0x01 (RT_CLASS_1)

Send Clock Factor / Reduction Ratio

0x20 / 0x100

Modules

2 (slot 0: DAP + port submodules; slot 1: digital IO module)

Submodules

5 (4 DAP/port submodules in slot 0; 1 bidirectional IO submodule in slot 1, subslot 0x0001)

IO Data Length (in/out)

1 byte each

Input / Output Image Offset

0x0000 / 0x0000

RT-Labs Reference Device (Device Index 1)

Station Name

rt-labs-dev

Vendor ID / Device ID

0x0493 / 0x0002

RT Class

0x02

Send Clock Factor / Reduction Ratio

0x20 / 0x100

Modules

2 (slot 0: DAP + port submodules; slot 1: IO module)

Submodules

4 (3 DAP/port submodules in slot 0; 1 bidirectional IO submodule in slot 1, subslot 0x0001)

IO Data Length (in/out)

1 byte each

Input / Output Image Offset

0x0001 / 0x0001

Note

The two devices are mapped to adjacent 1-byte offsets in the IO image (offset 0 for the Advantech device and offset 1 for the RT-Labs device), demonstrating how multiple devices share a single flat IO image.

Default Controller Configuration

When PN_CONSOLE_ENABLED is 0, the following hard-coded defaults are used:

Controller IP Address

192.168.29.2

Subnet Mask

255.255.255.0

Gateway

192.168.29.1

Device IP Scan Range

192.168.10.3192.168.10.200

Station Name

controller

Timeout

5000 ms

Device Port

0x8892

Network Interface

enp0s8

Supported Device Count

2

Note

The global g_pn_controller_config also carries a static compile-time initializer (IP 192.168.10.10, port 0x8894, interface enp0s8, timeout 1000 ms). When PN_CONSOLE_ENABLED is 0, get_controller_config() overwrites the relevant fields with the defaults listed above. Ensure the interface name matches the actual Ethernet interface on the target system.

Cyclic IO Data Exchange

During STATE_RUNNING, the demo iterates over a lookup table (dio_lookup[MAX_DIG_INPUT]) of 8 entries. Each entry maps an input image offset and expected input byte value to a corresponding output image offset and output byte value.

For each lookup entry:

  1. rs_pn_controller_read_pnio_data() is called with RS_PN_PNIO_IOCS_GOOD as the local consumer status.

  2. The returned iops_status is checked against RS_PN_PNIO_IOPS_GOOD (0x80) before the data is used.

  3. If the read byte matches the in_cmp_val for that entry, rs_pn_controller_write_pnio_data() is called to write the corresponding out_data_val to the output image offset.

This pattern demonstrates the recommended practice of always validating the provider status (IOPS) before acting on received input data.

Digital IO Lookup Table (dio_lookup)

Index

Input Offset

Output Offset

Compare Value

Output Value

0

0x00000000

0x00000000

0

0

1

0x00000000

0x00000000

2

1

2

0x00000000

0x00000000

4

4

3

0x00000000

0x00000000

8

8

4

0x00000000

0x00000000

16

16

5

0x00000000

0x00000000

32

32

6

0x00000000

0x00000000

64

64

7

0x00000000

0x00000000

128

127

Note

All lookup entries currently use offset 0x00000000 for both input and output. In a production application these offsets should be updated to match the actual input_image_start_offset and output_image_start_offset of each configured device.

Callback Implementations

The demo provides stub implementations for all required stack callbacks. Only the two callbacks relevant to device lifecycle management contain non-trivial logic:

Callback

Demo Behaviour

rcb_pn_controller_dcp_identify_result

Iterates over all configured devices and compares discovery_resp_info->device_stationname against each device’s configured stn_name. On a match, copies the full rs_pn_discovery_resp_info_t into g_arr_device_info[] and sets the DEVICE_DISCOVERED flag.

rcb_pn_controller_rpc_connection_result

If s32_result == RS_ERR_OK, sets the DEVICE_CONNECTED flag in g_arr_device_info[device_index].device_state.

rcb_pn_controller_dcp_get_req_result

Stub — returns RS_ERR_OK.

rcb_pn_controller_dcp_set_req_result

Stub — returns RS_ERR_OK.

rcb_pn_controller_dcp_error_callback

Stub — returns RS_ERR_OK.

rcb_pn_controller_rpc_release_result

Stub — returns RS_ERR_OK.

rcb_pn_controller_rpc_error_callback

Stub — returns RS_ERR_OK.

rcb_pn_controller_pnio_input_data_changed

Stub — returns RS_ERR_OK.

rcb_pn_controller_alarm_callback

Stub — returns RS_ERR_OK; the stack automatically sends the ACK frame.

Console Configuration (PN_CONSOLE_ENABLED)

When PN_CONSOLE_ENABLED is set to 1, the function get_controller_config() prompts the operator for all controller network parameters via stdin before the main loop begins. The following internal helpers are used:

Console Helper Functions

Function

Description

console_read_line

Reads a newline-terminated string from stdin into a caller-supplied buffer; strips the trailing newline.

console_read_int

Prompts for an integer within a specified [min, max] range. Retries up to MAX_CONSOLE_RETRIES (3) times on invalid input.

console_read_ip

Prompts for a dotted-decimal IPv4 address and validates all four octets are in the range 0–255. Retries up to MAX_CONSOLE_RETRIES times.

console_read_string

Prompts for a string up to max_len characters. Copies the result into the destination buffer and writes the actual length to out_len. Retries up to MAX_CONSOLE_RETRIES times.

The prompts and their corresponding rs_pn_controller_config_t fields are: Timeout (ms)timeout_ms; Interface Nameraw_sock_config.iface_name; Device Portdevice_port; Station Namestn_name / stn_name_len; Controller IPip_addr; Subnet Masksubnet_mask; Gatewaygateway; Device IP Startdev_ip_start; Device IP Enddev_ip_end.

Key Constants

Constant

Value

Description

PN_IP_START

100

First octet of the device IP scan range (last octet).

PN_IP_MAX

254

Last octet upper bound for device IP scan range.

CONNECTION_TIMEOUT_MS

5000

Per-device connection timeout in milliseconds.

MAX_DIG_INPUT

8

Number of entries in the digital IO lookup table.

IO_BUF_SIZE

1440

Bytes allocated per device IO buffer.

MAX_CONSOLE_RETRIES

3

Maximum re-prompt attempts for invalid console input (PN_CONSOLE_ENABLED only).

Building and Running

  1. Ensure the RAPIDSEA library (rs_lib.h) and the PROFINET Controller header (rs_profinet_controller.h) are on the include path.

  2. Link against the RAPIDSEA stack library.

  3. If PN_XML_CONFIG_ENABLED is 1, also compile and link utils_xml_parser.c and provide a valid XML configuration file.

  4. Set raw_sock_config.iface_name to the Ethernet interface connected to the PROFINET network (default: enp0s8).

  5. Run the binary with sufficient privileges for raw socket access (e.g., sudo on Linux).

Note

Raw socket operations (AF_PACKET) require either root privileges or the CAP_NET_RAW capability on Linux.

Dependency

This demo depends on the PROFINET Controller stack and its underlying interfaces:

Source Reference

Warning

doxygenfile: Cannot find file “profinet_controller_demo_app.c