PROFINET Controller Stack

Overview

RAPIDSEA supports PROFINET protocol as a comprehensive IO-Controller implementation. This page explains the controller architecture and details how users should interface the stack with their custom logic to realize PROFINET controller functionality quickly. It also provides guidelines on adopting the stack for different systems.

The PROFINET Controller stack implements all essential protocols:

  • DCP (Discovery and Configuration Protocol): Device identification and configuration

  • PN-RPC (PROFINET Remote Procedure Call): Connection establishment and acyclic data exchange

  • PNIO (PROFINET IO): Cyclic real-time data exchange

  • Alarm Protocol: Asynchronous event notification and acknowledgment

The below diagram captures the block level diagram of the PROFINET Controller and how it interfaces with other modules.

PROFINET Controller Stack Block Diagram

PROFINET Controller Stack Block Diagram

Controller API Interface

The RAPIDSEA PROFINET Controller stack handles protocol-level functionality including device discovery, connection management, cyclic data exchange, and alarm processing.

The below table captures the main functions to be called to drive the stack.

Controller API Functions

Function

Description

rs_pn_controller_open

Open and initialize the PROFINET controller instance with provided configuration

rs_pn_controller_close

Close the PROFINET controller and release associated resources

rs_pn_controller_process

Main cyclic processing function; handles PNIO transmission, raw socket reception, and connection management

rs_pn_controller_send_dcp_command

Send a DCP command (Identify, Set Name, Set IP, etc.) to a specific device

rs_pn_controller_connect_device

Initiate connection to a PROFINET device by sending a Connect Request (AR establishment)

rs_pn_controller_release_device

Release connection to a PROFINET device by sending a Release Request

rs_pn_controller_ping_device

Ping a PROFINET device to check reachability

rs_pn_controller_write_pnio_data

Write data to the PROFINET output IO image for a target address

rs_pn_controller_read_pnio_data

Read data from the PROFINET input IO image for a target address

rs_pn_controller_write_data_record

Write an acyclic data record to a specific slot/subslot of a PROFINET device

rs_pn_controller_read_data_record

Read an acyclic data record from a specific slot/subslot of a PROFINET device

rs_pn_controller_get_version_info

Retrieve the version information of the PROFINET Controller module

Stack Callbacks

The below table lists the callback functions that the caller must implement to receive asynchronous results and events from the stack.

Stack Callbacks

Callback

Description

rcb_pn_controller_dcp_identify_result

Invoked when a DCP Identify All response arrives; provides MAC address and discovery information

rcb_pn_controller_dcp_get_req_result

Invoked with the result of a DCP GET request (e.g., Get IP Parameters, Get Station Name)

rcb_pn_controller_dcp_set_req_result

Invoked with the result of a DCP SET request (e.g., Set IP Parameters, Set Station Name)

rcb_pn_controller_dcp_error_callback

Invoked when a DCP-level error occurs

rcb_pn_controller_rpc_connection_result

Invoked when an RPC connection attempt (AR establishment) completes

rcb_pn_controller_rpc_release_result

Invoked when an RPC release operation completes

rcb_pn_controller_rpc_error_callback

Invoked when an RPC-level error is reported

rcb_pn_controller_pnio_input_data_changed

Notification that PNIO input data has changed at the specified IO image offset

rcb_pn_controller_alarm_callback

Invoked directly when an alarm notification is received from a device; the stack automatically sends the ACK

PROFINET Controller Configuration Parameters

Controller Configuration (rs_pn_controller_config_t)

Parameter

Description

timeout_ms

General purpose timeout value in milliseconds

device_port

Dedicated destination port used by all PROFINET devices for receive

stn_name / stn_name_len

Station name of the controller and its length

ip_addr

IP address of the controller

subnet_mask

Subnet mask of the controller

gateway

Default gateway of the controller

dev_ip_start / dev_ip_end

IP address range for device discovery

supported_device_count

Number of PROFINET devices this controller manages

device_config

Array of device configurations (up to RS_PN_DEVICE_MAX_COUNT)

raw_sock_config

Raw Ethernet socket configuration (used for PNIO and DCP)

udp_client_config

