Fsoe Refman
Fsoe Refman
rt-labs AB
https://rt-labs.com
Revision: 588
Contents
2 Introduction 3
1 Overview of FSoE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2 Overview of the stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Porting the stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4 Building the stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
5 Configuring the stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
v
vi CONTENTS
2 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
3 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4 Optional functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6 Checklists 65
1 Checklist for implementing FSoE master device . . . . . . . . . . . . . . . . . . . . . . 65
2 Checklist for implementing FSoE slave device . . . . . . . . . . . . . . . . . . . . . . . 67
3 Checklist for implementing platform abstraction layer . . . . . . . . . . . . . . . . . . . . 70
Index 73
Chapter 1
1 Scope
This user manual describes how to configure, create and use an FSoE master to slave connection or an
FSoE slave to master connection in accordance with the ETG.5100 "Safety Over EtherCAT" specifica-
tion using the provided FSoE stack implementation. The user manual does not include instructions or
guidelines for how to implement functional safety software or hardware sufficient to qualify it as an FSoE
device; instead follow the safety functional requirements described in ETG.5100 ch 6.1 "Safety functional
requirements". ETG.9100 "FSoE Policy" defines further rules and requirements for using and implement-
ing the Safety over EtherCAT technology. All requirements defined in the ETG.9100 that are applicable for
a device shall be fully met. The user manual contains implementation checklists, in chapter Checklists,
that the user shall go through.
3 Abbreviations
4 References
1. IEC 61784-3 Industrial communication networks - Profiles - Part 3: Functional Safety fieldbuses
1
2
5 Release Notes
This is the first official release of the user manual. It corresponds to version 1.0.0 of the software stack.
Chapter 2
Introduction
1 Overview of FSoE
Safety over EtherCAT/FailSafe over EtherCAT (FSoE) describes a protocol for transferring safety data up
to SIL3 between FSoE devices. Safety PDUs are transferred by a subordinate fieldbus that is not included
in the safety considerations, since it can be regarded as a black channel. The Safety PDU exchanged
between two communication partners is regarded by the subordinate fieldbus as process data that are
exchanged cyclically.
FSoE uses a unique master/slave relationship between the FSoE Master and the FSoE Slave, called an
FSoE Connection. In the FSoE Connection, Safety PDUs are exchanged between the FSoE Master and
its FSoE Slave in a ping-pong scheme. The FSoE Master can handle more than one FSoE Connection to
support several FSoE Slaves.
An FSoE Connection is controlled by two state machines, one on the slave side and one on the master
side. Both the FSoE Master and the FSoE Slave starts up in Reset state. Master will then configure the
slave through three intermediate states. Slave will verify that received configuration is valid. If configura-
tion succeeds, Master will order Slave to enter Data state, which is the only state where interchange of
process data takes place.
State transitions are initiated by the FSoE Master and acknowledged by the FSoE Slave, except if the
FSoE Slave detects an error, in which case it will transition to the Reset state on its own.
3
4
• Sequence number for detecting interchange, repetition, insertion or loss of whole messages.
• Unique connection identification for detecting misrouted messages via a unique address relation-
ship.
• Cyclic redundancy checking for data integrity for detecting message corruption from source to sink.
As a fail-safe mechanism, the FSoE protocol ensures that data exchanged between the FSoE Master and
Slave reverts to fail-safe data (defined as all zeros) if either end detects any communication error.
The FSoE Master and Slave both have a special flag variable specifying if sending valid process data is
enabled, or if only fail-safe data may be sent. The flag variable on Slave is independent of the flag variable
on the Master, with the exception that both will revert to false if either side detects an error. Thus, Slave
may send valid process data to Master while Master only sends fail-safe data to Slave, or vice versa. At
start-up, the flag variable is false on both Master and Slave. Neither the FSoE Slave nor the Master state
machine will ever set the variable to true on their own. The FSoE protocol offers a way for the application
on either side to set the variable to true.
2 Overview of the stack 5
The FSoE stack provides the safety user application with means to establish an FSoE Connection to a
remote FSoE device, enabling cyclical exchange of safety process data.
The stack contains two major components: An implementation of the FSoE master state machine as
specified in ETG.5100 and an implementation of the FSoE slave state machine also specified in ETG.←-
5100. The stack is accessed from application through two main APIs; the header file fsoemaster.h for the
master state machine and fsoeslave.h for the slave state machine. These APIs are described in chapters
Master State Machine API and Slave State Machine API.
Some behaviour of the stack is application-specific. The application customises such behaviour to fit the
application by implementing a set of callback functions. The callback functions are declared in the header
file fsoeapp.h. The following callback functions are available:
The stack is tested for validity using a set of unittests with full code coverage. Both the stack and the
unittests are delivered as source code for integration into target safety platform. The stack is written in C
while the unittests are written in C++ using the Google Test framework. The source and header files are
laid out in the following directory structure:
6
The FSoE stack provides a platform abstraction layer. The abstraction layer supports both OS-hosted or
bare-metal systems. It shall be implemented in a separate directory src/port/PLATFORM_NAME. Both
the stack and the unittests should be ported to the target platform.
For more information, see Platform Abstraction Layer.
The FSoE stack are delivered with build instructions using CMake for various platforms. If your platform
is not present it can be added. For further instructions on how to generate the CMake projects, read the
file README.md.
It is also possible to build the source by just adding the source to an existing platform project. If CMake is
not used, the header files options.h, fsoeoptions.h and fsoeexport.h must be created manually.
After the stack is built, its configuration may be changed using ccmake or cmake-gui. The following options
may be changed:
1 Overview
The FSoE Master state machine API provides the user with the following functionality:
• Support for sending process data outputs (called SafeOutputs in ETG.5100) to Slave and for re-
ceiving process data inputs (called SafeInputs in ETG.5100) from Slave.
• Support for user application to control if sending valid process data should be allowed, or if only
fail-safe data should be sent (the default).
• Support for user application to reset the FSoE Connection whenever it wishes.
The user API in header file fsoemaster.h allows any number of master state machines to be configured,
instantiated and used. Each state machine instance is independent of all other instances. Global variables
are not used. Because of this, the stack has no way to verify that instances are not configured in a
conflicting way, e.g. by using the same Connection IDs or Slave Addresses. The application shall ensure
that instances are not configured in a way that causes conflicts. See Functions.
The callback API in header file fsoeapp.h declares four callback functions that shall be implemented by
application. See Callback functions and types.
2 Macros
Public macro constants and functions ("defines") used by the master state machine are listed here. The
following are available:
7
8
These codes are sent between master and slave when either side requests connection to be reset. They
are sent in Reset frames. Local reset (FSOEMASTER_RESETREASON_LOCAL_RESET) may be re-
quested by any master or slave application. Local reset is also the reset reason sent by master to slave
at startup. All other reset reasons are error conditions detected by an FSoE state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave application requested connection to be reset. Also sent by master state machine at
startup.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame whose type was
not valid for current state.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame of unknown type.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame with invalid Con-
nection ID.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame with invalid CRCs.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after watchdog timer expired while waiting
for a frame to be received.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Connection frame with incorrect
slave address from master. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master state machine requested connection to be reset after receiving Connection or Parameter frame
from slave containing different data than what was sent to it. Never requested by slave state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incorrect
size of Communication Parameters from master. Never requested by master state machine. The only
communication parameter is the watchdog timeout, whose size is always two bytes.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
watchdog timeout from master. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
size for Application Parameters. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
Application Parameters. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
Application Parameters. Never requested by master state machine. The device-specific error codes are
in the range 0x80 ... 0xFF.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
Application Parameters. Never requested by master state machine. The device-specific error codes are
in the range 0x80 ... 0xFF.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Number of bytes in FSoE Safety PDU frame containing data_size data bytes
Parameters
Returns
#define FSOEMASTER_FRAME_SIZE(data_size) (\
((data_size) == 1) ? 6 : (2 * (data_size) + 3) )
3 Types 11
User API functions return codes. Returned from each API function to indicate if user called the function
correctly as described in the function's documentation.
2.3.1 Status OK
User violated the function's preconditions. fsoeapp_handle_user_error() callback will give detailed infor-
mation about what caused the function to return ERROR.
3 Types
Public types for the FSoE master state machine are listed here. The following are available:
Status returned from API function Returned from each API function to indicate if user called the function
correctly as described in the function's documentation. See FSOEMASTER_STATUS_OK See FSOE←-
MASTER_STATUS_ERROR
A reset of connection between master and slave may be initiated by either side sending a Reset frame
containing a code describing why the reset was initiated, such as an error detected by FSoE stack, system
startup (only master to slave) or application request.
3.5 Configuration
/*
* Connection ID
/*
* Timeout value in milliseconds for the watchdog timer
/*
* Application parameters (optional)
/*
* Size in bytes of the application parameters
* Valid values are 0 - FSOE_APPLICATION_PARAMETERS_MAX_SIZE.
* This value will be sent to slave when connection is established.
* May be zero if no application parameters are needed.
* Slave will refuse the connection if it expected a different size.
/*
* Size in bytes of the outputs to be sent to slave
* Only even values are allowed, except for 1, which is also allowed.
* Maximum value is FSOE_PROCESS_DATA_MAX_SIZE.
14
/*
* Size in bytes of the inputs to be received from slave
* Only even values are allowed, except for 1, which is also allowed.
* Maximum value is FSOE_PROCESS_DATA_MAX_SIZE.
An FSoE master state machine instance handles the connection with a single slave. Multiple state ma-
chines instances are supported, where each one has their own Connection ID and associated slave.
User may allocate the instance statically or dynamically using malloc() or on the stack. To use an allocated
4 Functions 15
4 Functions
For macros used by the functions, see Macros. For types used by the functions, see Types.
Parameters
in reset_reason Reset reason
Returns
String describing the reset reason, e.g. "local reset" or "INVALID_CRC", unless reset_reason is not
a valid reset reason, in which case "invalid error code" is returned. In either case, the returned string
is null- terminated and statically allocated as a string literal.
Example:
#include <fsoemaster.h>
void handle_connection_reset_by_slave (uint8_t reset_reason)
{
printf ("Slave initiated connection reset due to %s (%u)\n",
fsoemaster_reset_reason_description (reset_reason),
reset_reason);
}
Parameters
in state State
Returns
String describing the state, unless state is not a valid state, in which case "invalid" is returned. In
either case, the returned string is null- terminated and statically allocated as a string literal.
Example:
#include <fsoemaster.h>
fsoemaster_state_t state;
fsoemaster_status_t fsoemaster_update_sra_crc (
uint32_t * crc,
const void * data,
size_t size);
4 Functions 17
This function will calculate the SRA CRC for data in data. If this is the first time the function is called, then
user should first set crc to zero before calling the function. If this is a subsequent call then the previously
calculated CRC value will be is used as input to the CRC calculation. The CRC crc will be updated
in-place.
SRA CRC is an optional feature whose use is not mandated nor specified by the FSoE ETG.5100 specifi-
cation. If used, the SRA CRC should be sent to slave as Application parameter, where it should be placed
first (encoded in little endian byte order).
See ETG.5120 "Safety over EtherCAT Protocol Enhancements", ch. 6.3 "SRA CRC Calculation".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
in,out crc SRA CRC value to update in-place. If this is the first call to
fsoemaster_update_sra_crc() then its value should first be set to zero.
in data Buffer with data.
in size Size of buffer in bytes. If zero, crc will be left unmodified.
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status1;
fsoemaster_status_t status2;
uint32_t crc;
crc = 0;
status1 = fsoemaster_update_sra_crc (&crc, data1, sizeof (data1));
status2 = fsoemaster_update_sra_crc (&crc, data2, sizeof (data2));
if (status1 == FSOEMASTER_STATUS_OK &&
status2 == FSOEMASTER_STATUS_OK)
{
printf ("Calculated SRA CRC: 0x%x\n", crc);
}
else
{
printf ("We called function incorrectly (with null-pointers)\n");
}
fsoemaster_status_t fsoemaster_get_state (
const fsoemaster_t * master,
fsoemaster_state_t * state);
18
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
fsoemaster_state_t state;
fsoemaster_status_t fsoemaster_get_master_session_id (
const fsoemaster_t * master,
uint16_t * session_id);
The Master Session ID was generated by the master state machine when entering Session state.
Calling this function while master state machine is in Reset state is not allowed as no Master Session ID
has yet been generated.
See ETG.5100 ch. 8.2.2.3: "Session state".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
4 Functions 19
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
uint16_t session_id;
fsoemaster_status_t fsoemaster_get_slave_session_id (
const fsoemaster_t * master,
uint16_t * session_id);
The Slave Session ID was generated by slave and then received by the master state machine when
entering Connection state.
Calling this function while master state machine is in Reset or Session state is not allowed as no Slave
Session ID has yet been received.
See ETG.5100 ch. 8.2.2.3: "Session state".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
uint16_t session_id;
fsoemaster_status_t fsoemaster_get_time_until_timeout_ms (
const fsoemaster_t * master,
uint32_t * time_ms);
Get time remaining until watchdog timer timeouts, in milliseconds. This function is mainly used for unit-
testing purposes.
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition..
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
uint32_t time_ms;
fsoemaster_status_t fsoemaster_get_process_data_sending_enable_flag (
const fsoemaster_t * master,
bool * is_enabled);
Get flag indicating if sending process data to slave is enabled. This will only check a flag indicating that
everything is OK from the perspective of the application. Master state machine will not send normal
process data if connection with slave is not fully established (Data state), even if application allows it.
See ETG.5100 ch. 8.4.1.2 "Set Data Command event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
• false if not.
22
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
bool is_enabled;
fsoemaster_status_t fsoemaster_clear_process_data_sending_enable_flag (
fsoemaster_t * master);
This will clear a flag indicating that everything is OK from the perspective of the application. Master will
only send fail-safe data (zeros) to slave. This is the default setting after power-on and after detection of
any errors.
See ETG.5100 ch. 8.4.1.2 "Set Data Command event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
fsoemaster_status_t fsoemaster_set_process_data_sending_enable_flag (
fsoemaster_t * master);
This will set a flag indicating that everything is OK from the perspective of the application. Setting the flag
will cause master to send outputs containing valid process data once connection is established, assuming
no errors are detected. If any errors are detected, this flag will revert to its disabled state and only fail-safe
outputs will be sent.
See ETG.5100 ch. 8.4.1.2 "Set Data Command event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
24
#include <fsoemaster.h>
fsoemaster_status_t status;
fsoemaster_status_t fsoemaster_set_reset_request_flag (
fsoemaster_t * master);
This will set a flag, which in next call to fsoemaster_sync_with_slave() will cause the master state ma-
chine to send the Reset frame to slave and then enter the Reset state. Fail-safe mode will then be en-
tered, where normal process data outputs will not be sent even after connection has been re-established.
Application needs to explicitly re-enable process data outputs in order to leave fail-safe mode. See
fsoemaster_set_process_data_sending_enable_flag().
See ETG.5100 ch. 8.4.1.2 "Reset Connection event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_status_t status;
fsoemaster_status_t fsoemaster_sync_with_slave (
fsoemaster_t * master,
const void * outputs,
void * inputs,
fsoemaster_syncstatus_t * sync_status);
Needs to be called periodically in order to avoid watchdog timeout. It is recommended that delay between
calls to the function is no more than half the watchdog timeout.
Depending on current state, the master state machine may try to send a single frame or read a single
frame by calling fsoeapp_send() and/or fsoeapp_recv(), which are non-blocking functions.
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOEMASTER_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
fsoemaster_syncstatus_t sync_status;
fsoemaster_status_t status;
uint8_t inputs[2];
outputs[0] = 0x12;
outputs[1] = 0x34;
status = fsoemaster_sync_with_slave (master, outputs, inputs, &sync_status);
if (status == FSOEMASTER_STATUS_OK)
{
if (sync_status.reset_event != FSOEMASTER_RESETEVENT_NONE)
{
printf ("Connection was reset by %s. Cause: %s\n",
sync_status.reset_event == FSOEMASTER_RESETEVENT_BY_MASTER ?
"master" : "slave",
fsoemaster_reset_reason_description (sync_status.reset_reason));
}
26
if (sync_status.is_process_data_received)
{
handle_received_data (inputs);
}
else
{
printf ("No valid process data was received\n");
}
}
else
{
printf ("We called function incorrectly\n");
}
fsoemaster_status_t fsoemaster_init (
fsoemaster_t * master,
const fsoemaster_cfg_t * cfg,
void * app_ref);
Precondition
Parameters
Returns
Status:
• FSOEMASTER_STATUS_OK if function was called correctly.
• FSOEMASTER_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoemaster.h>
const fsoemaster_cfg_t cfg =
{
.slave_address = 0x0304,
.connection_id = 8,
.watchdog_timeout_ms = 100,
.application_parameters = NULL,
.application_parameters_size = 0,
.outputs_size = 2,
.inputs_size = 2,
5 Callback functions and types 27
};
fsoemaster_t master;
fsoemaster_status_t status;
The following callback functions are declared in fsoeapp.h and shall be implemented in application:
The functions fsoeapp_send() and fsoeapp_recv() are the means for the state machine to access the
black channel. Application may implement these with support for cross-checking. The arrows in picture
below denote direct function calls:
The master state machine does not verify that the Session ID returned from fsoeapp_generate_session←-
_id() is generated correctly. To pass the conformance test, the application should ensure that the Session
ID is re-generated as a random number in accordance with the specification.
The function fsoeapp_handle_user_error() can be implemented as a system restart, or it can be imple-
mented as an empty function which does nothing.
The header file also makes the following type available:
28
The header file also makes the following function available for convenience when logging:
Passed to fsoeapp_handle_user_error() when an API function detects that user violated a precondition.
See also
fsoeapp_handle_user_error().
fsoeapp_user_error_description().
Return description of user error as a string literal. This is just a helper function which may be used for
logging the error code passed to fsoeapp_handle_user_error(). It is implemented by the FSoE stack itself.
Parameters
in user_error User error
Returns
String describing the user error, unless user_error is not a valid error, in which case "invalid error
code" is returned. In either case, the returned string is null- terminated and statically allocated as a
string literal
5 Callback functions and types 29
Example:
#include <fsoeapp.h>
void fsoeapp_handle_user_error (
void * app_ref, fsoeapp_usererror_t user_error)
{
printf ("We called an API function incorrectly: %s\n",
fsoeapp_user_error_description (user_error));
}
See also
fsoeapp_handle_user_error().
Send a complete FSoE PDU frame. An FSoE PDU frame starts with the Command byte and ends with
the Connection ID. Its size is given by the formula MAX (3 + 2 ∗ data_size, 6), where data_size is the
number of data bytes to send and is given by a field in fsoemaster_cfg_t or fsoeslave_cfg_t.
See ETG.5100 ch. 8.1.1 "Safety PDU structure".
This callback function is called by the FSoE stack when it wishes to send a frame. Application is required
to be implement this by making an attempt to send the frame in supplied buffer. If application wishes to
communicate an error condition to the FSoE stack then it may do so by calling fsoemaster_set_reset_←-
request_flag() or fsoeslave_set_reset_request_flag().
NOTE: If cross-checking is required it depends on implemented model if the data is cross-checked before
sending or not, the example models from iec61784-3 suggest cross-checking to be performed before
sending if only a single frame is sent, this is typically true for a FSoE device running on EtherCAT Slave
Controller HW.
NOTE: If the FSoE stack runs on a different thread or execution context than the thread or execution
context where the frame is actually sent, then the application has to ensure that no race condition can
occur. Otherwise, a partial frame may be sent, causing CRC error and a reset of connection. Race
conditions may be avoided by means of a mutex, a semaphore, by locking interrupts or some other
mechanism.
Parameters
in,out app_ref Application reference. This pointer was passed to stack in fsoemaster_init() or
fsoeslave_init(). Application is free to use this as it sees fit.
in buffer Buffer containing a PDU frame to be sent.
in size Size of PDU frame in bytes. Always the same, as given by formula above.
Try to receive a complete FSoE PDU frame. An FSoE PDU frame starts with the Command byte and
ends with the Connection ID. Its size is given by the formula MAX (3 + 2 ∗ data_size, 6), where data_size
is the number of data bytes to receive and is given by a field in fsoemaster_cfg_t or fsoeslave_cfg_t.
See ETG.5100 ch. 8.1.1 "Safety PDU structure".
This callback function is called by the FSoE stack when it wishes to receive a frame. Application is
required to implement this by first checking if a frame was received. If no new frame was received then
the function should either
If a frame was received then its content should be copied to buffer. If application wishes to communi-
cate an error condition to the FSoE stack then it may do so by calling fsoemaster_reset_connection() or
fsoeslave_reset_connection().
NOTE: If cross-checking is required, no cross-checking is performed here but on decoded data returned
by the stack.
NOTE: If the FSoE stack runs on a different thread or execution context than the thread or execution
context where the frame is actually received, then the application has to ensure that no race condition
can occur. Otherwise, fsoeapp_recv() may receive a partial frame, causing CRC error and a reset of
connection. Race conditions may be avoided by means of a mutex, a semaphore, by locking interrupts or
some other mechanism.
Parameters
in,out app_ref Application reference. This pointer was passed to stack in fsoemaster_init() or
fsoeslave_init(). Application is free to use this as it sees fit.
out buffer Buffer where recieved PDU frame will be stored.
in size Size of PDU frame in bytes. Always the same, as given by formula above.
5 Callback functions and types 31
Returns
Number of bytes received. Should be equal to size if a frame was received. If no frame was
received, it may be equal 0. Alternatively, the last received frame may be put in the buffer with size
bytes returned.
Example:
Parameters
in,out app_ref Application reference. This pointer was passed to stack in fsoemaster_init() or
fsoeslave_init(). Application is free to use this as it sees fit.
Returns
A generated Session ID
Example:
void fsoeapp_handle_user_error (
void * app_ref,
fsoeapp_usererror_t user_error);
User called an API function in a way that violated a precondition. The API function detected this and
before returning it called this function.
Application may implement this by restarting the system if running on an embedded target or quit the
process if running on a PC. In these cases, the API function will not return and the user does not need to
check the returned error code.
Application may also implement this by returning to the API function. The API function will then return
the error to user, which should then handle the error. Note that any elaborate error handling by user
is unlikely to succeed as it was the user who committed the error in the first place by violating the API
function's preconditions.
Note
Parameters
in user_error Type of error user made when calling the API function.
Example:
#include <fsoeapp.h>
void fsoeapp_handle_user_error (
void * app_ref, fsoeapp_usererror_t user_error)
{
printf ("User called API function incorrectly: %s, app_ref: %p\n"),
fsoeapp_user_error_description (user_eror), app_ref);
assert (0);
}
Chapter 4
1 Overview
The FSoE Slave state machine API provides the user with the following functionality:
• Support for sending process data inputs (called SafeInputs in ETG.5100) to Master and for receiving
process data outputs (called SafeOutputs in ETG.5100) from Master.
• Support for user application to control if sending valid process data should be allowed, or if only
fail-safe data should be sent (the default).
• Support for user application to reset the FSoE Connection whenever it wishes.
The user API in header file fsoeslave.h allows the slave state machine to be configured, instantiated and
used. See Functions.
The callback API in header file fsoeapp.h declares five callback functions that shall be implemented by
application. See Callback functions and types.
2 Macros
Public macro constants and functions ("defines") used by the slave state machine are listed here. The
following are available:
33
34
These codes are sent between master and slave when either side requests connection to be reset.
They are sent in Reset frames. Local reset (FSOESLAVE_RESETREASON_LOCAL_RESET) may be
requested by any master or slave application. Local reset is also the reset reason sent by master to slave
at startup. All other reset reasons are error conditions detected by an FSoE state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave application requested connection to be reset. Also sent by master state machine at
startup.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame whose type was
not valid for current state.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame of unknown type.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame with invalid Con-
nection ID.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after receiving a frame with invalid CRCs.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master or slave state machine requested connection to be reset after watchdog timer expired while waiting
for a frame to be received.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Connection frame with incorrect
slave address from master. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Master state machine requested connection to be reset after receiving Connection or Parameter frame
from slave containing different data than what was sent to it. Never requested by slave state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incorrect
size of Communication Parameters from master. Never requested by master state machine. The only
communication parameter is the watchdog timeout, whose size is always two bytes.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
watchdog timeout from master. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
size for Application Parameters. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
Application Parameters. Never requested by master state machine.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
Application Parameters. Never requested by master state machine. The device-specific error codes are
in the range 0x80 ... 0xFF.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Slave state machine requested connection to be reset after receiving Parameter frame with incompatible
Application Parameters. Never requested by master state machine. The device-specific error codes are
in the range 0x80 ... 0xFF.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
Number of bytes in FSoE Safety PDU frame containing data_size data bytes
Parameters
Returns
#define FSOESLAVE_FRAME_SIZE(data_size) (\
((data_size) == 1) ? 6 : (2 * (data_size) + 3) )
3 Types 37
User API functions return codes. Returned from each API function to indicate if user called the function
correctly as described in the function's documentation.
2.3.1 Status OK
User violated the function's preconditions. fsoeapp_handle_user_error() callback will give detailed infor-
mation about what caused the function to return ERROR.
3 Types
Public types for the FSoE slave state machine are listed here. The following are available:
Status returned from API function Returned from each API function to indicate if user called the function
correctly as described in the function's documentation. See FSOESLAVE_STATUS_OK See FSOESL←-
AVE_STATUS_ERROR
A reset of connection between master and slave may be initiated by either side sending a Reset frame
containing a code describing why the reset was initiated, such as an error detected by FSoE stack, system
startup (only master to slave) or application request.
3.5 Configuration
/*
* Expected size in bytes of the application parameters
/*
* Size in bytes of the inputs to be sent to master
* Only even values are allowed, except for 1, which is also allowed.
* Maximum value is FSOE_PROCESS_DATA_MAX_SIZE.
/*
* Size in bytes of the outputs to be received from master
* Only even values are allowed, except for 1, which is also allowed.
* Maximum value is FSOE_PROCESS_DATA_MAX_SIZE.
An FSoE slave state machine instance handles the connection with a single master.
User may allocate the instance statically or dynamically using malloc() or on the stack. To use an allocated
instance, pass a pointer to it as the first argument to any API function.
This struct is made public as to allow for static allocation.
40
NOTE: User of the API is prohibited from accessing any of the fields as the layout of the structure is to
be considered an implementation detail. Only the stack-internal file "fsoeslave.c" may access any field
directly.
4 Functions
For macros used by the functions, see Macros. For types used by the functions, see Types.
Parameters
in reset_reason Reset reason
Returns
String describing the reset reason, e.g. "local reset" or "INVALID_CRC", unless reset_reason is not
a valid reset reason, in which case "invalid error code" is returned. In either case, the returned string
is null- terminated and statically allocated as a string literal.
Example:
#include <fsoeslave.h>
void handle_connection_reset_by_master (uint8_t reset_reason)
{
printf ("Master initiated connection reset due to %s (%u)\n",
fsoeslave_reset_reason_description (reset_reason),
reset_reason);
}
Parameters
in state State
Returns
String describing the state, unless state is not a valid state, in which case "invalid" is returned. In
either case, the returned string is null- terminated and statically allocated as a string literal.
Example:
#include <fsoeslave.h>
fsoeslave_state_t state;
fsoeslave_status_t fsoeslave_update_sra_crc (
uint32_t * crc,
const void * data,
size_t size);
42
This function will calculate the SRA CRC for data in data. If this is the first time the function is called, then
user should first set crc to zero before calling the function. If this is a subsequent call then the previously
calculated CRC value will be is used as input to the CRC calculation. The CRC crc will be updated
in-place.
SRA CRC is an optional feature whose use is not mandated nor specified by the FSoE ETG.5100 specifi-
cation. If used, the SRA CRC should be sent to slave as Application parameter, where it should be placed
first (encoded in little endian byte order).
See ETG.5120 "Safety over EtherCAT Protocol Enhancements", ch. 6.3 "SRA CRC Calculation".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
in,out crc SRA CRC value to update in-place. If this is the first call to
fsoeslave_update_sra_crc() then its value should first be set to zero.
in data Buffer with data.
in size Size of buffer in bytes. If zero, crc will be left unmodified.
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status1;
fsoeslave_status_t status2;
uint32_t crc;
crc = 0;
status1 = fsoeslave_update_sra_crc (&crc, data1, sizeof (data1));
status2 = fsoeslave_update_sra_crc (&crc, data2, sizeof (data2));
if (status1 == FSOESLAVE_STATUS_OK &&
status2 == FSOESLAVE_STATUS_OK)
{
printf ("Calculated SRA CRC: 0x%x\n", crc);
}
else
{
printf ("We called function incorrectly (with null-pointers)\n");
}
fsoeslave_status_t fsoeslave_get_state (
const fsoeslave_t * slave,
fsoeslave_state_t * state);
4 Functions 43
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status;
fsoeslave_state_t state;
fsoeslave_status_t fsoeslave_get_slave_session_id (
const fsoeslave_t * slave,
uint16_t * session_id);
The Slave Session ID was generated by the slave state machine when entering Session state.
Calling this function while slave state machine is in Reset state is not allowed as no Slave Session ID has
yet been generated.
See ETG.5100 ch. 8.2.2.3: "Session state".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
44
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status;
uint16_t session_id;
fsoeslave_status_t fsoeslave_get_master_session_id (
const fsoeslave_t * slave,
uint16_t * session_id);
The Master Session ID was generated by master and received by the slave state machine while in Session
state.
Calling this function while slave state machine is in Reset or Session state is not allowed as no Slave
Session ID has yet been received.
See ETG.5100 ch. 8.2.2.3: "Session state".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status;
uint16_t session_id;
fsoeslave_status_t fsoeslave_get_process_data_sending_enable_flag (
const fsoeslave_t * slave,
bool * is_enabled);
Get flag indicating if sending process data to master is enabled. This will only check a flag indicating
that everything is OK from the perspective of the application. Slave will not send normal process data if
connection with master is not fully established (Data state), even if application allows it.
See ETG.5100 ch. 8.5.1.2 "Set Data Command event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status;
bool is_enabled;
fsoeslave_status_t fsoeslave_clear_process_data_sending_enable_flag (
fsoeslave_t * slave);
This will clear a flag indicating that everything is OK from the perspective of the application. Slave will only
send fail safe data (zeros) to master. This is the default setting after power-on and after detection of any
errors.
See ETG.5100 ch. 8.5.1.2 "Set Data Command event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status;
fsoeslave_status_t fsoeslave_set_process_data_sending_enable_flag (
fsoeslave_t * slave);
This will set a flag indicating that everything is OK from the perspective of the application. Setting the flag
will cause slave to send inputs containing valid process data once connection is established, assuming no
errors are detected. If any errors are detected, this flag will revert to its disabled state and only fail-safe
inputs will be sent.
See ETG.5100 ch. 8.5.1.2 "Set Data Command event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
48
#include <fsoeslave.h>
fsoeslave_status_t status;
fsoeslave_status_t fsoeslave_set_reset_request_flag (
fsoeslave_t * slave);
This will set a flag, which in next call to fsoeslave_sync_with_master() will cause the slave state machine
to send a Reset frame to master and then wait for master to re-establish connection. Fail-safe mode will
then be entered, where normal process data inputs will not be sent even after connection has been re-
established. Application needs to explicitly re-enable process data inputs in order to leave fail-safe mode.
See fsoeslave_set_process_data_sending_enable_flag().
See ETG.5100 ch. 8.5.1.2 "Reset Connection event".
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_status_t status;
fsoeslave_status_t fsoeslave_sync_with_master (
fsoeslave_t * slave,
const void * inputs,
void * outputs,
fsoeslave_syncstatus_t * sync_status);
Needs to be called periodically in order to avoid watchdog timeout. It is recommended that delay between
calls to the function is no more than half the watchdog timeout.
Depending on current state, the slave state machine may try to send a single frame or read a single frame
by calling fsoeapp_send() and/or fsoeapp_recv(), which are non-blocking functions.
Before taking any action, function will first validate that its preconditions (see below) were respected. If
this was not the case, the function fsoeapp_handle_user_error() will first be called after which function will
exit with status FSOESLAVE_STATUS_ERROR.
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
fsoeslave_syncstatus_t sync_status;
fsoeslave_status_t status;
uint8_t outputs[2];
inputs[0] = 0x56;
inputs[1] = 0x78;
status = fsoeslave_sync_with_master (slave, inputs, outputs, &sync_status);
if (status == FSOESLAVE_STATUS_OK)
{
if (sync_status.reset_event != FSOESLAVE_RESETEVENT_NONE)
{
printf ("Connection was reset by %s. Cause: %s\n",
sync_status.reset_event == FSOESLAVE_RESETEVENT_BY_MASTER ?
"master" : "slave",
fsoeslave_reset_reason_description (sync_status.reset_reason));
}
50
if (sync_status.is_process_data_received)
{
handle_received_data (outputs);
}
else
{
printf ("No valid process data was received\n);
}
}
else
{
printf ("We called function incorrectly\n");
}
fsoeslave_status_t fsoeslave_init (
fsoeslave_t * slave,
const fsoeslave_cfg_t * cfg,
void * app_ref);
Precondition
Parameters
Returns
Status:
• FSOESLAVE_STATUS_OK if function was called correctly.
• FSOESLAVE_STATUS_ERROR if user violated a precondition.
Example:
#include <fsoeslave.h>
const fsoeslave_cfg_t cfg =
{
.slave_address = 0x0304,
.application_parameters_size = 0,
.inputs_size = 2,
.outputs_size = 2,
};
fsoeslave_t slave;
fsoeslave_status_t status;
5 Callback functions and types 51
The following callback functions are declared in fsoeapp.h and shall be implemented in application:
The functions fsoeapp_send() and fsoeapp_recv() are the means for the state machine to access the
black channel. Application may implement these with support for cross-checking. The arrows in picture
below denote direct function calls:
The slave state machine does not verify that the Session ID returned from fsoeapp_generate_session_←-
id() is generated correctly. To pass the conformance test, the application should ensure that the Session
ID is re-generated as a random number in accordance with the specification.
The function fsoeapp_verify_parameters() should verify that parameters received from Master are valid.
The parameters include both the watchdog timeout and application-specific parameters.
52
The header file also makes the following function available for convenience when logging:
Note that values in the range 0x80 - 0xff are also allowed, indicating that some application-specific pa-
rameter is invalid.
See ETG.5100 ch. 8.3. table 28: "FSoE communication error codes".
#define FSOEAPP_STATUS_OK 0
#define FSOEAPP_STATUS_BAD_TIMOUT 9
#define FSOEAPP_STATUS_BAD_APP_PARAMETER 11
User error. Passed to fsoeapp_handle_user_error() when an API function detects that user violated a
precondition. See fsoeapp_handle_user_error() and fsoeapp_user_error_description().
See also
fsoeapp_handle_user_error().
fsoeapp_user_error_description().
Return description of user error as a string literal This is just a helper function which may be used for
logging the error code passed to fsoeapp_handle_user_error(). It is implemented by the FSoE stack
itself.
Parameters
in user_error User error
Returns
String describing the user error, unless user_error is not a valid error, in which case "invalid error
code" is returned. In either case, the returned string is null- terminated and statically allocated as a
string literal
Example:
#include <fsoeapp.h>
void fsoeapp_handle_user_error (
void * app_ref, fsoeapp_usererror_t user_error)
{
printf ("We called an API function incorrectly: %s\n",
fsoeapp_user_error_description (user_error));
}
See also
fsoeapp_handle_user_error().
Send a complete FSoE PDU frame. An FSoE PDU frame starts with the Command byte and ends with
the Connection ID. Its size is given by the formula MAX (3 + 2 ∗ data_size, 6), where data_size is the
number of data bytes to send and is given by a field in fsoemaster_cfg_t or fsoeslave_cfg_t.
See ETG.5100 ch. 8.1.1 "Safety PDU structure".
54
This callback function is called by the FSoE stack when it wishes to send a frame. Application is required
to be implement this by making an attempt to send the frame in supplied buffer. If application wishes to
communicate an error condition to the FSoE stack then it may do so by calling fsoemaster_set_reset_←-
request_flag() or fsoeslave_set_reset_request_flag().
NOTE: If cross-checking is required it depends on implemented model if the data is cross-checked before
sending or not, the example models from iec61784-3 suggest cross-checking to be performed before
sending if only a single frame is sent, this is typically true for a FSoE device running on EtherCAT Slave
Controller HW.
NOTE: If the FSoE stack runs on a different thread or execution context than the thread or execution
context where the frame is actually sent, then the application has to ensure that no race condition can
occur. Otherwise, a partial frame may be sent, causing CRC error and a reset of connection. Race
conditions may be avoided by means of a mutex, a semaphore, by locking interrupts or some other
mechanism.
Parameters
in,out app_ref Application reference. This pointer was passed to stack in fsoemaster_init() or
fsoeslave_init(). Application is free to use this as it sees fit.
in buffer Buffer containing a PDU frame to be sent.
in size Size of PDU frame in bytes. Always the same, as given by formula above.
Try to receive a complete FSoE PDU frame. An FSoE PDU frame starts with the Command byte and
ends with the Connection ID. Its size is given by the formula MAX (3 + 2 ∗ data_size, 6), where data_size
is the number of data bytes to receive and is given by a field in fsoemaster_cfg_t or fsoeslave_cfg_t.
See ETG.5100 ch. 8.1.1 "Safety PDU structure".
5 Callback functions and types 55
This callback function is called by the FSoE stack when it wishes to receive a frame. Application is
required to implement this by first checking if a frame was received. If no new frame was received then
the function should either
If a frame was received then its content should be copied to buffer. If application wishes to communi-
cate an error condition to the FSoE stack then it may do so by calling fsoemaster_reset_connection() or
fsoeslave_reset_connection().
NOTE: If cross-checking is required, no cross-checking is performed here but on decoded data returned
by the stack.
NOTE: If the FSoE stack runs on a different thread or execution context than the thread or execution
context where the frame is actually received, then the application has to ensure that no race condition
can occur. Otherwise, fsoeapp_recv() may receive a partial frame, causing CRC error and a reset of
connection. Race conditions may be avoided by means of a mutex, a semaphore, by locking interrupts or
some other mechanism.
Parameters
in,out app_ref Application reference. This pointer was passed to stack in fsoemaster_init() or
fsoeslave_init(). Application is free to use this as it sees fit.
out buffer Buffer where recieved PDU frame will be stored.
in size Size of PDU frame in bytes. Always the same, as given by formula above.
Returns
Number of bytes received. Should be equal to size if a frame was received. If no frame was
received, it may be equal 0. Alternatively, the last received frame may be put in the buffer with size
bytes returned.
Example:
Parameters
in,out app_ref Application reference. This pointer was passed to stack in fsoemaster_init() or
fsoeslave_init(). Application is free to use this as it sees fit.
Returns
A generated Session ID
Example:
void fsoeapp_handle_user_error (
void * app_ref,
fsoeapp_usererror_t user_error);
User called an API function in a way that violated a precondition. The API function detected this and
before returning it called this function.
Application may implement this by restarting the system if running on an embedded target or quit the
process if running on a PC. In these cases, the API function will not return and the user does not need to
check the returned error code.
Application may also implement this by returning to the API function. The API function will then return
the error to user, which should then handle the error. Note that any elaborate error handling by user
is unlikely to succeed as it was the user who committed the error in the first place by violating the API
function's preconditions.
Note
Parameters
in user_error Type of error user made when calling the API function.
Example:
#include <fsoeapp.h>
void fsoeapp_handle_user_error (
void * app_ref, fsoeapp_usererror_t user_error)
{
printf ("User called API function incorrectly: %s, app_ref: %p\n"),
fsoeapp_user_error_description (user_eror), app_ref);
assert (0);
}
uint8_t fsoeapp_verify_parameters (
void * app_ref,
uint16_t timeout_ms,
const void * app_parameters,
size_t size);
The parameters include both communication parameters (the watchdog timeout) as well as application-
specific parameters.
See ETG.5100 ch. 7.1 "FSoE Connection".
This callback function is called by FSoE slave when all parameters have been received from master.
Application is required to be implement this by verifying that the parameters are valid, returning an error
code if not. If error is returned, slave will reset the connection and send the specified error code to master.
The master stack does not call this function.
Parameters
Returns
Error code:
• FSOEAPP_STATUS_OK if all parameters are valid,
• FSOEAPP_STATUS_BAD_TIMOUT if the watchdog timeout is invalid,
• FSOEAPP_STATUS_BAD_APP_PARAMETER if application-specific parameters are invalid,
• 0x80-0xFF if application-specific parameters are invalid and cause is given by application-
specific error code.
Example:
uint8_t fsoeapp_verify_parameters (
void * app_ref,
uint16_t timeout_ms,
const void * app_parameters,
size_t size)
{
/* Verify watchdog */
if (timeout_ms < FSOE_MIN_WATCHDOG || timeout_ms >= FSOE_MAX_WATCHDOG)
{
/* FSOEAPP_STATUS_BAD_TIMOUT */
return FSOEAPP_STATUS_BAD_TIMOUT;
}
/* Verify application parameters */
if(size > 0)
{
uint16_t * param1 = (uint16_t *)app_parameters;
uint16_t * param2 = (uint16_t *)app_parameters + 1;
parameters_t * temp_param = (parameters_t *)app_ref;
if(*param1 != temp_param->app_param1 ||
*param2 != temp_param->app_param2)
{
/* FSOEAPP_STATUS_BAD_APP_PARAMETER */
return FSOEAPP_STATUS_BAD_APP_PARAMETER;
}
}
return FSOEAPP_STATUS_OK;
}
Chapter 5
1 Overview
The platform abstraction layer is composed of the macros and functions listed below. The functions are
declared in the stack-internal header file fsoeport.h and should be implemented in a file fsoeport.c. The
macros should be implemented in a file fsoeport_macros.h. Both files should be placed in a directory
src/port/PLATFORM_NAME, where PLATFORM_NAME is the name of the platform added to the FSoE
stack.
List of required macros:
2 Macros
Assertions shall never fail. An assertion failure indicates that a fatal event has occurred, likely some kind
of memory corruption. Program is no longer in a defined state and should be terminated as to avoid safety
violations. Termination may be accomplished by means of a watchdog reset or some other mechanism.
59
60
Parameters
in exp Expression which should always be true
Example:
#include <assert.h>
#ifdef NDEBUG
#define FSOEPORT_ASSERT(exp) fsoeport_assert (exp);
static inline void fsoeport_assert (int exp)
{
if (!exp)
{
/* Wait for watchdog reset */
for (;;);
}
}
#else
#define FSOEPORT_ASSERT(exp) assert (exp);
#endif /* NDEBUG */
If set to 1 then this is a big endian platform. The most significant 8 bits of a word are stored at the lowest
byte address. If set to 0 then this is a little endian platform. The least significant 8 bits of a word are stored
at the lowest byte address.
Note
The defines used in sample code below might not be applicable for the user platform, The user shall
ensure that correct endianness is configured.
Example:
This function attribute is used to enable compiler to emit warnings if types of supplied arguments do not
match supplied format string. If compiler does not have such function attribute then this can be defined
as an empty macro.
Parameters
in str Position of the format string within the argument list. Argument positions start at 1.
in arg Position of first argument of the variable number of arguments. Argument positions start
at 1.
Example:
3 Functions
Time should be monotonically increasing (except for wrap-around). When time is close to 0xffffffff it should
wrap around to a value close to zero.
Time will be used for determining whether the watchdog timer has expired or not. It may also be used for
logging purposes.
Returns
Example:
Copies the values of num bytes from the location pointed to by src directly to the memory block pointed to
by dest. The blocks may not overlap.
Parameters
out dest Pointer to the destination array where the content is to be copied.
in src Pointer to the source of data to be copied.
in num Number of bytes to copy.
Example:
#include <string.h>
void fsoeport_memcpy (void * dest, const void * src, size_t num)
{
(void)memcpy (dest, src, num);
}
Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by
ptr2, returning zero if they all match or a value different from zero otherwise.
Parameters
Returns
Result of comparison:
• Negative if the first byte that does not match in both memory blocks has a lower value in ptr1
than in ptr2 (if evaluated as unsigned char values).
• Zero if the contents of both memory blocks are equal.
• Positive if the first byte that does not match in both memory blocks has a greater value in ptr1
than in ptr2 (if evaluated as unsigned char values).
Example:
#include <string.h>
int32_t fsoeport_memcmp (const void * ptr1, const void * ptr2, size_t num)
{
return memcmp (ptr1, ptr2, num);
}
Sets the first num bytes of the block of memory pointed by ptr to the specified value.
Parameters
Example:
#include <string.h>
void fsoeport_memset (void * ptr, uint8_t value, size_t num)
{
(void)memset (ptr, value, num);
}
4 Optional functions
Logging is an optional feature useful for development purposes. If logging is not enabled, then this function
does not need to be implemented.
Note
Enabling logging functions require support for printf macros defined by inttypes.h
Parameters
Example:
#include <stdio.h>
#include <stdarg.h>
void fsoeport_log (uint8_t type, const char * fmt, ...)
{
va_list list;
Checklists
65
66