TICS100MOD-SDK  2026.0.0
TICS100MOD-SDK
Loading...
Searching...
No Matches
Common API

1. Overview

TICS100MOD is an industrial communication module board supporting EtherCAT, EtherNet/IP, and PROFINET. It connects a host application to a PLC or other industrial communication controller. The host communicates with the module through SPI and GPIO signals and may be a microcontroller (MCU), a Linux-based board, or another controller with the required interfaces.

The TICS100MOD SDK separates the customer's application logic from industrial communication, making the host application as protocol-agnostic as possible. Customers develop their application around a common API and a repository of variables, while the module handles the complete industrial protocol stack and its protocol-specific behavior. This lets customers focus on their application's functionality while using a consistent software interface across EtherCAT, EtherNet/IP, and PROFINET.

Conceptual overview of the PLC, TICS100MOD module, and host controller

Conceptual system overview. The PLC communicates with TICS100MOD using EtherCAT, EtherNet/IP, or PROFINET; the host communicates with the module through SPI and GPIOs.

The SDK provides the software framework for developing host applications that use TICS100MOD. A shared core component is used by both the module's target software and the host application. It provides common mechanisms for repository access, command processing, and data exchange between the two sides. Protocol-specific integration is handled within the module, with configuration supplied by the host application where required.

This document explains the SDK's key concepts, system architecture, and operating principles. It describes how the host and target interact, how the shared core and repository support that interaction, and where protocol-specific configuration applies. SDK setup procedures and step-by-step application development instructions are outside its scope.

Glossary

Term Meaning
TICS100MOD Industrial communication module that connects a host controller to an industrial network.
SDK Software framework used by the host application to configure and communicate with TICS100MOD.
Host MCU, Linux board, or other SPI-capable controller running the customer's application.
Target TICS100MOD software and hardware that manages the industrial protocol stack.
PLC / industrial controller Industrial controller connected to TICS100MOD through EtherCAT, EtherNet/IP, or PROFINET.
Shared core Common component used by the host and target for repository access, command handling, serialization, and data exchange.
Repository Hierarchical collection of SDK objects and variables used to represent application data.
IcsObject Opaque SDK handles representing repository objects.
Configurator Desktop tool that generates repository, device, channel, and protocol configuration data.
Bus State Built-in repository variable indicating the state of the industrial communication bus.

2. System Architecture

The system divides responsibilities between the host, which runs the customer application, and the target, which is the TICS100MOD module. The host accesses application data through the common SDK API, while the target handles the industrial protocol stack and protocol-specific integration. Both sides use the same core source code and include a communication interface based on SPI and GPIO signals.

System architecture block diagram

System view: the target handles industrial communication, while the host uses the common SDK API. Green blocks identify the shared core.

Component Host controller TICS100MOD target
Application or protocol layer Customer application logic using the SDK API. Industrial protocol stack and protocol-specific handling.
Shared core Repository access and processing of commands exchanged with the target. Repository access and processing of commands exchanged with the host.
Communication interface SPI and GPIO interface to the target. SPI and GPIO interface to the host.

The target software is a black box from the customer's perspective. The customer interacts with its capabilities through the host SDK and configuration tools; knowledge of the target's internal execution environment is not required.

Target architecture block diagram

Target view: conceptual responsibilities for protocol handling, industrial protocol integration, shared core operations, and host communication.

The shared core provides the common mechanisms used on both sides of the SPI link. It implements the interprocessor communication (IPC) protocol, serializes and deserializes exchanged data, handles commands, and reads and writes repository variables. Using the same core on the host and target gives both sides a common representation of the commands and data exchanged between them. The communication interface carries these exchanges through SPI, with GPIO signals supporting communication between the two sides.

The host owns the repository definition and composes its object structure. For objects represented on both sides, the host and target each maintain local data storage. Application code works with repository variables through the common SDK API. The target maps these variables to protocol-specific identifiers using configuration supplied by the host application. Protocol-specific mapping and exceptions are described in Chapter 5.

The following API operations exchange values with the target and connect PLC access to application callbacks:

Operation Purpose
IcsObject_refresh Retrieves an object's data from the target into the host repository.
IcsObject_apply Sends an object's data from the host repository to the target, subject to the callback restrictions in Chapter 4.
IcsObject_registerWriteCallback Registers a callback that runs after a PLC-written value has been copied into the host repository.
IcsObject_registerReadCallback Registers a callback that can update the local value before it is returned through the target to the PLC.

Local data access uses IcsObject_get and IcsObject_set; exchanges with the target use refresh and apply. The application therefore works with a common object model while the target handles the selected industrial protocol. Repository behavior, callbacks, and command restrictions are described in Chapter 4.

Host architecture block diagram

Host view: application logic accesses the host-owned repository through the SDK, with commands exchanged through the shared core and communication interface.

The framework also provides built-in services initiated by the target. These act as remote procedure calls (RPCs), allowing the target to request an application action and receive output parameters through a registered execution callback.

Industrial protocol selection is managed through the desktop Configurator tool. Its role and configuration workflow will be described later in the documentation.

3. Communication

The host and TICS100MOD communicate through an SPI data interface and GPIO control signals. SPI carries the exchanges handled by the shared core, while the GPIO signals support communication requests, target status indication, and module reset.

The host is the SPI master, and TICS100MOD is the SPI slave. The target can request communication with the host through a dedicated GPIO signal, but the host remains responsible for generating the SPI clock and carrying out the transfer.

3.1 Signals

The SPI interface uses three signal wires: SCLK, MOSI, and MISO, connected to module pins SPI0_CLK, SPI0_D0, and SPI0_D1, respectively. It operates without an SPI chip-select signal. In this document, three-wire SPI refers to these three separate clock and data signals.

The interface uses SPI Mode 0 and has been tested at 1 MHz. This is the tested operating frequency, not a specified maximum; operation at higher frequencies has not yet been validated.

Four additional control signals connect the host and target. The module pin SPI0_CS is used as Target Request Feed, an interrupt input on the target side. It does not serve as the SPI peripheral's chip-select signal in this interface. GPIO8 and GPIO14 connect to interrupt inputs on the host.

Signal Module pin Direction Role
SCLK SPI0_CLK Host to target SPI clock generated by the host.
MOSI SPI0_D0 Host to target Data sent by the host to TICS100MOD.
MISO SPI0_D1 Target to host Data sent by TICS100MOD to the host.
Target Request Feed SPI0_CS Host to target Host GPIO output connected to an interrupt input on the target.
Target Busy GPIO8 Target to host Target GPIO output connected to a host interrupt input; indicates that the target is busy.
Target Request GPIO14 Target to host Target GPIO output connected to a host interrupt input; allows the target to request communication.
Reset PORZ_HOST Host to target Host GPIO output connected to the module's reset input.
Combined SPI and GPIO signal connections between the host and TICS100MOD

Signal connections: the host provides the SPI clock, with separate data signals in each direction and four GPIO control signals. Arrows indicate signal direction. Power, ground, active levels, interrupt edges, and handshake timing are omitted.

4. Repository & Core Concept

The shared core combines device and channel configuration, a repository of application objects, and commands exchanged between the host and target. Configuration supplies the connection, firmware, and protocol settings. The host defines the repository structure, and the core manages local data access and exchanges with the target.

An IcsDevice represents a TICS100MOD module connected to the host. The current framework supports communication with one device. The application obtains its handle through Ics_getDevice using device index 0. The IcsHandle returned by Ics_create identifies the host framework instance used to access that device.

A communication channel represents logical communication with the connected device. The current implementation supports one channel. Its channel settings are a blob of protocol-specific data generated by the Configurator and supplied to the core through an application-provided function. These settings are distinct from the IcsCommChannelConfig structure declared in the API.

Each device has an IcsDeviceConfig describing its host connection and firmware provisioning settings. The desktop Configurator generates this configuration in device_settings.c alongside the repository definition. Configuration changes should be managed through the Configurator, which produces the generated files. Platform-specific connection details belong in the platform migration guide.

The following fields describe the currently established device configuration behavior:

Field Role and current usage
Type Must be IcsDeviceType_Spi, the currently supported host connection type.
ConnectionString Selects the platform SPI and control-signal instances and supplies the SPI clock frequency and mode. The generated connection settings should generally be retained.
Firmware Points to the IcsFirmware entries describing the firmware images supplied by the host for the module.
FirmwareCount Specifies the number of firmware entries supplied through Firmware.
Name, DeviceId, FirmwareDownloadRetries, WriteMemoryFireAndForget Present in the configuration structure but currently unused.

The connection string associates logical communication signals with host platform instances. The standard configuration is:

Spi=0;Request=0;BusyFeed=0;RequestFeed=1;Clock=1000000;Mode=0
Connection key Meaning
Spi SPI instance used to communicate with the module; the standard configuration uses instance 0.
Request GPIO output driving Target Request Feed; the standard configuration uses pin instance 0.
BusyFeed ICU instance receiving the Target Busy interrupt; the standard configuration uses instance 0.
RequestFeed ICU input receiving Target Request; the standard configuration uses instance 1.
Clock SPI clock frequency in Hz; the tested configuration uses 1000000 (1 MHz). This setting can be changed, subject to validation at the selected frequency.
Mode SPI mode; must remain 0.

The host application can supply firmware to the module during startup, including for flashing or updating it. The Configurator generates the firmware blobs in target_firmware.c. When this capability is used, Firmware must reference the corresponding IcsFirmware entries and FirmwareCount must match their number.

The Configurator generates the channel settings in **channel_settings.c**, which defines the byte array icsChannelSettingsBuffer and its size, icsChannelSettingsBufferSize. The size is calculated with sizeof(icsChannelSettingsBuffer) and is expressed in bytes. The blob carries information specific to the selected industrial protocol; its content is described in Chapter 5.

The application makes this generated data available to the core by implementing the following function:

IcsStatus IcsUser_getChannelSetting(
IcsHandle handle,
uint8_t* buffer,
uint32_t bufferLength,
uint32_t offset,
uint32_t* dataSize,
uint32_t* totalSize,
void* context);

The core calls IcsUser_getChannelSetting as part of **Ics_start**. It requests a portion of the blob by supplying an offset and a destination buffer. The application copies the requested portion from the generated array and reports both the number of bytes supplied and the total blob size. This interface allows the settings to be retrieved in portions without requiring the destination buffer to hold the entire blob.

Parameter Role
handle ICS instance handle supplied to the function.
buffer Destination buffer into which the application copies the requested settings data.
bufferLength Available destination capacity, in bytes.
offset Starting position in the settings blob, in bytes.
dataSize Output: number of bytes copied for this request.
totalSize Output: total size of the settings blob in bytes, independent of the requested portion.
context Context pointer supplied with the call.

For a valid request, the application copies the smaller of the destination capacity and the number of bytes remaining from the requested offset. It sets dataSize to that count, sets totalSize to icsChannelSettingsBufferSize, and returns IcsStatus_OK. The application supplies the generated bytes through this hook; protocol-specific interpretation remains part of the framework's handling of the settings.

4.1 Repository

The repository is a tree of objects, represented by the common IcsObject handle. Each object has an object type that determines its role in the tree. The root is a repository object; sections and groups organize the hierarchy, and variables represent the application data on which user logic operates.

typedef enum ObjectType_t
{
ICS_OT_Repository = 0xAB,
ICS_OT_Section = 0xAC,
ICS_OT_Group = 0xAD,
ICS_OT_Variable = 0xAE,
ICS_OT_ObjectReference = 0xAF
} ObjectType;

The repository hierarchy follows these containment rules:

Object type Role and permitted contents
ICS_OT_Repository Root of the tree; contains a list of sections.
ICS_OT_Section Contains groups, variables, or both.
ICS_OT_Group Contains groups, variables, or both, allowing nested organization. A group created with size = 0 is a dynamic group whose size is calculated from its children.
ICS_OT_Variable Represents application data; referred to as an IcsVariable in application code.
ICS_OT_ObjectReference Refers to an existing object without allocating another copy of its data.

A section may contain variables directly alongside groups. Groups may nest further groups and variables. The following tree shows object types, not application object names:

ICS_OT_Repository
+-- ICS_OT_Section
+-- ICS_OT_Variable
+-- ICS_OT_Group
+-- ICS_OT_Variable
+-- ICS_OT_Group
+-- ICS_OT_Variable

An object reference (ICS_OT_ObjectReference) points to an object that already exists. It provides indirection to that object without reallocating its data, rather than creating an independent copy of the value. Its application-specific use is outside this repository overview.

A dynamic group is created with size = 0. Its size is calculated from its children rather than specified explicitly by the application. A group created with a nonzero size allocates its own data buffer, using the size supplied in bits. This zero-size rule applies to groups; variables still require an explicit size in bits.

When a group is accessed as a whole, child data is combined in creation order, including the contents of nested groups. Child values occupy whole bytes; bit-sized values are rounded to byte storage. Nested group contents follow the same ordering rule.

The SDK exposes opaque handles for the objects:

typedef void* IcsRepository;
typedef void* IcsSection;
typedef void* IcsGroup;
typedef void* IcsVariable;
typedef void* IcsObject;

These aliases are all defined as void*; they name the roles of the handles used by application code. The object's ObjectType distinguishes its role in the tree. Object creation returns an IcsObject handle, which may also be held in the corresponding role-specific alias, such as IcsVariable.

For variables represented on both the host and target, the core allocates the required value storage independently on each side. The application accesses a variable through its handle rather than supplying the backing storage during object creation. Repository ownership describes the host's responsibility for composing the tree and using its variables, while allocation is handled by the core. Protocol-specific exceptions, including host-only objects, are described in Chapter 5.

The host application composes the repository using ICS_ADD_OBJECT. The public API defines this macro as follows:

#define ICS_ADD_OBJECT(id, parent, type, size, dataType, accessFlags, settings, settingsSize) \
id = IcsObject_addObject((parent), (type), (size), (dataType), \
(accessFlags), #id, (settings), (settingsSize))

The macro creates an object under the supplied parent and assigns the returned handle to id. The arguments describe both the object's role in the tree and its data characteristics:

Argument Meaning
id Application handle variable that receives the created object. Its token text also supplies the object name through #id.
parent Handle of the parent under which the object is added.
type Object role, expressed as an ObjectType, such as ICS_OT_Section or ICS_OT_Variable.
size Object data size in bits, supplied explicitly for every variable, including typed variables. For a group, 0 selects dynamic sizing based on its children; a nonzero size allocates the group's own data buffer. Size does not apply to repositories or sections.
dataType Data category expressed as a VariableType, such as ICS_VT_UINT32.
accessFlags Object flags passed to creation, using the IcsFlags definitions.
settings Pointer to object settings passed to creation.
settingsSize Size of the supplied object settings.

The macro converts the handle variable token into the object name through #id and assigns the returned handle to that variable. The underlying IcsObject_addObject function accepts the name explicitly as a const char*.

Object names must be unique across the entire repository, including objects under different sections or groups. Applications must preserve this uniqueness when constructing the tree and when adding objects at runtime.

IcsObject_find searches all descendants of the supplied object by name, including nested children. It requires a valid starting object and does not accept NULL. By contrast, Ics_findObject accepts NULL as its object argument to search across the entire repository. Applications can retain the handles returned during creation and use name-based lookup when they need to locate an existing object.

Objects are configured through the accessFlags argument using the IcsFlags definitions. The read and write permissions describe PLC access to the object.

Flag Application-facing meaning
ICS_FLAGS_READ Permits the PLC to read the object.
ICS_FLAGS_WRITE Permits the PLC to write the object.
ICS_FLAGS_READ_WRITE Combines PLC read and write permissions.
ICS_FLAGS_PERSISTENT Marks the object's value for persistent storage on the module.
ICS_FLAGS_ARRAY Identifies an array. Its supplied size is expressed in bits; the interpretation as the total array size is to be reviewed.

Protocol-specific flags and object behavior, including ICS_FLAGS_OWNED_BY_PROTOCOL, ICS_FLAGS_OWNED_BY_REPOSITORY, ICS_FLAGS_ENUM, ICS_FLAGS_VIRTUAL_GROUP, and ICS_FLAGS_HOST_ONLY, are described in Chapter 5.

For objects represented on both sides, host-side additions are reflected on the target through ICS_CMD_OBJECT_ADD_CHILD_REQ. The host defines the structure, and the target creates the corresponding object with its own local storage. This exchange is synchronous: the host waits until the target has handled the request and returned a reply.

The application supplies the repository construction logic through IcsCommChannel_buildRepository, a hook called automatically by the core from IcsCommChannel_start:

extern IcsStatus IcsCommChannel_buildRepository(
IcsCommChannel channel,
IcsRepository repository);

The hook receives the communication channel and the repository root to populate. Its implementation uses ICS_ADD_OBJECT to create parents before their children, supplying the object types, sizes, flags, and settings. It returns an IcsStatus result to the core. The repository definition supplied with the generated configuration provides the intended object structure for this application-provided construction logic.

The host startup sequence is organized around the following API calls and application configuration step:

Stage API or application action Purpose
Create Ics_create Creates the ICS instance and returns its handle.
Initialize Ics_initialize Initializes the instance and returns an initialization status.
Obtain the device Ics_getDevice Retrieves the supported device using index 0.
Obtain the repository IcsDevice_getDefaultRepository Retrieves the device's default repository handle.
Configure protocol parameters Application-provided protocol configuration Applies the device parameters after successful initialization. Protocol-specific configuration is described in Chapter 5.
Start Ics_start Retrieves channel settings through IcsUser_getChannelSetting and triggers IcsCommChannel_start, which invokes the repository construction hook. The application checks the returned status before starting its own tasks.
Initialize protocol-specific application support Application repository hooks Create built-in objects during repository construction as described below, then register application callbacks against the constructed objects.

During Ics_start, the core retrieves channel settings through IcsUser_getChannelSetting and starts the channel through IcsCommChannel_start. Channel startup invokes IcsCommChannel_buildRepository to populate the root obtained earlier. These are core-invoked hooks; the application supplies their implementations. This description does not prescribe the order of settings retrieval and repository construction within Ics_start.

Protocol initialization follows the application's repository construction hooks. EtherNet/IP calls IcsEthernetip_initialize(repository) inside IcsRepository_initialize(), which runs during Ics_start(). Initialize its built-in attributes and register callbacks after creating those objects in that hook. Check the returned IcsStatus against IcsStatus_OK.

For PROFINET and EtherCAT, follow the initialization hooks in the matching host example. EtherCAT service creation uses IcsEthercat_createServices(repository). After Ics_start() succeeds, application setup can locate the constructed objects and register application callbacks before starting its own tasks.

When the application ends a running cycle, the shutdown and reset sequence is **Ics_stop → IcsDevice_reset (hard reset) → Ics_shutdown → Ics_destroy**. A subsequent cycle creates and initializes a new ICS instance, obtains its device and repository handles, configures protocol parameters, and starts again. Repository construction runs again through the build hook during that new startup.

The target must be in bootloader mode before communication is restarted. The application calls IcsDevice_reset with IcsDeviceResetType_Hard after Ics_stop and before Ics_shutdown. This performs a power-on reset of the target and returns its firmware to the initial bootloader state. The host then shuts down and destroys the instance before beginning the next cycle.

Application lifecycle with repository construction and target reset

Normal application cycle: startup constructs the repository, followed by protocol-specific application initialization and the main application logic. At the end of the cycle, the instance is stopped, the target is hard-reset into bootloader mode, and the instance is shut down and destroyed.

Application data operations center on IcsVariable objects. An object's type identifies its role in the repository, while its VariableType describes its data representation. These are separate properties: ICS_OT_Variable identifies a variable object, while ICS_VT_STRUCT is assigned to a group containing variable children.

typedef enum VariableType_e
{
ICS_VT_NONE = 0,
ICS_VT_UINT8,
ICS_VT_UINT16,
ICS_VT_UINT32,
ICS_VT_UINT64,
ICS_VT_BOOLEAN,
ICS_VT_STRUCT,
ICS_VT_RAW_VAR,
ICS_VT_RAW
} VariableType;

The declared types include unsigned integers, Boolean values, and the following structured or raw data categories:

Data type Concept
ICS_VT_STRUCT Assigned to a group whose variable children represent the structure's fields.
ICS_VT_RAW A byte array with a fixed size.
ICS_VT_RAW_VAR A byte array with a variable length.

The application must supply each variable's size explicitly in bits, even when a data type is specified. A size of 0 does not select a default size from the data type. For arrays marked with ICS_FLAGS_ARRAY, size is also expressed in bits; its interpretation as the total array size is marked to be reviewed in Section 4.3.

Repository backing memory is cleared to zero when allocated. Application logic should establish meaningful default values before using the variables and explicitly exchange values between host and target where required. Values marked persistent are saved on the module.

Use local get/set on objects with data storage. For an object reference, access the underlying variable or use the reference-aware read/write operations. Group access combines child data as described above. Local value access and host-to-target exchange remain separate operations:

API operation Effect when called on the host
IcsObject_set Writes the selected object's data in the local host repository. It does not send the data to the target.
IcsObject_get Reads the selected object's data from the local host repository. It does not retrieve new data from the target.
IcsObject_apply Sends the selected object's current host-side data to the target. For an individual variable, this is forbidden when a write callback is registered on it.
IcsObject_refresh Retrieves the selected object's target-side data and updates the local host repository.

IcsObject_applyRawVar is the specialized apply operation for ICS_VT_RAW_VAR variables. It accepts an IcsObjectValue describing the data to send and is used only with this variable-length byte-array type.

Outside callbacks, and for a variable without a registered write callback, the application can provide a value to the target by first writing it locally with IcsObject_set, then sending it with IcsObject_apply. To read an updated value from the target, it first calls IcsObject_refresh, then reads the local result with IcsObject_get. The apply and refresh exchanges follow the synchronous command model described in Section 4.2.

Read and write callbacks are registered separately for each variable through IcsObject_registerReadCallback and IcsObject_registerWriteCallback. A variable can have both callbacks registered at the same time, with at most one read callback and one write callback per variable. Registration is permitted at any point after the object has been created, including within the repository construction hook after the object is added or after startup. These callbacks allow application logic to participate in PLC access to that variable.

PLC operation Callback sequence
Write The received value is copied into the host repository before the write callback runs. The callback can read that updated local value with IcsObject_get.
Read The read callback runs before the value is returned to the target and then to the PLC. The callback can prepare or modify the local value with IcsObject_set; the core returns the value as part of handling the PLC read.

Within either callback, variable value access must use only IcsObject_get and IcsObject_set. Calling IcsObject_apply or IcsObject_refresh from a callback is forbidden. Updating a value in a read callback therefore does not require an explicit apply call.

A registered write callback also imposes a restriction outside callback execution: **IcsObject_apply must not be called on that variable while the write callback is registered.** Local value access and callback-driven handling must respect these restrictions, summarized in Section 4.3.

After startup, the application decides when and how frequently to update its variables. Cyclic updates of critical variables are recommended, but are not mandatory. The application selects the variables and update intervals according to its requirements, using refresh to retrieve target values and apply to send local values where permitted. These exchanges remain subject to the callback restrictions above.

The repository includes a built-in Bus State variable that reports the state of the industrial communication bus. BUS ON generally indicates an established connection between TICS100MOD and the industrial controller. It describes the industrial-network connection; successful SDK startup or host-to-module SPI communication alone does not establish that this connection is active.

The public API provides ICS_CHANNEL_BUS_STATE_SECTION_ID for the bus-state section name and ICS_CHANNEL_BUS_STATE_VARIABLE_ID for the variable name. The application can locate this built-in variable through the repository's object lookup APIs and use its value when deciding how to respond to the industrial connection state. Protocol-specific interpretations of bus state are described in Chapter 5.

The repository can also be extended while the application is running. Objects may be added after startup through ICS_ADD_OBJECT; construction is not restricted to IcsCommChannel_buildRepository. New objects follow the same creation and target-reflection mechanisms, and callbacks can be registered once the objects exist.

Applications must synchronize concurrent access to shared local repository data and structural changes. Local get/set operations copy data without application-level locking. Communication serialization does not make a sequence of application operations atomic. The callback restrictions still apply.

4.2 Commands

Host-initiated commands use a synchronous request/reply model: the host waits until the target has handled the request and returned a reply. This applies to repository construction and data exchanges such as apply and refresh. For example, ICS_CMD_OBJECT_ADD_CHILD_REQ creates the target-side counterpart of a host object, and the host waits for the reply before continuing that operation. Local get and set calls access the host repository without a target exchange.

The framework also provides services through which the target requests an action from the host application. A service represents an operation, with input and output parameters, rather than an ordinary application data value. For example, a PROFINET factory-reset request requires the host to perform application-specific reset actions. The target delivers that request through a service.

All services are built into the framework. Applications can use the supplied services but cannot create new ones. Each service is represented by an object that the application locates by name. Service-name macros contain the corresponding object names.

Service handlers are registered by application code after successful Ics_start, during protocol-specific application initialization. For PROFINET, the application calls IcsProfinet_initialize(repository) at this stage. To handle a service, the application locates its object using Ics_findObject, passing NULL as the object argument to search the entire repository. It checks that the returned handle is not NULL and registers an execution callback with IcsObject_registerExecuteCallback. For the PROFINET factory-reset service, ICS_SERVICES_PN_SV_FACTORY_RESET supplies the service object name. The execution callback receives the service object and the context supplied during registration.

The callback processes the service through the following sequence:

Step Application responsibility API
Locate parameters Find the service's input and output parameter objects relative to the service object. IcsObject_find
Read inputs Read the input parameter values from their local objects. IcsObject_get
Perform the action Carry out the application-specific work requested by the service and determine the result. Application logic
Write outputs Store the output parameter values, including the result, before returning from the callback. IcsObject_set

The PROFINET factory-reset service has an input parameter identified by ICS_SERVICES_PN_SV_FACTORY_RESET_OPTION and an output parameter identified by ICS_SERVICES_PN_SV_FACTORY_RESET_RESULT. Both are accessed as uint32_t values using ICS_UINT32. Parameter lookup, input reading, and output writing form the fixed service-handling pattern; the application implements the requested reset actions and assigns the result. The option meanings and result codes belong to Chapter 5. This service is distinct from the module hard reset used in the lifecycle: it requests application-specific factory-reset work from the host.

Execution callbacks use the same callback mechanism as read callbacks: the public API defines IcsObject_registerExecuteCallback as an alias of IcsObject_registerReadCallback. Use local IcsObject_get and IcsObject_set operations inside the service callback; IcsObject_apply and IcsObject_refresh are forbidden. The output parameters provide the service response through this callback mechanism.

4.3 Limitations

The following support limits, restrictions, and unresolved cases apply to the framework:

Context Restriction
Supported configuration One device and one logical communication channel are currently supported. The host connection type is IcsDeviceType_Spi.
Object names Names must be unique across the entire repository, including across different parents.
Object lookup IcsObject_find requires a valid starting object. Ics_findObject accepts NULL as its object argument for a repository-wide search.
Callback registration The object must already exist. Each variable supports at most one read callback and one write callback; both may be registered together.
Read, write, or service execution callback Use only IcsObject_get and IcsObject_set for value access. IcsObject_apply and IcsObject_refresh are forbidden within callbacks.
Variable with a registered write callback IcsObject_apply is forbidden on that variable, including outside callback execution.
Group containing a variable with a registered write callback To be reviewed: behavior of IcsObject_apply on the group has not been specified.
Service creation Services are built in. Applications can register handlers for existing services but cannot define new services.
Array sizing To be reviewed: size is expressed in bits; confirm its interpretation as the total array size for objects marked with ICS_FLAGS_ARRAY.
IcsObject_applyRawVar Used only with ICS_VT_RAW_VAR variables.

4.4 Target / Module Lifecycle

The target starts in bootloader mode. In this state, it initializes the module and waits for the host to select how the target software should be started. The host can either start a protocol firmware already stored in the module's flash or provide firmware images for the target to write to flash before booting.

Start from firmware already stored in flash

The host sends a start request containing the protocol index to boot:

Protocol index Protocol
0 EtherCAT
1 PROFINET
2 EtherNet/IP

The target selects the firmware associated with that index from flash, boots it, and starts the selected industrial protocol implementation.

Start with firmware supplied by the host

The host sends the required firmware image or images to the target during startup. The target writes the received firmware to flash and then boots from the newly stored image. This path supports initial provisioning and firmware updates from the host application.

After the target has booted the selected firmware, the host continues with the normal SDK startup sequence described in this chapter: it initializes the ICS instance, configures the device, starts the communication channel, builds the repository, and initializes the selected protocol support. When communication must be restarted, the host stops the SDK instance and performs a hard target reset so the target returns to bootloader mode for the next startup cycle.

5. Protocol Specific

5.1 Profinet

This section describes the PROFINET-specific generator and repository model. The generator uses a GSDML file, an XML device-description format, as its input. Only the GSDML elements that affect the SDK repository, PROFINET object metadata, I/O data, parameter records, and channel settings are covered here; the complete GSDML specification is outside the scope of this document.

The generator produces three main outputs:

Generated output Purpose
repository.c Defines the generated IcsObject handles and implements IcsCommChannel_buildRepository.
repository.h Declares the generated object handles with extern for use by the application.
channel_settings.c Separate generated source file containing the GSDML-derived channel-settings byte array and its size. The core retrieves this data through IcsUser_getChannelSetting during Ics_start.

These files are generated artifacts. When the GSDML configuration changes, regenerate the repository and channel settings together instead of editing the generated files manually.

5.1.1 Code Generation

Repository data section

Repository generation starts by creating a dedicated DataSection under the repository root. This section groups the generated PROFINET data and keeps it separate from other objects that may be added by the application or framework.

The generated source declares the section handle as a global IcsObject and creates it from IcsCommChannel_buildRepository:

IcsObject DataSection;
extern IcsStatus IcsCommChannel_buildRepository(
IcsCommChannel channel,
IcsRepository repository)
{
IcsStatus result = IcsStatus_OK;
uint32_t size = 0;
uint8_t buffer[16] = {0};
ICS_ADD_OBJECT(DataSection, repository,
ICS_OT_Section, 0, ICS_VT_NONE,
0x00000000, NULL, 0);
/* Generated PROFINET objects follow. */
}

The generated header exports the handle so application code can refer to it:

extern IcsObject DataSection;

The same pattern is used for every generated object: repository.c owns the definition, and repository.h makes the handle available to other compilation units.

GSDML hierarchy and repository hierarchy

The generator maps the relevant GSDML hierarchy to the SDK repository hierarchy:

GSDML element Generated object Role in the repository
Module ICS_OT_Group Groups all generated objects belonging to one module.
Submodule ICS_OT_Group Groups the records and I/O data belonging to one submodule.
ParameterRecordDataItem ICS_OT_Group Groups the parameters contained in one parameter record.
Ref inside a parameter record ICS_OT_Variable Represents one parameter value.
Input data ICS_OT_Group with child variables Groups the input data items of a submodule.
Output data ICS_OT_Group with child variables Groups the output data items of a submodule.

Each generated handle is declared globally in repository.c and exported with extern in repository.h. The generated names are derived from the GSDML identifiers, allowing application code to access known objects directly after repository construction.

Modules and submodules

Each configured module is added as a group below DataSection. Each submodule is then added as a child group of its module:

ICS_ADD_OBJECT(IDM_IM_V1, DataSection,
ICS_OT_Group, 0, ICS_VT_NONE,
0x00000000, NULL, 0);
ICS_ADD_OBJECT(IDM_IM_V1_IDS_IM_MAP, IDM_IM_V1,
ICS_OT_Group, 0, ICS_VT_NONE,
0x00000000,
IcsObject_serializeParameters(
buffer, sizeof(buffer), &size,
0x03010100, 0x03010101,
0xFFFFFFFF, 0xFFFFFFFF),
size);

The serialized settings carry the PROFINET metadata required to associate the object with its module or submodule. The generator creates these values from the GSDML input; application code should treat them as generated configuration.

The module and submodule IDs are read from the corresponding GSDML attributes. The last two metadata values are reserved and supplied by the generator. For example, the sample GSDML contains a module, its submodule, and a parameter record:

<ModuleItem ID="IDM_IM_V1"
ModuleIdentNumber="0x03010100">
<VirtualSubmoduleItem ID="IDS_IM_MAP"
SubmoduleIdentNumber="0x03010101">
<RecordDataList>
<ParameterRecordDataItem Index="4096" Length="16">
<Ref ID="IDR_PIC" ByteOffset="2"
DataType="BitArea" BitOffset="0" BitLength="2"/>
</ParameterRecordDataItem>
</RecordDataList>
</VirtualSubmoduleItem>
</ModuleItem>

The generator obtains the values as follows:

Metadata value GSDML source Value in this example
Module ID ModuleItem/@ModuleIdentNumber 0x03010100
Submodule ID VirtualSubmoduleItem/@SubmoduleIdentNumber 0x03010101
Reserved value 1 Generator-managed Reserved; retain the generated value.
Reserved value 2 Generator-managed Reserved; retain the generated value.

These values are passed to IcsObject_serializeParameters in the same order used by the generated repository:

IcsObject_serializeParameters(
buffer, sizeof(buffer), &size,
0x03010100, /* module ID */
0x03010101, /* submodule ID */
0x1000, /* reserved: generated value */
0x2); /* reserved: generated value */

For both parameter-record and I/O objects, the final two metadata values are reserved. Applications must preserve the generated values without interpreting or modifying them.

Parameter records and references

Each ParameterRecordDataItem is represented by a group below its submodule. Each Ref in that record becomes a variable below the record group. The variable size and SDK data type are generated from the reference's data description, while the serialized settings preserve the PROFINET addressing information.

ICS_ADD_OBJECT(IDM_IM_V1_IDS_IM_MAP_IDT_MOD_Param,
IDM_IM_V1_IDS_IM_MAP,
ICS_OT_Group, 128, ICS_VT_NONE,
0x00000000,
IcsObject_serializeParameters(
buffer, sizeof(buffer), &size,
0x03010100, 0x03010101,
0x1000, 0x0),
size);
ICS_ADD_OBJECT(IDM_IM_V1_IDS_IM_MAP_IDT_MOD_Param_Dummy_Byte0,
IDM_IM_V1_IDS_IM_MAP_IDT_MOD_Param,
ICS_OT_Variable, 8, ICS_VT_UINT8,
0x00000081,
IcsObject_serializeParameters(
buffer, sizeof(buffer), &size,
0x03010100, 0x03010101,
0x1000, 0x0),
size);

The record group represents the complete record, while its child variables represent the individual references. Application code can therefore work with a complete record or with one parameter variable, using the common repository APIs described in Chapter 4.

I/O data

The IOData element of a GSDML submodule describes its process data. Input and output are defined from the PLC's perspective: input data is supplied by the device to the PLC; output data is sent by the PLC to the device.

GSDML direction Application data flow Generated repository structure
Input Host application → TICS100MOD → PLC An _Input group below the submodule, with one variable for each DataItem.
Output PLC → TICS100MOD → host application An _Output group below the submodule, with one variable for each DataItem.

A submodule can contain inputs, outputs, or both. When both are present, the generator creates separate input and output groups under that submodule. Each group represents the complete data block for its direction; its child variables expose the individual items to application code.

For example, the following excerpt from the supplied GSDML describes a submodule with one input item:

<SubmoduleItem ID="IDS_TI1" SubmoduleIdentNumber="0x31010001">
<IOData>
<Input Consistency="All items consistency">
<DataItem DataType="OctetString" TextId="IDT_TI1"
Length="1" UseAsBits="true" />
</Input>
</IOData>
</SubmoduleItem>

Here, the OctetString has a length of one byte. The generated child variable therefore has a size of 8 bits. Because this input contains only one item, its parent input group also has a size of 8 bits. With multiple items, the group size covers all of them, and their byte offsets follow their order in the GSDML.

When this submodule belongs to module IDM_IM_V1 (ModuleIdentNumber="0x03010100"), the generator creates the following input group and child variable:

ICS_ADD_OBJECT(IDM_IM_V1_IDS_TI1_Input,
IDM_IM_V1_IDS_TI1,
ICS_OT_Group, 8, ICS_VT_NONE,
0x00000001,
IcsObject_serializeParameters(
buffer, sizeof(buffer), &size,
0x03010100, 0x31010001,
0x0, 0xFFFFFFFF),
size);
ICS_ADD_OBJECT(IDM_IM_V1_IDS_TI1_Input_IDT_TI1,
IDM_IM_V1_IDS_TI1_Input,
ICS_OT_Variable, 8, ICS_VT_NONE,
0x00000081,
IcsObject_serializeParameters(
buffer, sizeof(buffer), &size,
0x03010100, 0x31010001,
0x0, 0x0),
size);

The group name combines the module and submodule identifiers with _Input. The child name adds the data item's TextId, producing a handle the application can use to access that item.

The four metadata values passed to IcsObject_serializeParameters identify the I/O data as follows:

Metadata field Input group in this example Child variable in this example
Module ID 0x03010100, from the parent module's ModuleIdentNumber. Same module ID.
Submodule ID 0x31010001, from SubmoduleIdentNumber. Same submodule ID.
Reserved value 1 Generator-managed; retain the generated value. Generator-managed; retain the generated value.
Reserved value 2 Generator-managed; retain the generated value. Generator-managed; retain the generated value.

The third and fourth metadata values are reserved for both I/O and parameter-record objects. Their generated values must be retained. Object sizes supplied to ICS_ADD_OBJECT remain expressed in bits.

The generated input group has read access from the PLC's perspective (0x00000001). Its child variables also carry the host-only flag (0x00000081 in this example). They provide local access to individual items, while exchanges with the target operate on the parent I/O group. For input data, the application sets the child values locally and applies the input group. For output data, it refreshes the output group and then reads the child values locally, subject to the callback restrictions in Chapter 4.

Output generation follows the same pattern, using an _Output group and PLC write-access flags. A submodule containing both directions keeps these two data blocks separate.

Channel settings

The generator also converts the GSDML-derived PROFINET channel configuration into channel_settings.c:

The channel settings are not stored in repository.c or repository.h; they are emitted as a separate generated source file and compiled with the repository sources.

uint8_t icsChannelSettingsBuffer[] = {
/* generated PROFINET settings */
};
uint32_t icsChannelSettingsBufferSize =
sizeof(icsChannelSettingsBuffer);

The host application exposes this buffer through IcsUser_getChannelSetting. During Ics_start, the core retrieves the blob in one or more portions and passes it to the communication channel. The repository and channel settings therefore come from the same GSDML input and should be regenerated together.

The channel-settings blob contains the PROFINET configuration required by the industrial stack to establish and operate the device. Depending on the selected GSDML configuration, this includes the configured modules and submodules, their slot and subslot placement, available ports, which modules may be plugged into which slots, and the other relationship and identification information needed to validate the device layout and run the PROFINET communication.

5.1.2 Specific Features

PROFINET initialization. After Ics_start has successfully built the repository, the application initializes the PROFINET support with:

IcsProfinet_initialize(repository);

This creates the built-in PROFINET service objects used by the target to request application actions. Applications locate the supplied service objects and register execution callbacks for them.

Input parameters are supplied by the target and read by the host callback. Output parameters are written by the callback and returned to the target. Parameter identifiers name child objects of the corresponding service object.

The registration examples run after PROFINET initialization and use application-provided handlers. Check that service lookup returned a valid handle before registering a callback. Within a handler, use ICS_UINT32 for integer parameters and ICS_BOOL for the LED state.

Factory Reset Service

Requests application-specific factory-reset actions using the supplied reset option.

Service Identifier
ICS_SERVICES_PN_SV_FACTORY_RESET
Input Parameters
ICS_SERVICES_PN_SV_FACTORY_RESET_OPTION
Parameter Description
Option Requested factory-reset option (uint32_t).
Output Parameters
ICS_SERVICES_PN_SV_FACTORY_RESET_RESULT
Parameter Description
Result Result of the application reset operation returned to the target (uint32_t).
Registering the Handler
IcsObject factoryResetService =
Ics_findObject(
icsHandle,
NULL,
ICS_SERVICES_PN_SV_FACTORY_RESET);
IcsObject_registerExecuteCallback(
factoryResetService,
OnExecute_PN_factoryReset,
NULL);

Set LED Service

Requests a state change for the identified LED.

Service Identifier
ICS_SERVICES_PN_SV_SET_LED
Input Parameters
ICS_SERVICES_PN_SV_SET_LED_LED
ICS_SERVICES_PN_SV_SET_LED_STATE
Parameter Description
LED Identifier of the LED to control (uint32_t).
State Requested LED state (bool).
Output Parameters
ICS_SERVICES_PN_SV_SET_LED_RESULT
Parameter Description
Result Result of the LED state change returned to the target (uint32_t).
Registering the Handler
IcsObject setLedService =
Ics_findObject(
icsHandle,
NULL,
ICS_SERVICES_PN_SV_SET_LED);
IcsObject_registerExecuteCallback(
setLedService,
OnExecute_PN_setLed,
NULL);

Start LED Blink Service

Requests blinking for the specified port LED at the supplied frequency.

Service Identifier
ICS_SERVICES_PN_SV_START_LB
Input Parameters
ICS_SERVICES_PN_SV_START_LB_PORTNUM
ICS_SERVICES_PN_SV_START_LB_FREQUENCY
Parameter Description
Port Number Port whose LED should blink (uint32_t).
Frequency Requested blink frequency in Hz (uint32_t).
Output Parameters
ICS_SERVICES_PN_SV_START_LB_RESULT
Parameter Description
Result Result of the request to start blinking returned to the target (uint32_t).
Registering the Handler
IcsObject startLedBlinkService =
Ics_findObject(
icsHandle,
NULL,
ICS_SERVICES_PN_SV_START_LB);
IcsObject_registerExecuteCallback(
startLedBlinkService,
OnExecute_PN_startLedBlink,
NULL);

Stop LED Blink Service

Requests that blinking stop for the specified port LED.

Service Identifier
ICS_SERVICES_PN_SV_STOP_LB
Input Parameters
ICS_SERVICES_PN_SV_STOP_LB_PORTNUM
Parameter Description
Port Number Port whose LED should stop blinking (uint32_t).
Output Parameters
ICS_SERVICES_PN_SV_STOP_LB_RESULT
Parameter Description
Result Result of the request to stop blinking returned to the target (uint32_t).
Registering the Handler
IcsObject stopLedBlinkService =
Ics_findObject(
icsHandle,
NULL,
ICS_SERVICES_PN_SV_STOP_LB);
IcsObject_registerExecuteCallback(
stopLedBlinkService,
OnExecute_PN_stopLedBlink,
NULL);

Service callbacks follow the common service pattern described in Chapter 4: find the input and output parameter objects relative to the service object, read the input values with IcsObject_get, perform the application action, and write the result with IcsObject_set. For example, a start-LED-blink handler reads the port number and frequency, performs the requested application action, and writes the result:

void OnExecute_PN_startLedBlink(IcsObject object, void* context)
{
IcsObject portNumObj =
IcsObject_find(object, ICS_SERVICES_PN_SV_START_LB_PORTNUM);
IcsObject frequencyObj =
IcsObject_find(object, ICS_SERVICES_PN_SV_START_LB_FREQUENCY);
IcsObject resultObj =
IcsObject_find(object, ICS_SERVICES_PN_SV_START_LB_RESULT);
uint32_t portNum;
uint32_t frequency;
uint32_t result = 0;
IcsObject_get(portNumObj, ICS_UINT32(portNum));
IcsObject_get(frequencyObj, ICS_UINT32(frequency));
/* Application-specific LED handling uses portNum and frequency. */
IcsObject_set(resultObj, ICS_UINT32(result));
}

The factory-reset and stop-LED-blink services use the same pattern with their corresponding service-name macros and parameters. Service callbacks must use only local IcsObject_get and IcsObject_set operations; IcsObject_apply and IcsObject_refresh are not used inside them.

PROFINET diagnostics. A diagnostic must first be represented by the required repository objects. The SDK provides helper macros for creating diagnostic channels. The application supplies the diagnostic metadata when it invokes the macro:

IcsProfinetDiag MyDiag;
ICS_PROFINET_ADD_DIAG_CHANNEL(
MyDiag,
DataSection,
0,
0x03010300,
0x03010301,
2,
5,
1,
0,
0,
1);

The macro arguments are ordered as follows:

#define ICS_PROFINET_ADD_DIAG_CHANNEL(
id, parent, flags, module, submodule,
channel, error, mReq, mDem, dir, diagTag)