UDP client socket configuration (used for RPC request send and receive response)

udp_server_tx_config

UDP server transmit socket configuration (used for RPC response send)

udp_server_rx_config

UDP server receive socket configuration (used for RPC request receive)

ptr_input_io_image

Pointer to the input IO image buffer

ptr_output_io_image

Pointer to the output IO image buffer

Device Configuration Parameters

Each PROFINET device managed by the controller requires configuration via rs_pn_device_config_t:

Device Configuration

Parameter

Description

stn_num

Logical device number

stn_name

PROFINET station name (up to 240 characters)

send_clock_factor

Send clock factor (multiple of 31.25µs)

reduction_ratio

Reduction ratio for the send clock

rt_class

Real-Time communication class (e.g., RT_CLASS_1)

vendor_id

Device Vendor ID

device_id

Device ID

instance

Device instance number

io_frame_type

Frame type used for IO data exchange (e.g., RTC1, RTC2)

type

Type of the device (IO, Drive, Switch)

startup_mode

Startup mode: 1 = Legacy, 2 = Advanced

writeable_im_records

Writeable IM records for the device

no_of_modules

Number of modules in the device

no_of_sub_modules

Total number of submodules in the device

no_of_records

Total number of parameter records

module[]

Array of module configurations (rs_pn_pnc_mod_data_t)

sub_module[]

Array of submodule configurations (rs_pn_pnc_submod_data_t)

parameter_record[]

Array of parameter record configurations (rs_pn_parameter_record_t)

input_image_start_offset

Byte offset of input IO data within the controller’s IO image

output_image_start_offset

Byte offset of output IO data within the controller’s IO image

io_input_data_length

Length of the input IO data buffer

io_output_data_length

Length of the output IO data buffer

Implementation Guide

This section explains how the PROFINET Controller can be implemented using the RAPIDSEA stack. The stack is available in source form; the steps to be followed are:

  1. Prepare IO Images: Declare static input_io_image[RS_PN_INPUT_IO_IMAGE_LENGTH] and output_io_image[RS_PN_OUTPUT_IO_IMAGE_LENGTH] arrays; assign their pointers in rs_pn_controller_config_t

  2. Configure Controller: Fill rs_pn_controller_config_t — network interface name (raw_sock_config.iface_name), IP/subnet/gateway, station name, timeout, device port, and device IP scan range

  3. Configure Each Device: Populate one rs_pn_device_config_t per controlled device including its modules, submodules (with IO image offsets), and optional parameter records

  4. Open Controller: Call rs_pn_controller_open() to initialize all communication subsystems; retain the returned handle

  5. Device Discovery Phase: Send CMD_DCP_IDENTIFY_ALL via rs_pn_controller_send_dcp_command(); wait ~2 s for all rcb_pn_controller_dcp_identify_result callbacks to arrive

  6. Configure Device Network Parameters: Optionally iterate DCP Set commands (CMD_DCP_SET_IP_PARAMS, CMD_DCP_SET_STATION_NAME) to assign device identity on the network

  7. Connection Establishment: For each discovered device call rs_pn_controller_connect_device(); wait for confirmation via rcb_pn_controller_rpc_connection_result

  8. Cyclic Processing: Enter the running loop — call rs_pn_controller_write_pnio_data() / rs_pn_controller_read_pnio_data() for IO data, and call rs_pn_controller_process() on every iteration

  9. Alarm Handling: Alarms are delivered directly via rcb_pn_controller_alarm_callback; no polling or queue management is required

  10. Shutdown Sequence: Call rs_pn_controller_release_device() for each connected device, then rs_pn_controller_close()

The high level flow is depicted below:

PROFINET Controller DCP Flow Diagram
PROFINET Controller RPC Flow Diagram

PROFINET Protocol Layers

The PROFINET Controller stack operates across multiple protocol layers:

Real-Time Classes

The stack supports multiple real-time communication classes:

  • RT_CLASS_1: Standard cyclic real-time communication over Ethernet

Frame ID Ranges

PROFINET uses specific frame ID ranges for different purposes:

PROFINET Frame ID Ranges

Frame ID Range

Type

Description

0x0000-0x001F

Reserved

