Preamble

This document and accompanying code copyright © 2017-2021 EMPHYSIS partners.
This document released under Attribution-ShareAlike 4.0 International.
XML-schema files, that accompany this specification document, are released under the 3-Clause BSD License.

.2. Release Notes

.2.1. Version 1.0.0-alpha.4

Disclaimer

This alpha release is a draft version of the eFMI standard (= Functional Mock.Up Interface for embedded systems). It is planned to standardize a potentially improved version by the Modelica Association.

.3. Abstract

The eFMI (FMI for embedded systems) standard specified in this document aims to extend the scope of FMI (https://fmi-standard.org) from simulation towards software development. The eFMI standard is intended as exchange format for workflows and tool chains from physical models to embedded software. It is defined as a layered approach built upon the FMI for Co-Simulation standard (any version). An eFMI component, that is an eFMU (Functional Mock-Up Unit for embedded systems), can be packed in different formats. Especially, an eFMU can be packed as FMU and can then be simulated with any FMI compliant tool (https://fmi-standard.org/tools) to perform Software-in-the-loop (SiL) testing. Code generation for an embedded device requires however dedicated tool support for eFMI.

This effort is motivated by the fact that especially the development of advanced control functions and diagnosis functions can benefit from physical models. As of today the realization of such model-based functions incorporating physical models, in the following refered to as physics-based functions, is very involved. The expertise from the physical modeling domains, control design and numerics for real time applications are required as well as implementation knowledge in terms of rules & regulations for embedded software have to be taken into account in order to supply an industry grade function on an embedded device.

The eFMI standard describes a container format that will allow to exchange models in a variety of different types of model representations:

InputOutputBlock
  • The Algorithm Code representation describes the mathematical model in a target and implementation independent fashion as input/output, sampled data block with one fixed or variable sample time using the standardized intermediate language GALEC (Guarded Algorithmic Language for Embedded Control) developed for this purpose. GALEC is based on a small subset of Modelica functions together with changes and extensions as needed for embbeded real-time systems. GALEC code can be scrambled to provide a certain degree of Intellectual Property protection. Physical modeling tools should be able to generate this representation with reasonable effort.

  • The Production Code representations allow to ship C or C++ code within the same container, either as nearly target-independent generic code and/or as highly optimized target specific code. Contrary to FMI, there is no standardized API (getX, setX, doStep, …​), but a description of the actual code interface to allow the code to be integrated into existing software architectures with minimal calling overhead. When an eFMI is packed as FMU, an FMU wrapper is added to a selected code representation. Software development tools should be able to provide the transformation from an Algorithm Code to one or more Production Code representations with reasonable effort.

  • The Binary Code representations provide target specific executable codes. These code representations naturally provide the best Intellectual Property protection.

  • The Behavioral Model representation provides references results for different scenarios to allow automatic tests of the Production and Binary Code representations. In the future this representation might be extended to include the original model from which the eFMI representations are derived, or computable scenarios might be added in form of FMUs.

By means of one global content XML description of all parts of an eFMU and by one XML manifest file for every eFMI representation shipped in an eFMU, a highly flexible and extensible mechanism is provided that allow to integrate eFMUs into arbitrary software architectures being deployed to any kinds of execution environment, including for example AUTOSAR or adaptive AUTOSAR.

.4. Overview

This document specifies the eFMI (FMI for embedded systems standard) with references to the FMI (Functional Mock-Up Interface) standard (https://fmi-standard.org/)

In section Section .5 the development of the eFMI standard and its intended usage is motivated.

The technical key concepts with reference to the current FMI standard are explained in section Chapter 1 for the better understanding of the later sections.

Thereafter the eFMI standard is specified starting with the description of the overall container structure of an eFMU (Functional Mock-Up Unit for embedded systems) in section Chapter 2.

The following sections Chapter 3, Chapter 4, Chapter 5, Chapter 6 are dedicated to the different types of model representations supported by eFMI. Each description consists of an introductory section followed by the specifications of the corresponding meta data and language:

  • The Behavioral Model representation provides reference results to allow automatic verification of the Production and Binary Code representations.

  • The Algorithm Code representation describes the mathematical model of discrete-time, sampled data, input/output blocks in a target and implementation independent fashion with the standardized intermediate language GALEC (Guarded Algorithmic Language for Embedded Control - a small subset of the Modelica language (https://www.modelica.org/modelicalanguage) with extensions as needed for embbeded systems).

  • The Production Code representation defines one or more mappings of an Algorithm Code representation to C or C++ Code (for example 32-bit and/or 64-bit representation of floating point numbers, generic ANSI C-Code and/or code specialized to a particular target environment like AUTOSAR and/or specific target processors).

  • The Binary Code representation provides one or more target specific executable codes for one production code representation.

In the following image an overview of the eFMI representations is given, together with examples for potential tool chains:

efmi representations

This standard document is accompanied by the following open source codes and files to allow tools to more easily support the eFMI standard:

  • XML schema files for all xml manifest files defined in this document.

  • An eFMI compliance checker in form of a Python library, to check compliance of eFMUs (Functional Mock-Up Units for embedded systems) with this specification.

  • The eFMI_TestCases Modelica package providing > 20 dedicated Modelica models and variants of them to test eFMI tool chains.

  • The eFMI Modelica package providing all eFMI builtin-functions as Modelica functions with a Modelica implementation, in order that Modelica models can use these functions.

  • ReferenceResults for the models of the eFMI_TestCases library in form of > 50 csv files.

  • eFMUs for the eFMI_TestCases library generated with various tools.

.5. Introduction

The goal of the eFMI standard (FMI for embedded Systems) is to enhance Production Code of embedded control systems by physics-based models in an automated way. This shall improve the performance of the underlying systems, reduce the maintenance costs and increase the productivity of software development for embedded systems.

Embedded software is commonly used on ECUs (Electronic Control Units) to control or monitor a system. In these cases it is beneficial to incorporate knowledge of the system behavior into the function. Physical models aim to describe the behaviour of the system for a given range of operation. These models are well described by differential- and algebraic equations or can be approximated by projection on a neural network.

Physical models can be utilized to achieve a significantly better performance of the system in applications such as:

  • observers/virtual sensors (e.g. extended and unscented Kalman filters, moving horizon estimation),

  • model-based diagnosis (e.g. signal based fault detectors, linear/nonlinear residual generators),

  • feedback and feedforward controllers (e.g. linear controllers with gain scheduling, nonlinear inverse models, nonlinear dynamic inversion, feedback linearization, linear/nonlinear model-predictive control),

  • neural networks to approximate physical models and/or the above applications.

These types of functions are typically hand-coded software implemented and tested in an elaborate and time-consuming fashion. The eFMI standard aims to provide model exchange capabilities that allow to transfer physical models created in dedicated modeling and simulation tools to embedded code generating tools for ECU software. This enables an end to end workflow from physical modeling to the deployment of the software function on an embedded device.

The eFMI standard is an open standard based on the FMI standard (Functional Mock-Up Interface, https://fmi-standard.org/). eFMI components are able to interoperate with software components according to the automotive embedded system standards AUTOSAR (https://www.autosar.org/standards/classic-platform/) and Adaptive AUTOSAR (https://www.autosar.org/standards/adaptive-platform/). Generated code shall refer to typical safety measures and coding guidelines, e.g. in the Automotive industry the ISO 26262 and MISRA-C 2012 for Autocode (https://www.misra.org.uk/Activities/MISRAAutocode/tabid/72/Default.aspx).

Different types of model representation shall allow to separate the concerns of deriving a proper computation algorithm and its compliant implementation for an embedded device. The container architecture and rich meta information, extending the FMI model description, support the integration in existing development processes and tool chains.

1. General concepts

This section describes the general concepts of the eFMI standard

The goal of the standard is to extend the existing FMI standard to the embedded domain. The FMI standard is focused on simulation of models and model parts, on few standardized execution platforms (Windows, Linux) with well known tool chains. With this context in mind, the FMI standard does not consider any constraints with respect to resource consumption or run time characteristics of the model.

In contrast there is a considerable diversity of embedded platforms, each with their own constraints with respect to runtime performance, memory limits or available compiler support. Given these additional constraints the goal of the FMI standard "Compile once, run everywhere" is neither feasible nor desirable.

A further aspect is the use of models not only for the sake of simulation but in a broad application range, from advanced control strategies like model predictive control to model based diagnosis. The eFMI standard must consider these aspects and is therefore designed as an extension to the FMI standard as described in the following.

1.1. Comparing FMI with eFMI

A major enhancement of the eFMI standard in comparison to the FMI standard is the introduction of different abstraction levels. The FMI standard is based on an executable C Code with an interface of fixed and well defined functions (like getX, setX and doStep). This approach is well suited for the purpose of simulation on a standardized platform (either Windows or Linux).

However, such an approach is not very suitable for (deeply) embedded code due to the following reasons:

  • Support of a diverse number of execution targets.

  • Support of a diverse number of compilers.

  • Integration of the code into existing code structures (in the following we will call this the "Software context") with minimum overhead in data passing and function calling.

For this reason one fixed C Code (or one fixed executable) representing the implementation is not sufficient. Instead the eFMI supports the concept of several C Code implementations (or also binary implementations), each with a description of the interface of the C Code. These descriptions are defined in so-called manifest files and are bundled with the corresponding code files into a Production code container. More details on these manifest files can be found in the section on Production Code manifests (Section 5.2). Here you will also find examples demonstrating the influence of the software context onto the generated code and manifest descriptions.

An FMU represents exactly one model (implemented by the C Code or executable). The same shall be true also for an eFMU despite of the fact that it may contain any number of C Code implementations, and additionally, it shall be easily possible to add further implementations (e.g. for different targets or software contexts) into the eFMU at any time.

This requirement is enabled by adding a higher level abstraction to the eFMU, namely the "Algorithm Code".

The Algorithm Code contains an abstracted description of the function(s) to be computed, and serves as the input to generate the C Code implementations. The functions are described in a pseudo programming language (influenced by Modelica functions), and the meta data is also given in a manifest file. The Algorithm Code is a solution to a causalization of this system by specifying

  • Causalization: the input/output behaviour of the system.

  • Discretization: discretization of differential equations (use of solver, time discretization).

The Algorithm Code is organized in code containers in the eFMU, similar to the Production Code container. For more details on the organization of these containers to form a valid eFMU, please see the section on container architecture (Chapter 2).

The following table summarizes the differences between FMI and eFMI.

Topic

FMI

eFMI

Goal

(co-) simulation

efficient ECU implementation

Execution platform

standardized (Windows (.dll), Linux)

diverse: different ECUs, different compilers

Reuse

"as is" in "all" simulation environments

highly limited (therefore several implementations possible)

Interface

fixed based on standardized API (getX, setX, doStep, …​)

not fixed, but description of the actual interface

Implementation

one implementation (one source code, one binary)

any number of implementations (target, vendor and "architecture" dependent)

Abstraction level

C Code level

Abstract model representation algorithm (Algorithm Code) in addition to (derived) C Code implementation (Production Code)

1.2. FMI compliance

An important fact is that despite the broadened scope of the eFMI, an eFMU can be packed into an FMU. This is achieved by taking a distinguished Production Code level implementation and wrapping this to an FMI compliant interface with corresponding model description file. Surely this Production Code level implementation must be target independent and suitable for simulation targets like Windows or Linux.

1.3. Functions in eFMI

In the following different kinds of functions considered in the eFMI standard are described. It is mentioned for which model representation a certain function kind is available. Differences between the kind of functions and consequences and requirements for e.g. transformation tools are also covered.

1.3.1. Block methods

(Available in Algorithm Code and Production Code model representation)

The Algorithm and Production Code model representation is mathematically defined as a sampled input/output block with one (potentially varying) sample period for the whole block. All variables of the block have a defined type and all statements of the block are sorted and explicitely solved for a particular variable. Three block methods are defined, so functions that operate on the same memory self that is exchanged between the function calls. Especially, methods are provided to initialize the self memory with function Startup and to perform one step at the actual sample instant with method DoStep.

The block methods are defined in the Algorithm Code representation. A Production Code generator translates these methods to C-functions. It is also possible to define Production Code interface functions directly in C, without providing an Algorithm Code representation.

On Production Code level the block methods are highly integrated in the environment provided by the embedded control unit (ECU). For example, if the ECU provides input signals at certain addresses in memory or the parameters are part of an overall global C-struct. Consequently the actual implementation/interface of the methods is at liberty of the Production Code generating tool.

1.3.2. Built-in functions

(Available in Algorithm Code and Production Code model representation)

Built-in functions are functions with well defined syntax and semantics in the eFMI standard. This includes elementary functions such as sin, cos, log, exp, but also functions to solve linear equation systems in various ways, for example

  x := solveLinearEquations(A, b);

to solve the linear equation system A*x = b with regular A matrix for x.

Built-in functions can be used in Algorithm Code or Production Code. All built-in functions that are supported by the eFMI standard are defined in Section 4.2.6. The names of the built-in functions are reserved and must not be declared by the user.

A tool that transforms Algorithm Code into Production Code doesn’t need additional information for those functions, because their syntax and semantics are clearly defined thus the tool knows how to handle it.

1.3.3. Local functions

(Available at Algorithm Code and Production Code level)

In Algorithm Code, local functions can be defined together with the physics-based model that underlies the eFMU. A local function is formally defined with the GALEC language, see section [GALEC Language]. A Production Code generator generates a C-function from this definition. Alternatively, a local function can be provided as C Code, together with a GALEC wrapper that defines how the call of the GALEC function is mapped to C (the syntax and semantics is identical to the Modelica external function interface). The declaration of the logical function interface must be provided in the corresponding manifest file.

Example of a local function implemented with the GALEC language:

function add
  input  Real u1;
  input  Real u2;
  output Real y;
algorithm
  y := u1 + u2;
end add

Example of a local function wrapper with the GALEC language around a C-function:

// GALEC function wrapper
function dot  // scalar product
  input  Real v1[:];
  input  Real v2[size(v1,1)];
  output Real y;
  external "C" y = dot(size(v1,1), v1, v2)
end dot

// C Code signature
float_t dot(const int32_t n, float_t const v1[], float_t const v2[]);

2. eFMU container architecture

An eFMU can be packed in different formats. The basic structure of the eFMU specific part is always:

<eFMU root directory>  // depends on the package format
    // Directories for eFMU model representations (tool specific)
    schemas            // directory with the used eFMI schemas
    __content.xml      // defines the eFMU folder structure

The only required names are the file name __content.xml and the directory name schemas at the root of the eFMU folder. All other directory and file names are defined by the eFMU generation tool. The used directory and file names are stored in the __content.xml file and can therefore be deduced by reading this file.

The following eFMU package formats are defined:

  1. The <eFMU root directory> is a standard directory in the file system.
    [This is useful to hold an eFMU in a text-based version control system, such as github, gitlab or svn.]

  2. The <eFMU root directory> of (1) is zipped with the efmu-content, especially __content.xml, at the root of the zip-file. The zip-file has the extension .efmu.
    [This packaging is useful to ship or distribute an eFMU.]

  3. The <eFMU root directory> of (1) is path extra/org.efmi-standard inside a standard FMU (Functional Mock-Up Unit) of any FMU type and any FMU version. The path is defined according to the FMI 3.0 specification. With attribute activeFMU inside the __content.xml file it is defined which of the Algorithm, Production or Binary code representations is used as basis of the FMU.
    [This package format is useful to ship or distribute an eFMU for Software-in-the-Loop simulation with any suitable FMU tool.]

Note, Algorithm Code, Production Code and Binary Code representations can optionally store associated FMUs. For example Algorithm Code can store a Model-in-the-Loop FMU and Production Code can store one or more Software-in-the-Loop FMUs for different targets. In order to execute these FMUs directly, an eFMI tool is needed. Otherwise, one of the stored FMUs can be selected for package format (3) in order that any FMI-tool can simulate this specific FMU.

Example:

An eFMU could be stored as zip-file with extension .fmu having the following internal structure:

modelDescription.xml      // required FMI file
// optional FMI directories and files
extra                     // extra directoy of FMI 2.0 and 3.0
    org.efmi-standard     // eFMU root directory
        // tool specific directories, e.g. AlgorithmCode
        schemas           // directory with the used eFMI schemas
        __content.xml     // defines the eFMU folder structure

An eFMU may contain any number of additional subfolders below the <eFMU root directory> with one subfolder for each model representation. An eFMU container can contain only one Behavioral Model Representation, one Algorithm Code Model Representation, but can contain multiple Production Code Model Representations and also multiple Binary Code Model Representations. Each Model Representation itself can be organized in subfolders. It must have a dedicated manifest file. Other files describing the model representation such as code, an FMU, documentation, or license files may be organized in this subfolder.

The following diagram sketches the eFMU containers visually (details are given in the next sub-section):

efmi container architecture

2.1. Content description (efmiContainerManifest.xsd)

The __content.xml file is the registry for all model representations in the eFMU container. It has the following schema definition:

ContainerManifest
Name Description

xsdVersion

Version of the __content.xml schema file in semantic version number format (https://semver.org).

activeFMU

Value of name attribute of model representation whose FMU is currently unpacked in the root directory of the FMU. If no FMU is unpacked currently, the value of this attribute must not be set.

efmiManifestAttributesBase

A group of attributes that is identical for all manifest files. For details see [ManifestAttributesBase].

Each model representation that is a part in the eFMU container must have a corresponding entry in the __content.xml file with the following information:

ModelRepresentation
Name Description

name

Unique name of the container, also defining its root directory name.

kind

The type of the model representation. The allowed values are AlgorithmCode, ProductionCode, BinaryCode, BehavioralModel.

manifest

Name of the container’s manifest file. The manifest is located in the container’s root directory, cf. "name" attribute.

checksum*

SHA-1 checksum of the binary content of the manifest file. A checksum of the whole subfolder is not required, because the files belonging to a model representation and their checksums are listed in the manifest file itself.

manifestRefId

The unique GUID of the manifest file (= corresponding attribute of ManifestReference). References a manifest using the Manifest elements id attribute. This information has been added for technical purposes only to speedup resolving references between manifest files via the manifestRefId outlined below. Otherwise, following an inter-manifest reference (via a manifestRefId used in the source manifest) would demand to read other manifest files until a manifest with the desired id is found).

The following is an example of such a content file:

<?xml version="1.1" encoding="utf-8"?>
<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="schemas/efmiContainerManifest.xsd"
         xsdVersion ="0.9.0"
         efmiVersion="1.0.0"
         id         ="{92b7edbe-e77d-419a-8457-bf8d452a98f6}"
         name       ="MyModel"
         generationDateAndTime="2021-02-27T15:43:25Z"
>
	<ModelRepresentation kind         ="ProductionCode"
                         name         ="TLGeneratedCode_v1"
                         manifest     ="mark.xml"
                         checksum     ="e29810938a2a535dc8f6f9b8f51c5febe834ee01"
                         manifestRefId="63f8c810-f008-47f0-a4b6-7a243f83e46b" />
	<ModelRepresentation kind         ="AlgorithmCode"
                         name         ="algoCode_v1"
                         manifest     ="luke.xml"
                         checksum     ="e29810938a2a535dc8f6f9b8f51c5febe834ee05"
                         manifestRefId="63f8c810-f008-47f0-a4b6-7a243f85e46b" />
	<ModelRepresentation kind         ="BinaryCode"
                         name         ="binCode_v1"
                         manifest     ="matthew.xml"
                         checksum     ="e29810938a2a535dc8f6f9b8f51c5febe834ee08>"
                         manifestRefId="63f8c810-f008-47f0-a4b6-7a243f85e47b" />
</content>

This __content.xml file describes therefore the following directory structure:

<eFMU root directory>
    TLGeneratedCode_v1
        mark.xml
    algoCode_v1
        luke.xml
    binCode_v1
        matthew.xml
    schemas               // directory with the used eFMI schemas
    __content.xml         // the xml-file of the example above

This example just demonstrates that the folder names of the model representations and the manifest file names are defined by the generating tool. Typically, more descriptive names would be used, such as:

<eFMU root directory>
    BehavioralModel
        manifest.xml
    AlgorithmCode
        manifest.xml
    ProductionCode_Generic_C_Float32
        manifest.xml
    ProductionCode_Generic_C_Float64
        manifest.xml
    ProductionCode_Autosar_Float32
        manifest.xml
    schemas
    __content.xml

2.2. Structure of Model Representations

Each model representation can have its own flexible structure. Its content and the structuring of information is described in the manifest file (for details on specific manifest files for the different kind of model representations refer to the corresponding sections). Which file in a model representation is its manifest file can be found as the reference entry in the __content.xml file. The manifest file must be located in the model representation’s root folder.

eFMI allows for having model representations consisting of a manifest file only, hence information should not be doubled. For example, a tool generating directly a Production Code Model Representation must also generate an Algorithm Code Model Representation, because information relevant for Algorithm Code is stored only in the corresponding manifest file and not in the Production Code manifest.

2.3. Model Representation Manifests

The model representation manifests share the same guiding principles:

  1. Entity names start with a capital letter

  2. Attribute names start with a lower-case letter and use camelCase where needed.

  3. Entities that serve as a group get the name of the grouped entities and an 's' as postfix.

  4. Each entity that should be referred to has an attribute called id.

  5. The type of an id attribute is an arbitrary string.

  6. All id attribute values in a manifest file are unique.

  7. References to other elements within or across manifest are established through attributes ending with "RefId". The value is the id of the referenced element.

  8. For file references a string attribute is used and the value is interpreted as the relative path starting at the corresponding model representations root folder.

  9. The context of a reference is specified in the definition of the manifest element and could be either within the same manifest (local context) or within the a referenced manifest (foreign context).

All manifests also share the principles outlined in the following sections:

2.3.1. Attributes of manifest files (efmiManifestAttributes.xsd)

The top-level element of a manifest file has the two attributes xsdVersion and kind that have a fixed value that is specific to the corresponding manifest file. For example, these two attributes are defined for the AlgorithmCode manifest file in the following way:

ManifestAttributesFixedValues

The attributes have the following meaning:

AName Description

xsdVersion

The version of this manifest schema file in semantic version number format (https://semver.org).

kind

The type of this manifest file. The allowed values are
AlgorithmCode, ProductionCode, BinaryCode, BehavioralModel.

Additionally, the top-level element of a manifest file has the following attributes (that are not specific to the manifest kind):

ManifestAttributesBase

The attributes have the following meaning:

Name Description

efmiVersion

The version of the efmi Standard in semantic version number format (https://semver.org) (currently: "0.7.0").

id

The UUID for this manifest file.

name

The name of the block (controller, diagnosis system etc.) as used in the modeling environment from which the manifest file was created, such as "Modelica.Mechanics.Rotational.Examples.CoupledClutches".

description

Optional string with a brief description of the block.

version

Optional version number of the block as used in the modeling environment from which the manifest file was created. [Example: "1.0"].

generationDateAndTime

Date and time of the last modification of the manifest file. The format is a subset of "xs:dateTime" and should be: "YYYY-MM-DDThh:mm:ssZ" (with one "T" between date and time; "Z" characterizes the Zulu time zone, in other words, Greenwich meantime).
[Example: "2009-12-08T14:33:22Z"].

generationTool

Optional name of the tool that created the manifest file. If the files have been created manually use generationTool="manual".

copyright

Optional information on the intellectual property copyright for the manifest and code files.
[Example: copyright = "© My Company 2020"].

license

Optional information on the intellectual property licensing for the manifest and code files.
[Example: license = "BSD license <license text or link to license>" or "Proprietary" or "Public Domain"].

Note, optional attributes defined in the __content.xml file, hold also for the manifest files in folders below this file, if not redefined in a manifest file. For example, if attribute license is defined in the __content.xml, but in no other manifest file of this eFMU, then the defined license holds for all directories and files below the <eFMU root directory>. If, say, a Production Code manifest defines a license attribute, then this license holds for all directories and folders in this Production Code model representation, independently what is defined in the __content.xml file.

2.3.2. Listing of relevant other manifest files (efmiManifestReferences.xsd)

The information about the eFMU is layered into several model representations (e.g. Algorithm Code, Production Code). In order to allow cross referencing between these model representations, the manifest files to be referenced need to be registered in a manifest file of a certain model representation. For this the ManifestReference tag is used with the following attributes

ManifestReference
Name Description

id

Unique id of the manifest reference entry. This id is used to establish cross manifest references.

manifestRefId

The unique GUID of the manifest. [Note, the name of the associated model representation in the __content.xml file is not used, in order to decouple the manifest files from the container manifest.]

checksum

The checksum of the referenced manifest file.

origin

Boolean flag to indicate if that referenced model representation is the one that was used to derive the current model representation.

Example:

<ManifestReferences>
  <ManifestReference id           ="ID_1"
                     manifestRefId="{63f8c810-f008-47f0-a4b6-7a243f85e46b}"
                     checksum     ="e29810938a2a535dc8f6f9b8f51c5febe834ee05"
                     origin       = true />
  <ManifestReference id           ="ID_2"
                     manifestRefId="{63f8c810-f008-47f0-a4b1-7a243f85222b}"
                     checksum     ="b4b84af148e587b95300d7a734302d1b911a6e58"
                     origin       =false />
</ManifestReferences>

2.3.3. Listing of files belonging to the model representation (efmiFiles.xsd)

Each manifest contains a list of the files that are part of its model representation. These files are listed in a manifest as follows in the Files elements tag.

FileList

A File element has the following attributes:

Name Description

id

id of the file reference entry. This is id is used to refer to the file reference within the manifests.

name

Name of the file

path

Directory part of path to the file (relative to root of model representation). Value has to start with ./ and end with /.

needsChecksum

boolean flag indicating that the file is considered in the checksum calculation (default value "true")

checksum

The checksum of the file.

role

The role of the file in the model representation. This attribute is an enumeration with the following valid values:

- "Code": File containing code (Algorithm Code, Production Code or Binary Code).

- "Manifest": The manifest file itself.

- "FMU": One and only zip-file that is an FMU-container. Any version and any representation of an FMU can be used (for example FMI for ModelExchange, or FMI for CoSimulation, or FMU with a DLL, or an FMU with C-Code). This representation is useful to directly utilize the FMU in any FMI-compliant tool.

- "FMUFolder": The content of an FMU (so the files after unzipping an FMU). Any version and any representation of an FMU can be used. This representation is useful when an eFMU is stored in a version control system, such as github, gitlab or svn.

- "ReferenceData": File containing reference data (for example a csv file that stores reference values of variables).

- "other": All other files (for example an AUTOSAR description file *.arxml). Note, a description of the file can be stored in attribute description.

NOTE: The enumeration values have been selected such that each value may be used on an arbitrary level of abstraction, that is kind of model representation. In the future, more enumeration values might be added.

description

An optional description of the file (especially if role = \"other\").

ForeignFile

See below.

Example of a list of files:

<Files>
    <File id="ID_1" name         ="model.c"
                    path         ="./code/"
                    needsChecksum="true"
                    checksum     ="b4b84af148e587b95300d7a734302d1b912a6e58"
                    role         ="Code"/>
    <File id="ID_2" name         ="model.h"
                    path         ="./code/"
                    needsChecksum="true"
                    checksum     ="b4b84af148e587b95300d7a734402d1b911a6e58"
                    role         ="Code"/>
    <File id="ID_3" name         ="misra.doc"
                    path         ="./code/"
                    needsChecksum="true"
                    checksum     ="b4b84af148e587b95300d7a734302d1b914a6e58"
                    role         ="other"/>
    <File id="ID_4" name         ="model.arxml"
                    path         ="./code/"
                    needsChecksum="true"
                    checksum     ="b4b84af148e587b95300d7a734302d1b911a7e58"
                    role         ="other"/>
    <File id="ID_5" name         ="model.doc"
                    path         ="./description/"
                    needsChecksum="false"
                    role         ="other"/>
</Files>

2.3.4. Referencing

Referencing inside a model representation

Reference attributes pointing to entities in the same manifest must fulfill the naming convention that the attribute name consists of the original entity name and adding "RefId" as postfix. The value of the reference attribute must thereby be a valid id in the given context of the reference attribute, meaning that the id must exist in the context and be of the right type. For example a value of reference attribute variableRefId is an id number in the same manifest referencing a variable. In the Production Code Model Representation manifest file shown below, the DataReference with ID_100 references the variable T with ID_33 using the attribute variableRefId.

Referencing files

Files play a certain role in the eFMU model representation and are listed in a Files element of each manifest. Referencing files inside a model representation is done by using a FileReference element that comes along with Files and File element itself and not using a fileRefId attribute only. The reason to use a certain FileReference element is that the element comes along with a kind attribute of type string to allow for specifying the kind of a file in more detail.

FileReference
Name Description

fileRefId

Reference to the id in the file overview

kind

Attribute for a more detailed specification of the kind of file used. The list of allowed values is not predescribed but should follow the guideline ????

<CodeFile id="ID_13" fileType="ProductionCode">
    <FileReference fileRefId="ID_1" kind="SourceCode"/>
</CodeFile>

Note, that a FileReference attribute has no id attribute and therefore can’t be referenced. This prevents transitive file referencing.

Referencing into other model representation - ForeignReference (efmiManifestReferences.xsd)

The eFMU describes one model on different levels of abstraction. Thereby the level of abstraction decreases in the following order

  1. Behavioral Model

  2. Algorithm Code

  3. Production Code

  4. Binary Code

ForeignReference

In order to establish cross referencing between these model representations, the "derived" model representation must include a ManifestReference to that model representation as described above. The consistency to the referenced one is ensured as follows:

The manifestRefId is used to retrieve the (current) model representation checksum of the entry in the __content.xml file. This (current) checksum can be compared with the (stored) checksum that is part of the ManifestReference and is the checksum at the point of creation of that container. Through comparison of both consistency can be ensured.

In order to cross reference into a referenced container’s manifest, a ForeignReference element is present that has the following required two attributes:

Name Description

manifestReferenceRefId

The (manifest local) id of a ManifestReference.

foreignRefId

The id inside the referenced manifest file.

Example:

<ManifestReferences>
    <ManifestReference id           ="ID_1"
                       manifestRefId="{63f8c810-f008-47f0-a4b6-7a243f85e46b}"
                       checksum     ="e29810938a2a535dc8f6f9b8f51c5febe835ee05"
                       origin       ="true"/>
    ...
</ManifestReference>
 ...
        <Variable name        ="T"
                  id          ="ID_33"
                  typeDefRefId="ID_25"
                  pointer     ="false"
                  value       ="0.1"
                  const       ="false"
                  volatile    ="true"
                  static      ="false" />
        <Variable name        ="_Clocks_interval"
                  id          ="ID_34"
                  typeDefRefId="ID_25"
                  pointer     ="false"
                  value       ="0.005"
                  const       ="false"
                  volatile    ="true"
                  static      ="false" />
        <Variable name        ="gearRatio"
                  id          ="ID_35"
                  typeDefRefId="ID_25"
                  pointer     ="false"
                  value       ="105"
                  const       ="false"
                  volatile    ="true"
                  static      ="false" />
    ...
        <DataReferences>
            <DataReference id="ID_100" variableRefId="ID_33" >
                <ForeignVariableReference manifestReferenceRefId="ID_1" foreignRefId="ALG_ID_101"/>
            </DataReference>
            <DataReference id="ID_101" variableRefId="ID_34" >
                <ForeignVariableReference manifestReferenceRefId="ID_1" foreignRefId="ALG_ID_100"/>
            </DataReference>
            <DataReference id="ID_102" variableRefId="ID_35" >
                <ForeignVariableReference manifestReferenceRefId="ID_1" foreignRefId="ALG_ID_103"/>
            </DataReference>
	...

In the example above (a cut-out of a Production Code Model Representation manifest file), the manifestReferenceRefId attribute (with value "ID_1") identifies the ManifestReference as the one that references the Algorithm Code Model Representation with the Manifest id "63f8c810-f008-47f0-a4b6-7a243f85e46b" in the eFMU container and the foreignVariableRefId attribute the element in that container with the given id (e.g. "ALG_ID_102").

It has to be checked, that the referenced ids actually are valid and are used for the objects of the right type.

Important restriction: The names of a variable can differ in the manifests of the Behavioral Model, the Algorithm Code, and the Production Code. But for input and output variables of the eFMI block, that are defined in the Algorithm Code manifest, the structure (e.g. scalar or vector or matrix) has to be preserved over the different model representations. It means, an output vector y in the Algorithm Code manifest corresponds to a vector with the same length in all other model representations.

Referencing Files in Foreign Model Representations (efmiFiles.xsd)

In cases where a file in another model representation is used without change in the current model representation, one should use ForeignFile elements in the Files list.

ForeignFile
Name Description

id

The (manifest local) id.

ForeignReference

Identifying the foreign manifest and the file inside the manifest.

Example:

<ManifestReferences>
    <ManifestReference id="ID_0" manifestRefId="{63f8c810-f008-47f0-a4b6-7a243f85e46b}" checksum="???" origin="true"/>
    ...
</ManifestReference>
 ...
<Files>
    <File id="ID_1" name="model.c" path="./code"
          needsChecksum="true" checksum="e29810938a2a535dc8f6f9b8f51c5febe835ee05" role="Code"/>
    <File id="ID_2" name="model.h" path="./code"
          needsChecksum="true" checksum="e29810938a2a535dc8f6f9b8f51c6febe835ee05" role="Code"/>
    <File id="ID_3" name="misra.doc" path="./code"
          needsChecksum="true" checksum="e29810938a2a535dc8f6f9b8f51c5febe835ee06" role="other"/>
    <File id="ID_4" name="model.arxml" path="./code"
          needsChecksum="true" checksum="e29810938a2a535dc8f6f9b8f51c5febe835ee08" role="other"/>
    <File id="ID_5" name="model.doc" path="./description"
          needsChecksum="false" role="other"/>
    <ForeignFile id="ID_6">
        <ForeignFileReference manifestReferenceRefId="ID_0"
                              foreignRefId          ="ID_26" />
    </ForeignFile>
</Files>
Annotations (efmiAnnotation.xsd)

Additional data that a vendor might want to store and that other vendors might ignore are defined with element Annotations (this definition is identical to the corresponding element of FMI 3.0):

Annotations
Name Description

type

Domain name in reverse domain notation of the tool that can interpret the annotation. Must be unique with respect to all other elements of the Annotation list. Domain names under both the "org.modelica" and "org.efmi-standard" domains are reserved for future eFMI versions.

2.3.5. Checksum calculation

The checksum is the mean to ensure integrity across different containers in an eFMU. These different container relate to each other and may be changed independent of each other. In order to ensure / check the integrity, with each change of a container, its checksum is updated in the reference entry in the __content.xml file.

For containers, that reference information from other containers or depend on them, also the checksum of these referenced containers is locally stored in that manifest. The comparison of these checksums is now an appropriate mean to check the consistency within the eFMU.

The calculation of checksums is done on the files that are listed in the manifest of the container (for which the checksum attribute has the value "true") and the checksum is stored in the checksum attribute of the corresponding "File" list entry of the "Files" elememt of each manifest file. The calculation for each file is based on a hash algorithm, currently SHA1 [SHA1Wiki] (https://en.wikipedia.org/wiki/Secure_Hash_Algorithms).

The overall checksum of a model representation is the checksum of the manifest file, where all checksums of files of the model representation has been stored. Since the paths of the files are part of the manifest file itself it is ensured that a change of names, structure or content of the concerned files will result in a different checksum and allows for detecting changes, e.g. a model representation has been changed in the container, but has been taken as input for transformation tools before.

On the other hand, changes to "unchecksummed" files (e.g. description files) will not affect the checksum as well as adding of files not listed in the manifest (listing in the manifest would also alter the checksum).

2.3.6. FMU File References

An eFMU container must be downward-compatible to an FMU container. Hence, it may have an FMU which is stored in the root directory of the container (above the "eFMU" directory). Such FMU needs to be associated with a certain model representation located in the eFMU container. In general, each model representation may have an optional FMU, especially a Production Code model representation.

The currently activated FMU needs to be specified in the __content.xml file by using the optional attribute activeFmu. If it is set, its value must correspond to the name of the associated model representation. If no FMU is unpacked currently, the value of this attribute must not be set.

The optional FMU of a model representation is specified within the manifest file of the model representation, where one and only one file in the list of files has the role attribute set to FMU. Its value must be a relative path inside the model representation to the FMU file.

When the FMU of a model representation M is activated, the following steps are performed:

  1. All files in the container’s root except the "eFMU" directory are removed.

  2. The FMU file referenced by M is unzipped to the container’s root.

  3. The value of the attribute activeFmu is set to the name of the model representation M.


3. Behavioral Model Representation

3.1. Introduction

The optional Behavioral Model representation provides reference results for different scenarios to allow automatic verification of the Production and Binary Code representations. The reference results are stored in csv format under the Behavioral Model folder (for details see section Section 3.3). In the future this representation might be extended to include the original model from which the eFMI representations are derived, or computable scenarios might be added in form of FMUs.

Basically, one reference result set consists of a table, where the columns represent the time and variables of the original source model (for example a AMEsim, Modelica, or syq model). Typically, these are the input and output variables of the Algorithm Code representation and the data is produced by simulating the original source model and storing the result in csv file format. Hereby, it is assumed that the simulations use the default values of the tunable parameters and the initial values of the states as defined in the Startup() method of the Algorithm Code model representation.

Automatic testing of a Production Code or Binary Code representation requires the following steps:

  1. The Algorithm Code variable ids of the input/output variables in the Production Code manifest need to be determined (note, the C variable names of the variables are usually different to the variables names in the Algorithm Code). Therefore an indirect link between the variables in the Production Code manifest and the Behavioral Model manifest is established. With additional information in the Behavioral Model manifest the expected reference results for the input/output variables of the Production Code can be deduced from the corresponding csv-files inside the Behavioral Model folder.

  2. The units of the variables are defined in the Algorithm Code manifest file.

  3. The results produced by executing compiled Production Code resp. Binary Code have to be compared with the results stored in the Behavioral Model representation. In the Behavioral Model manifest optionally relative and absolute error tolerances are defined to assess the match between the data. A second possibilty to specify error tolerances is enabled by having whole data sets of time dependent lower and upper bounds of variables in the reference results. More details are given in the next subsection.

3.2. Behavioral Model Manifest

The manifest file of the Behavioral Model representation is an instance of an XML schema definition and defines the available scenarios with reference results and maximum acceptable deviations from them.

3.2.1. Definition of an eFMU Behavioral Model (efmiBehavioralModelManifest.xsd)

This is the root-level schema file of the Behavioral Model representation and contains the following definition:

BehavioralModelManifest
Element-Name Description

attributes

The attributes of the top-level element are the same for all manifest kinds and are defined in section Section 2.3.1.
Current kind-specific values: kind = "BehavioralModel", xsdVersion (value is the current xsd version of the schema for the Behavioral model manifest), .

ManifestReferences

References to manifest files of other model representations for which referencing is needed within this Behavioral Model manifest. Mainly, the Algorithm Code manifest on which this Behavioral Model manifest is based on has to be listed. This element is the same for all manifest kinds and is defined in section Section 2.3.4.3.

Files

List of files referenced in this model representation. There must be at least one file that contains reference results in csv format. This element is the same for all manifest kinds and is defined in section Section 2.3.3.

Scenarios

A scenario groups several simulation results (parts of one scenario) to one unit. At least one scenario definition must be present. For details see Section 3.2.2.

Variables

Required list of variables for which a link between columns in reference results and variables in the Algorithm code manifest is established in the Behavioral Model manifest. For details see Section 4.1.6.

CsvData

Optional element that defines how the columns of the csv files are mapped to the variables. It also provides information for the variables in each scenario part how acceptable deviations between simulation results of Production/Binary code and reference results are specified. For details see [definition-of-csvdata].

Annotations

Additional data that a vendor might want to store and that other vendors might ignore. For details see Section 2.3.4.5.

3.2.2. Definition of a Scenario (efmiScenarios.xsd)

A scenario (e.g. open loop test simulations) consists of one or more scenario parts (e.g. simulation runs with different numerical solvers).

Scenario
Element-Name Description

name

Optional name of the scenario.

id

The id of the scenario.

One simulation within a scenario is defined with a ScenarioPart element. The essential content of this element is the reference to a csv file.

ScenarioPart
Element-Name Description

name

Optional name of the scenario part.

id

The id of the scenario part.

fileRefId

The reference id of the csv file, in which the reference result data for this scenario part is stored.

3.2.3. Definition of Variables (efmiVariable.xsd)

The variables to be compared in one of the scenario parts are listed in the following element:

Variables
Element-Name Description

id

The id of the variable within the Behavioral Model manifest.

ForeignVariableReference

The reference to the variable defined in the Algorithm Code manifest file. For details see Section 2.3.4.3. A reference to other model representations is not allowed. It is not necessary to define all variables of the Algorithm Code manifest here. Only the variables for that reference data in csv files is provided need to be listed.

3.2.4. Definition of CsvData (efmiCsvData.xsd)

This element is the essential part of the Behavioral Model manifest and provides the information where for the variables the data can be found in the reference data files (= csv files). It also contains the information how the assessment can be realized, that deviations between the eFMI simulation results (by compiled Production Code or Binary Code) and the reference data in the csv files are acceptable.

CsvData
Element-Name Description

TimeData

Information where the time vectors can be found in the csv files.

name

The name of the time variable in the header of the csv files that are referenced by the listed scenario parts in Part.

SenarioPartRefId

The reference id of the scenario part to which this definition of the time vector is associated with.

Data

Information about reference data and acceptable deviations associated with all variables (without time) of all scenario parts.

In one element Data the information about reference data and acceptable deviations associated with one variables (but not time) of one or several scenario parts are contained. Several scenario part can only be included, if the information to be provided is identical for these scenario parts. For the scenario parts, for which the information is different for a specific variable, a new element Data has to be listed for this variable. The whole list of all Data elements contains a combination of variables and scenario parts. It is not permitted to have the same combination twice, because otherwise the information is not unique.

Data
Element-Name Description

variableRefId

Reference id of the variable to be considered in this Data element.

scenarioPartRefId

Reference id of the associated scenario part for which the information is provided in this Data element. Several scenario parts can be listed within the element Parts.

Nominal

The nominal reference value of the variable that is associated with a column of the table in the csv files. If the variable is a vector or a multidimensional array, then each relevant component of the vector/array is listed by a separate element Nominal.

name

The name of the nominal variable in the header of the csv files that are referenced by the listed scenario parts in Part.

index

Index of vectors resp. flattend index of multidimensional arrays. The element has to be absent for scalar variables and is required for vectors and mutlidimensional arrays. The index corresponds to the referenced Algorithm code variable (referenced by the element variableRefId and the corresponding element ForeignVariableReference in the element Variable). For multidimensional arrays the scalar index is according to a row-major order of all elements of the array.

Tolerances

Optional error tolerance information to be used for comparison of computed and given values in the csv files of the variable considered in this Data element.

The details of the error tolerance information valid for one variable (scalar or vector or multidimensional array) is given with the following element. For each possible value of floatPrecision maximum one element Tolerance has to be present.

Tolerance
Element-Name Description

floatPrecision

Floating point precision that has to be used to run the compiled Production Code or Binary code to be compared with the reference results (32-bit or 64-bit).

absTol

Optional default value for the absolute error tolerance that should be used for signal comparisons. For vectors or multidimensional arrays these default values are used for all components.

relTol

Optional default value for the relative error tolerance that should be used for signal comparisons. For vectors or multidimensional arrays these default values are used for all components.

ToleranceItem

Optional list of detailed information about error tolerances and additional columns for time-dependent lower/upper bounds of nominal reference result values.

The element ToleranceItem contains detailed error tolerance information about a scalar variable resp. one component of a vector/multidimensional array. If the considered variable is a scalar, then only one element ToleranceItem has to be present within the list of the element Tolerance. For vectors or multidimensional arrays only entries for relevant indices are needed and the values of the attribute index have to be different for each of the entries.

ToleranceItem
Element-Name Description

absTol

Optional absolute error tolerance of the scalar value considered in this tolerance item. If there is already a default value of absTol specified in the element Tolerance, then this more specific value of the element ToleranceItem has to be used.

relTol

Optional relative error tolerance of the scalar value considered in this tolerance item. If there is already a default value of relTol specified in the element Tolerance, then this more specific value of the element ToleranceItem has to be used.

csvLower

Optional name of the lower bound variable in the header of the csv files that are referenced by the listed scenario parts in Part.

csvUpper

Optional name of the upper bound variable in the header of the csv files that are referenced by the listed scenario parts in Part.

index

Index of vectors resp. flattend index of multidimensional arrays. The element has to be absent for scalar variables and is required for vectors and mutlidimensional arrays. The index corresponds to the referenced Algorithm code variable (referenced by the element variableRefId and the corresponding element ForeignVariableReference in the element Variable). For multidimensional arrays the scalar index is according to a row-major order of all elements of the array.

The lower and upper bound variables are not listed or referenced elsewhere in the manifest. The corresponding columns in the csv files contain data to define time-dependent lower/upper bounds of an acceptable simulation with the given float precision in the element Tolerance.

It is permitted to set all elements absTol, relTol, csvLower and csvUpper. If absTol or relTol are set, then csvLower and csvUpper cannot be set and vice versa. For the case, that csvLower and csvUpper are set and if there is already a default value of relTol or absTol specified in the element Tolerance, then these default values have to be ignored for the specific scalar variable/component in this ToleranceItem.

3.2.5. Comparison of signals

The Behavioral Model manifest contains the neccessary information to use inputs in csv files and to compare the simulation results of compiled Production Code or Binary Code with reference results in csv files. For the assessment, if the result deviations are acceptable, two cases have to be distinguished (depends individually on each variable and scenario part):

  1. Check by using absolute and/or relative error tolerances or

  2. Check by using lower and/or upper bounds.

For a scalar variable there is a column in a csv file that corresponds to the reference result data of this variable. Each row of the data is associated to a time instant of the time vector. In the following the data vector is called y_ref. The corresponding simulation result is called y_sim (also a time dependent vector with the same length as y_ref and the values of the variable at the time instants given by the time vector). If the check is based on lower/upper bounds, then there are further columns in the csv files that are associated to the time dependent lower and upper bounds of the variable. In the following the vectors are called lower and upper. The i-th component of all the described vectors are access by y_ref_i, y_sim_i, lower_i and upper_i.

If for all time instances t_i the following holds, then the test is passed otherwise not:

  1. abs(y_ref_i - y_sim)_i ≤ max(absTol, relTol*abs(y_ref_i)) resp.

  2. lower_i ≤ y_sim_i ≤ upper_i

3.3. Behavioral Model Data

The csv files as they are contained in a Behavioral Model representation are according to (https://en.wikipedia.org/wiki/Comma-separated_values). In the first line there is a list of header names that define the names of the columns separated by a colon. In the following lines for each of the variables defined in the header a numeric value is provided separated by colon.

The unit of the time is seconds. Values of Boolean variables have to be represented by the Integer values 0 (false) and 1 (true).

Example:

Time,wLoadRef,wMotor,vMotor,isReset
0,0,10,-200,0
0.001,0.003,10,-193.70000000000002,0
0.002,0.006,10,-187.41e3,1
0.003,0.009,10,-181.12958499999996,1
0.004,0.012,10,-174.85834414999999,0

4. Algorithm Code Model Representation

InputOutputBlock

The Algorithm Code model is a portable and tool-independent intermediate representation for coupling physics-modeling tools with embedded Production Code generation. Mathematically, it is described as a sampled input/output block with one (potentially varying) sample period Ti for the whole block where inputs ui and previous (block internal) states xi are provided at sample time ti and outputs yi and new states xi+1 are computed and are latest used at sample time ti+1 = ti + Ti (see figure to the right). All variables of the block have a defined type and all statements of the block are sorted and explicitely solved for a particular variable. Functions are provided to execute the relevant parts of the block, especially to initialize it and to perform one step.

The purpose of the Algorithm Code model representation is to provide a well defined reusable basis for the Production Code generating tools. It can be seen as a target-independent Production Code on a logical level where the relationship to the original model is clearly visible (for example, the hierarchy of the original model is visible in the variable names). Depending on the embedded device the eFMU should be run on, a single Algorithm Code model representation can be used to generate multiple Production Code model representations and is therefore the last target independent model representation of the eFMU.

The Algorithm Code model representation consists

  • of a manifest file in XML format in which all interface variables are defined (see section [Algorithm Code Manifest]),

  • one code file with extension .alg that represents the executable part of the block consisting of a block with declarations, and mandatory definitions of the three methods Startup, DoStep and Recalibrate. These methods are defined in a target-independent way with the new language GALEC (Guarded Algorithmic Language for Embedded Control) which is based on the syntax of a Modelica function (https://www.modelica.org/modelicalanguage) with extensions as needed for embbeded systems (see section [GALEC - The Algorithm Code Language]).

In the Algorithm Code specification and its examples the following coding conventions are used:

  • Types — primitives and components — start with capital letters, and each successive word part starts capitalized. Examples: Real, Boolean, Pid, GearBox, CrankShaftPid.

  • Stateless functions — including builtin functions — are defined with keyword function. The function names start with lower-case letters, and each successive word part starts capitalized. Examples: sin, solveLinearEquations, computeCrankShaftPid.

  • Stateful functions are defined with keyword method. The method names start with capital letters, and each successive word part starts capitalized. Examples: Startup, Recalibrate, DoStep.

  • Functions for scalars that are generalized to one and two dimensions use the scalar function name with suffix 1D and 2D appended. Examples: roundTowardsZero1D, interpolate2D.

4.1. Manifest

InputOutputBlock

The manifest file of the Algorithm Code model representation is an instance of an XML schema definition and defines the variables and block methods that represent a sampled input/output block, see figure to the right.


4.1.1. Definition of an eFMU Algorithm Code (efmiAlgorithmCodeManifest.xsd)

This is the root-level schema file of the Algorithm Code model representation and contains the following definition:

ManifestMainLevel

On the top level, the schema consists of the following elements (see figure above):

Element-Name Description

attributes

The attributes of the top-level element are the same for all manifest kinds and are defined in section Section 2.3.1.
Current kind-specific values: kind = "AlgorithmCode", xsdVersion (value is the current xsd version of the schema for the Algorithm Code model manifest).

Files

List of files referenced in this model representation. There must be at least one file that contains the code of the BlockMethods. This element is the same for all manifest kinds and is defined in section Section 2.3.3.

Clock

A reference to the fixed or variable sample period defined by a block variable. For details see Section 4.1.2.

BlockMethods

The properties of the block methods DoStep, Recalibrate, and DoStep. For details see Section 4.1.3.

ErrorSignalStatus

Semantic error signal status to be referenced from ProductionCode manifest to mark the single variable that represents the error status. For details see Section 4.1.4.

Units

An optional global list of unit and display unit definitions. These definitions are used in the XML element Variables. This element is nearly identical to the corresponding FMI 3.0 UnitDefinitions element. For details see Section 4.1.5.

Variables

A list of all variables that are accessible from the block methods defined in element BlockMethods. A variable might be a scalar or an array of an elementary type. Contrary to FMI 3.0, no target type variables (such a Float64) are defined here, but mathematical variable types (such as RealVariable). The reason is that target specific types are defined for the Production Codes [otherwise it would not be possible to define, for example, Float32 and Float64 Production Codes in the same eFMU] . For details see Section 4.1.6.

Annotations

Additional data that a vendor might want to store and that other vendors might ignore. For details see Section 2.3.4.5.

4.1.2. Definition of Clock

Element Clock provides a reference to the fixed or variable sample period defined by a block variable. The block should be executed periodically with the defined fixed or variable sample period.

Clock
Element-Name Description

id

The id of the sample period of the block.

variableRefId

Reference to the variable in <Variables> that defines the sample period. This variables is only allowed to have the following values for variable attribute blockCausality:
constant: Sample period cannot be changed.
tunableParameter: Sample period can be changed in the calibration phase.
input: Sample period from previous to current clock tick

The referenced variable variableRefId defines the sample period for which the block was designed. When the production code of this block is integrated in the target system (for example as AUTOSAR runnable), then it is expected that the block is executed as periodic sampled data system with this sample period. It might be that also a slightly changed sample period in the target system may still result in reasonable performance.

4.1.3. Definition of BlockMethods

Element BlockMethods defines properties of the defined block methods. Exactly three BlockMethod elements must be defined.

BlockMethods
BlockMethodSignals
Name Description

fileRefId

A reference to the file (defined in <Files><File>, see section Section 2.3.3) in which the code of the block methods is stored.

writeOutputs

Defines the recommended implementation scheme to utilize the calculated outputs. Default is Undefined. The currently only allowed other value is AsSoonAsPossible, meaning to utilize the outputs at once when they are computed, more details are given below.

id

The ID of the block method

kind

The kind of the block method (this is also the name of the method). Currently possible values are Startup, DoStep, Recalibrate.

Signals

The error signals exposed by the respective block method (for details Section 4.2.5.1) Attribute value defines the value of the signal. Currently, the following values are possible:
"INVALID_ARGUMENT" (= the value of an input variable is not correct)
"OVERFLOW" (= the value of a variable is Inf)
`"NAN" (= the value of a variable is Not-A-Number)
"SOLVE_LINEAR_EQUATIONS_FAILED" (= failed to solve a linear equation system)
"NO_SOLUTION_FOUND" (= no solution found for other equation systems)
"UNSPECIFIED_ERROR" (= error not further specified)

The scheme writeOutputs = "AsSoonAsPossible" is typically used when the controller computes the outputs for the current clock tick (e.g. integrates from the previous to the current clock tick). Pseudo-Code for this scheme:

self = <instance of efmi component>
<initialize self with the manifest start values> or self.Startup()
<write outputs>
<wait until clock starts>

<at every clock tick>
   <read inputs>
   self.DoStep()
   <write outputs>
   if <calibration phase and tunable parameters available>
       <set tunable parameters>
       self.Recalibrate()
   end
   <wait for next clock tick>
<end>

The drawback of this scheme is that the computing time of efmu.DoStep() introduces a time delay until the outputs are available.

Note, it is also possible to write the outputs inside DoStep directly after they are computed (without waiting until all statements are processed and the method returns). This implementation scheme of the Production Code is recommended if attribute writeOutputs has value AsSoonAsPossible.

[There are also other implementation schemes that might by useful (currently, it is not possible to state this in the Manifest file). Examples:

Write outputs at next clock tick

This scheme is typically used when the controller computes the outputs for the next clock tick (e.g. integrates from the current to the next clock tick). Pseudo Code:

self = <instance of efmi component>
<initialize self with the manifest start values> or self.Startup()
<write outputs>

<at every clock tick>
   <write outputs>
   <read inputs>
   self.DoStep()
   if <calibration phase and tunable parameters available>
       <set tunable parameters>
       self.Recalibrate()
   end
   <wait for next clock tick>
<end>

The drawback of this scheme is that the inputs are extrapolated over the sample period because the inputs at the next clock tick are utilized in DoStep but are not known when DoStep is called.

Two different clocks for reading inputs and writing outputs

The reading of inputs and the writing of outputs might be performed with different clocks that have the same sample period, but the clock for the outputs is shifted relative to the clock for the inputs.

Event clock (purely event based)

The block might be triggered by an external event (e.g. at a particular angle of the engine shaft). The sample period (from the previous to the current clock tick) is provided as input signal.

4.1.4. Definition of ErrorSignalStatus

This element defines the single, hidden, error signal variable that holds the error signal status and is referenced from the ProductionCode manifest. It consists only of attribute id that defines the ID of this hidden variable:

ErrorSignalStatus

4.1.5. Definition of Units

Element Units defines the units that are used by the Variables element.

This element is identical to element UnitDefinitions of FMI 3.0 with the only exception that there is an additional attribute id to identify a unit uniquely in the AlgorithmCode manifest file and without element DisplayUnit:

Units
BaseUnit

4.1.6. Definition of Variables

The Variables element consists of an ordered list of all variables used as model states of the methods defined in element BlockMethods, so the values of these variables can be directly accessed and changed in the respective method using the name of the variable prepended with the instance name self (for example self.previous_x if the variable has name previous_x). Variables that are defined with blockCausality = input are set from the environment at the beginning of a sampling period. Variables that are defined with blockCausality = output are used at the end of the sampling period by the environment in an appropriate way. Variables that are defined locally in a block method are not listed in the Variables element.

Variables are defined as (hereby one variable is defined according to schema group efmiVariable in file efmiVariable.xsd):

Variables

The schema definition contains basically the same information as element ModelVariables in FMI 3.0, but using mathematical instead of target types and having the following deviations:

  • There is no String type.

  • A type might have Dimensions where the size of a dimension is an Integer literal (a dimension cannot depend on a structural parameter as in FMI 3.0).

  • The variable attributes causality, variability and initial of FMI 3.0 are replaced with the new attribute blockCausality (see below).

  • The following FMI 3.0 attributes are not present:

    • valueReference

    • canHandleMultipleSetPerTimeInstant

    • clockReference

    • clockElementIndex

    • intermediateUpdate

    • declaredType

    • quantity

    • displayUnit

    • unbounded

    • derivative

    • reinit

Variable Base (attributes + elements)

All variable kinds (so RealVariable, IntegerVariable, BooleanVariable) have the following base attributes/elements:

VariableBase
Name Description

id

The unique identification of the variable with respect to the AlgorithmCode manifest file (can be referenced from other manifest files).

name

The full, unique name of the variable. Every variable is uniquely identified within an eFMI AlgorithmCode instance by this name.

description

An optional description string describing the meaning of the variable.

blockCausality

Enumeration that defines the causality, variability and initialization of the variable. Allowed values of this enumeration:

  • "input": The variable value is set by the environment at the start of a sampling period.

  • "output": The variable value can be used by the environment once it is computed.

  • "tunableParameter": Independent parameter that is constant during a call to DoStep() and can be calibrated.

  • "calculatedParameter": A data value that is constant during a call to DoStep() and is computed during initialization or when tunable parameters change.

  • "constant": The value of the variable defined with the start attribute never changes.

  • "state": Local state variable that is initialized in Startup and is calculated from other variables. The value of this variable is kept between method calls.

start

Initial value of the variable as defined by default initialization.

The given xs:token value can encode either a scalar value or a multi-dimensional value where each element value is separated by an XML whitespace character. In the latter case, the array elements are given in row-major order, that is the elements of the last index are given in sequence.

[For example, a table T[4,3,2] (first dimension 4 entries, second dimension 3 entries, third dimension 2 entries) is mapped into the following sequence of values:
T[1,1,1],
T[1,1,2],
T[1,2,1],
T[1,2,2],
T[1,3,1],
T[1,3,2],
T[2,1,1],
T[2,1,2],
T[2,3,1],
…​
]

If the variable is a scalar, the string must encode a scalar value. If the variable is a multi-dimensional array, the string can either: (1) encode a scalar value, meaning that each element of the multi-dimensional array has the respective scalar value as start value or (2) encode a multi-dimensional value, meaning that the start values of the elements of the multi-dimensional array are the respective encoded multi-dimensional value.

Encoded values must be of the variable’s type and each must satisfy its min and max value (if min and/or max elements are defined).

Dimensions

If the variable is an array, then the fixed dimensions of the array are defined by this element. For every dimension, the number defines the number of the dimension (must be consecutive numbers 1, 2, …​) and size defines the fixed size of the dimension (must be >= 1).

Annotations

Additional data of the variable, e.g., for the dialog menu or the graphical layout. For details see Section 2.3.4.5.

In FMI 3.0 the attributes causality, variability, initial are defined, which combinations are allowed and why the allowed combinations are needed for an offline simulation program with events. However, for eFMI most of the combinations cannot occur. For simplicity, eFMI uses therefore only the attribute blockCausality. In the following table the mapping of blockCausality to the FMI 3.0 attributes is defined:

eFMI FMI 3.0

blockCausality

causality

variability

initial

input

input

discrete

--- (no initial)

output

output

discrete

exact

tunableParameter

parameter

tunable

exact

dependentParameter

calculatedParameter

tunable

calculated

constant

local

constant

exact

state

local

discrete

exact

RealVariable-specific attributes

The following RealVariable specific attributes are defined:

RealVariableAttributes
Attribute-Name Description

unitRefId

Identifier of the unit of the variable defined in list Units.Unit (Section 4.1.5). The value of the variable is with respect to this unit.

relativeQuantity

Defines if BaseUnit-based unit conversions have to consider the base-unit’s offset (relativeQuantity=false) or not (relativeQuantity=true). [For example, 10 degree Celsius = 10 Kelvin if relativeQuantity = "true" and not 283.15 Kelvin.]

min

Minimum value of variable (variable value ≥ min). If not defined, the minimum is the largest negative number that can be represented on the machine. If the variable is a multi-dimensional array, min is a scalar value that holds for all array elements.

max

Maximum value of variable (variable value ≤ max). If not defined, the maximum is the largest positive number that can be represented on the machine. If the variable is a multi-dimensional array, max is a scalar value that holds for all array elements.

nominal

Nominal value of variable. If the variable is a multi-dimensional array, nominal is a scalar value that holds for all array elements.

If not defined and no other information about the nominal value is available, then nominal = 1 is assumed.
[The nominal value of a variable can be, for example, used to define tolerances or scaling values for numerical algorithms in which the variable is used.]

Example:

<Units>
  <Unit id="UnitID_1" name="s"/>
</Units

<Variables>
  <RealVariable id="ID_1" name="Ti" unitRefId="UnitID_1" blockCausality="tunableParameter" start="0.1"/>
  <RealVariable id="ID_A" name="A" blockCausality="constant" start="1.1 1.2 2.1 2.2">
      <Dimensions>
           <Dimension number="1", size="4"/>
      </Dimensions>
  </RealVariable>
  <RealVariable id="ID_2" name="previous(I.x)"  blockCausality="state" start="0.0" min="0.0" />
</Variables>
IntegerVariable-specific attributes

The following IntegerVariable specific attributes are defined:

IntegerVariableAttributes
Attribute-Name Description

min

Minimum value of variable (variable value ≥ min). If not defined, the minimum is the largest negative number that can be represented on the machine. If the variable is a multi-dimensional array, min is a scalar value that holds for all array elements.

max

Maximum value of variable (variable value ≤ max). If not defined, the maximum is the largest positive number that can be represented on the machine. If the variable is a multi-dimensional array, max is a scalar value that holds for all array elements.

Examples:

<Variables>
  <IntegerVariable id="ID_11" name="numberOfCylinders" blockCausality="tunableParameter" start="6" min="0" />
  <IntegerVariable id="ID_12" name="pivots" start="0">
     <Dimensions>
        <Dimension number="1" size="8"/>
     </Dimensions>
  </IntegerVariable>
</Variables>
BooleanVariable-specific attributes

The BooleanVariable element has no additional attributes.

4.2. GALEC: The Programming Language for Algorithm Code Containers' Source Code

InputOutputBlock

The algorithm that defines an input/output, sampled data block is defined with the new language GALEC (Guarded Algorithmic Language for Embedded Control) that is specified in this sub-section. GALEC is based on a small subset of the Modelica Language (especially on Modelica functions, Modelica External Function Interface, and on Synchronous Language Elements) of the Modelica Specification 3.4 (https://www.modelica.org/documents/ModelicaSpec34.pdf) together with changes and extensions as needed for embbeded real-time systems. GALEC has the following features that are not present in the Modelica Language:

  • The language is designed so that only algorithms can be defined that have an upper-bound on the number of operations for each control-cycle to satisfy hard real-time constraints (for example, there are no while loops). Furthermore, all needed memory, especially of arrays and operations on arrays, is known statically.

  • The language is designed for computational safety. For example it can be statically guaranteed that out-of-bounds and otherwise illegal memory accesses for all possible executions cannot occur at run-time.

  • The language is designed for traceability so that GALEC code can be understood in terms of the original model and vice versa.

  • The language has a restricted set of methods to efficiently pass the block state between functions.

  • A set of built-in functions is defined so that physical models and their solvers can be reasonably mapped to GALEC code. For example, there are built-in functions for interpolation and for the solution of linear equation systems.

  • The language is designed to handle erroneous situations in a safe way. For example, it is possible to determine at the end of the algorithm whether the computed outputs can be used for further processing, or whether it is necessary to switch to a backup code, for example, if operations produced qNaN (quiet-Not-a-Number) values. Furthermore, min/max values defined in the declaration of variables are used to implicitly limit the variable values at the start and at the end of the DoStep method. This is different to the Modelica language that raises assertions if min/max definitions are violated.

The GALEC code of a block is stored in a file with extension *.alg and is a self-contained file that can be parsed and interpreted without inspecting the Algorithm Code manifest file. For examples of GALEC programs, see Section 4.2.7.

4.2.1. Language-design Overview

GALEC code generation is subject to many, often contradicting, requirements imposed by physics and mathematics (physics-modeling domain), embedded real-time system-control (Production Code domain) and development processes for certified systems (embedded development domain):

(a) An algorithmic source-language for embedded real-time

GALEC code has to take into account that further embedded code generation typically must satisfy hard real-time constraints. Generated algorithmic solutions must have an upper-bound of algorithmic steps executed each control-cycle, such that termination within a statically fixed number of computational steps can be guaranteed. To derive such upper-bounds for actual GALEC code is subject of the termination-analysis, which checks that functions of GALEC code are transitively non-recursive and loops always have a statically fixed maximal number of iterations. To transform equation-based models to such solutions may not always be possible. To that end, GALEC code generators are free to reject valid models of their modeling-language as not being suitable for GALEC code generation.

Another important concern of embedded applications is computational safety, requiring for example that programs are free of out-of-bounds or otherwise illegal memory accesses for all possible executions; and that control-flows for error detection and handling always shortcut normal program execution [1]. To that end, a dimensionality-analysis is enforced, which statically defines the sizes of multi-dimensions w.r.t. function call contexts; considering all possible call contexts is required to support generic functions working on arbitrary sized multi-dimensions. The dimensions derived are used to statically ensure that all multi-dimensional accesses always will be within bounds throughout later program executions. Dimensionality and termination-analysis are closely linked; bounded loops can conveniently iterate multi-dimensions whose statically known dimensions in turn define respective upper iteration bounds. Since iteration bounds can depend on the sizes of any multi-dimension, other iteration indices or integer expressions combining such, GALEC code supports advanced iteration schemes that are still guaranteed to be well-defined.

(b) An algorithmic target-language for simulation of physics-models

GALEC code generators have to rearrange original physics-model equations to derive an algorithmic solution. The more comprehensive, complex and mathematically challenging a controller design is — and therefore interesting for modeling its physics — the more rigorous such transformations are typically. Particularly later real-time constraints as described in (a) often require radical transformations to handle algebraic loops and enable equation-system optimisations like symbolic processing, tearing and index reduction. GALEC code generators are therefore encouraged to apply whichever mathematical and logical equation-system transformations they consider required to yield an equivalent algorithmic solution.

Besides the requirement to achieve an algorithmic solution in terms of expression- and assignment-sequences that compute the next state of the simulated control-cycle, no further transformation has to be performed. GALEC provides means to compute with structured-data as common in physics-modeling languages, particularly higher-level matrix-operations. And a library of builtin functions supports common mathematical tasks like solving a linear system of equations. The exact implementation of all these mathematical-abstractions is the responsibility of Production Code generators, leaving opportunity for later target-machine specific optimization. To that end, GALEC code generators are highly encouraged to leverage on the provided mathematical-abstractions.

(c) An intermediate-language leaning towards algorithm-logics and mathematical-optimization, not algorithm-implementation and target-specific optimization

The emphasis in (b) has been on mathematical transformations only; otherwise GALEC code generators should not apply transformations that curtail Production Code generators in their code generation decisions, particularly regarding optimisations leveraging on target-specifics. Typical target-specific optimisations are for example data-structure changes to improve memory-layout for faster access-operations or optimisations of the trade-off between code-size and performance like loop-unrolling. Especially higher-level matrix-operations and builtin function calls are interesting for target-specific Production Code optimisations. Although it seems obvious not to further reduce such mathematical abstractions, it is non-trivial in practice.

The mathematical equation-system transformations described in (b) typically imply separation or reduction of existing and introduction of new multi-dimensional data-structures, influencing matrix-operation and builtin function calls in turn. For example, tearing may be used to reduce the required numerical integration, in turn yielding smaller but also more frequent matrix allocations for linear solving. Fortunately, such mathematical transformations most often also result in more efficient embedded code generated by Production Code generators; but that is hard to say in general. Of course, if required to achieve an algorithmic solution at all, such transformations have to be done. But otherwise, the resulting decomposition of matrices accompanied by matrix-operation flattening and therefore increase in code size may very well supersede the advantage.

On the other hand, GALEC code generators have the domain-knowledge for mathematical-optimisations that Production Code generators lack. An important case for trade-offs between mathematical and Production Code optimisations is scalarization to eliminate controller-output irrelevant or redundant state-variables and equations. Physics-models often contain simple equality-equations between the state-variables of two components; likewise, the components constituting a certain controller may be generalized for more advanced cases than their actual application context, leaving equation-parts unused. GALEC code generators are encouraged to eliminate such system parts, which typically results in multi-dimensions with unused elements like a 2x3 matrix of which only four entries are actually required to compute the outputs. Eliminating the unused entries means to change model structure, while shifting the matrix or changing its dimensionality is not an option because of traceability and a lack of knowledge regarding the final matrix-layout Production Code will eventually apply.

As an alternative, GALEC code can scalarize such multi-dimensions, i.e., flatten the higher-level multi-dimensional entity to a set of scalars — and therefore dimension-less — otherwise equally typed entities. Unused scalars can then just be discarded. The drawback of scalarization is, that all expressions containing higher-level matrix-operations with scalarized multi-dimensions and loops referring to such must be expanded to respective sequences of scalar operations. Besides being in conflict with the requirement to not curtail Production Code from optimizing higher-level matrix-operations, the resulting code-size increase due to expansions may very well render the savings in elements futile.

(d) A language for algorithmic controller implementation

TODO: Startup and DoStep (with input parameters); eFMU state and method vs. function; previous and derivative state-variables.

(e) A language part of a trustworthy tool-chain from physics-models to embedded-code

GALEC code generators have to maintain traceability, such that embedded solutions derived from physics-based controller designs can be understood in terms of the original model; and vice versa, all parts of a controller-model can be traced to its embedded implementation. To link individual physics-equations to their respective algorithmic solution is very challenging in general, since equations are likely subject to rigorous transformations as described in (b). A common denominator between a physics-model and its transformed solution is however, that both simulate the same system. It therefore is a starting point for GALEC code to at least refer to the states of the original physics-model components whenever using or updating such. The premise is of course, that controllers are modeled as systems consisting of well-structured parts; only then GALEC code generators can, and are highly encouraged, to utilize original system-structure for traceability. To that end, GALEC does not only provide mathematical multi-dimensions as described in (b), but also nested multi-dimensional components with matrix- and scalar-variables; and in case of optimisations resulting in scalarization as described in (c), a quotation-based notation can be used to denote scalarized elements as if their original multi-dimensions still exist. GALEC code generators have to maintain traceability, such that embedded solutions derived from physics-based controller designs can be understood in terms of the original model; and vice versa, all parts of a controller-model can be traced to its embedded implementation. To link individual physics-equations to their respective algorithmic solution is very challenging in general, since equations are likely subject to rigorous transformations as described in (b). A common denominator between a physics-model and its transformed solution is however, that both simulate the same system. It therefore is a starting point for GALEC code to at least refer to the states of the original physics-model components whenever using or updating such. The premise is of course, that controllers are modeled as systems consisting of well-structured parts; only then GALEC code generators can, and are highly encouraged, to utilize original system-structure for traceability. To that end, GALEC does not only provide mathematical multi-dimensions as described in (b), but also nested multi-dimensional components with matrix- and scalar-variables; and in case of optimisations resulting in scalarization as described in (c), a quotation-based notation can be used to denote scalarized elements as if their original multi-dimensions still exist. For example, a scalarized real variable may have the name 'a.b[2].c[2,3]', linking it with original model structure for traceability although all output-relevant combinations of components a and b and matrix c are scalarized into individual variables.

(f) A portable and tool-independent language for standardized tool-integration and distribution of controller implementations

GALEC code is at the center of eFMUs, linking physics-modeling with embedded-development tooling. Although eFMUs are free to only contain target-specific source code, build scripts and resulting binaries, such eFMUs are just fancy containers for embedded solutions; and vice versa, a pure modeling eFMU without executable embedded-solutions misses the actual purpose of eFMI compared to the ordinary FMI standard. It is the GALEC code that brings both worlds together and exposes their relation to eFMU users. The latter does not only imply traceability as described in (e), but also to adhere to a common specification of controller inputs, outputs, states and parameters and control-cycle functionality — an abstract controller usage interface. In the spirit of the FMI standard, and to not preclude a potential future integration with it, this interface is given in terms of an FMI like XML manifest declaring all entities and functionalities of interest for users of the eFMU. The control-state defined in GALEC code — the state components with state variables, control-inputs and -outputs and their nesting — therefore always is linked to entities declared in the manifest; likewise, the initialization and control-cycle functions are exposed in the manifest to clearly declare the functionality an eFMU provides. GALEC code generators are required to derive respective manifests if asked for.

4.2.2. Notation Conventions

The concrete syntax of GALEC code is defined using Extended Backus–Naur Form (EBNF) according to ISO/IEC 14977. The whole grammar is split into different sections, each defining a specific language construct — i.e., syntactic concept — of GALEC code like lexemes, references, expressions, statements etc. The EBNF-rules — i.e., syntactic rules — defining the syntactic concept a section is about can be amended with further semantic rules given in prose. Semantic rules constrain the applicability of the syntactic rules they refer to. They are in turn classified w.r.t. the different semantic concepts of GALEC code they contribute to like type-analysis, dimensionality-analysis, termination-analysis etc.

Due to the decision to structure the whole specification w.r.t. language constructs, semantic concepts cross-cut sections. Table TODO summarizes all semantic concepts, the semantic rules contributing to their definition and the section they are defined. The inevitable complexity of cross-dependencies, typical for any serious formal language, is further attenuated by using a consistent notation for semantic rules, enabling explicit linkage between defined rules, the semantic concepts they contribute to and further rules relevant for or later refining a definition. Likewise, syntactic rules are well-prepared for usage in semantic-rules, i.e., usage in prescriptive definitions given in prose.

Syntactic Rules, Terms and Relations

Each syntactic rule has a unique rule-number of the form G-X1.X2, where X1 is the section the rule is part of and X2 is its unique rule-number within that section; the actual EBNF rule follows separated by a colon. The non-terminals defined by syntactic rules are human readable terms that are well-suited for prose-text usage. Semantic rules denote such usage by writing the respective non-terminal in italic. For readability reasons, every non-terminal can be used in plural or singular form and its first letter can be capitalized when used at the beginning of a sentence. The meaning of a non-terminal within a semantic rule is defined by the following meta-rule:

M-1.1 (syntactic term / Meta-rules, terminology): Parts of semantic rules typeset in italic refer to non-terminals; they are called syntactic term. Let N be a non-terminal referred to in a semantic rule S; let G be the syntactic rule defining N (cf. M-1.2 for uniqueness of syntactic rules). The semantic of N in S is: a code fragment F of a whole GALEC program P, where F is derived according to G throughout the derivation of P and satisfies all semantic rules amended to G.

M-1.1 requires that the syntactic rule a syntactic term refers to is unique; to that end we define:

M-1.2 (uniqueness of syntactic rules / Meta-rules): For every non-terminal N exists a single syntactic rule whose EBNF syntax-rule has N as meta-identifier (cf. ISO/IEC 14977).

M-1.1 has severe consequences. If, for example, the specification refers to loop-iterator-declarations, it is clear that this must be names declared by a for-loop regardless in which context the syntactic term loop-iterator-declaration is used; this implication is given because loop-iterator-declaration just derives to name and is only used by bounded-iteration[2] which in turn is only used by for-loop. Besides such implicit restrictions, further explicit restrictions about the syntactic relation between syntactic terms — i.e., that some term’s own derivation must be in a well-defined relation to another term’s derivation throughout the whole derivation — are used:

M-1.3 (syntactic relations / Meta-rules, terminology): Let N1 and N2 be syntactic terms.

N1 is contained in N2, if, and only if, N1 is derived throughout the derivation of N2; in this case N2 is called a container of N1 and we say N2 contains N1 and N1 is part of N2. If, and only if, N2 contains N1 and both refer to the same non-terminal N, N1 is called a nested N. N2 is the closest container of N1, if, and only if, N2 contains N1 and for all N3 containing N1 and that refer to the same non-terminal as N2 it holds that N3 contains N2.

N1 is preceding N2, if, and only if, neither is contained in the other and the left-most derivation of the closest container of N1 and N2 derives N1 before N2; in this case N2 follows N1. Instead of preceding also the term before is used; and instead of follows also the term after. If, and only if, either, N1 follows N2 or N2 follows N1, both are siblings. N1 and N2 are different, if, and only if, they are siblings or the one contains the other.

N1 is lexically-equivalent to a sequence of characters α, written N1 =lexical α, if, and only if, N1 derives to α. N1 is lexically-equivalent to N2, written N1 =lexical N2, if, and only if, N1 and N2 derive to the same sequence of characters.

If, and only if, N2 contains N1 and throughout all possible derivations of the non-terminal N2 refers to the non-terminal N1 refers to can be derived at most once, we speak of the N1 of N2; obviously, N2 is the closest container of N1 in that case.

Let d = β1, …​, βn be a single definition according to ISO/IEC 14977; βi with 1 ≤ i ≤ n is called the i’th factor of d. A δz is called the γ2-…​-γz'th factor of δ1, if, and only if, ∀i,j∈ℕ+; i = j - 1; 2 ≤ j ≤ z: δj is the γj'th factor of δi. Let G be the syntactic rule of N2. We call N1 the i1-…​-ik'th child of N2, if, and only if, N1 has been derived for the i1-…​-ik'th factor of G when deriving N2; in this case N2 is called the parent of N1. If, and only if, the i1-…​-ik'th factor of G has been derived when deriving N2, we say N2 has a i1-…​-ik'th child; otherwise it is without i1-…​-ik'th child.

A syntactic term F is without a code fragment according to some non-terminal N, if, and only if, N is not derived throughout the derivation of F; in this case, we say F does not contain a N, it is N-free. Note, that F is a syntactic term — i.e., a code fragment derived according to the syntactic rule for the non-terminal F — whereas N is just a non-terminal referring to some syntactic rule; nevertheless, N will be highlighted italic in semantic rules as if it is a syntactic term, denoting that it is a non-existing code fragment.

E-1: The derivation of the following block fragment defines various syntactic relations (denoted by using capitals only). Note, that according to M-1.1 syntactic relations are only defined for syntactically correct inputs, i.e., blocks (cf. S-2.1).

/*
    For-loop CONTAINING another for-loop.
    Thus, neither for-loop is BEFORE or AFTER the other.
    Both for-loops are function-call-FREE:
*/
for i in 1:size(A,1) loop
    /*
        If-statement PART OF a for-loop and CONTAINING a
        DIFFERENT for-loop. The if-statement is WITHOUT a
        function-call since it does NOT CONTAIN such:
    */
    if
        /*
            The 2ND CHILD of the if-statement is an expression:
        */
        mod(i,2) == 0
    then
        /*
            NESTED for-loop, i.e., a for-loop CONTAINED in
            another for-loop. The NESTED for-loop FOLLOWS its
            CONTAINING if-statement's 2ND CHILD:
        */
        for j in 1:size(A,2) loop
            /*
                Assignment α PRECEDING another assignment β, with
                which its 1ST CHILD is LEXICALLY-EQUIVALENT.
                The assignment is also BEFORE another assignment γ
                that is DIFFERENT to β; all three assignments are
                SIBLINGS:
            */
            A[i,j] := 1; // α
        end for;
    else
        /*
            Assignment β AFTER a PRECEDING assignment α with
            LEXICALLY-EQUIVALENT 1ST CHILD:
        */
        A[i,j] := 0; // β
    end if;
end for;
/*
    Assignment γ most likely not PART OF a for-loop,
    but for sure with exactly one function-declaration CONTAINER
    that trivially is its CLOSEST function-declaration CONTAINER:
*/
A[size(A,1), size(A,2)] := -1; // γ

E-2: Consider the syntactic rule G-2.3:

function-declaration =
    ( "function" | "method" ),
    name,
    { parameter-declaration },
    [ "protected", { local-variable-declaration } ],
    "algorithm",
    { statement },
    "end",
    name,
    ";" ;

Its first factor is ( "function" | "method" ), its 1-2’th factor is "method", its 4’th factor is [ "protected", { local-variable-declaration } ], its 4-2’th factor is { local-variable-declaration } and its 4-2-1’th factor is local-variable-declaration. According to the presented syntactic rule, every function-declaration must have a 5’th child lexically-equivalent to "algorithm" even if it contains no statements; it can also be without 4-2’th child although it has a 4’th and 4-1’th child. It is important to note here, that if without 4-2’th child, a function-declaration cannot contain local-variable-declarations; the reason is because the 4-2’th factor is the only possibility to derive local-variable-declaration throughout any possible derivation of function-declaration. Likewise the 6’th factor is the only possibility to derive statements throughout the derivation of function-declarations. Finally, note the difference between without an i'th child vs. without a code fragment according to some non-terminal. Local-variable-declaration and parameter-declaration will always derive variable-declaration throughout their own derivation. Thus, function-declarations for example can be without 4-2’th child and still contain a variable-declaration if they have a 3’rd child, i.e., a function-declaration can be without 4-2’th child but still not variable-declaration-free.

Consider the following function-declaration:

function foo
protected
algorithm
end foo;

Its second and eight children are names lexically-equivalent to foo. It is without 1-2’th child because it has a 1-1’th child lexically-equivalent to "function". And although it has a 4’th child, it is without a local-variable-declaration.

Using syntactic relations, complicated constraints can be conveniently and precisely defined. For example, the usage of references in statically-evaluated expressions is restricted; on the one hand, they never must be used to access control-state-dependent — i.e., runtime — values, but on the other hand, they should be available to access runtime-independent values provided by the dimensionality- and termination-analysis like the dimensional-sizes of variables or the iteration-values of loop-iterator variables which are always statically-bound. A respective formal definition, based on syntactic relations only, is: every reference contained in a constant-scalar-integer-expression must either, be the 3’rd child of a dimension-query or have a unique for-loop container whose loop-iterator-declaration is lexically-equivalent to the reference. Although such constraints sound like common prose, they are completely formally well-defined by meta-rules M-1.1 to M-1.3 and the derivation semantics of EBNF as defined in Section 5 of ISO/IEC 14977.

It is important to note, that meta-rules, like M-1.1 to M-1.3, are used by nearly all semantic rules and therefore not explicitly referenced by definitions even if relevant.

Semantic Rules

Likewise syntactic rules, also semantic rules have unique rule-numbers. The structure for semantic rule-numbers is S-X1.X2; again X1 is the section the rule is part of and X2 a unique rule-number within that section. The unique rule-number is followed by an informal rule name describing the rule-intention, a slash and finally one or more semantic concepts the rule contributes to, all wrapped in parenthesis. The actual definition follows separated by colon.

As an example consider the following semantic rule:

S-TODO (guarded multi-dimension access / Dimensionality-analysis): For each dimensional-context of the function-declaration a reference R is part of (cf. S-TODO), the dimensional-bounds of the computed-dimensions of R must be within the dimensional-bounds of the declaration R refers to (cf. S-TODO).

The general definition of dimensional-bounds and what it means for one to be within another is given by meta-rule M-TODO to which — like for all common meta-rules — is not explicitly referred to.

Rationales, Limitations and Examples

Besides syntactic and semantic rules, sections also list rationales, limitations and examples. A rationale gives further reason why something is specified as it is, like usage-considerations, other specifications of interest or easy overlooked cases that are non-trivial to handle. A limitation clarifies a language constraint that might be relaxed in further iterations of the standard to support future use-cases, that is required to support further tooling working with GALEC code or that is very hard to ease in general for which reason it has been introduced. Examples are used to investigate the implications of the specification by demonstrating code fragments that are illegal GALEC code or that are valid but with a twist fostering understanding of the specification. All three — rationales, limitations and examples — can be part of semantic rules, in which case they are uniquely numbered within the rule they are part of. If more general, they can also be freestanding, in which case their unique number is constructed likewise syntactic and semantic rule numbers, only that rationales are prefixed by R-, limitations by L- and examples by E-. In any case, rationales and limitations have an informal name describing their intention likewise semantic rules have. If freestanding, they also can be associated with semantic concepts, again separated by a slash like for semantic rules; if not freestanding and part of a semantic rule, they implicitly contribute to the same semantic concepts as the rule they are part of.

As an example consider the following non-freestanding rationales, example and limitation:

S-TODO (uniqueness of early loop exits / Termination-analysis): Let B1 and B2 be two different early-loop-exits. Their respective closest for-loop containers must be different; and their loop-iterator-references must refer to different for-loops.

R-1 (well-formedness): That early-loop-exits must be part of a for-loop, and the name-analysis of their loop-iterator-references, are already defined by S-TODO.

R-2 (MISRA C:2012 compliance): The rule is introduced to enforce compliance with MISRA C:2012, Rule 15.4.

E-1: The following for-loop is illegal due to multiple early loop exits for each of the nested loops:

for i in 1:3 loop // Outer loop.
    for j in 1:3 loop // Inner loop.
        if b1 then
            break i; // First break of outer and inner loop.
        else
            break j; // Illegal: Second break of inner loop.
        end if;
    end for;
    if b3 then
        break i; // Illegal: Second break of outer loop.
    end if;
end for;

L-1 (relaxation of MISRA C:2012 compliance): To transform non-unique early loop exists to a unique form complying with MISRA C:2012 is not trivial. Production code generators may miss support for such transformations, to which end this rule has been introduced. On the other hand, it may unnecessarily constrain GALEC code generators, even forcing them to fail to generate an algorithmic solution. To shift the responsibility of compliance from GALEC code generators to Production Code generators, the rule can be disabled using the consider-misra=false flag throughout GALEC code generation.

Other specification parts can refer to enclosed rationales, limitations and examples by appending their unique number separated by a colon to the number of the enclosing semantic rule; for example, one can refer to the limitation of above example by writing S-TODO:L-1.

4.2.3. Block-interface and life-cycle

This Section investigates the utilization of GALEC programs (i.e., blocks) that are due for deployment on an embedded target and its runtime environment.

§1: Embedded target, runtime environment, system integration, block instance & block-interface (terminology, system integration)

GALEC defines an operational interface for blocks — called block-interface — that must be preserved by Production Code generators when translating a block to code that is subject of embedded system integration. Embedded system integration is not just achieved by means of a block’s interface; it must over and above adhere to the operational restrictions defined in §1 to §3 (particularly the block life-cycle of §3 must be satisfied).

A single block can be instanziated many times on an embedded target and its runtime environment; each instance is operationally isolated. There are no restrictions on the number or kind of block instances (in particular different blocks can be instanciated within the same runtime environment). Any interaction of the runtime environment with a block instance must be via its block-interface (even instances of the same block must interact via their block-interface).

§2: Block-interface variables & methods (runtime semantic, system integration)

The block-interface constitues of block-interface variables and block-interface methods.

The block-interface variables are:

  • Block inputs: The sampling inputs provided by the runtime environment.

  • Block outputs: The sampling results consumed by the runtime environment; they must never be written by the runtime environment.

  • Tunable parameters: Parameters sporadically, and not necessarily each sampling, changed by the runtime environment.

Besides this block-interface variables, other block-variables exist, which are block internal and therefore cannot (and must not, cf. §1) be written or read by the runtime environment:

  • Dependent parameters: The parameters derived from tunable parameters.

  • Block states: The internal states.

All block-variables are persistently stored in block instances, such that their values survive block-interface method calls and therefore can be used in call sequences of such. Each block instance has its individual set of block-variables; changing some tunable parameter t of a block instance b1 does not change t of another block instance b2 of the same block.

The block-interface methods are:

  • Startup(): Computes initial values for all block-variables.

  • Recalibrate(): Updates the dependent parameters considering the currently set tunable parameters.

  • DoStep(): Computes the block outputs and updates the block states for the given block inputs and the current tunable and dependent parameters for a single sampling.

L-1 (design-space of Production Code generation and system integration): Production Code generators and system integration are free to realize a GALEC block by any means they see fit as long as its operational semantic is satisfied. They can achieve a mutual agreement that block-interface functionality is not supported, like recalibration by means of Recalibrate() or reading block inputs from the runtime environment, given that the use-case and system integration scenario does not require such. In general however, Production Code generators must support the full block-interface and life-cycle to be eFMI specification conformant.

Examples of integration scenario specific design-space agreements are:

  1. Not generate and call Startup(), but instead statically evaluate it and store start values in read only memory or only load them once when the runtime system boots.

  2. Not generate a dedicated DoStep() function, but instead inline the implementation in the runtime environment.

  3. Not generate Recalibrate(), transforming tunable and dependent parameters to become constants which can be constant-folded.

  4. Store block-variables globally, leveraging on knowing that there is exactly one instance and not several (no need to support individual block-instances).

  5. Not persist block inputs (cf. §3:R-1, last paragraph), but instead provide new values for every input every sampling, for example as function arguments to DoStep().

Particularly (3) is a common integration scenario, since recalibration typically is only performed during the development phase of an embedded system and no longer supported in production systems.

R-1 (block-variable initialization and Algorithm Code Container manifest start values): The start values of the variables in the manifest of an Algorithm Code Container are conceptually determined by calling Startup() on the target system and its runtime environment. A Production Code generator can for example (1) use these start values directly in the C-Code for static initialization (i.e., as precomputed values), hereby casting from the concrete manifest-variable type in which the start-values are stored to the best fitting concrete type of the target system, or (2) provide an implementation of Startup() to be called by the runtime environment during startup, or (3) use any other means to ensure block-variables have initial values according to Startup() (cf. §2:R-1).

§3: Block life-cycle (runtime semantic, system integration)

The permitted interactions with block instances are defined by the following state machine, specifying a universal life-cycle for block instances, called block life-cycle (the do-actions of states refer to the block-interface methods defined in §2):