The module and submodule values identify the PROFINET location, while the remaining values describe the diagnostic channel, error, maintenance requirements, direction, and diagnostic category according to the PROFINET configuration. The generated or configured values should be used for a specific device layout.

After creation, the application activates the diagnostic channel through its generated activation object and applies the parent diagnostic object:

bool add = true;
IcsObject_set(MyDiag.diagChannelActivation, ICS_BOOL(add));
IcsObject_apply(MyDiag.diagChannel);

The activation value is written locally first, then IcsObject_apply sends the diagnostic-channel configuration to the target.

5.2 EthernetIp

5.2.1 Code Generation

The Configurator tool is used to generate the source files required for EtherNet/IP integration. The planned workflow is based on an EDS file provided by the user, from which the tool extracts the device information and generates the corresponding configuration and repository.

The final implementation will allow the user to:

  • Import an EDS file.
  • Review and modify the configuration extracted from the EDS.
  • Add additional EtherNet/IP objects, assemblies, attributes, and other repository elements.
  • Configure the channel settings.
  • Generate a JSON configuration file containing all EtherNet/IP-related information.
  • Generate the corresponding C source files from the JSON configuration.

Current Limitations

At the time of this release, the EtherNet/IP GUI-based configuration and code generation workflow is not yet fully implemented.