Reserved for future use

0x0020-0x0021

PTCP Sync

Precision Time Protocol synchronization with follow-up

0x0080-0x0081

PTCP Sync

Precision Time Protocol synchronization without follow-up

0x0100-0x06FF

RTC3

Real-Time Class 3 (non-redundant, normal or DFP)

0x0700-0x0FFF

RTC3

Real-Time Class 3 (redundant, normal or DFP)

0x8000-0xBBFF

RTC1 Unicast

Real-Time Class 1 unicast (non-redundant)

0xBC00-0xBFFF

RTC1 Multicast

Real-Time Class 1 multicast (non-redundant)

0xC000-0xF7FF

RTC1 Legacy

Real-Time Class 1 legacy unicast cyclic

0xF800-0xFBFF

RTC1 Legacy

Real-Time Class 1 legacy multicast cyclic

0xFC01

Alarm High

High-priority alarm frames

0xFE01

Alarm Low

Low-priority alarm frames

0xFEFC

DCP Hello

DCP hello frames

0xFEFD

DCP Get/Set

DCP get/set parameter frames

0xFEFE

DCP Request

DCP identify multicast request

0xFEFF

DCP Response

DCP identify response

0xFF00-0xFF01

PTCP Announce

PTCP announcement frames

0xFF20-0xFF21

PTCP Follow-up

PTCP follow-up frames

0xFF40-0xFF43

PTCP Delay

PTCP delay measurement frames

DCP (Discovery and Configuration Protocol)

DCP Commands

The DCP protocol supports the following commands (defined as RS_PN_CMD_DCP_* macros):

Identify Operations:

  • RS_PN_CMD_DCP_IDENTIFY_ALL (1): Discover all PROFINET devices on the network

  • RS_PN_CMD_DCP_IDENTIFY_BY_NAME (2): Find a specific device by its station name

Query Operations:

  • RS_PN_CMD_DCP_GET_IP_PARAMS (3): Query current IP configuration

  • RS_PN_CMD_DCP_GET_STATION_NAME (4): Retrieve the current station name

Configuration Operations:

  • RS_PN_CMD_DCP_FLASH_LED (5): Trigger LED flashing for physical device identification

  • RS_PN_CMD_DCP_SET_IP_PARAMS (6): Configure IP address, subnet mask, and gateway

  • RS_PN_CMD_DCP_SET_STATION_NAME (7): Assign or change a device’s station name

  • RS_PN_CMD_DCP_FACTORY_RESET (8): Reset device configuration to factory defaults

DCP Workflow

  1. Call rs_pn_controller_send_dcp_command() with the desired command and a populated rs_pn_dcp_req_t

  2. The stack sends the DCP request (multicast for Identify All, unicast for targeted commands)

  3. On response reception, the stack invokes the appropriate callback (rcb_pn_controller_dcp_identify_result, rcb_pn_controller_dcp_get_req_result, or rcb_pn_controller_dcp_set_req_result)

  4. On failure or timeout, rcb_pn_controller_dcp_error_callback is invoked

PN-RPC (Remote Procedure Call)

RPC Operations

The PN-RPC protocol handles connection management and acyclic data exchange:

Connection Management:

  • Connect Request: Establish an Application Relation (AR) with a device via rs_pn_controller_connect_device()

  • Release Request: Terminate an existing Application Relation via rs_pn_controller_release_device()

Acyclic Data Exchange:

  • Read Record: Read an acyclic data record from device via rs_pn_controller_read_data_record()

  • Write Record: Write an acyclic data record to device via rs_pn_controller_write_data_record()

Connection Establishment Sequence

The typical connection sequence follows these phases:

  1. Connect Phase: rs_pn_controller_connect_device() sends a Connect request with AR parameters

  2. Parameterization Phase: Stack automatically writes configured parameter records to the device

  3. Parameter End: Stack sends PRM_END control command

  4. Application Ready Phase: Exchange APP_READY signals

  5. Data Exchange Phase: Begin cyclic data communication; rcb_pn_controller_rpc_connection_result is invoked on completion

PNIO (Cyclic Data Exchange)

IO Image

