FFFIScom User Guide
FFFIScom User Guide
0 User Guide
FFFISCom Library V1.0 User Guide
Table of Contents
1. Introduction ....................................................................................... 1
1.1. What this document is... ............................................................. 1
1.2. What this document is not... ........................................................ 1
2. Installation ........................................................................................ 2
2.1. Missing section title .................................................................. 2
3. The basic concepts .............................................................................. 3
3.1. A pure library ........................................................................... 3
3.2. Layers .................................................................................... 3
3.2.1. Decomposing the functionality of the application layer .................. 4
3.3. Configuration structures ............................................................. 4
3.4. Nodes ..................................................................................... 4
3.4.1. The data structure ................................................................... 4
3.4.2. Initializing the structure ........................................................... 5
3.4.3. The clock reference node ......................................................... 5
3.4.4. Dealing with functions returning pointers to structures ................... 5
3.5. Connections ............................................................................. 6
3.6. Timing .................................................................................... 7
3.7. Threading ................................................................................ 7
3.8. Error-detecting codes ................................................................. 7
3.8.1. Redundant hashes ................................................................... 7
3.8.2. Barriers ................................................................................ 8
4. The source files .................................................................................. 9
4.1. The header files to include .......................................................... 9
4.2. The header file to update ............................................................ 9
5. Typical usage ................................................................................... 10
5.1. Using the protocol layers (STL and SLL) ..................................... 10
5.1.1. Hardware initialization .......................................................... 10
5.1.2. Global Initialization .............................................................. 10
5.1.3. Node Definition ................................................................... 10
5.1.4. Synchronization ................................................................... 11
5.1.5. Connection creation .............................................................. 11
5.1.6. Wait for the connections to be established ................................. 11
5.1.7. Main loop ........................................................................... 12
5.1.8. Using the codecs .................................................................. 13
6. How to... ......................................................................................... 14
6.1. Use my own CRC function than the one provided with the library .... 14
6.2. Increase the size of the connection-specific incoming FIFO's ........... 14
6.3. Increase the size of the global outgoing FIFO's ............................. 14
iv
Chapter 1. Introduction
1.1. What this document is...
This document describes the FFFisCom library V1.0, its underlying concepts and important proper-
ties. It does:
• Explain the properties that are relevant for a developer who considers using the library: its rela-
tionship to threading, timing considerations, interfaces to hardware, etc.
• Explain the mapping between the subset 56, 57 and 58 concepts and their representation in the
library
• Provide a complete explanation of the protocol one must follow to use the library, the meaning
of the important parameters, and the sequence in which the various functions must be called.
• It is not a tutorial about the subset 56, 57 and 58. At least a basic knowledge of these standards
and their practical implications is assumed.
• It is not a tutorial about C either: the language, its constructs, their semantics and idiomatic uses
(such as header files, conditional compilation, etc.) are considered as prerequisite knowledge to
use this document proficiently.
• It is a user guide as opposed to a source navigation document: its aims is to explain how one can
use the library proficiently, not to provide a detailed description of the internals.
• It is not an exhaustive descriptive document on the API and its underlying data types, which are
better and more accurately explained in the documentation derived from the implementation, in
HTML form accessible from $INSTALLDIR/doc/html/index.html. Would this online
documentation contradict the current document in any way, the former is to consider more relev-
ant, as it is generated automatically from the source code, and hence, is to be considered a better
description of its actual behaviour.
1
Chapter 2. Installation
2.1. Missing section title
The library comes in the form of a single .tgz file, which must be expanded in an ad hoc directory. It
contains two subdirectories:
• doc contains the documentation, that is, this document and an html subdirectory which con-
tains the documentation generated automatically from the source code
2
Chapter 3. The basic concepts
3.1. A pure library
This library implements the UNISIG subsets 56, 57 and 58 (hereafter referred to as the standard) so
that a developer can write applications that communicate with other compliant equipements without
having to care for all the low-level technicalities described in the standards. The entire issue of com-
munication is addressed by a number of high-level functions only.
The library provides ultimate flexibility, by being self-contained. It does not call any standard lib-
rary function, and furthermore, it does not perform explicit calls to a timing function, nor to hard-
ware access functions to actually send and receive data on the ProfiBus.
• Read the hardware bus, by means of interrupt function, polling or any other mechanism suppor-
ted by his ProfiBus hardware and supporting computing platform, and provide the raw incoming
message(s) to the library
• Notify the library often enough to allow time-related functions (timeouts, idle messages, etc.) to
perform appropriately. Please note that this implies that the current time must be provided by the
user as parameter to a number of the functions of the public API.
• Query the library for any incoming message that has been identified as user-data
• Provide the library with application-level outgoing data that must be sent on the bus
• Send the outgoing telegrams on the ProfiBus hardware at hand when, as a result of one of the ac-
tions listed above, one or more outgoing telegrams must be sent.
3.2. Layers
The standard is divided in three layers:
The two former deal with the safe transmission of sequences of bytes; the latter with the representa-
tion of meaningful data out of such sequences of bytes.
The FFFisCom library supports all three layers, but without introducing excessive coupling: applica-
tion programmers can use it to send proprietary trafic on the SLL and STL without being restricted
to what the application layer allows.
More specifically, this means that even if it makes little sense in practice, it is perfectly poossible to
use the SLL and the STL to send information of a totally different nature from what the application
layer recognizes, and conversely, the application layer could be used to decode traffic that has been
sent through entirely different means.
Since these two parts of the library are entirely decoupled, the related deliverables will be decoupled
accordingly: test, documentation, etc.
3
The basic concepts
These layers are easy to track down in the code: every item related to the STL has a "STL",
"__STL__" or "Stl" prefix attached to it, every item attached to the SLL has a "SLL", "__SLL__" or
"Sll" prefix attached to it, and quite predictably, every item attached to the application layer has a
"APP", "__APP__" or "App" prefix attached to it.
It is intuitively clear that decoding involves a form of validation: of all the possible sequences of
bytes, of all lengths and contents, only a tiny fraction is valid for decoding.
What is less clear, is the fact that the application layer of this library will distinguish between two
forms of validity checks to be performed:
• It will first ensure that messages are structurally correct, in the sense that it can interpret the en-
tire sequence of bytes and explode it into messages, etc.
• It will then ensure that atomic - non-composite - values are valid, that is, they lie between the
corresponding validity bounds defined in the standard.
The two levels of validations are separate, implemented as separate functions, so that the decoding
process does not stop when an invalid value has been found, thereby allowing for more fine-grained
control on the process.
3.4. Nodes
3.4.1. The data structure
4
The basic concepts
This structure defines the equipment where the library runs, its behaviour in terms of the various de-
grees of liberty supported by the standard, and its internal state at all time. It must be given as para-
meter to virtually every function of the library, as the library is stateless; it contains no global in-
formation of its own.
The internal structure of a node is opaque: at no point should the application programmer access the
structure's internals directly 1. Access functions are provided instead.
Except for extreme cases, where a single process should communicate on two disjoint ProfiBus net-
works (not just a Dual bus), every process should hold only one instance of such node structure.
The Random_Number parameter is used to initialize the random number generator used by the lib-
rary. If you wish to have a strictly reproducible sequence of random number for simulation pur-
poses, you may just provide a constant value for this parameter. However, in production environ-
ments, it is probably more appropriate to provide a value which is more genuinely random, by
provide the time - or any time-derived value - as seed for the random number generator.
A FFFis network must contain a reference clock node, which is responsible for maintaining the ref-
erence time against which the others must measure. Drifts with regard to this reference time must be
measured, and threshold violations must induce appropriate action.
• The user should never even try to deallocate this return value
1 There is no formal way to ensure that the structure is never accessed directly, as C provide no such protection mechanism. However, since
the internals of the data strutures might change in non reverse compatible ways, any piece of code which refers to the data structure's field
directly might not compile with future versions of the library.
5
The basic concepts
• The content of this private field might change due to subsequent calls to library functions. Any
value which should be retained for long amounts of time should be copied elsewhere.
3.5. Connections
Connections are represented by id's only, which receive value when connections are open. Connec-
tions can be of two kinds:
• Point to point (P2P) where two actors send each other private informations the other devices do
not handle. When using a connection in this mode, each node has a different role:
• One node must act as master node and initiate the connection
• The other node must act as slave node and does very little, as it relies on the master node for
the initiation
• Multicast, where one sender node sends broadcast data to any receiver node caring to listen,
thereby defining two roles.
Separate functions are used to open a connection of each of these kinds, depending on the role of the
current node2:
Connection id's are not global entities: they are related to nodes. In other words, whenever a connec-
tion will have to be referred to, for instance when passing parameters to a function, both the node (in
the form of a pointer to a ESSL_Node_Struct) and the connection id must be specified.
• Disconnected. This is the initial state. The only operation valid in this state is to attempt to con-
nect
• Connecting. This is a transient state when a connection operation has been initiated, waiting for
the prologue to complete. The only operation that can be performed in this state is a disconnect.
• Connected. This is the state where all preconditions for the connection to function have been
met. One can receive data, send data or disconnect when in this state.
Some severe error conditions can cause the library to close the connection. One can then distinguish
between a connection which is diconnected because it has never been connected; and connection
which has been disconnected by an external condition by calling the:
const Sll_Disconnect_Context_Struct *
ESSL_Get_Disconnect_Context (
const ESSL_Node_Struct *const Node,
const ESSL_Connection_Id Connection_Id)
2 We shall refer to the current node as the node on which the library runs, described by the ESSL_Node_Struct* given as parameter to
these connection initiation function.
6
The basic concepts
function. If it returns NULL, the connection has never been opened. If it returns any non-NULL
value, the connection has been opened, and closed due to some condition detailed in the returned
Sll_Disconnect_Context_Struct
Similarly to what was described in Section 3.4.4, “Dealing with functions returning pointers to
structures”, the structure returned by the ESSL_Get_Disconnect_Context function is not al-
located on the heap, and must therefore not be deallocated explicitly.
3.6. Timing
The library has no internal clock, nor does it access an external clock behind the scenes. The only
source for timing information it will ever use is the Now parameter declared in most public functions
except for the application layer which only provides time-insensitive coding and decoding services.
The Now parameter is a 32-bit unsiged integer, representing the amount of miliseconds elapsed since
the start of the system using the library.
It is the user's responsibility to ensure that the time value given to the library is monotonous and ac-
curate. It is also the user's responsibility to ensure the library is called often enough to guarantee that
all time-related behaviour is correct (time outs, idle messages, etc.)
For instance, if an idle message must be sent at most every 500 milliseconds, the system is con-
figured to send it a bit faster for security, say, every 400 ms; the library must be called at least once
every 100 ms and preferably, twice as fast, to ensure that outgoing idle messages are not retained for
longer than acceptable.
3.7. Threading
The library is stateless in the sense that all the information it maintains across function calls is stored
in the node structure. Hence, multi-threaded accesses to separate nodes is perfectly safe. On the oth-
er hands, if various function calls related to the same node must be performed from different
threads, access must be protected to avoid reentrance.
The library does not provide any of such protection mechanism. It is the user's responsibility to pro-
tect access to a node's data structure using semaphores, critical sections, mutexes or any semantic-
ally equivalent protection mechanism.
These locks will only hold for very limited amounts of time, as the library performs no I/O nor
polling. Thereby, the time span between every function entry and exit is bounded.
In order to address this issue, the libray provides two optional facilities that can be enabled or dis-
abled by simple compilation directives, and which can be used depending on the criticalness of the
application at hand as well as the available computing power.
These two facilities are mutually exclusive, since computing hashes will detect undesired memory
overwrite more accurately than barriers would.
7
The basic concepts
idea is to detect a memory corruption as early as possible - as even a minor change would cause the
hash value to be invalidated, ensuring that the process would not continue in case of a memory cor-
ruption.
A similar scheme computes a hash on the node data structure stripped from the connections it con-
tains.
This option is of course fairly computationally intensive, since the connection data structures con-
tain FIFO's, and computing a hash, even a very simplistic one, requires that the entire data structure
is scanned on every function call that deals with the connection.
3.8.2. Barriers
Barriers are integer fields inserted at the beginning and at the end of every connection structure. For
the connection to be valid, the two barriers must be the negated values of each other. Every time a
function is called, the barriers are checked against this negation property. In case of failure, the lib-
rary is stopped, as it indicates that the data struture has been overwritten from neighbouring memory
areas.
Barriers do not protect the library from random alterations inside the connection data structures,
since only the extremities - the barriers - are actually checked for validity. However, they detect buf-
fer overruns that cause memory to be overwritten beyond its intended area.
8
Chapter 4. The source files
4.1. The header files to include
In an application module which must interact with the library, depending on the library is used, the
following files must be included:
• essl_api.h contains the prototypes for the functions required to create nodes and connec-
tions, to send and receive data on connections, etc. It is required by all application that use the
library's implementation of the STL and the SLL.
• essl_app.h contains the application-level codecs prototypes. If you wich to use the library
for the two lower layers only, using your own application messages rather than the standard sub-
set 58 messages, you do not need to include this file.
Including any of these header files will result in including other header files - including
essl_user.h, of course (see below) - but these two are basically all you need from an applica-
tion point of view.
Any alteration of any file of the library, other than essl_user.h and which is not endorsed ex-
plictly by ERTMS Solutions instantly voids any of our support obligations, would you have a ongo-
ing maintenance contract.
Please bear in mind that any change performed on this file will be lost whenever you install a new
version of the library, unless you carefully save it beforehand. You might consider saving it on a
version control system, as it is, in fact, one of your own source files rather than a component of the
library per se.
9
Chapter 5. Typical usage
This chapter lists the steps that your application program should follow in order to interact grace-
fully with the library. Please refer to the sample application example_master.c available in the
HTML documentation for a more detailed explanation, as this chapter and this sample application
are direct reflections of each other.
This chapter assumes that three utility functions are provided by the user:
• Initialize_Hardware performs any one-time initialization required for the ProfiBus hard-
ware at hand to work appropriately..
• Receive_From_Bus attempt to read an incoming telegram from the hardware, and returns
true to indicate that a telegram was read, false if no such telegram could be read.
must be the first function of the library to be called. It must be called once only.
At the time of this writing, this function does nothing, since the library is entirely stateless, and
maintains all the persistent information it needs in the node structures. However, it is to be con-
sidered good practice to still call this initialization function as the stateless property of the library
might change in future versions.
10
Typical usage
Please note that the Config parameter is passed by value, as its relevant content is copied into the
node data structure rather than referred to by a pointer.
5.1.4. Synchronization
Before starting the true mainloop where messages can be sent and received, one must first wait for
the node to be synchronized. This can be checked for by calling the
ESSL_Clock_Is_Synchronized function repeatedly until it returns true or until a time out
condition occurs. This function always returns true if the node was initialized as being the master
clock.
• Read any incoming message from the hardware bus and pass it to the node, by means of the
ESSL_Handle_Incoming_Telegram function.
• Update the node's internal state by calling the ESSL_Update_Node function. When it will
have received the appropriate synchronization messages, it will set its status to synchronized,
and exit the loop.
As shown in the example above, if opening the connection is successful, the corresponding connec-
tion id can be retrieved from the resulting status structure.
Please note that this connection creation is purely logical, the underlying hardware connection must
have been initialized previously as part of hardware initialization phase under the user's responsibil-
ity.
11
Typical usage
The actual message will only be sent when querying for any outgoing message to be sent on the
ProfiBus network.
Then, both if it the master and the slave of the connection, it must wait for the connection to be es-
tablished, by means of a loop which reads incoming messages from the hardware, update the node
and the connection, and send outgoing messages if necessary. When the appropriate messages will
have been exchanged, the connection's status will move to active automatically.
In the example above, sending data if available must be represented by a loop such as:
which flushes the output FIFO, and sends the telegrams it contains over the bus.
The following sections list the actions that must be followed within that loop.
5.1.7.5. Connect/disconnect/send/receive
Depending on whether the connection is a P2P or multicast one, depending on its status
(disconnected, connected or connecting), the user can perform several operations:
• Send messages if currently connected. The message will be enclosed in the appropriate envel-
12
Typical usage
oppe (status information, checksums, etc...) and stored in the node's outgoing FIFO. Check Sec-
tion 5.1.8, “Using the codecs” for more information on how to encode application-level data into
telegrams.
• Receive application messages, by polling every connection's incoming FIFO. In fact, these mes-
sages will have been received earlier (in the sense of being transmitted from the hardware),
when collecting incoming messages, but the receive operation as described here will only deal
with application messages, protocol messages (idle, synchronization, etc.) are thus not propag-
ated through the incoming FIFO's. Check Section 5.1.8, “Using the codecs” for more informa-
tion on how to encode application-level data into telegrams.
13
Chapter 6. How to...
6.1. Use my own CRC function than the one
provided with the library
This can be provided by redefining the ESSL_CALCULATE_CRC macro in essl_user.h to call
you own function rather than the default behaviour. This is the only header file in the library which
is meant to be altered directly by the user to tune the library's behaviour to environment-specific
constraints.
14