The following features are not yet available:

  • Importing and parsing EDS files.
  • Generating JSON file.
  • Creating additional objects, assemblies, attributes, and other repository elements through the Configurator GUI.
  • Configuring channel settings through the Configurator GUI.

Channel Settings Configuration

‍Note Unlike the EtherCAT and PROFINET protocols code generation process, where the channel_settings.c file is automatically generated by the Configurator tool, the EtherNet/IP integration does not currently support automatic generation of this file. The user is responsible for creating and populating the channel settings manually.

The channel settings structure is defined in:

source/TICOM/protocol/ethernetip/ethernetip_settings.h

For a reference implementation, users can refer to the example provided in the SDK:

examples/ics-host/am64-main-app/linux-app/ethernetip/gen/channel_settings.c

Example:

#include "ethernetip/ethernetip_settings.h"
IcsEthernetipSettings EthernetipSettings = {
.cip.MaxInstanceNum = 320,
.cip.MaxConnectionSize = 511,
.cip.MaxAsycInstances = 4,
.identity.EnableResetService = 1,
.identity.VendorId = 806,
.identity.DeviceType = 0x002B,
.identity.ProductCode = 0x65FF,
.identity.SerialNumber = 0,
.identity.RevisionMajor = 0x03,
.identity.RevisionMinor = 0x09,
.identity.ProductName = "AM64-EVM Generic Device",
.tsync.EnableSupport = 1,
.tcpip.EnableQuickConnectSupport = 0,
.DLR.EnableSupervisorSupport = 1,
.bridgingAndRouting.EnableSupport = 0, //Bridging and Routing feature is not supported yet.
.assembly.EnableInputOnlyAssembly = 1,
.assembly.EnableListenOnlyAssembly = 1,
.acd.InitialDelay = 200,
.HW.Configurable = 0,
.HW.HwSettingsEnabled = 0,
.HW.DhcpEnabled = 0,
.aCustomServices.NbCustomServices = 2,
.aCustomServices.aCustomServices = {
{ .ClassId = 0x70, .InstanceId = 0x00, .ServiceCode = 0x4B },
{ .ClassId = 0x70, .InstanceId = 0x01, .ServiceCode = 0x4C },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 },
{ .ClassId = 0x0000, .InstanceId = 0x0000, .ServiceCode = 0x0000 }
}
};
const uint8_t* icsChannelSettingsBuffer = (const uint8_t*)&EthernetipSettings;
uint32_t icsChannelSettingsBufferSize = sizeof(EthernetipSettings);

Repository Generation

Repository generation is supported by the Configurator tool.

At the time of this release, the input JSON file must be created and maintained manually by the user. This JSON file describes the EtherNet/IP objects and repository elements that shall be generated.

The Configurator tool uses this JSON file as input and generates the corresponding repository.h and repository.c files. The generated repository structure directly reflects the hierarchy defined in the JSON file.

Repository JSON Format

Root Object

The root object shall always be defined as follows:

{
"ObjectType": "ICS_OT_Section",
"Name": "userObjectsSection",
"VariableSettings": "[0x0000, 0x0000, 0x0000, 0x0000]",
"SizeInBits": 0,
"AccessRight": "0x01000000"
}

All user-defined EtherNet/IP objects shall be added as children of this root object.

Common Object Fields

Each object definition may contain the following fields:

Field Description
ObjectType ICS object type used by the repository generator.
Name Unique object name. The same name shall not be used by multiple objects.
VariableSettings String containing an array of four uint16_t values.
SizeInBits Object size in bits.
AccessRight Encodes the EtherNet/IP object type and associated flags.
VariableType Data type of the object.
Children Child objects belonging to the current object.

VariableSettings Format

The VariableSettings field is a string containing an array of four uint16_t values:

[classId, instanceId, attributeId, reserved]
Index Description
0 Class ID
1 Instance ID
2 Attribute ID
3 Reserved, currently unused

Example:

"VariableSettings": "[0x0070, 0x0001, 0x0300, 0x0000]"

This identifies:

  • Class ID = 0x70
  • Instance ID = 0x01
  • Attribute ID = 0x300

AccessRight Encoding

The AccessRight field is used to define the EtherNet/IP object type and its associated configuration flags.

31 28 27 24 23 16 15 0
+----------------+----------------+----------------------+------------------------------+
| Reserved | Object Type | Flags | Core Reserved |
+----------------+----------------+----------------------+------------------------------+

Bits [15:0]

Reserved for internal use by the ICS core and shall not be modified.

Bits [23:16]

Object-specific flags.

The meaning of these flags depends on the object type being created.

Bits [27:24]

Defines the EtherNet/IP object type.

Bits [31:28]

Currently unused.

Supported Object Types

The following EtherNet/IP object types are supported:

Value Object Type
0x01 Logical Group
0x02 Class
0x03 Instance
0x04 Attribute
0x05 Attribute Member
0x06 Assembly
0x07 Assembly Parameter

Object Type Mapping

The repository generator expects the following JSON ObjectType values:

EtherNet/IP Object Type JSON ObjectType
Class ICS_OT_Group
Instance ICS_OT_Group
Assembly ICS_OT_Group
Attribute ICS_OT_Variable
Assembly Parameter ICS_OT_Variable

Class and Instance Flags

The following flags may be used when creating Class and Instance objects:

Flag Value Description
SERVICE_FLAG_GET_ATTRIBUTE_SINGLE 1 << 0 Enable Get Attribute Single support.
SERVICE_FLAG_SET_ATTRIBUTE_SINGLE 1 << 1 Enable Set Attribute Single support.

Attribute Flags

The following flags may be used when creating Attribute objects:

Flag Value Description
ATTR_FLAG_SET_ACCESS 1 << 0 Attribute supports write access.
ATTR_FLAG_GET_ACCESS 1 << 1 Attribute supports read access.

For attributes that are not mapped to an assembly (acyclic attributes), the attribute object shall:

  • Be a child of its owner object (Class or Instance).
  • Use ICS_OT_Variable as the JSON ObjectType.

Assembly Flags

The following flags may be used when creating Assembly objects:

Flag Value Description
AS_FLAG_SET_ACCESS 1 << 0 Assembly supports write access.
AS_FLAG_GET_ACCESS 1 << 1 Assembly supports read access.
AS_FLAG_CONFIGURATION 1 << 2 Configuration assembly.
AS_FLAG_CUSTOM_MAPPED 1 << 3 Custom assembly mapping.
AS_FLAG_32BIT_RUN_IDLE_HEADER 1 << 4 Enable the 32-bit Run/Idle header option.

‍Note If both AS_FLAG_SET_ACCESS and AS_FLAG_GET_ACCESS are disabled, the assembly configuration is rejected.

‍Note AS_FLAG_CONFIGURATION and AS_FLAG_32BIT_RUN_IDLE_HEADER cannot be enabled simultaneously.

Assembly Parameter Flags

The following flags may be used when creating Assembly Parameter objects:

Flag Value Description
AS_PARAM_FLAG_32BIT_RUN_IDLE_HEADER 1 << 0 Run/Idle header parameter associated with an assembly.

Assembly Structure

An assembly object shall be created using the following hierarchy.

Assembly With Run/Idle Header

If the assembly has the AS_FLAG_32BIT_RUN_IDLE_HEADER flag enabled:

  1. The first child shall be an object of type OBJ_TYPE_ASSEMBLY_PARAMETER.
  2. The assembly parameter object shall:
    • Have type OBJ_TYPE_ASSEMBLY_PARAMETER.
    • Have SizeInBits equal to 32.
    • Have VariableType equal to ICS_VT_UINT32.
    • Have the AS_PARAM_FLAG_32BIT_RUN_IDLE_HEADER flag enabled.
  3. The second child shall be the Assembly Data Attribute (Attribute ID 3).

Example:

Assembly
├── RunIdleHeaderParameter
└── AssemblyDataAttribute

Assembly Without Run/Idle Header

If the assembly does not use the Run/Idle header, the first child shall be the Assembly Data Attribute (Attribute ID 3).

Non-Custom-Mapped Assemblies

For standard assemblies (without AS_FLAG_CUSTOM_MAPPED):

  • The Assembly Data Attribute shall use:
"ObjectType": "ICS_OT_Group"
  • SizeInBits shall be set to zero.
  • All attributes mapped into the assembly shall be added as children of the Assembly Data Attribute object.

Example:

Assembly
└── AssemblyDataAttribute
├── Attribute1
├── Attribute2
└── AttributeN

Custom-Mapped Assemblies

For custom-mapped assemblies (AS_FLAG_CUSTOM_MAPPED enabled):

  • The Assembly Data Attribute shall use:
"ObjectType": "ICS_OT_Variable"
  • SizeInBits shall contain the actual assembly size in bits.
  • Mapped attributes shall not be added as children of the Assembly Data Attribute.
  • Mapped attributes shall instead be added directly under the Assembly object.

Example:

Assembly
├── AssemblyDataAttribute
├── Attribute1
├── Attribute2
└── AttributeN

Example Class Definition

The following example creates Class 0x70 with support for both Get Attribute Single and Set Attribute Single services:

{
"ObjectType": "ICS_OT_Group",
"Name": "Class0x70",
"VariableSettings": "[0x0070, 0x0000, 0x0000, 0x0000]",
"SizeInBits": 0,
"AccessRight": "0x02030000",
"Children": []
}

In this example:

  • Object type = 0x02 (Class)
  • Flags = 0x03
    • SERVICE_FLAG_GET_ATTRIBUTE_SINGLE
    • SERVICE_FLAG_SET_ATTRIBUTE_SINGLE
  • Lower 16 bits are reserved for the ICS core.

5.2.2 EtherNet/IP adapter initialization

EtherNet/IP Initialization

Inside the application-provided IcsRepository_initialize() hook, called during repository construction within Ics_start(), initialize EtherNet/IP built-in objects:

IcsEthernetip_initialize(repository);

This API creates all EtherNet/IP built-in objects required by the ICS EtherNet/IP integration. These objects are automatically added to the repository and provide access to protocol configuration attributes, protocol services, status variables, and event notifications.

After the repository has been initialized, the application is responsible for locating the required built-in objects, assigning their initial values, and registering the necessary callbacks.

‍Note Initialize EtherNet/IP built-in attributes during repository construction, before channel startup completes. A recommended approach is to invoke IcsEthernetip_initialize() and initialize the required built-in attributes from within IcsRepository_initialize(), which is one of the callbacks implemented by the user application.

</blockquote>

Built-In Adapter Configuration Objects

The EtherNet/IP initialization creates a set of built-in configuration attributes representing the configuration of the EtherNet/IP adapter.

The application should locate these attributes using IcsObject_find() and initialize them with the desired configuration values before starting communication.

These attributes may also be modified at runtime by an EtherNet/IP scanner or engineering tool. Therefore, the application should register write callbacks on the relevant objects to detect configuration changes and take any required actions, such as:

  • Updating the running configuration.
  • Storing the new value in non-volatile memory.
  • Scheduling a device restart if required by the application.

!> Note

‍Some EtherNet/IP adapter parameters, such as the Identity Object attributes (e.g. Vendor ID, Product Code, Revision, Serial Number, etc.), are not exposed as ICS repository objects. These parameters are configured through the channel settings mechanism instead. Unlike the built-in configuration attributes described below, these values are intended to be defined during device initialization and cannot be modified at runtime by an EtherNet/IP scanner. For this reason, no corresponding ICS objects are created for them.

TCP/IP Object Attributes (Class 0xF5)