The controller maintains a flat IO image for all devices:

  • Input IO Image: Up to RS_PN_INPUT_IO_IMAGE_LENGTH (4096) bytes; holds data received from all devices

  • Output IO Image: Up to RS_PN_OUTPUT_IO_IMAGE_LENGTH (4096) bytes; holds data to be sent to all devices

Each device’s submodule data is mapped at a specific offset within the IO image using input_image_start_offset and output_image_start_offset in the device configuration.

IO Data Access

The stack accesses IO data using address-based APIs:

  • Write Output Data: rs_pn_controller_write_pnio_data(handle, u32_addr, ptr_data, num_bytes, local_iops, ptr_remote_iocs)

  • Read Input Data: rs_pn_controller_read_pnio_data(handle, u32_addr, ptr_data, ptr_data_len, buffer_len, local_iocs, ptr_remote_iops)

IOPS/IOCS Status Values

IO Status Values

Macro

Value

Description

RS_PN_PNIO_IOPS_GOOD

0x80

IO Provider Status: data is valid

RS_PN_PNIO_IOPS_BAD

0x60

IO Provider Status: data is invalid

RS_PN_PNIO_IOCS_GOOD

0x80

IO Consumer Status: consumer is ready

RS_PN_PNIO_IOCS_BAD

0x60

IO Consumer Status: consumer is not ready

Return Codes for PNIO Operations

PNIO Return Codes

Macro

Value

Description

RS_PN_PNIO_OK

0

Operation successful

RS_PN_PNIO_INVALID_PARAM

-1

Invalid parameter supplied

RS_PN_PNIO_ERR_VALUE_LEN

-2

Data length error

RS_PN_PNIO_UNKNOWN_ADDR

-3

Unknown IO image address

Module and Submodule Configuration

Each device consists of modules and submodules:

Module Configuration (rs_pn_pnc_mod_data_t):

  • API identifier (api)

  • Slot number (slot)

  • Module identification number (module_id_num)

  • Module properties (module_prop)

  • Number of submodules (no_of_sub_modules)

Submodule Configuration (rs_pn_pnc_submod_data_t):

  • API, slot, and subslot numbers

  • Submodule identification number (submod_id_num)

  • Input/output data lengths (in_sub_mod_data_length, out_sub_mod_data_length)

  • IOPS/IOCS lengths per direction

  • Data direction via sub_mod_prop

  • IO image offsets (input_image_offset, output_image_offset)

  • Pointers to data buffers (input_data, output_data)

Parameter Record Configuration (rs_pn_parameter_record_t):

  • Slot and subslot numbers

  • Record index (record_index)

  • Data length and pointer (length, ptr_data)

  • Value constraints: default_value, min_value, max_value, is_Changeable

Submodule Types

Submodule Types

Type

Description

RS_PN_SUBMODULE_PROP_TYPE_DAP

Device Access Point (DAP) — mandatory slot 0

RS_PN_SUBMODULE_PROP_TYPE_INPUT

Input-only submodule (data flows from device to controller)

RS_PN_SUBMODULE_PROP_TYPE_OUTPUT

Output-only submodule (data flows from controller to device)

RS_PN_SUBMODULE_PROP_TYPE_IO

Bidirectional submodule (both input and output data)

Alarm Protocol

Alarm Types

PROFINET alarms provide asynchronous event notification:

  • Diagnosis Alarms: Report diagnostic events from devices

  • Process Alarms: Indicate process-related events

  • Pull/Plug Alarms: Notify about module removal/insertion

  • Status Alarms: Report status changes

  • Update Alarms: Indicate configuration updates

  • Redundancy Alarms: Report redundancy-related events

  • Controlled by Supervisor: Special alarm management

  • Released: Alarm release notifications

  • Port Data Change Notification: Network topology changes

Alarm Handling

Alarms are delivered directly to the caller via the rcb_pn_controller_alarm_callback callback — there is no queue to poll. The stack handles the full alarm lifecycle internally:

  1. Alarm Reception: Device sends an alarm notification frame (high-priority on Frame ID 0xFC01, low-priority on 0xFE01)

  2. Immediate Callback: Stack parses the frame and invokes rcb_pn_controller_alarm_callback directly with the alarm type, device index, and status bytes

  3. Automatic Acknowledgment: The stack automatically sends the ACK frame back to the device upon callback return