Attribute ID Member ID Size (Bytes) Macro Description
3 - 1 ICS_EIP_BUILTIN_ATTR_TCPIP_CFG_METHOD Configuration Control
5 - 68 ICS_EIP_BUILTIN_ATTR_TCPIP_ITF_CFG Interface Configuration
5 1 4 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_IP_ADDRESS IP Address
5 2 4 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_NETMASK Network Mask
5 3 4 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_IP_GATEWAY Default Gateway
5 4 4 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_NAMESERVER1 Primary DNS Server
5 5 4 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_NAMESERVER2 Secondary DNS Server
5 6 48 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_DOMAIN_NAME Domain Name
6 - 64 ICS_EIP_BUILTIN_ATTR_TCPIP_HOSTNAME Host Name
8 - 1 ICS_EIP_BUILTIN_ATTR_TCPIP_TTL_VALUE TTL Value
9 - 7 ICS_EIP_BUILTIN_ATTR_TCPIP_MCAST_CFG Multicast Configuration
9 1 1 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_MCAST_ALLOC_CTRL Allocation Control
9 2 2 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_MCAST_NUM Number of Multicast Addresses
9 3 4 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_MCAST_START_ADDR Start Multicast Address
10 - 1 ICS_EIP_BUILTIN_ATTR_TCPIP_ACD_ACTIVE ACD Active
11 - 35 ICS_EIP_BUILTIN_ATTR_TCPIP_LAST_CONFLICT_DETECTED Last Conflict Detected
11 1 1 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_ACD_STATE ACD State
11 2 6 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_ACD_ADDR Remote MAC Address
11 3 28 ICS_EIP_BUILTIN_ATTR_MEMBER_TCPIP_ACD_HEADER ARP PDU Header
12 - 1 ICS_EIP_BUILTIN_ATTR_TCPIP_QUICK_CONNECT_ENABLED Quick Connect Enabled
13 - 2 ICS_EIP_BUILTIN_ATTR_TCPIP_ENCAP_INACTIVITY_TIMEOUT Encapsulation Inactivity Timeout

QoS Object Attributes (Class 0x48)

Attribute ID Member ID Size (Bytes) Macro Description
2 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_PTP_EVENT DSCP PTP Event
3 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_PTP_GENERAL DSCP PTP General
4 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_URGENT DSCP Urgent
5 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_SCHEDULED DSCP Scheduled
6 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_HIGH DSCP High
7 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_LOW DSCP Low
8 - 1 ICS_EIP_BUILTIN_ATTR_QOS_DSCP_EXPLICIT DSCP Explicit

Ethernet Link Object Attributes (Class 0xF6)

Instance 1 (Port 1)

Attribute ID Member ID Size (Bytes) Macro Description
6 - 3 ICS_EIP_BUILTIN_ATTR_ETHLINK_PORT1_ITF_CTRL Interface Control
6 1 1 ICS_EIP_BUILTIN_ATTR_MEMBER_ETHLINK_PORT1_AUTONEG Auto Negotiation
6 2 1 ICS_EIP_BUILTIN_ATTR_MEMBER_ETHLINK_PORT1_FULL_DUPLEX Full Duplex
6 3 1 ICS_EIP_BUILTIN_ATTR_MEMBER_ETHLINK_PORT1_100MB 100 Mbps
9 - 1 ICS_EIP_BUILTIN_ATTR_ETHLINK_PORT1_ADMIN_STATE Administrative State

Instance 2 (Port 2)

Attribute ID Member ID Size (Bytes) Macro Description
6 - 3 ICS_EIP_BUILTIN_ATTR_ETHLINK_PORT2_ITF_CTRL Interface Control
6 1 1 ICS_EIP_BUILTIN_ATTR_MEMBER_ETHLINK_PORT2_AUTONEG Auto Negotiation
6 2 1 ICS_EIP_BUILTIN_ATTR_MEMBER_ETHLINK_PORT2_FULL_DUPLEX Full Duplex
6 3 1 ICS_EIP_BUILTIN_ATTR_MEMBER_ETHLINK_PORT2_100MB 100 Mbps
9 - 1 ICS_EIP_BUILTIN_ATTR_ETHLINK_PORT2_ADMIN_STATE Administrative State

LLDP Management Object Attributes (Class 0x109)

Attribute ID Member ID Size (Bytes) Macro Description
1 - 3 ICS_EIP_BUILTIN_ATTR_LLDP_ENABLE LLDP Enable
1 1 2 ICS_EIP_BUILTIN_ATTR_MEMBER_LLDP_ENABLE_ARRAY_LENGTH Enable Array Length
1 2 1 ICS_EIP_BUILTIN_ATTR_MEMBER_LLDP_ENABLE_ARRAY_BITS Enable Array Bits
2 - 2 ICS_EIP_BUILTIN_ATTR_LLDP_MSG_TX_INTERVAL Message Transmit Interval
3 - 1 ICS_EIP_BUILTIN_ATTR_LLDP_MSG_TX_HOLD Message Hold Time

Time Synchronization Object Attributes

Attribute ID Member ID Size (Bytes) Macro Description
1 - 1 ICS_EIP_BUILTIN_ATTR_TIMESYNC_PTP_ENABLE PTP Enable
13 - 1 ICS_EIP_BUILTIN_ATTR_TIMESYNC_PORT_ENABLE Port Enable
14 - 2 ICS_EIP_BUILTIN_ATTR_TIMESYNC_PORT_LOG_ANNOUCE_INTERVAL Log Announce Interval
15 - 2 ICS_EIP_BUILTIN_ATTR_TIMESYNC_PORT_LOG_SYNC_INTERVAL Log Sync Interval
18 - 1 ICS_EIP_BUILTIN_ATTR_TIMESYNC_DOMAIN_NUMBER Domain Number
23 - 128 ICS_EIP_BUILTIN_ATTR_TIMESYNC_USER_DESCRIPTION User Description
24 - 128 ICS_EIP_BUILTIN_ATTR_TIMESYNC_PRODUCT_DESCRIPTION Product Description
25 - 128 ICS_EIP_BUILTIN_ATTR_TIMESYNC_REVISION_DATA Revision Data

DLR Object Attributes

Attribute ID Member ID Size (Bytes) Macro Description
4 - 12 ICS_EIP_BUILTIN_ATTR_DLR_SUPERVISOR_CFG Supervisor Configuration
4 1 1 ICS_EIP_BUILTIN_ATTR_MEMBER_DLR_SUPER_ENABLE Supervisor Enable
4 2 1 ICS_EIP_BUILTIN_ATTR_MEMBER_DLR_SUP_PRECEDENCE Supervisor Precedence
4 3 4 ICS_EIP_BUILTIN_ATTR_MEMBER_DLR_BEACON_INTERVAL Beacon Interval
4 4 4 ICS_EIP_BUILTIN_ATTR_MEMBER_DLR_BEACON_TIMEOUT Beacon Timeout
4 5 2 ICS_EIP_BUILTIN_ATTR_MEMBER_DLR_VLAN_ID VLAN ID

Example

The following example locates and initializes the Host Name attribute:

IcsObject hostNameObj =
IcsObject_find(repository,
ICS_EIP_BUILTIN_ATTR_TCPIP_HOSTNAME);
IcsObject_set(hostNameObj, ICS_DATA("MyDevice"));

The application may optionally register a write callback to be notified when the attribute is modified by an external EtherNet/IP controller:

IcsObject_registerWriteCallback(
hostNameObj,
hostNameChangedCallback,
NULL);

Built-In Services and Special Objects

In addition to the built-in configuration attributes, IcsEthernetip_initialize() creates a number of built-in objects used by the EtherNet/IP integration.

These objects can be divided into three categories:

  • Services, which invoke application-defined execute callbacks when protocol requests are received.
  • Events, which notify the application about protocol-specific events.
  • Special Objects, which provide status information or enable specific interactions with the EtherNet/IP stack.

The following sections describe each object and its intended usage.


Built-In Services

The following service objects are created automatically:

ICS_EIP_SERVICE_IDENTITY_RESET
ICS_EIP_SERVICE_CONNECTION_MANAGER
ICS_EIP_SERVICE_CUSTOM_SERVICES_MNGR

Applications locate these service objects using IcsObject_find() and register execution callbacks using IcsObject_registerExecuteCallback().


Identity Reset Service

The Identity Reset Service is executed when a Reset service request is received by the EtherNet/IP adapter.

Applications may use this service to reboot the device, restore factory defaults, or restore factory defaults while preserving communication-related parameters.

Service Identifier
ICS_EIP_SERVICE_IDENTITY_RESET

Input Parameters
ICS_EIP_SERVICE_IDENTITY_RESET_FLAG
Parameter Description
Reset Flag Requested reset operation.

Reset Flag Values
Value Description
0 Reset the device.
1 Restore factory defaults and reset the device.
2 Restore factory defaults except communication-related parameters and reset the device.

Output Parameters

None.

Registering the Handler
IcsObject resetService =
IcsObject_find(
icsHandle,
NULL,
ICS_EIP_SERVICE_IDENTITY_RESET);
IcsObject_registerExecuteCallback(
resetService,
IcsEthernetip_onReset,
NULL);

Connection Manager Service

The Connection Manager Service is executed whenever a Forward Open, Large Forward Open, or Forward Close request is received from an EtherNet/IP scanner.

The application may use this service to validate connection requests and return the corresponding CIP response.

Service Identifier
ICS_EIP_SERVICE_CONNECTION_MANAGER

Input Parameters
ICS_EIP_SERVICE_CMGR_SERVICE_CODE
ICS_EIP_SERVICE_CMGR_PRIORITY_TIME_TICK
ICS_EIP_SERVICE_CMGR_TIMEOUT_TICKS
ICS_EIP_SERVICE_CMGR_O2T_NETWORK_CONNECTION_ID
ICS_EIP_SERVICE_CMGR_T2O_NETWORK_CONNECTION_ID
ICS_EIP_SERVICE_CMGR_CONNECTION_SERIAL_NUMBER
ICS_EIP_SERVICE_CMGR_ORIGINATOR_VENDOR_ID
ICS_EIP_SERVICE_CMGR_ORIGINATOR_SERIAL_NUMBER
ICS_EIP_SERVICE_CMGR_TIMEOUT_MULTIPLIER
ICS_EIP_SERVICE_CMGR_O2T_PRI
ICS_EIP_SERVICE_CMGR_O2T_CONNECTION_PARAMS
ICS_EIP_SERVICE_CMGR_T2O_PRI
ICS_EIP_SERVICE_CMGR_T2O_CONNECTION_PARAMS
ICS_EIP_SERVICE_CMGR_TYPE_TRIGGER
ICS_EIP_SERVICE_CMGR_IS_LARGE_FW_OPEN
ICS_EIP_SERVICE_CMGR_CONNECTION_PATH_SIZE_IN_WORDS
ICS_EIP_SERVICE_CMGR_CONNECTION_PATH
Parameter Description
Service Code Requested Connection Manager service.
Priority Time Tick Time tick used for timeout calculation.
Timeout Ticks Connection timeout value.
O→T Network Connection ID Originator-to-Target connection identifier.
T→O Network Connection ID Target-to-Originator connection identifier.
Connection Serial Number Connection serial number.
Originator Vendor ID Vendor ID of the scanner.
Originator Serial Number Serial number of the scanner.
Timeout Multiplier Connection timeout multiplier.
O→T RPI Requested Packet Interval for O→T data.
O→T Connection Parameters O→T connection parameters.
T→O RPI Requested Packet Interval for T→O data.
T→O Connection Parameters T→O connection parameters.
Transport Type Trigger Trigger and transport information.
Large Forward Open Flag Indicates whether the request is a Large Forward Open.
Connection Path Size Size of the connection path in 16-bit words.
Connection Path Requested connection path.

Output Parameters
ICS_EIP_SERVICE_CMGR_GENERAL_STATUS
ICS_EIP_SERVICE_CMGR_EXTENDED_STATUS_SIZE
ICS_EIP_SERVICE_CMGR_EXTENDED_STATUS_ARRAY
Parameter Description
General Status CIP General Status returned to the scanner.
Extended Status Size Number of 16-bit extended status words.
Extended Status Array Extended status information.

Supported Service Codes
Service Code
Forward Open 0x54
Large Forward Open 0x5B
Forward Close 0x4E

Registering the Handler
IcsObject cmgrService =
IcsObject_find(
icsHandle,
NULL,
ICS_EIP_SERVICE_CONNECTION_MANAGER);
IcsObject_registerExecuteCallback(
cmgrService,
IcsEthernetip_onConnectionManager,
NULL);

Custom Services Manager

The Custom Services Manager allows applications to implement vendor-specific CIP services.

Whenever a custom service request is received, the EtherNet/IP stack invokes the callback registered on this service object.

Service Identifier
ICS_EIP_SERVICE_CUSTOM_SERVICES_MNGR

Input Parameters
ICS_EIP_SERVICE_CUSTOM_SERVICES_CODE
ICS_EIP_SERVICE_CUSTOM_SERVICES_CLASS_ID
ICS_EIP_SERVICE_CUSTOM_SERVICES_INSTANCE_ID
ICS_EIP_SERVICE_CUSTOM_SERVICES_CONTEXT
ICS_EIP_SERVICE_CUSTOM_SERVICES_INOUT_ACT_DATA
ICS_EIP_SERVICE_CUSTOM_SERVICES_INOUT_DATA
Parameter Description
Service Code Custom CIP service code.
Class ID Target class identifier.
Instance ID Target instance identifier.
Context Request context used for asynchronous responses.
Data Length Number of bytes received from the requester.
Data Buffer Request payload buffer.

Output Parameters
ICS_EIP_SERVICE_CUSTOM_SERVICES_RETURN_CODE
ICS_EIP_SERVICE_CUSTOM_SERVICES_INOUT_ACT_DATA
ICS_EIP_SERVICE_CUSTOM_SERVICES_INOUT_DATA
Parameter Description
Return Code Indicates how the request was handled.
Data Length Number of response bytes.
Data Buffer Response payload buffer.

Return Codes
EI_CIP_SERVICE_eERR_INVALID
EI_CIP_SERVICE_eERR_RESPONSE
EI_CIP_SERVICE_eERR_ERR_RESPONSE
EI_CIP_SERVICE_eERR_ASYNC_RESPONSE
EI_CIP_SERVICE_eERR_NO_RESPONSE
Return Code Description
EI_CIP_SERVICE_eERR_INVALID Unsupported service.
EI_CIP_SERVICE_eERR_RESPONSE Synchronous response.
EI_CIP_SERVICE_eERR_ERR_RESPONSE Error response.
EI_CIP_SERVICE_eERR_ASYNC_RESPONSE Response will be sent later asynchronously.
EI_CIP_SERVICE_eERR_NO_RESPONSE No response generated.

Registering the Handler
IcsObject customService =
IcsObject_find(
icsHandle,
NULL,
ICS_EIP_SERVICE_CUSTOM_SERVICES_MNGR);
IcsObject_registerExecuteCallback(
customService,
IcsEthernetip_onCustomService,
NULL);

Built-In Events

Connection Timeout Event