Alarm Frame Types

Alarm Frame Type Macros

Macro

Value

Description

RS_PN_ALARM_FRAME_ACK

0

Acknowledgment frame sent automatically by the stack

RS_PN_ALARM_FRAME_DATA

1

Data frame, typically part of a high-priority alarm sequence

RS_PN_ALARM_FRAME_RAISE

2

Frame to raise a new alarm from controller to device

RS_PN_ALARM_FRAME_RESPONSE

3

Generic response frame in an alarm sequence

Alarm Priority Levels

The stack supports two alarm priority levels:

  • High-priority alarms (Frame ID: 0xFC01)

  • Low-priority alarms (Frame ID: 0xFE01)

Both priority levels are delivered directly through the same rcb_pn_controller_alarm_callback.

PROFINET Controller Stack Buffer Details

The PROFINET Controller stack maintains dedicated buffers for different communication channels:

Raw Socket Buffers

  • TX Buffer (raw_sock_tx_buffer): rs_pn_stream_buffer_t of RS_PN_STREAM_BUFFER_SIZE bytes; used for constructing outgoing DCP and PNIO frames

  • RX Buffer (raw_sock_rx_buffer): RS_PN_ETH_FRAME_LEN (1514) bytes; holds received raw Ethernet frames

UDP Buffers

  • TX Buffer (udp_tx_buffer): rs_pn_stream_buffer_t for RPC request construction

  • RX Buffer (udp_rx_buffer): RS_PN_ETH_FRAME_LEN bytes for incoming RPC responses

Alarm Buffers

  • Alarm RX Buffer Count: RS_PN_ALARM_RX_BUFFER_COUNT = 6 buffers

  • Buffer Size: RS_PN_ETH_FRAME_LEN bytes per buffer

  • Max Alarm Data Size: RS_PN_MAX_ALARM_DATA_SIZE = 1440 bytes

Device Management

  • Max Devices Supported: RS_PN_DEVICE_MAX = 64

  • Configured Devices: RS_PN_DEVICE_MAX_COUNT = 2 (user-configurable)

  • Max Slots per Device: RS_PN_MAX_DEVICE_SLOTS = 256

  • Max Subslots: RS_PN_MAX_SUBSLOTS = 64

  • Max Modules per Device: RS_PN_MAX_MODULES_PER_DEVICE = 8

  • Max Submodules per Device: RS_PN_MAX_SUBMODULES_PER_DEVICE = 32

  • Max Records per Device: RS_PN_MAX_RECORDS_PER_DEVICE = 128

PROFINET Controller Stack Memory Details

Static Memory Allocations

PROFINET Controller Static Memory

Structure / Field

Macro / Size

Description & Impact

rs_pn_controller_instance_t

Core structure

Main instance holding socket handles, device list, buffers, and connection info

device_list[RS_PN_DEVICE_MAX_COUNT]

2 × rs_pn_device_instance_t

Per-device runtime state including AR info, IOCR layouts, and cycle data

raw_sock_tx_buffer

RS_PN_ETH_FRAME_LEN bytes

Stream buffer for constructing outgoing raw Ethernet frames

raw_sock_rx_buffer

1514 bytes

Buffer for received DCP and PNIO frames

udp_tx_buffer

RS_PN_ETH_FRAME_LEN bytes

Stream buffer for constructing outgoing RPC frames

udp_rx_buffer

1514 bytes

Buffer for received RPC responses

rs_pn_device_config_t.module[]

8 × rs_pn_pnc_mod_data_t

Module configuration array per device

rs_pn_device_config_t.sub_module[]

32 × rs_pn_pnc_submod_data_t

Submodule configuration array per device; includes IO buffer pointers

rs_pn_device_config_t.parameter_record[]

128 × rs_pn_parameter_record_t

Parameter record configuration array per device

rs_pn_pnc_iocr_data_t (in/out)

Per device

Input and output IOCR data structures containing IO data objects and IOCS objects

IO Image Buffers

Up to 4096 bytes each

Caller-provided input and output IO image buffers