The Connection Timeout Event is triggered whenever an established EtherNet/IP I/O connection times out.

Applications can use this event to perform cleanup operations, stop application processing related to the affected connection, or generate diagnostics.

Event Identifier
ICS_EVENTS_EIP_EVT_CONNECTION_TIMEOUT

Input Parameters
ICS_EVENTS_EIP_EVT_CONNECTION_TIMEOUT_ORIGINATOR_VENDOR_ID
ICS_EVENTS_EIP_EVT_CONNECTION_TIMEOUT_CONNECTION_SERIAL_NUMBER
ICS_EVENTS_EIP_EVT_CONNECTION_TIMEOUT_ORIGINATOR_SERIAL_NUMBER
Parameter Description
Originator Vendor ID Vendor ID of the originator device.
Connection Serial Number Timed-out connection serial number.
Originator Serial Number Serial number of the originator device.

Output Parameters

None.

Registering the Handler
IcsObject timeoutEvent =
IcsObject_find(
icsHandle,
NULL,
ICS_EVENTS_EIP_EVT_CONNECTION_TIMEOUT);
IcsObject_registerExecuteCallback(
timeoutEvent,
IcsEthernetip_onConnectionTimeout,
NULL);

Special Objects

The following objects are not services and do not require execute callbacks.

They are used either as status indicators or as helper objects to support asynchronous service handling.

ICS_VARS_EIP_NETWORK_STATUS
ICS_VARS_EIP_MODULE_STATUS
ICS_EIP_SERVICE_ASYNC_CUSTOM_SERVICES_RESP_HANDLER

Network Status Variable

The Network Status variable reflects the current EtherNet/IP network state.

Applications may register a write callback to be notified whenever the network status changes.

Object Identifier
ICS_VARS_EIP_NETWORK_STATUS

Registering the Handler
IcsObject networkStatus =
IcsObject_find(
icsHandle,
NULL,
ICS_VARS_EIP_NETWORK_STATUS);
IcsObject_registerWriteCallback(
networkStatus,
IcsEthernetip_onNetworkStatusChanged,
NULL);

Module Status Variable

The Module Status variable reflects the current EtherNet/IP adapter state.

Applications may register a write callback to be notified whenever the module status changes.

Object Identifier
ICS_VARS_EIP_MODULE_STATUS

Registering the Handler
IcsObject moduleStatus =
IcsObject_find(
icsHandle,
NULL,
ICS_VARS_EIP_MODULE_STATUS);
IcsObject_registerWriteCallback(
moduleStatus,
IcsEthernetip_onModuleStatusChanged,
NULL);

Asynchronous Custom Service Response Handler

The Asynchronous Custom Service Response Handler is used to send deferred responses for previously received custom service requests.

It shall only be used when the Custom Services Manager callback returns:

EI_CIP_SERVICE_eERR_ASYNC_RESPONSE

In this case, the application may complete the processing later and send the response asynchronously.

Object Identifier
ICS_EIP_SERVICE_ASYNC_CUSTOM_SERVICES_RESP_HANDLER

Required Parameters

Before triggering the response handler, the application shall populate the following objects:

ICS_EIP_SERVICE_ASYNC_CUSTOM_SERVICES_CONTEXT
ICS_EIP_SERVICE_ASYNC_CUSTOM_SERVICES_PRODUCER_ACT_DATA
ICS_EIP_SERVICE_ASYNC_CUSTOM_SERVICES_PRODUCER_BUFFER_DATA
Parameter Description
Context Context received in the original custom service request.
Producer Data Length Number of bytes in the asynchronous response.
Producer Data Buffer Response payload buffer.

Sending the Response

Once the response parameters have been updated, the application shall apply the response handler object:

IcsObject asyncHandler =
IcsObject_find(
icsHandle,
NULL,
ICS_EIP_SERVICE_ASYNC_CUSTOM_SERVICES_RESP_HANDLER);
IcsObject_apply(asyncHandler);

The EtherNet/IP stack uses the supplied context to correlate the response with the original request.

5.3 EtherCAT

5.3.1 Code Generation

Overview

The EtherCAT code generation process requires an EtherCAT Subdevice description file (ESI) to generate source files used by the ICS host.

The generation process produces two primary outputs:

  • Channel settings contains the device-level EtherCAT Subdevice configurations required by the communication channel.
  • Repository definitions contains the EtherCAT Subdevice object dictionary represented as an ICS repository.

The generated files are overwritten during regeneration. Recommended to keep any user specific application changes outside the generated files.

Inputs

The generator consumes an EtherCAT Subdevice ESI file.

The XML contains:

  • Device information
  • Object Dictionary definitions
  • Data type definitions
  • Array definitions
  • Record definitions
  • Access permissions
  • PDO mappings
  • Backup attributes
  • Enumeration definitions
  • Sync Manager definitions
  • Mailbox configuration
  • EEPROM configuration

‍NOTE: Invalid or missing information in the ESI file affects the EtherCAT SubDevice behavior on the network.

Channel Settings Generation

Overview

The channel settings contain device-level EtherCAT SubDevice information required by the EtherCAT communication channel during the initialization.

Generated Configuration Structure
  • Subdevice identification information
  • Product information
  • Hardware and software versions
  • EEPROM configuration
  • Bootstrap mailbox configuration
  • Standard mailbox configuration
  • Sync Manager configuration
  • Process data capabilities
  • Enumeration definitions
  • PDO assignment descriptions

Subdevice Identification Generation

These parameters are used by EtherCAT Maindevices and engineering tools to identify the EtherCAT Subdevice and determine compatibility.

The generated configuration contains the following identification parameters:

  • Vendor ID
  • Product Code
  • Revision Number
  • Serial Number

These parameters are used by EtherCAT Maindevices and engineering tools to identify the subdevice and determine compatibility.

Source XML Fields

The identification information is extracted from the EtherCAT Subdevice description file using the following XML fields:

Vendor ID ← Vendor/Id
Product Code ← Type/@ProductCode
Revision Number ← Type/@RevisionNo
Serial Number ← Type/@SerialNo
Example
<Vendor>
<Id>#xE000059D</Id>
</Vendor>
<Type
ProductCode="#x54490037"
RevisionNo="#x00010000"
SerialNo="#x00000000">
TICS100MOD
</Type>

Generated configuration:

Vendor ID : 0xE000059D
Product Code : 0x54490037
Revision Number : 0x00010000
Serial Number : 0x00000000

Product Information Generation

The generator extracts descriptive information about the EtherCAT Subdevice and stores it in the generated channel settings.

The generated configuration contains the following product information:

  • Product Name
  • Group Type
  • Hardware Version
  • Software Version

This information is typically displayed by EtherCAT Maindevices and engineering tools and can be used to identify the device family, hardware revision, and firmware version.

Source XML Fields

The product information is extracted from the EtherCAT Subdevice description using the following XML fields:

Product Name ← Device/Name
Group Type ← Device/GroupType
Hardware Version ← Object 0x1009
Software Version ← Object 0x100A
Example
<Device>
<Name>TICS100MOD</Name>
<GroupType>EtherCAT Toolkit</GroupType>
</Device>
<Object>
<Index>#x1009</Index>
<Name>Hardware Version</Name>
<Info>
<DefaultString>R01</DefaultString>
</Info>
</Object>
<Object>
<Index>#x100A</Index>
<Name>Software Version</Name>
<Info>
<DefaultString>2.0.0.4</DefaultString>
</Info>
</Object>

Generated configuration:

Product Name : TICS100MOD
Group Type : EtherCAT Toolkit
Hardware Version : R01
Software Version : 2.0.0.4

EEPROM Configuration Generation

The generator extracts EtherCAT EEPROM configuration parameters from the device description file and stores them in the generated channel settings.

The generated configuration contains the following EEPROM-related information:

  • PDI Control
  • PDI Configuration
  • Sync Pulse Length

These parameters define low-level EtherCAT Subdevice behavior and are used during communication channel initialization.

Source XML Fields

The EEPROM configuration is extracted from the EtherCAT Subdevice description using the following XML fields:

PDI Control ← Eeprom/ConfigData[0..1]
PDI Configuration ← Eeprom/ConfigData[2..3]
Sync Pulse Length ← Eeprom/ConfigData[4..5]

The generator extracts these values directly from the EtherCAT EEPROM ConfigData field.

Example
<Eeprom>
<ConfigData>
803EE088E8030000000000000000
</ConfigData>
</Eeprom>

Generated configuration:

PDI Control : 0x3E80
PDI Configuration : 0x88E0
Sync Pulse Length : 0x03E8

Bootstrap Mailbox Generation

The generator extracts the EtherCAT Subdevice Bootstrap Mailbox configuration from the device description file and stores it in the generated channel settings.

The generated configuration contains the following Bootstrap Mailbox information:

  • Bootstrap Mailbox RX Offset
  • Bootstrap Mailbox RX Size
  • Bootstrap Mailbox TX Offset
  • Bootstrap Mailbox TX Size

These parameters define the mailbox memory layout used while the EtherCAT Subdevice operates in Bootstrap mode.

Source XML Fields

The Bootstrap Mailbox configuration is extracted from the EtherCAT Subdevice description file using the following XML field:

Bootstrap Mailbox RX Offset ← Eeprom/BootStrap[0..1]
Bootstrap Mailbox RX Size ← Eeprom/BootStrap[2..3]
Bootstrap Mailbox TX Offset ← Eeprom/BootStrap[4..5]
Bootstrap Mailbox TX Size ← Eeprom/BootStrap[6..7]

The generator extracts these values directly from the EtherCAT EEPROM BootStrap field.

Example
<Eeprom>
<BootStrap>
0010000100120001
</BootStrap>
</Eeprom>

Generated configuration:

Bootstrap Mailbox RX Offset : 0x1000
Bootstrap Mailbox RX Size : 0x0100
Bootstrap Mailbox TX Offset : 0x1200
Bootstrap Mailbox TX Size : 0x0100

Standard Mailbox Generation

The generator extracts the standard EtherCAT mailbox configuration from the device description file and stores it in the generated channel settings.

The generated configuration contains the following Standard Mailbox information:

  • Standard Mailbox RX Offset
  • Standard Mailbox RX Size
  • Standard Mailbox TX Offset
  • Standard Mailbox TX Size

These parameters define the mailbox memory layout used for EtherCAT Subdevice mailbox protocols such as AoE, CoE, FoE, EoE and VoE.

Source XML Fields

The Standard Mailbox configuration is extracted from the Sync Manager definitions using the following XML fields:

Standard Mailbox RX Offset ← Sm(MBoxOut)/@StartAddress
Standard Mailbox RX Size ← Sm(MBoxOut)/@DefaultSize
Standard Mailbox TX Offset ← Sm(MBoxIn)/@StartAddress
Standard Mailbox TX Size ← Sm(MBoxIn)/@DefaultSize
Example
<Sm StartAddress="#x1000"
DefaultSize="1024">
MBoxOut
</Sm>
<Sm StartAddress="#x1400"
DefaultSize="1024">
MBoxIn
</Sm>

Generated configuration:

Standard Mailbox RX Offset : 0x1000
Standard Mailbox RX Size : 1024
Standard Mailbox TX Offset : 0x1400
Standard Mailbox TX Size : 1024

Sync Manager Generation

The generator extracts the EtherCAT Subdevice Sync Manager configuration from the device description file and stores it in the generated channel settings.

The generated configuration contains one entry for each Sync Manager and includes the following information:

  • Sync Manager Index
  • Start Offset
  • Size
  • Control Byte
  • Enable State

The generated Sync Manager table is used by the EtherCAT Subdevice communication stack to configure mailbox and process data communication areas.

Source XML Fields

The Sync Manager configuration is extracted from the Sync Manager definitions using the following XML fields:

Start Offset ← Sm/@StartAddress
Size ← Sm/@DefaultSize
Control Byte ← Sm/@ControlByte
Enable State ← Sm/@Enable

The Sync Manager Index is assigned by the generator when building the Sync Manager table.

Example
<Sm StartAddress="#x1000"
DefaultSize="1024"
ControlByte="#x26"
Enable="1">
MBoxOut
</Sm>
<Sm StartAddress="#x1400"
DefaultSize="1024"
ControlByte="#x22"
Enable="1">
MBoxIn
</Sm>

Generated configuration:

SM0
├── Offset : 0x1000
├── Size : 1024
├── Control : 0x26
└── Enabled : Yes
SM1
├── Offset : 0x1400
├── Size : 1024
├── Control : 0x22
└── Enabled : Yes

The generator creates one Sync Manager configuration entry for each <Sm> definition present in the EtherCAT Subdevice description file.

Process Data Capability Generation

The generator extracts the maximum process data sizes supported by the EtherCAT Subdevice and stores them in the generated channel settings.

The generated configuration contains:

  • Maximum Output Process Data Size
  • Maximum Input Process Data Size

These values define the maximum size of the process data exchanged through EtherCAT Subdevice PDO communication.

Source XML Fields

The process data capabilities are extracted from the Sync Manager definitions using the following XML fields:

Maximum Output Process Data Size ← Sm(Outputs)/@MaxSize
Maximum Input Process Data Size ← Sm(Inputs)/@MaxSize
Example
<Sm StartAddress="#x1600"
DefaultSize="256"
MaxSize="256">
Outputs
</Sm>
<Sm StartAddress="#x1A00"
DefaultSize="512"
MaxSize="512">
Inputs
</Sm>

Generated configuration:

Maximum Output Process Data Size : 256 bytes
Maximum Input Process Data Size : 512 bytes

Enumeration Generation

The generator extracts enumeration definitions associated with generated repository objects and stores them in the generated channel settings.

The generated configuration contains:

  • Enumeration Name
  • Enumeration Values
  • Enumeration Display Strings

These enumerations allow runtime conversion between numeric values and symbolic names.

In addition to the runtime enumeration information, the generator also produces C enumeration definitions in the generated repository.h file, allowing the application to use symbolic enumeration values directly from source code.

Source XML Fields

Enumeration information is extracted from referenced datatype definitions using the following XML fields:

Enumeration Name ← DataType/@Name
Enumeration Display Text ← EnumInfo/Text
Enumeration Value ← EnumInfo/Enum
Example
<DataType Name="DT0800EN16">
<EnumInfo>
<Text>Reset</Text>
<Enum>100</Enum>
</EnumInfo>
<EnumInfo>
<Text>Session</Text>
<Enum>101</Enum>
</EnumInfo>
</DataType>

Generated channel settings:

DT0800EN16
├── 100 → Reset
└── 101 → Session

Generated repository header:

typedef enum DT0800EN16_e {
DT0800EN16_Reset = 100,
DT0800EN16_Session = 101,
} DT0800EN16;

Current Limitations

The generated channel settings currently support the following limits.

String Length Limits

The following generated fields are limited to 64 characters:

  • Product Name
  • Group Type
  • Hardware Version
  • Software Version
Sync Manager Limits

A maximum of 8 Sync Managers can be stored in the generated channel settings.

Only the first 8 Sync Manager definitions can be represented in the generated configuration.

Enumeration Limits

The generated channel settings support:

  • Up to 16 enumerations
  • Up to 16 values per enumeration
  • Enumeration names up to 32 characters

Only enumerations associated with generated repository objects are exported to the generated channel settings.

Summary

The channel settings generator transforms the EtherCAT Subdevice description into a runtime communication channel configuration.


Repository Generation


Overview

The repository generation process converts an EtherCAT Subdevice description XML file into a C source file (repository.c) containing the complete ICS repository definition used by the host application.

The generated repository exposes the EtherCAT Subdevice Object Dictionary as a hierarchy of ICS objects that can be accessed through the ICS API.

The generated file must never be modified manually because it will be overwritten during the next generation cycle.


Generated Repository Structure

The generated repository follows the hierarchy:

Repository
└── Object Dictionary
├── Variable
├── Group (Record)
│ ├── Variable
│ ├── Variable
│ └── Variable
├── Array
│ ├── Element
│ ├── Element
│ └── Element
├── TxPDO
│ └── References
└── RxPDO
└── References

The root Object Dictionary section is always created first.

ICS_ADD_OBJECT(
Object_Dictionary,
repository,
ICS_OT_Section,
...
);

Object Generation Rules
Simple Variable Objects

XML object definitions without subindices become repository variables.

XML

<Object>
<Index>#x2001</Index>
<Name>Test Variable</Name>
<Type>UDINT</Type>
</Object>

Generated

ICS_ADD_OBJECT(
Test_Variable,
Object_Dictionary,
ICS_OT_Variable,
32,
ICS_VT_UINT32,
...
);

The generator extracts:

  • Name → Object Name
  • Type → ICS Variable Type
  • BitSize → Variable Size
  • Access → Access Flags

Record Objects

Datatypes containing SubItem entries are generated as groups.

XML

<DataType Name="DT2000">
<SubItem>
<SubItem>
<SubItem>
</DataType>

Generated

ICS_ADD_OBJECT(
Out_Object_Record,
Object_Dictionary,
ICS_OT_Group,
...
);

and child variables:

ICS_ADD_OBJECT(
Out_Object_Record_i2c_leds,
Out_Object_Record,
ICS_OT_Variable,
...
);

Each XML subindex becomes a child repository object.


Array Objects

Array types are converted into a parent group plus individual elements.

XML

<DataType Name="DT2003ARR">
<ArrayInfo>
<Elements>5</Elements>
</ArrayInfo>
</DataType>

Generated

Backup_Parameter_Array
├── Backup_Parameter_Array_1
├── Backup_Parameter_Array_2
├── Backup_Parameter_Array_3
├── Backup_Parameter_Array_4
└── Backup_Parameter_Array_5

Each generated array element becomes an individual repository object.


Enumeration Objects

Enumeration definitions associated with generated repository objects are extracted from the referenced datatype definitions.

Only enumerations referenced by generated repository objects are included in the generated outputs.

The generated enumerations are:

  • Exported to the generated channel settings.
  • Generated as C enumeration definitions in repository.h.

XML

<DataType Name="DeviceMode">
<EnumInfo>
<Text>Idle</Text>
<Enum>0</Enum>
</EnumInfo>
<EnumInfo>
<Text>Run</Text>
<Enum>1</Enum>
</EnumInfo>
</DataType>

Generated

typedef enum DeviceMode_e
{
DeviceMode_Idle = 0,
DeviceMode_Run = 1
}
DeviceMode;

This allows applications to use symbolic enumeration values while preserving runtime enumeration information.


Datatype Mapping

The generator converts EtherCAT data types into ICS variable types.

EtherCAT Type ICS Type
BOOL ICS_VT_BOOLEAN
USINT ICS_VT_UINT8
UINT ICS_VT_UINT16
UDINT ICS_VT_UINT32
ULINT ICS_VT_UINT64
Record ICS_VT_STRUCT
Array Base Type + ARRAY Flag

Access Rights Mapping

Access Rights Mapping

EtherCAT object access rights and communication attributes are converted into a combination of standard ICS access flags and EtherCAT-specific flags.

Standard Access Permissions
EtherCAT Access ICS Flags
ro ICS_FLAGS_READ
wo ICS_FLAGS_WRITE
rw ICS_FLAGS_READ_WRITE

PDO Mapping Flags

Objects that participate in PDO communication receive additional mapping flags.

#define ICS_ETHERCAT_RXPDO_MAPPING (1 << 16)
#define ICS_ETHERCAT_TXPDO_MAPPING (1 << 17)
EtherCAT Attribute ICS Flag
RxPDO Mapping ICS_ETHERCAT_RXPDO_MAPPING
TxPDO Mapping ICS_ETHERCAT_TXPDO_MAPPING

Example:

XML

<Object>
<Index>#x2000</Index>
<Flags>
<RxPdoMapping>1</RxPdoMapping>
</Flags>
</Object>

Generated Flags

ICS_FLAGS_READ_WRITE |
ICS_ETHERCAT_RXPDO_MAPPING

State-Based Read Restrictions

EtherCAT objects may restrict read access depending on the current EtherCAT state.

#define ICS_ETHERCAT_READ_RESTRICTION_PRE_OP (1 << 18)
#define ICS_ETHERCAT_READ_RESTRICTION_SAFE_OP (1 << 19)
#define ICS_ETHERCAT_READ_RESTRICTION_OP (1 << 20)
EtherCAT Restriction ICS Flag
Read in PRE-OP only ICS_ETHERCAT_READ_RESTRICTION_PRE_OP
Read in SAFE-OP only ICS_ETHERCAT_READ_RESTRICTION_SAFE_OP
Read in OP only ICS_ETHERCAT_READ_RESTRICTION_OP

Example:

XML

<Flags>
<Access>ro</Access>
<ReadRestriction>OP</ReadRestriction>
</Flags>

Generated Flags

ICS_FLAGS_READ |
ICS_ETHERCAT_READ_RESTRICTION_OP

State-Based Write Restrictions

EtherCAT objects may restrict write access depending on the EtherCAT state.

#define ICS_ETHERCAT_WRITE_RESTRICTION_PRE_OP (1 << 21)
#define ICS_ETHERCAT_WRITE_RESTRICTION_SAFE_OP (1 << 22)
#define ICS_ETHERCAT_WRITE_RESTRICTION_OP (1 << 23)
EtherCAT Restriction ICS Flag
Write in PRE-OP only ICS_ETHERCAT_WRITE_RESTRICTION_PRE_OP
Write in SAFE-OP only ICS_ETHERCAT_WRITE_RESTRICTION_SAFE_OP
Write in OP only ICS_ETHERCAT_WRITE_RESTRICTION_OP

Example:

XML

<Flags>
<Access>rw</Access>
<WriteRestriction>PREOP</WriteRestriction>
</Flags>

Generated Flags

ICS_FLAGS_READ_WRITE |
ICS_ETHERCAT_WRITE_RESTRICTION_PRE_OP

Persistent Parameters (Backup Parameter Support)

Certain Object Dictionary entries may be marked as persistent in the EtherCAT Subdevice XML description using the Backup attribute.

Example:

XML

<Flags>
<Access>rw</Access>
<Backup>1</Backup>
</Flags>

During code generation, the Backup attribute is converted into the ICS_FLAGS_PERSISTENT flag and encoded in the generated object flags. The generated repository object is therefore automatically identified as persistent by the ICS runtime.

Generated

ICS_ADD_OBJECT(
Backup_Parameter_Variable,
Object_Dictionary,
ICS_OT_Variable,
32,
ICS_VT_UINT32,
0x00000013,
...
);

The flag value 0x13 is decoded as:

0x01 ICS_FLAGS_READ
0x02 ICS_FLAGS_WRITE
0x10 ICS_FLAGS_PERSISTENT
-------------------------
0x13

The persistence information is stored in the generated object flags (accessFlags).

Persistence is supported for:

  • Variables
  • Arrays
  • Records

PDO Generation

PDO definitions are generated as reference groups.

XML

<TxPdo>
<Entry>
<Index>#x2002</Index>
<SubIndex>2</SubIndex>
</Entry>
</TxPdo>

Generated

ICS_ADD_OBJECT(
TxPDO,
Object_Dictionary,
ICS_OT_Group,
...
);

References are then added:

ICS_ADD_REFERENCE(
TxPDO,
Test_Record_SubIndex_2,
...
);

The generator resolves each PDO entry to its corresponding repository object and creates an object reference.


Repository Metadata

Every generated repository object contains metadata linking it to the originating EtherCAT Subdevice Object Dictionary entry.

Metadata may include:

  • Index
  • SubIndex
  • Name
  • Size
  • Variable Type
  • Access Rights

Example:

IcsObject_serializeParameters(
buffer,
sizeof(buffer),
&size,
0x2000,
0,
"Out Object Record"
);

This metadata allows runtime mapping between ICS repository objects and EtherCAT Subdevice Object Dictionary entries.


Example Mapping

XML

<Object>
<Index>#xFB00</Index>
<Name>Command</Name>
<Type>DTFB00</Type>
</Object>

The corresponding datatype contains:

Request
Status
Response

Generated

Command
├── Command_Request
├── Command_Status
└── Command_Response

Each subitem becomes a repository variable under the generated group.


Runtime Initialization

The generated file contains:

IcsStatus IcsCommChannel_buildRepository(
IcsCommChannel channel,
IcsRepository repository
)

Responsibilities:

  1. Create repository objects.
  2. Build the object hierarchy.
  3. Create PDO structures.
  4. Attach EtherCAT metadata.
  5. Initialize the repository.

Final step:

result = IcsRepository_initialize(repository);

The behavior of IcsRepository_initialize() is protocol-specific. During this phase, protocol-specific initialization is performed. This may include initialization of the generated EtherCAT objects, creation of built-in protocol objects, and addition of application-specific repository objects that are not part of the generated repository.

Once initialization completes, the repository becomes available through the ICS API.


Supported Features

The repository generator currently supports the following EtherCAT Object Dictionary constructs.

Supported Object Types

The following Object Dictionary object types are supported:

  • Variables
  • Records
  • Arrays

Variables are generated as individual repository variables.

Records are generated as repository groups containing one child object per subindex.

Arrays are generated as repository groups containing one child object per array element.

Supported Data Types

The following EtherCAT data types are converted into ICS variable types:

EtherCAT Type ICS Type
BOOL ICS_VT_BOOLEAN
USINT ICS_VT_UINT8
UINT ICS_VT_UINT16
UDINT ICS_VT_UINT32
ULINT ICS_VT_UINT64

Supported Enumeration Definitions

Enumeration definitions associated with generated repository objects are supported.

Generated enumerations are:

  • Exported to the generated channel settings.
  • Generated as C enumeration definitions in repository.h.

Only enumerations referenced by generated repository objects are included in the generated output.

Supported Access Attributes

The generator supports:

  • Read access (ro)
  • Write access (wo)
  • Read/Write access (rw)
  • RxPDO Mapping
  • TxPDO Mapping
  • Read Restrictions
    • PRE-OP
    • SAFE-OP
    • OP
  • Write Restrictions
    • PRE-OP
    • SAFE-OP
    • OP
  • Backup (Persistent) attributes

Supported PDO Definitions

The generator supports:

  • TxPDO definitions
  • RxPDO definitions
  • PDO entry to repository object resolution
  • PDO reference generation

Current Limitations

The repository generator currently applies the following rules and restrictions.

Repository Object Naming

Generated repository object names must be unique across the entire repository.

This restriction applies to:

  • Variables
  • Record members
  • Array elements
  • PDO objects

Name collisions may prevent repository generation or result in ambiguous object lookups.

Repository object names are limited to 64 characters.


Summary

The repository generator transforms an EtherCAT XML description into an ICS repository by:

  1. Parsing supported Object Dictionary entries.
  2. Parsing referenced DataType definitions.
  3. Generating variables for simple objects.
  4. Generating groups for record objects.
  5. Generating element collections for arrays.
  6. Translating EtherCAT access rights into ICS flags.
  7. Translating EtherCAT data types into ICS variable types.
  8. Generating enumeration definitions.
  9. Creating TxPDO and RxPDO groups.
  10. Creating references between PDO entries and repository objects.
  11. Serializing EtherCAT metadata into generated objects.
  12. Producing a fully initialized repository.c source file.

5.3.2 Specific Features

EtherCAT API Usage Guide

Introduction

The objective of this chapter is to help application developers understand how to access EtherCAT services, interact with Object Dictionary entries, register callbacks, and exchange data using the ICS API.


CoE (CANopen over EtherCAT)

The Object Dictionary is accessed using standard repository APIs.

Example:

IcsObject variable =
Ics_findObject(
icsHandle,
NULL,
"Write_Variable");

Write data:

uint32_t value = 100;
IcsObject_set(
variable,
ICS_UINT32(value));
IcsObject_apply(variable);

Read data:

IcsObject_refresh(variable);
IcsObject_get(variable, ICS_UINT32(value));

CoE over AoE

The EtherCAT configuration enables AoE and ADS Router support.

No additional API is required by the application. Object Dictionary access through the ICS repository can be made available through CoE over AoE services provided by the EtherCAT stack.


PDO Communication

Updating a TxPDO

Update PDO variables:

IcsObject_set(
Test_Record_SubIndex_2,
ICS_UINT8(value1));
IcsObject_set(
Test_Record_SubIndex_3,
ICS_UINT8(value2));
IcsObject_set(
Test_Record_SubIndex_4,
ICS_UINT16(value3));

Transmit PDO:

IcsObject_apply(TxPDO);

Reading PDO Data
IcsObject_refresh(TxPDO);
IcsObject_get(
Test_Record_SubIndex_2,
ICS_UINT8(value));

FoE (File over EtherCAT)

The framework exposes File access over EtherCAT (FoE) operations through a set of built-in services.

These services allow an EtherCAT Maindevice to access application-managed files. The EtherCAT Subdevice stack handles the FoE protocol, while the application implements the file operations by registering callbacks for the corresponding service objects.

The following services are available:

#define ICS_EC_FOE_SV_FILE_OPEN
#define ICS_EC_FOE_SV_FILE_READ
#define ICS_EC_FOE_SV_FILE_WRITE
#define ICS_EC_FOE_SV_FILE_CLOSE

Applications locate these service objects using Ics_findObject() and register execution callbacks using IcsObject_registerExecuteCallback().


File Open Service

Opens a file requested by the EtherCAT Maindevice.

Service Identifier
ICS_EC_FOE_SV_FILE_OPEN
Input Parameters
ICS_EC_FOE_SV_FILE_OPEN_NAME
ICS_EC_FOE_SV_FILE_OPEN_PASSWORD
ICS_EC_FOE_SV_FILE_OPEN_ACCESS
Parameter Description
File Name Name of the file requested by the Maindevice
Password FoE password supplied by the Maindevice
Access Mode Requested file access mode
Output Parameters
ICS_EC_FOE_SV_FILE_OPEN_RESULT
Parameter Description
Result Operation result returned to the EtherCAT Maindevice
Registering the Handler
IcsObject openFileService =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_FOE_SV_FILE_OPEN);
IcsObject_registerExecuteCallback(
openFileService,
IcsEthercat_onOpenFile,
NULL);

File Read Service

Reads data from a previously opened file.

Service Identifier
ICS_EC_FOE_SV_FILE_READ
Input Parameters
ICS_EC_FOE_SV_FILE_READ_OFFSET
ICS_EC_FOE_SV_FILE_READ_LENGTH
Parameter Description
Offset File offset from which to begin reading
Length Number of bytes requested
Output Parameters
ICS_EC_FOE_SV_FILE_READ_DATA
ICS_EC_FOE_SV_FILE_READ_READ
Parameter Description
Data Buffer containing file data
Read Number of bytes returned
Registering the Handler
IcsObject readFileService =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_FOE_SV_FILE_READ);
IcsObject_registerExecuteCallback(
readFileService,
IcsEthercat_onReadFile,
NULL);

File Write Service

Writes data to a previously opened file.

Service Identifier
ICS_EC_FOE_SV_FILE_WRITE
Input Parameters
ICS_EC_FOE_SV_FILE_WRITE_DATA
ICS_EC_FOE_SV_FILE_WRITE_LENGTH
Parameter Description
Data Data provided by the EtherCAT Maindevice
Length Number of bytes received
Output Parameters
ICS_EC_FOE_SV_FILE_WRITE_RESULT
Parameter Description
Result Operation result
Registering the Handler
IcsObject writeFileService =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_FOE_SV_FILE_WRITE);
IcsObject_registerExecuteCallback(
writeFileService,
IcsEthercat_onWriteFile,
NULL);

File Close Service

Closes the currently opened file and releases any associated resources.

Service Identifier
ICS_EC_FOE_SV_FILE_CLOSE
Input Parameters

None.

Output Parameters
ICS_EC_FOE_SV_FILE_CLOSE_RESULT
Parameter Description
Result Operation result
Registering the Handler
IcsObject closeFileService =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_FOE_SV_FILE_CLOSE);

EoE (Ethernet over EtherCAT)

Ethernet over EtherCAT (EoE) allows Ethernet configuration and Ethernet frames to be exchanged through the EtherCAT network.

The framework provides built-in repository objects for:

  • Ethernet configuration settings
  • Receiving Ethernet frames
  • Sending Ethernet frames

Receiving EoE Settings

The EtherCAT Maindevice can configure network parameters through the built-in EoE Settings object.

Repository Object
ICS_EC_EOE_GP_SETTINGS

When the EtherCAT Maindevice updates the configuration, the framework updates this object and triggers the registered write callback.

Registering the Callback
IcsObject eoeSettings =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_EOE_GP_SETTINGS);
IcsObject_registerWriteCallback(
eoeSettings,
IcsEthercat_eoESettingsReceived,
NULL);
Available Parameters

The EoE Settings object contains the following child objects:

ICS_EC_EOE_VR_SETTINGS_MAC_ADDRESS
ICS_EC_EOE_VR_SETTINGS_IP_ADDRESS
ICS_EC_EOE_VR_SETTINGS_SUBNET_MASK
ICS_EC_EOE_VR_SETTINGS_GATEWAY_ADDRESS
ICS_EC_EOE_VR_SETTINGS_DNS_IP

These parameters provide:

  • MAC Address
  • IP Address
  • Subnet Mask
  • Gateway Address
  • DNS Address
Accessing Parameter Values

Inside the callback, the application locates the required child objects and retrieves their values.

Example:

IcsObject macAddress =
IcsObject_find(
eoeSettings,
ICS_EC_EOE_VR_SETTINGS_MAC_ADDRESS);

The callback is responsible for applying the received network configuration to the application network stack or operating system.


Receiving Ethernet Frames

Received Ethernet frames are provided through a built-in repository object.

Repository Object
ICS_EC_EOE_GP_FRAME_RECEIVE

When an Ethernet frame is received from the EtherCAT Maindevice, the framework updates this object and triggers the registered write callback.

Registering the Callback
IcsObject eoeReceiveFrame =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_EOE_GP_FRAME_RECEIVE);
IcsObject_registerWriteCallback(
eoeReceiveFrame,
IcsEthercat_eoEFrameReceived,
context);
Available Parameters
ICS_EC_EOE_VR_FRAME_RECEIVE_DATA
ICS_EC_EOE_VR_FRAME_RECEIVE_SIZE
Parameter Description
DATA Ethernet frame payload
SIZE Ethernet frame length in bytes

The application retrieves the frame data and forwards it to the local network stack.


Sending Ethernet Frames

Ethernet frames can be transmitted through the built-in EoE transmit object.

Repository Object
ICS_EC_EOE_GP_FRAME_SEND
Available Parameters
ICS_EC_EOE_VR_FRAME_SEND_DATA
ICS_EC_EOE_VR_FRAME_SEND_SIZE
Parameter Description
DATA Ethernet frame payload
SIZE Ethernet frame length in bytes
Sending a Frame

Locate the EoE transmit object:

IcsObject sendEoEframe =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_EOE_GP_FRAME_SEND);

Populate the frame payload and length:

IcsObject sendDataPtr =
IcsObject_find(
sendEoEframe,
ICS_EC_EOE_VR_FRAME_SEND_DATA);
IcsObject sendDataSize =
IcsObject_find(
sendEoEframe,
ICS_EC_EOE_VR_FRAME_SEND_SIZE);
IcsObject_set(sendDataPtr, &frameData);
IcsObject_set(sendDataSize, ICS_UINT32(length));

Transmit the frame:

IcsObject_apply(sendEoEframe);

The EtherCAT stack then encapsulates the Ethernet frame and transmits it to the EtherCAT Maindevice.


EEPROM

EEPROM Device Information Erase

The framework provides a built-in repository object to erase device information stored in the EEPROM.

Repository Object
ICS_EC_VR_EEPROM_ERASE
Available Values
typedef enum EepromSection
{
Eeprom_None = 0,
Eeprom_DeviceInfo
} EepromSection_t;
Example Usage

The host example adds the EEPROM erase object separately from IcsEthercat_createServices. After that application setup, erase the device information by setting the object to Eeprom_DeviceInfo:

IcsObject eepromErase =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_VR_EEPROM_ERASE);
uint8_t eepromSection = Eeprom_DeviceInfo;
IcsObject_set(eepromErase, ICS_UINT8(eepromSection));
IcsObject_apply(eepromErase);

Emergency Messages

The host example implements the following helper for generating emergency messages:

Emergency_sendMessage(
icsHandle,
code,
length,
data);

where:

  • code identifies the emergency condition.
  • length specifies the size of the emergency data.
  • data points to the emergency payload.

Example:

uint32_t emergencyData = 0x12345678;
Emergency_sendMessage(
icsHandle,
15,
sizeof(emergencyData),
(uint8_t*)&emergencyData);

The EtherCAT Maindevice receives the supplied emergency code together with the associated emergency data.


Diagnostic Messages

Diagnostic messages can be used to report application-specific diagnostic information to the EtherCAT Maindevice.

A diagnostic message consists of:

  • A diagnostic code.
  • A diagnostic type.
  • A text identifier.
  • Zero or more diagnostic parameters.

Diagnostic parameters are added to the message before it is transmitted.

Adding Diagnostic Parameters

The host example helper appends diagnostic parameters using:

Diagnostics_addParamToMessage(...);

Multiple parameters may be added before transmitting the message.

Sending a Diagnostic Message

After adding parameters, the host example transmits the message using its helper:

Diagnostics_sendMessage(
icsHandle,
diagCode,
type,
textId,
parameterCount,
parameterData,
parameterLength);

where:

  • diagCode identifies the diagnostic condition.
  • type specifies the diagnostic message type.
  • textId identifies the associated diagnostic text.
  • parameterCount specifies the number of diagnostic parameters included in the message.
  • parameterData points to the parameter data buffer.
  • parameterLength specifies the size of the parameter data buffer.

Typical Workflow
Create diagnostic parameters
│
▼
Add parameters to message
│
▼
Send diagnostic message

The EtherCAT Maindevice receives the diagnostic information together with any associated diagnostic parameters.


Persistent Parameters (Backup Support)

Persistent parameters can be restored by the EtherCAT Maindevice using the standard EtherCAT Backup Parameter Restore object (0x1011).

When a restore operation is performed, the associated repository objects are updated with their restored values.

Applications that need to react to a restored value can register a write callback:

IcsObject_registerWriteCallback(
Backup_Parameter_Variable,
OnWrite_backupVariable,
NULL);

The callback is executed after the restored value has been written to the repository, allowing the application to perform any additional processing required by the parameter change.

The persistence behavior itself is configured through the EtherCAT XML description and generated repository flags and does not require special handling by the application.


Command Interface

The command interface provides a standardized mechanism for exchanging commands and responses between the EtherCAT Maindevice and the application.

The interface is implemented using Object Dictionary entry 0xFB00, which is generated as a repository group containing the following objects:

Command
├── Request
├── Status
└── Response

The EtherCAT Maindevice writes Request. The host application handles that write through its registered callback, then updates and applies Status and Response for the master to read. The Command objects come from the ESI-generated repository.

Processing a Controller Command

The master writes the Request object through CoE. In the host application, register a write callback on Command_Request. The callback reads the received request and schedules application processing. After processing, application task code sets and applies Command_Status and Command_Response. Follow the callback restrictions in Chapter 4 when exchanging data with the target.

See the host example's command handler in freertos-app/ethercat/ics_protocol_ethercat.c or linux-app/ethercat/ics_protocol_ethercat.c for the complete request, status, and response sequence.


Application Synchronization

An EtherCAT host application can run its cyclic processing in step with the EtherCAT network. To do this, the TICS100MOD provides two output pins that tell the host when to exchange process data:

Pin Synchronization Mode Signaled Event
SYNC0 DC-Synchron The synchronization time configured by the EtherCAT Maindevice is reached
IRQ2 SM-Synchron New output data has been received from the EtherCAT Maindevice

The TICS100MOD drives both pins automatically according to the synchronization mode selected by the EtherCAT Maindevice. The ICS API needs no call to configure or enable them.

The host application connects these pins to GPIO inputs with interrupts enabled. Which pin it uses depends on the synchronization mode selected by the EtherCAT Maindevice.

Synchronization Modes

The EtherCAT Maindevice selects the synchronization mode during network configuration.

Mode AssignActivate Synchronization Signal
Free Run - None. The application runs on its own local timer.
SM-Synchron 0x0 IRQ2
DC-Synchron 0x300 SYNC0

DC-Synchron Mode (SYNC0)

In DC-Synchron mode, the TICS100MOD drives the SYNC0 pin based on the Distributed Clocks system time shared by all devices on the network. The EtherCAT Maindevice configures the SYNC0 cycle time and shift time.

All DC-synchronized devices on the network receive their SYNC0 event at the same global time. The host application should therefore use SYNC0 when outputs must be applied, or inputs sampled, at the same moment across several devices.

SM-Synchron Mode (IRQ2)

In SM-Synchron mode, the application is synchronized to the arrival of process data rather than to a global time base. The TICS100MOD drives the IRQ2 pin each time the EtherCAT Maindevice writes new output data to the device.

The timing of this event follows the EtherCAT Maindevice's frame cycle. It therefore includes the master's cycle jitter.


Usage

The ICS startup sequence, repository creation process, and callback registration mechanisms are described in Chapter 4.

The EtherCAT features described in this chapter rely on a set of built-in repository objects and services. These objects are not created automatically and must be added to the repository before they can be used.

After the repository has been created and initialized, the application must call:

IcsEthercat_createServices(repository);

This function creates the built-in EtherCAT objects and services required for:

  • FoE (File over EtherCAT)
  • EoE (Ethernet over EtherCAT)
  • Emergency Messages
  • Diagnostic Messages
  • Command Interface

Initialization Sequence

The recommended initialization sequence is:

Ics_create()
│
▼
Ics_initialize()
│
▼
Ics_start()
│
▼
IcsEthercat_createServices(repository)
│
▼
Locate EtherCAT Objects
│
▼
Register Callbacks

Example:

Ics_start(icsHandle);
IcsEthercat_createServices(repository);
/* EtherCAT objects are now available */
IcsObject openFileService =
Ics_findObject(
icsHandle,
NULL,
ICS_EC_FOE_SV_FILE_OPEN);

Before IcsEthercat_createServices() is called, EtherCAT-specific objects and services do not exist in the repository and cannot be found using Ics_findObject().

After the services have been created, the application can:

  • Locate EtherCAT objects and services.
  • Register FoE handlers.
  • Register EoE handlers.
  • Generate emergency messages.
  • Generate diagnostic messages.
  • Use the command interface.

Current Limitations

The EtherCAT-specific objects and services described in this chapter are subject to the following limitations.

FoE Limitations

The File Open service supports file names up to 64 bytes.

The File Read and File Write services support a maximum data payload of 1012 bytes per request.

EoE Limitations

The EoE transmit and receive objects support Ethernet frame payloads up to 1014 bytes.

Applications should ensure that transmitted and received frames do not exceed the supported size of the generated repository objects.

Repository Requirements

EtherCAT-specific objects and services are not created automatically.

Applications must call:

IcsEthercat_createServices(repository);

before attempting to locate EtherCAT-specific objects or register callbacks.

Callback Restrictions

The callback restrictions described in Chapter 4 also apply to all EtherCAT-specific callbacks.

In particular:

  • IcsObject_apply() must not be called from a callback.
  • IcsObject_refresh() must not be called from a callback.
  • Object access inside callbacks should use IcsObject_get() and IcsObject_set().