Dynamic Memory Considerations

The following require dynamic allocation or caller-provided buffers:

  • IO Image Buffers: Caller must allocate and provide pointers in rs_pn_controller_config_t

  • Submodule Data Buffers: Each submodule’s input_data and output_data pointers must reference valid buffers

  • Record Data: Caller-allocated data buffers pointed to by rs_pn_parameter_record_t.ptr_data

Note

  • All buffer macros (e.g., RS_PN_ALARM_RX_BUFFER_COUNT, RS_PN_DEVICE_MAX_COUNT) define compile-time constants affecting static memory footprint

  • Increasing buffer counts improves communication robustness but increases RAM usage

  • The number of devices (RS_PN_DEVICE_MAX_COUNT) significantly impacts memory requirements

  • Each device’s module/submodule configuration proportionally affects memory consumption

AR (Application Relation) State

The controller tracks the AR establishment state for each device:

AR State Macros

Macro

Value

Description

RS_PN_AR_NOT_ESTABLISHED

0x00

No Application Relation established

RS_PN_AR_ESTABLISHMENT_IN_PROGRESS

0x01

AR establishment sequence is in progress

RS_PN_AR_ESTABLISHED

0x02

AR is fully established; cyclic data exchange active

Device Status

Device Operational Status (rs_pn_device_status_t)

Status

Description

DEVSTAT_init (0)

Device is initialized but not yet active

DEVSTAT_active (1)

Device is connected and in cyclic data exchange

DEVSTAT_inactive (2)

Device is connected but not in data exchange

DEVSTAT_offline (3)

Device is not reachable or has failed

DEVSTAT_inactive_offline (4)

Device was inactive and is now offline

Implementation Notes

Platform Requirements

  • Network Interface: Raw socket support (AF_PACKET on Linux) for DCP and PNIO; UDP sockets for RPC

  • Real-Time Scheduling: Recommended for deterministic cyclic communication

  • Threading: Support for concurrent alarm processing (RS_PN_ALARM_THREAD_STACK_SIZE = 128 KB)

  • Timing: Microsecond-precision timers for cycle counter management (max cycle time: RS_PN_MAX_CYCLE_TIME = 1024)

Error Handling

All API functions return rs_ret_val_t status codes. Asynchronous errors are reported via the error callbacks.

Thread Safety

  • Socket operations should be protected with appropriate synchronization

  • Device configuration should be set before calling rs_pn_controller_open()

  • rs_pn_controller_process() should be called from a single thread

Best Practices

  1. Initialize in Order: Open controller → DCP discover → wait for responses → DCP configure → RPC connect → Cyclic process

  2. Validate Callbacks: Always check the result parameter in DCP and RPC callbacks before acting on the result

  3. Add Discovery Delay: Insert a settling delay (e.g., 2 s via rs_os_msleep()) after broadcasting RS_PN_CMD_DCP_IDENTIFY_ALL to collect all responses before proceeding to configuration

  4. Gate Connection on Discovery: Check that the device has been discovered before calling rs_pn_controller_connect_device() to avoid connecting to a device that has not been found

  5. Drive Process Every Iteration: Call rs_pn_controller_process() unconditionally on every main-loop iteration, regardless of the current state

  6. Check IOPS Before Using Input Data: Always verify iops_status == RS_PN_PNIO_IOPS_GOOD before acting on data read from rs_pn_controller_read_pnio_data()

  7. Graceful Shutdown: Always call rs_pn_controller_release_device() for each connected device before calling rs_pn_controller_close()

Dependency

This stack depends on the below RAPIDSEA interfaces that can be obtained or custom implemented:

Example Demo

An example implementation is available along with the release and is described in PROFINET Controller Demo Application. The demo is provided as profinet_controller_demo_app.c and demonstrates a two-device setup with an Advantech ADAM-6100PN and an RT-Labs reference device. It supports optional console-based configuration (PN_CONSOLE_ENABLED) and XML-based device configuration (PN_XML_CONFIG_ENABLED).

PROFINET Controller Header Details

Documentation from the relevant header as follows:

Warning

doxygenfile: Cannot find file “rs_profinet_controller.h