diff --git a/Makefile b/Makefile index 54f1279..be972dc 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,7 @@ export PACKAGE_ARCH ?= linux-amd64 export PACKAGE_ARCH_LIST ?= $(PACKAGE_ARCH) export CMAKE_TOOLCHAIN_FILE ?= $(shell pwd -P)/extra/cmake/$(PACKAGE_ARCH).cmake SRC_DIR = $(NAMESPACE)/$(MODULE) -SUBDIRS = extra/external $(SRC_DIR)/fmi/examples -# $(NAMESPACE)/$(MODULE)/fmi/models +SUBDIRS = extra/external ############### diff --git a/doc/Makefile b/doc/Makefile index d3fe3d8..5534916 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -25,13 +25,6 @@ export _INDEX_MD_FILE DOC_OUTPUT_index := doc/content/apis/clib/_index.md -# Module "fmi" -DOC_INPUT_fmi := dse/clib/fmi/fmu.h -DOC_CDIR_fmi := dse/clib/fmi/fmu.c,dse/clib/fmi/importer.c,dse/clib/fmi/storage.c,dse/clib/fmi/strategy.c -DOC_OUTPUT_fmi := doc/content/apis/clib/fmi/index.md -DOC_LINKTITLE_fmi := FMI -DOC_TITLE_fmi := "FMI API Reference" - # Module "marshal" DOC_INPUT_marshal := dse/clib/data/marshal.h DOC_CDIR_marshal := dse/clib/data/marshal.c @@ -40,7 +33,7 @@ DOC_LINKTITLE_marshal := Marshal DOC_TITLE_marshal := "Marshal API Reference" # Targets -DOC_C_MODULES := fmi marshal +DOC_C_MODULES := marshal .PHONY: examples diff --git a/doc/content/apis/clib/fmi/fmu-model.png b/doc/content/apis/clib/fmi/fmu-model.png deleted file mode 100644 index 3466f66..0000000 Binary files a/doc/content/apis/clib/fmi/fmu-model.png and /dev/null differ diff --git a/doc/content/apis/clib/fmi/index.md b/doc/content/apis/clib/fmi/index.md deleted file mode 100644 index bcdaded..0000000 --- a/doc/content/apis/clib/fmi/index.md +++ /dev/null @@ -1,417 +0,0 @@ ---- -title: FMI API Reference -linkTitle: FMI ---- -## storage_get_bucket - - -Returns a reference/pointer to the requested storage bucket. - -### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor. - -type (storage_type) -: Indicate the storage type bucket which should be retrieved. - -### Returns - -storage_bucket* -: Reference to the requested storage bucket. - -NULL -: The specified storage bucket is not provisioned. - - - -## FMU Model API - - -The FMU Model API (a part of the DSE C Lib) provides a simplified interface for -developing Models which adhere to the Modelica Association FMI Standard. It has -the following notable capabilities: - -* Models are compatible with either FMI 2 or FMI 3 (selected via linker). -* Simple model lifecycle: - * `fmu_model_init()` - * `fmu_model_step()` - only function needed for a minimal FMU implementation! - * ... -* Storage system with fast hash based index for all FMI Variable types, including binary data. -* Integration with [DSE Network Codec API](https://github.com/boschglobal/dse.standards/tree/main/dse/ncodec) - which provides a MIMEtype selected (and configured) CAN Virtual Buses. The Network Codec has a simple - to use programming interface: - * `ncodec_write()` / `ncodec_flush()` - to send CAN frames - * `ncodec_read()` - to receive CAN frames. - - -### Component Diagram - - - -![fmu-model](fmu-model.png) - - -### Example - - -The following example shows a minimal model implementation which simply -increments a counter. - -{{< readfile file="../examples/counter.c" code="true" lang="c" >}} - - -### Linking - -When building an FMU, link the following files: - -- fmu.c : generic implementation parts -- storage.c : storage mechanism -- fmi2/fmi2fmu.c : version specific parts -- model.c : model specific parts - - - - -## fmu_model_create - - -Creates an FMU Model Descriptor object and performs any necessary -initialisation of the FMU Model. - -Called by `fmi2Instantiate()`. - -Called by `fmi3InstantiateCoSimulation()`. - -### Parameters - -fmu_inst (void*) -: FMU provided instance data. - -mem_alloc (FmuMemAllocFunc) -: Function pointer for the memory allocation function which the Model should - use. Recommend using calloc(). - -mem_free (FmuMemFreeFunc) -: Function pointer for the memory free function which the Model should use. - Typically free(). - -resource_location (const char*) -: A string referencing the path to the resource directory. - -### Returns - -FmuModelDesc* -: A new FMU Model Descriptor object. - - - -## Typedefs - -### FmuAdapterDesc - -```c -typedef struct FmuAdapterDesc { - const char* name; - FmuLoadHandler load_func; - FmuInitHandler init_func; - FmuStepHandler step_func; - FmuUnloadHandler unload_func; - FmuSetVarHandler set_var_func; - FmuGetVarHandler get_var_func; -} -``` - -### FmuInstDesc - -```c -typedef struct FmuInstDesc { - const char* name; - const char* path; - void* model_doc; - FmuAdapterDesc* adapter; - FmuStrategyDesc* strategy; - void* inst_data; - void* model_desc; -} -``` - -### FmuModelDesc - -```c -typedef struct FmuModelDesc { - FmuMemAllocFunc mem_alloc; - FmuMemFreeFunc mem_free; - const char* resource_location; - void* instance_data; - void* private; - int external_binary_free; -} -``` - -### FmuStrategyDesc - -```c -typedef struct FmuStrategyDesc { - const char* name; - FmuStrategyExecuteFunc exec_func; - FmuStrategyMapVariables map_func; - FmuStrategyToVariables marshal_to_var_func; - FmuStrategyFromVariables marshal_from_var_func; - FmuStrategyMapDestroy map_destroy_func; - double step_size; - double model_time; - double stop_time; - double model_time_correction; -} -``` - -### storage_bucket - -```c -typedef struct storage_bucket { - storage_type type; - int index; -} -``` - -## Functions - -### fmi2_cosim_execute - -Applies an action (load, init, step etc) from an FMI2 CoSim execution strategy -to the specified FMU instance. The strategy action will call FMU methods -according to the FMI Standard. - -#### Parameters - -inst (FmuInstDesc*) -: Model Descriptor, references various runtime functions and data. - -action (FmuStrategyAction) -: The action which should be executed by the strategy. - -#### Returns - -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. - - - -### fmu_model_destroy - -Called by `fmi2FreeInstance()`. - -Called by `fmi3FreeInstance()`. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -#### Returns - -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. - - - -### fmu_model_finalize - -Releases the resources created by `fmu_model_create()`. - -Called by `fmi2FreeInstance()`. - -Called by `fmi3FreeInstance()`. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - - - -### fmu_model_init - -Called by `fmi2ExitInitializationMode()` as the FMU exits initialisation mode. - -Called by `fmi3ExitInitializationMode()` as the FMU exits initialisation mode. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -#### Returns - -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. - - - -### fmu_model_step - -Called by `fmi2DoStep()`. - -Called by `fmi3DoStep()`. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -#### Returns - -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. - - - -### fmu_model_terminate - -Called by `fmi2Terminate()`. - -Called by `fmi3Terminate()`. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -#### Returns - -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. - - - -### storage_destroy - -Destroy any allocated storage. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor. - -#### Returns - -0 (int) -: Success. - -+ve (int) -: Failure, inspect errno for the failing condition. - - - -### storage_init - -Initialise the storage subsystem for an FMU. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor. - -#### Returns - -0 (int) -: Success. - -+ve (int) -: Failure, inspect errno for the failing condition. - - - -### storage_ref - -Get a reference (pointer to) the specified storage value. The returned -reference must be cast to the provided storage_type by the caller before -accessing the storage value. - -#### Parameters - -model_desc (FmuModelDesc*) -: Model Descriptor. - -vr (unsigned int) -: FMU Variable Reference. - -type (storage_type) -: Indicate the storage type bucket from which the storage reference should - be retrieved. - -#### Returns - -void* -: Reference to a storage value (caller must cast to storage_type). - -NULL -: A reference to the storage value could not be retrieved. - -#### Example - - -```c -#include - -static FmuModelDesc* model_desc; - -int set_int_value(unsigned int vr, int value) -{ - int *ref = (int*)storage_ref(model_desc, vr, STORAGE_INT); - if (ref == NULL) return 1; - *ref = value; - return 0; -} -``` - - - diff --git a/doc/content/apis/clib/marshal/index.md b/doc/content/apis/clib/marshal/index.md index 57a1a87..512f969 100644 --- a/doc/content/apis/clib/marshal/index.md +++ b/doc/content/apis/clib/marshal/index.md @@ -2,6 +2,37 @@ title: Marshal API Reference linkTitle: Marshal --- +## marshal_generate_signalmap + + +Creates a signal map between signals (i.e. the external signal +interface) and the source (i.e. the internal interface to the target). + +### Parameters + +signal (MarshalMapSpec) +: A map spec for the signals to be mapped (i.e. the representation of +the signal interface). + +source (MarshalMapSpec) +: A map spec for the source values to be mapped (i.e. the representation +of the target). + +ex_signals (SimpleSet*) +: A set used to keep track of signals between calls (to this function) +and prevent duplicate mappings. + +is_binary (bool) +: The signal map represents binary signals (i.e. `signal` and `source` +are binary signals). + +### Returns + +MarshalSignalMap +: A MarshalSignalMap object. + + + ## Marshal API @@ -20,7 +51,7 @@ externally defined data structures (i.e. C style structs). -![data-marshal-interface](data-marshal-interface.png) +![](data-marshal-interface.png) + + + +## marshal_type_size + + +Return the size of a `MarshalType` (in bytes). + +### Parameters + +type (MarshalType*) +: A marshal type. + +### Returns + +size_t +: The size of the type (in bytes). @@ -61,8 +109,10 @@ typedef struct MarshalGroup { MarshalKind kind; MarshalDir dir; MarshalType type; - struct (anonymous struct at dse/clib/data/marshal.h:116:5) target; - struct (anonymous struct at dse/clib/data/marshal.h:128:5) source; + struct (anonymous struct at dse/clib/data/marshal.h:133:5) target; + struct (anonymous struct at dse/clib/data/marshal.h:148:5) source; + struct (anonymous struct at dse/clib/data/marshal.h:160:5) functions; + uint64_t [4] __reserved__; } ``` @@ -72,7 +122,11 @@ typedef struct MarshalGroup { typedef struct MarshalMapSpec { const char* name; int count; + bool is_binary; const char** signal; + uint32_t* binary_len; + uint32_t* binary_buffer_size; + uint64_t [4] __reserved__; } ``` @@ -83,8 +137,9 @@ typedef struct MarshalSignalMap { char* name; int count; bool is_binary; - struct (anonymous struct at dse/clib/data/marshal.h:184:5) signal; - struct (anonymous struct at dse/clib/data/marshal.h:194:5) source; + struct (anonymous struct at dse/clib/data/marshal.h:227:5) signal; + struct (anonymous struct at dse/clib/data/marshal.h:239:5) source; + uint64_t [4] __reserved__; } ``` @@ -97,43 +152,14 @@ typedef struct MarshalStruct { void* handle; MarshalKind kind; MarshalDir dir; - struct (anonymous struct at dse/clib/data/marshal.h:147:5) target; - struct (anonymous struct at dse/clib/data/marshal.h:154:5) source; + struct (anonymous struct at dse/clib/data/marshal.h:179:5) target; + struct (anonymous struct at dse/clib/data/marshal.h:186:5) source; + uint64_t [4] __reserved__; } ``` ## Functions -### marshal_generate_signalmap - -Creates a signal map between signals (i.e. the external signal interface) and -the source (i.e. the internal interface to the target). - -#### Parameters - -signal (MarshalMapSpec) -: A map spec for the signals to be mapped (i.e. the representation of the signal -interface). - -source (MarshalMapSpec) -: A map spec for the source values to be mapped (i.e. the representation of the -target). - -ex_signals (SimpleSet*) -: A set used to keep track of signals between calls (to this function) and -prevent duplicate mappings. - -is_binary (bool) -: The signal map represents binary signals (i.e. `signal` and `source` are -binary signals). - -#### Returns - -MarshalSignalMap -: A MarshalSignalMap object. - - - ### marshal_group_destroy Release resources associated with a `MarshalGroup` table, and the table itself. @@ -169,13 +195,14 @@ mg_table (MarshalGroup*) ### marshal_signalmap_destroy -Release resources associated with a `MarshalSignalMap` table, and the table -itself. +Release resources associated with a `MarshalSignalMap` table, and the +table itself. #### Parameters map (MarshalSignalMap*) -: A MarshalSignalMap list (Null-Terminated-List, indicated by member `name`). +: A MarshalSignalMap list (Null-Terminated-List, indicated by member +`name`). @@ -183,10 +210,13 @@ map (MarshalSignalMap*) Marshal a `MarshalGroup` inwards (from the marshal target). + Signal <-[marshal_signalmap_in()]- Source -> Target + #### Parameters map (MarshalSignalMap*) -: A MarshalSignalMap list (Null-Terminated-List, indicated by member `name`). +: A MarshalSignalMap list (Null-Terminated-List, indicated by member +`name`). @@ -194,26 +224,13 @@ map (MarshalSignalMap*) Marshal a `MarshalSignalMap` outwards (towards the marshal target). -#### Parameters - -map (MarshalSignalMap*) -: A MarshalSignalMap list (Null-Terminated-List, indicated by member `name`). - - - -### marshal_type_size - -Return the size of a `MarshalType` (in bytes). + Signal -[marshal_signalmap_out()]-> Source -> Target #### Parameters -type (MarshalType*) -: A marshal type. - -#### Returns - -size_t -: The size of the type (in bytes). +map (MarshalSignalMap*) +: A MarshalSignalMap list (Null-Terminated-List, indicated by member +`name`). diff --git a/doc/static/dse.clib/arch__fmi_library.png b/doc/static/dse.clib/arch__fmi_library.png deleted file mode 100644 index 267cd3a..0000000 Binary files a/doc/static/dse.clib/arch__fmi_library.png and /dev/null differ diff --git a/dse/clib/fmi/examples/CMakeLists.txt b/dse/clib/fmi/examples/CMakeLists.txt deleted file mode 100644 index f4cec0f..0000000 --- a/dse/clib/fmi/examples/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - - - - -cmake_minimum_required(VERSION 3.21) - -project(FmiExamples DESCRIPTION "DSE C Lib - FMI Examples.") - -add_subdirectory(importer) diff --git a/dse/clib/fmi/examples/Makefile b/dse/clib/fmi/examples/Makefile deleted file mode 100644 index 96230d0..0000000 --- a/dse/clib/fmi/examples/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -export NAMESPACE = dse -export MODULE = clib -export EXTERNAL_BUILD_DIR ?= /tmp/$(NAMESPACE).$(MODULE) -export REPO_DIR = $(shell cd ../../../..; pwd -P) -export PACKAGE_ARCH ?= linux-amd64 -export CMAKE_TOOLCHAIN_FILE ?= $(REPO_DIR)/extra/cmake/$(PACKAGE_ARCH).cmake -export PROJECT_URL ?= https://github.com/boschglobal/$(NAMESPACE).$(MODULE).git -export PACKAGE_VERSION ?= 0.0.2 -export GCC_BUILDER_IMAGE ?= gcc-builder:latest - - -default: build - -build: - $(MAKE) do-build - -do-build: - if [ ! -d "build" ]; then make setup; fi - cd build; make - cd build; make install -# cd build/_out/example/fmu/counter; zip -q -r counter.fmu ./ - @echo "" - @echo "Sandbox files: - $$(pwd)/build/_out" - @echo "--------------" - @find build/_out/ -type f -name '*' -exec ls -sh --color=auto {} \; - -setup: - mkdir build; - cd build; cmake -DCMAKE_TOOLCHAIN_FILE=$(CMAKE_TOOLCHAIN_FILE) .. - -clean: - rm -rf build - -.PHONY: default build do-build setup clean diff --git a/dse/clib/fmi/examples/fmu/counter/CMakeLists.txt b/dse/clib/fmi/examples/fmu/counter/CMakeLists.txt deleted file mode 100644 index 277e2bb..0000000 --- a/dse/clib/fmi/examples/fmu/counter/CMakeLists.txt +++ /dev/null @@ -1,142 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.21) - -set(VERSION "$ENV{PACKAGE_VERSION}") -set(FMU_DESCRIPTION "DSE C Lib Example - FMU Counter.") -set(FMU_TARGET "counter") -set(FMU_OUTDIR "example/fmu/counter") - -project(fmu-counter - VERSION ${VERSION} - DESCRIPTION "${FMU_DESCRIPTION}" - HOMEPAGE_URL "${PROJECT_URL}" -) - - -# Set the default install location to build/_out (for unit testing). -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/_out - CACHE PATH "isolated build install" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - -# Make certain that CMAKE_INSTALL_INCLUDEDIR is set. -include(GNUInstallDirs) -if(NOT DEFINED ${CMAKE_INSTALL_INCLUDEDIR}) - set(CMAKE_INSTALL_INCLUDEDIR "include") -endif(NOT DEFINED ${CMAKE_INSTALL_INCLUDEDIR}) - - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED TRUE) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_C_FLAGS_DEBUG "-g -ggdb") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O3") -list(APPEND C_CXX_WARNING_FLAGS - -Wall - -W - -Wwrite-strings - -Wno-missing-field-initializers - -Wno-misleading-indentation -) -add_compile_options(${C_CXX_WARNING_FLAGS}) -add_compile_definitions(DLL_BUILD) - -set(CMAKE_SHARED_LIBRARY_PREFIX "") - - -# External Project - yaml -# ----------------------- -set(YAML_SOURCE_DIR "$ENV{EXTERNAL_BUILD_DIR}/yaml") -set(YAML_BINARY_DIR "$ENV{EXTERNAL_BUILD_DIR}/yaml") -find_library(YAML_LIB - NAMES - libyaml.a - PATHS - ${YAML_BINARY_DIR} - REQUIRED - NO_DEFAULT_PATH -) -add_library(yaml STATIC IMPORTED GLOBAL) -set_target_properties(yaml - PROPERTIES - IMPORTED_LOCATION "${YAML_LIB}" - INTERFACE_INCLUDE_DIRECTORIES "${YAML_BINARY_DIR}" -) - - -# DSE C Lib -# --------- -set(DSE_CLIB_SOURCE_DIR ../../../dse/clib) -set(DSE_CLIB_SOURCE_FILES - ${DSE_CLIB_SOURCE_DIR}/collections/hashmap.c - ${DSE_CLIB_SOURCE_DIR}/util/yaml.c - ${DSE_CLIB_SOURCE_DIR}/fmi/fmu.c - ${DSE_CLIB_SOURCE_DIR}/fmi/storage.c - ${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/fmi2api.c -) -set(DSE_CLIB_INCLUDE_DIR "${DSE_CLIB_SOURCE_DIR}/../..") -set(FMI2_INCLUDE_DIR "${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/headers") - - - -# Targets -# ======= - -# FMU Counter -# ----------- -add_library(${FMU_TARGET} SHARED - ${DSE_CLIB_SOURCE_FILES} - ${DSE_CLIB_SOURCE_DIR}/fmi/models/nop_weak.c - ${DSE_CLIB_SOURCE_DIR}/fmi/models/log_level.c - counter.c -) -target_include_directories(${FMU_TARGET} - PRIVATE - ${FMI2_INCLUDE_DIR} - ${YAML_SOURCE_DIR}/include - ${DSE_CLIB_INCLUDE_DIR} -) -target_link_libraries(${FMU_TARGET} - PRIVATE - yaml -) -set(FMU_EXAMPLE_MODEL_DESCRIPTION - modelDescription.xml -) -set(FMU_EXAMPLE_RESOURCE_FILES - fmu.yaml -) -install( - TARGETS - ${FMU_TARGET} - DESTINATION - ${FMU_OUTDIR}/binaries/linux64 -) -install( - FILES - ${FMU_EXAMPLE_MODEL_DESCRIPTION} - DESTINATION - ${FMU_OUTDIR} -) -install( - FILES - ${FMU_EXAMPLE_RESOURCE_FILES} - DESTINATION - ${FMU_OUTDIR}/resources -) - - - -# Package -# ======= -set(CPACK_SYSTEM_NAME $ENV{PACKAGE_ARCH}) -set(CPACK_PACKAGE_VENDOR "Robert Bosch GmbH") -set(CPACK_PACKAGE_DESCRIPTION "${FMU_DESCRIPTION}") -set(CPACK_OUTPUT_FILE_PREFIX _dist) -set(CPACK_GENERATOR "TGZ;ZIP") -set(CPACK_PACKAGE_CHECKSUM MD5) -set(CPACK_MONOLITHIC_INSTALL TRUE) -include(CPack) diff --git a/dse/clib/fmi/examples/fmu/counter/Makefile b/dse/clib/fmi/examples/fmu/counter/Makefile deleted file mode 100644 index 13db76a..0000000 --- a/dse/clib/fmi/examples/fmu/counter/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -export NAMESPACE = dse -export MODULE = clib -export EXTERNAL_BUILD_DIR ?= /tmp/$(NAMESPACE).$(MODULE) -export REPO_DIR = $(shell cd ../../..; pwd -P) -export PACKAGE_ARCH ?= linux-amd64 -export CMAKE_TOOLCHAIN_FILE ?= $(REPO_DIR)/extra/cmake/$(PACKAGE_ARCH).cmake -export PROJECT_URL ?= https://github.com/boschglobal/$(NAMESPACE).$(MODULE).git -export PACKAGE_VERSION ?= 0.0.2 -export GCC_BUILDER_IMAGE ?= gcc-builder:latest - - -ifneq ($(CI), true) - DOCKER_BUILDER_CMD := cd $(REPO_DIR); docker run -it --rm \ - --env CMAKE_TOOLCHAIN_FILE=/tmp/repo/extra/cmake/$(PACKAGE_ARCH).cmake \ - --env EXTERNAL_BUILD_DIR=$(EXTERNAL_BUILD_DIR) \ - --env PACKAGE_ARCH=$(PACKAGE_ARCH) \ - --env PACKAGE_VERSION=$(PACKAGE_VERSION) \ - --volume $$(pwd):/tmp/repo \ - --volume $(EXTERNAL_BUILD_DIR):$(EXTERNAL_BUILD_DIR) \ - --volume ~/.ccache:/root/.ccache \ - --workdir /tmp/repo/examples/fmu/counter \ - $(GCC_BUILDER_IMAGE) -endif - - -default: build - -build: - @${DOCKER_BUILDER_CMD} $(MAKE) do-build - -do-build: - if [ ! -d "build" ]; then make setup; fi - cd build; make - cd build; make install - cd build/_out/example/fmu/counter; zip -q -r counter.fmu ./ - @echo "" - @echo "Sandbox files: - $$(pwd)/build/_out" - @echo "--------------" - @find build/_out/ -type f -name '*' -exec ls -sh --color=auto {} \; - -setup: - mkdir build; - cd build; cmake -DCMAKE_TOOLCHAIN_FILE=$(CMAKE_TOOLCHAIN_FILE) .. - -clean: - rm -rf build - -.PHONY: default build do-build setup clean diff --git a/dse/clib/fmi/examples/fmu/counter/counter.c b/dse/clib/fmi/examples/fmu/counter/counter.c deleted file mode 100644 index 7067c80..0000000 --- a/dse/clib/fmi/examples/fmu/counter/counter.c +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH - -#include -#include - - -#define UNUSED(x) ((void)x) - -#define VR_COUNT 42 - - -int fmu_model_step(FmuModelDesc* model_desc, double model_time, double stop_time) -{ - UNUSED(model_time); - UNUSED(stop_time); - - int* value_ref = storage_ref(model_desc, VR_COUNT, STORAGE_INT); - if (value_ref == NULL) return -1; - - *value_ref += 1; - printf("count: %d\n", *value_ref); - - return 0; -} diff --git a/dse/clib/fmi/examples/fmu/counter/fmu.yaml b/dse/clib/fmi/examples/fmu/counter/fmu.yaml deleted file mode 100644 index 7871339..0000000 --- a/dse/clib/fmi/examples/fmu/counter/fmu.yaml +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - ---- -kind: Fmu -metadata: - name: Counter -spec: - description: Counter increments on each call to do_step(). - guid: fb480c6b-0058-4628-abd3-36ba2f2ecb5f - version: 1.0.0 - modes: - cosim: - stepsize: 0.005 - modelIdentifier: counter - variables: - count: - ref: 42 - type: int32 - parameters: [] diff --git a/dse/clib/fmi/examples/fmu/counter/modelDescription.xml b/dse/clib/fmi/examples/fmu/counter/modelDescription.xml deleted file mode 100644 index d660710..0000000 --- a/dse/clib/fmi/examples/fmu/counter/modelDescription.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/dse/clib/fmi/examples/fmu/nop/CMakeLists.txt b/dse/clib/fmi/examples/fmu/nop/CMakeLists.txt deleted file mode 100644 index da9f184..0000000 --- a/dse/clib/fmi/examples/fmu/nop/CMakeLists.txt +++ /dev/null @@ -1,139 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.21) - -set(VERSION "$ENV{PACKAGE_VERSION}") - -project(dse-clib-fmi-models - VERSION ${VERSION} - DESCRIPTION "DSE C Lib FMI Models." - HOMEPAGE_URL "${PROJECT_URL}" -) - -# Set the default install location to build/_out (for unit testing). -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/_out - CACHE PATH "isolated build install" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - -# Make certain that CMAKE_INSTALL_INCLUDEDIR is set. -include(GNUInstallDirs) -if(NOT DEFINED ${CMAKE_INSTALL_INCLUDEDIR}) - set(CMAKE_INSTALL_INCLUDEDIR "include") -endif(NOT DEFINED ${CMAKE_INSTALL_INCLUDEDIR}) - - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED TRUE) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_C_FLAGS_DEBUG "-g -ggdb") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O3") -list(APPEND C_CXX_WARNING_FLAGS - -Wall - -W - -Wwrite-strings - -Wno-missing-field-initializers - -Wno-misleading-indentation -) -add_compile_options(${C_CXX_WARNING_FLAGS}) -add_compile_definitions(DLL_BUILD) - -set(CMAKE_SHARED_LIBRARY_PREFIX "") - - -# External Project - yaml (used py process list) -# ----------------------- -set(YAML_SOURCE_DIR "$ENV{EXTERNAL_BUILD_DIR}/yaml") -set(YAML_BINARY_DIR "$ENV{EXTERNAL_BUILD_DIR}/yaml") -find_library(YAML_LIB - NAMES - libyaml.a - PATHS - ${YAML_BINARY_DIR} - REQUIRED - NO_DEFAULT_PATH -) -add_library(yaml STATIC IMPORTED GLOBAL) -set_target_properties(yaml - PROPERTIES - IMPORTED_LOCATION "${YAML_LIB}" - INTERFACE_INCLUDE_DIRECTORIES "${YAML_BINARY_DIR}" -) - - -# DSE C Lib -# --------- -set(DSE_CLIB_SOURCE_DIR ../../../../dse/clib) -set(DSE_CLIB_SOURCE_FILES - ${DSE_CLIB_SOURCE_DIR}/process/process.c - ${DSE_CLIB_SOURCE_DIR}/process/process_list.c - ${DSE_CLIB_SOURCE_DIR}/collections/hashmap.c - ${DSE_CLIB_SOURCE_DIR}/util/yaml.c - - ${DSE_CLIB_SOURCE_DIR}/fmi/fmu.c - ${DSE_CLIB_SOURCE_DIR}/fmi/storage.c - ${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/fmi2fmu.c -) -set(DSE_CLIB_INCLUDE_DIR "${DSE_CLIB_SOURCE_DIR}/../..") -set(FMI2_INCLUDE_DIR "${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/headers") - - - -# Targets -# ======= - -# Model Process List -# ------------------ -add_library(model-process-list SHARED - process-list.c - ${DSE_CLIB_SOURCE_FILES} -) -target_include_directories(model-process-list - PRIVATE - ${FMI2_INCLUDE_DIR} - ${YAML_SOURCE_DIR}/include - ${DSE_CLIB_INCLUDE_DIR} -) -target_link_libraries(model-process-list - PRIVATE - yaml -) -install(TARGETS model-process-list) - -# Model NOP with Weak Definition -# ------------------------------ -add_library(model-nop-weak SHARED - nop_weak.c - ${DSE_CLIB_SOURCE_FILES} -) -target_include_directories(model-nop-weak - PRIVATE - ${FMI2_INCLUDE_DIR} - ${YAML_SOURCE_DIR}/include - ${DSE_CLIB_INCLUDE_DIR} -) -target_link_libraries(model-nop-weak - PRIVATE - yaml -) -install(TARGETS model-nop-weak) - - - -# Package -# ======= -# OS and ARCH should match Docker metadata for multi-arch containers. -# os: linux -# arch: amd64 -# variant: v7 (optional, i.e. for arm) -# Combines to "linux-amd64" or "linux-arm-v7" -set(CPACK_SYSTEM_NAME $ENV{PACKAGE_ARCH}) -set(CPACK_PACKAGE_VENDOR "Robert Bosch GmbH") -set(CPACK_PACKAGE_DESCRIPTION "DSE C Lib FMI Models") -set(CPACK_OUTPUT_FILE_PREFIX _dist) -set(CPACK_GENERATOR "TGZ;ZIP") -set(CPACK_PACKAGE_CHECKSUM MD5) -set(CPACK_MONOLITHIC_INSTALL TRUE) -include(CPack) diff --git a/dse/clib/fmi/examples/fmu/nop/Makefile b/dse/clib/fmi/examples/fmu/nop/Makefile deleted file mode 100644 index 34096c1..0000000 --- a/dse/clib/fmi/examples/fmu/nop/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -############### -## Build parameters. -export EXTERNAL_BUILD_DIR ?= /tmp/dse.clib -export PACKAGE_ARCH ?= linux-amd64 -export CMAKE_TOOLCHAIN_FILE ?= $(shell pwd -P)/../../../extra/cmake/$(PACKAGE_ARCH).cmake -export PROJECT_URL ?= https://github.com/boschglobal/dse.clib.git -export PACKAGE_VERSION ?= 0.0.1 - - -default: build - -build: -# Build from scratch if no build dir. - if [ ! -d "build" ]; then \ - mkdir -p build; \ - cd build; \ - cmake -DCMAKE_TOOLCHAIN_FILE=$(CMAKE_TOOLCHAIN_FILE) .. ; \ - fi -# Build incremental. - cd build; make - cd build; make install - @echo "" - @echo "Sandbox files: - $$(pwd)/build/_out" - @echo "--------------" - @find build/_out/ -type f -name '*' -exec ls -sh --color=auto {} \; - -clean: - rm -rf build - -cleanall: clean - - -.PHONY: default build clean cleanall diff --git a/dse/clib/fmi/examples/fmu/nop/log_level.c b/dse/clib/fmi/examples/fmu/nop/log_level.c deleted file mode 100644 index 4094e85..0000000 --- a/dse/clib/fmi/examples/fmu/nop/log_level.c +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -uint8_t __log_level__ = LOG_DEBUG; diff --git a/dse/clib/fmi/examples/fmu/nop/nop_weak.c b/dse/clib/fmi/examples/fmu/nop/nop_weak.c deleted file mode 100644 index 7583e8a..0000000 --- a/dse/clib/fmi/examples/fmu/nop/nop_weak.c +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include - - -#define UNUSED(x) ((void)x) - - -/** - * fmu_model_init - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - * - * Returns - * ------- - * 0 : success. - */ -__attribute__((weak)) int fmu_model_init(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - return 0; -} - - -/** - * fmu_model_step - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - * - * Returns - * ------- - * 0 : success. - */ -__attribute__((weak)) int fmu_model_step( - FmuModelDesc* model_desc, double model_time, double stop_time) -{ - UNUSED(model_desc); - UNUSED(model_time); - UNUSED(stop_time); - - return 0; -} - - -/** - * fmu_model_terminate - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - * - * Returns - * ------- - * 0 : success. - */ -__attribute__((weak)) int fmu_model_terminate(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - return 0; -} - - -/** - * fmu_model_destroy - * - * Free the loaded process list. - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - */ -__attribute__((weak)) void fmu_model_destroy(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); -} diff --git a/dse/clib/fmi/examples/fmu/nop/process-list.c b/dse/clib/fmi/examples/fmu/nop/process-list.c deleted file mode 100644 index 6e75ed1..0000000 --- a/dse/clib/fmi/examples/fmu/nop/process-list.c +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - - -#define UNUSED(x) ((void)x) - -#define VR_EXPECTED_PROC_COUNT 100 -#define VR_REDIS_PORT 1001 -#define VR_SIMBUS_LOGLEVEL 1002 -#define VR_SIMBUS_TRANSPORT 1003 -#define VR_SIMBUS_URI 1004 -#define VR_MEASUREMENT_DIR 1005 - - -/* Process List. */ -static DseProcessDesc* process_list; -#define PROCESS_LIST_FILENAME "resources/process_list.yaml" - - -static void _set_envvar( - FmuModelDesc* model_desc, const char* name, unsigned int vr) -{ - char** value_ref = storage_ref(model_desc, vr, STORAGE_STRING); - if (value_ref) { - if ((*value_ref) && (strlen(*value_ref))) { - errno = 0; - int rc = setenv(name, *value_ref, true); - if (rc) log_error("Failed call to setenv() for %s", name); - } - } -} - - -/** - * fmu_model_init - * - * Load the process list and start all configured processes. - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - * - * Returns - * ------- - * 0 : success. - * +ve : failure, inspect errno for the failing condition. - */ -int fmu_model_init(FmuModelDesc* model_desc) -{ - process_list = dse_process_load_process_list(PROCESS_LIST_FILENAME); - - - /** - * Instrument the FMU. - * Process count (100) - */ - DseProcessDesc* process_desc = process_list; - int count = 0; - while (process_desc->name) { - count++; - process_desc++; - } - int* value_ref = - storage_ref(model_desc, VR_EXPECTED_PROC_COUNT, STORAGE_INT); - if (value_ref) *value_ref = count; - - /* Set Environment Variables before starting the processes. */ - _set_envvar(model_desc, "REDIS_PORT", VR_REDIS_PORT); - _set_envvar(model_desc, "SIMBUS_LOGLEVEL", VR_SIMBUS_LOGLEVEL); - _set_envvar(model_desc, "SIMBUS_TRANSPORT", VR_SIMBUS_TRANSPORT); - _set_envvar(model_desc, "SIMBUS_URI", VR_SIMBUS_URI); - _set_envvar(model_desc, "MEASUREMENT_DIR", VR_MEASUREMENT_DIR); - - /* Start the processes. */ - dse_process_start_all_processes(process_list); - - return 0; -} - - -/** - * fmu_model_step - * - * (Not used - required to complete the FMU Model API) - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - * - * Returns - * ------- - * 0 : success. - */ -int fmu_model_step(FmuModelDesc* model_desc, double model_time, double stop_time) -{ - UNUSED(model_desc); - UNUSED(model_time); - UNUSED(stop_time); - - return 0; -} - - -/** - * fmu_model_terminate - * - * Stop all running processes in the process list. - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - * - * Returns - * ------- - * 0 : success. - * +ve : failure, inspect errno for the failing condition. - */ -int fmu_model_terminate(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - dse_process_signal_all_processes(process_list, SIGTERM); - dse_process_waitfor_all_processes(process_list); - - return 0; -} - - -/** - * fmu_model_destroy - * - * Free the loaded process list. - * - * Parameters - * ---------- - * model_desc : FmuModelDesc - * Model Descriptor, references various runtime functions and data. - */ -void fmu_model_destroy(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - dse_process_free_process_list(process_list); -} diff --git a/dse/clib/fmi/examples/importer/CMakeLists.txt b/dse/clib/fmi/examples/importer/CMakeLists.txt deleted file mode 100644 index 57cdcd9..0000000 --- a/dse/clib/fmi/examples/importer/CMakeLists.txt +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright 2023 Robert Bosch GmbH -# -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.21) - -set(VERSION "$ENV{PACKAGE_VERSION}") - -project(dse-clib-importer - VERSION ${VERSION} - DESCRIPTION "DSE C Lib FMI Importer." - HOMEPAGE_URL "${PROJECT_URL}" -) - -# Set the default install location to build/_out (for unit testing). -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/_out - CACHE PATH "isolated build install" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - -# Make certain that CMAKE_INSTALL_INCLUDEDIR is set. -include(GNUInstallDirs) -if(NOT DEFINED ${CMAKE_INSTALL_INCLUDEDIR}) - set(CMAKE_INSTALL_INCLUDEDIR "include") -endif(NOT DEFINED ${CMAKE_INSTALL_INCLUDEDIR}) - - -set(CMAKE_C_STANDARD 99) -set(CMAKE_C_STANDARD_REQUIRED TRUE) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_C_FLAGS_DEBUG "-g -ggdb") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O3") -list(APPEND C_CXX_WARNING_FLAGS - -Wall - -W - -Wwrite-strings - -Wno-missing-field-initializers - -Wno-misleading-indentation -) -add_compile_options(${C_CXX_WARNING_FLAGS}) -add_compile_definitions(DLL_BUILD) - -set(CMAKE_SHARED_LIBRARY_PREFIX "") - - -# External Project - yaml -# ----------------------- -set(YAML_SOURCE_DIR "$ENV{EXTERNAL_BUILD_DIR}/yaml") -set(YAML_BINARY_DIR "$ENV{EXTERNAL_BUILD_DIR}/yaml") -find_library(YAML_LIB - NAMES - libyaml.a - PATHS - ${YAML_BINARY_DIR} - REQUIRED - NO_DEFAULT_PATH -) -add_library(yaml STATIC IMPORTED GLOBAL) -set_target_properties(yaml - PROPERTIES - IMPORTED_LOCATION "${YAML_LIB}" - INTERFACE_INCLUDE_DIRECTORIES "${YAML_BINARY_DIR}" -) - - -# DSE C Lib -# --------- -set(DSE_CLIB_SOURCE_DIR ../../../../../dse/clib) -set(DSE_CLIB_SOURCE_FILES - ${DSE_CLIB_SOURCE_DIR}/collections/hashmap.c - ${DSE_CLIB_SOURCE_DIR}/util/binary.c - ${DSE_CLIB_SOURCE_DIR}/util/strings.c - ${DSE_CLIB_SOURCE_DIR}/util/yaml.c - - ${DSE_CLIB_SOURCE_DIR}/fmi/fmu.c - ${DSE_CLIB_SOURCE_DIR}/fmi/importer.c - ${DSE_CLIB_SOURCE_DIR}/fmi/storage.c - ${DSE_CLIB_SOURCE_DIR}/fmi/strategy.c - - # ${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/fmi2fmu.c - ${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/fmi2importer.c -) -set(DSE_CLIB_INCLUDE_DIR "${DSE_CLIB_SOURCE_DIR}/../..") -set(FMI2_INCLUDE_DIR "${DSE_CLIB_SOURCE_DIR}/fmi/fmi2/headers") - - - -# Targets -# ======= - -# Importer -# -------- -add_executable(importer - importer.c - ${DSE_CLIB_SOURCE_FILES} -) -target_include_directories(importer - PRIVATE - ${FMI2_INCLUDE_DIR} - ${YAML_SOURCE_DIR}/include - ${DSE_CLIB_INCLUDE_DIR} -) -target_link_libraries(importer - PRIVATE - yaml - dl -) -install(TARGETS importer) - - - -# Package -# ======= -# OS and ARCH should match Docker metadata for multi-arch containers. -# os: linux -# arch: amd64 -# variant: v7 (optional, i.e. for arm) -# Combines to "linux-amd64" or "linux-arm-v7" -set(CPACK_SYSTEM_NAME $ENV{PACKAGE_ARCH}) -set(CPACK_PACKAGE_VENDOR "Robert Bosch GmbH") -set(CPACK_PACKAGE_DESCRIPTION "DSE C Lib FMI Models") -set(CPACK_OUTPUT_FILE_PREFIX _dist) -set(CPACK_GENERATOR "TGZ;ZIP") -set(CPACK_PACKAGE_CHECKSUM MD5) -set(CPACK_MONOLITHIC_INSTALL TRUE) -include(CPack) diff --git a/dse/clib/fmi/examples/importer/importer.c b/dse/clib/fmi/examples/importer/importer.c deleted file mode 100644 index 9a62efc..0000000 --- a/dse/clib/fmi/examples/importer/importer.c +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - - -#include -#include -#include -#include - - -uint8_t __log_level__ = LOG_DEBUG; - - -typedef struct SignalMap { - char** names; - double* signals; - size_t count; - void* var_map; -} SignalMap; - - -static FmuAdapterDesc adapter = { - .name = "fmi2_adapter", - .load_func = fmi2_load, - .init_func = fmi2_init, - .step_func = fmi2_step, - .unload_func = fmi2_unload, - .set_var_func = fmi2_set_var, - .get_var_func = fmi2_get_var, -}; - - -static FmuStrategyDesc strategy = { - .name = "fmi2_cosim_strategy", - .exec_func = fmi2_cosim_execute, - .map_func = fmu_map_variables, - .marshal_to_var_func = fmu_marshal_to_variables, - .marshal_from_var_func = fmu_marshal_from_variables, - .map_destroy_func = fmu_map_destroy, - /* Set step_size if FMU has fixed step size. */ - .step_size = 0.0005, -}; - - -int main(void) -{ - FmuInstDesc fmu = { - .name = "foo", - .path = "some/path/foo.dll", - .adapter = &adapter, - .strategy = &strategy, - }; - double model_time = 0.0; - - fmu_load(&fmu); - fmu_init(&fmu); - fmu_step(&fmu, &model_time, 0.2); - - /* Print the variable/signal map. */ - printf("Variables:\n"); - SignalMap* signal_map = fmu.inst_data; - for (size_t i = 0; i < signal_map->count; i++) { - printf(" %s = %f\n", signal_map->names[i], signal_map->signals[i]); - } - - fmu_unload(&fmu); - - return 0; -} diff --git a/dse/clib/fmi/fmi2/fmi2fmu.c b/dse/clib/fmi/fmi2/fmi2fmu.c deleted file mode 100644 index 4acace7..0000000 --- a/dse/clib/fmi/fmi2/fmi2fmu.c +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define UNUSED(x) ((void)x) - - -typedef void** buffer_ref; - -typedef struct Fmu2InstanceData { - /* FMI Instance Data. */ - const char* instance_name; - fmi2Type interface_type; - const char* resource_location; - const char* guid; - bool log_enabled; - /* FMI Callbacks. */ - const fmi2CallbackFunctions* callbacks; -} Fmu2InstanceData; - - -const char* fmi2GetTypesPlatform(void) -{ - return fmi2TypesPlatform; -} - - -const char* fmi2GetVersion(void) -{ - return fmi2Version; -} - - -fmi2Status fmi2SetDebugLogging(fmi2Component c, fmi2Boolean loggingOn, - size_t nCategories, const fmi2String categories[]) -{ - UNUSED(loggingOn); - UNUSED(nCategories); - UNUSED(categories); - assert(c); - return fmi2OK; -} - - -fmi2Component fmi2Instantiate(fmi2String instance_name, fmi2Type fmu_type, - fmi2String fmu_guid, fmi2String fmu_resource_location, - const fmi2CallbackFunctions* functions, fmi2Boolean visible, - fmi2Boolean logging_on) -{ - UNUSED(visible); - assert(functions); - assert(functions->allocateMemory); - assert(functions->freeMemory); - - /* Create the FMU Model Instance Data. */ - Fmu2InstanceData* fmu_inst = - functions->allocateMemory(1, sizeof(Fmu2InstanceData)); - fmu_inst->instance_name = instance_name; - fmu_inst->interface_type = fmu_type; - fmu_inst->resource_location = fmu_resource_location; - fmu_inst->guid = fmu_guid; - fmu_inst->log_enabled = logging_on; - fmu_inst->callbacks = functions; - - /** - * Calculate the offset needed to trim/correct the resource location. - * The resource location may take the forms: - * - * file:///tmp/MyFMU/resources - * file:/tmp/MyFMU/resources - * /tmp/MyFMU/resources - */ - int resource_path_offset = 0; - if (strstr(fmu_resource_location, FILE_URI_SCHEME)) { - resource_path_offset = strlen(FILE_URI_SCHEME); - } else if (strstr(fmu_resource_location, FILE_URI_SHORT_SCHEME)) { - resource_path_offset = strlen(FILE_URI_SHORT_SCHEME); - } - - /* Create the Model. */ - FmuModelDesc* model_desc = fmu_model_create( - fmu_inst, functions->allocateMemory, functions->freeMemory, - fmu_resource_location + resource_path_offset); - - return (fmi2Component)model_desc; -} - -fmi2Status fmi2SetupExperiment(fmi2Component c, fmi2Boolean toleranceDefined, - fmi2Real tolerance, fmi2Real startTime, fmi2Boolean stopTimeDefined, - fmi2Real stopTime) -{ - UNUSED(toleranceDefined); - UNUSED(tolerance); - UNUSED(startTime); - UNUSED(stopTimeDefined); - UNUSED(stopTime); - - assert(c); - return fmi2OK; -} - -fmi2Status fmi2EnterInitializationMode(fmi2Component c) -{ - assert(c); - /* FMI Master at this point may call fmi2SetX() to adjust any - * variables before the Model is started (in ExitInitialization). - */ - return fmi2OK; -} - -fmi2Status fmi2ExitInitializationMode(fmi2Component c) -{ - int rc = fmu_model_init(c); - return (rc == 0 ? fmi2OK : fmi2Error); -} - - -/** - * FMI 2 Variable GET Interface. - * - * Mapping of FMI Types to storage types: - * - * fmi2Real -> STORAGE_DOUBLE - * fmi2Integer -> STORAGE_INT - * fmi2Boolean -> STORAGE_INT - * fmi2String -> STORAGE_STRING - */ -fmi2Status fmi2GetReal(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, fmi2Real value[]) -{ - for (size_t i = 0; i < nvr; i++) { - double* value_ref = storage_ref(c, vr[i], STORAGE_DOUBLE); - if (value_ref) value[i] = *value_ref; - } - return fmi2OK; -} - -fmi2Status fmi2GetInteger(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, fmi2Integer value[]) -{ - for (size_t i = 0; i < nvr; i++) { - int* value_ref = storage_ref(c, vr[i], STORAGE_INT); - if (value_ref) value[i] = *value_ref; - } - return fmi2OK; -} - -fmi2Status fmi2GetBoolean(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, fmi2Boolean value[]) -{ - for (size_t i = 0; i < nvr; i++) { - int* value_ref = storage_ref(c, vr[i], STORAGE_INT); - if (value_ref) value[i] = (*value_ref) ? fmi2True : fmi2False; - } - return fmi2OK; -} - -fmi2Status fmi2GetString(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, fmi2String value[]) -{ - for (size_t i = 0; i < nvr; i++) { - const char** value_ref = storage_ref(c, vr[i], STORAGE_STRING); - if (value_ref) { - value[i] = strdup(*value_ref); - } - } - return fmi2OK; -} - -fmi2Status fmi2GetBinary(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, size_t valueSize[], fmi2Binary value[], size_t nValues) -{ - UNUSED(nValues); - for (size_t i = 0; i < nvr; i++) { - buffer_ref* value_ref = - (buffer_ref*)storage_ref(c, vr[i], STORAGE_BINARY); - uint32_t* size_ref = storage_ref(c, vr[i], STORAGE_BINARY_SIZE); - - if (value_ref == NULL || **value_ref == NULL || size_ref == NULL) { - value[i] = NULL; - valueSize[i] = 0; - continue; - } - - fmi2Binary buffer = malloc(*size_ref); - memcpy((void*)buffer, **value_ref, *size_ref); - value[i] = buffer; // Importer will call free(). - valueSize[i] = *size_ref; - } - return fmi2OK; -} - - -/** - * FMI 2 Variable SET Interface. - * - * Mapping of FMI Types to storage types: - * - * fmi2Real -> STORAGE_DOUBLE - * fmi2Integer -> STORAGE_INT - * fmi2Boolean -> STORAGE_INT - * fmi2String -> STORAGE_STRING - */ -fmi2Status fmi2SetReal(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, const fmi2Real value[]) -{ - for (size_t i = 0; i < nvr; i++) { - double* value_ref = storage_ref(c, vr[i], STORAGE_DOUBLE); - if (value_ref) *value_ref = value[i]; - } - return fmi2OK; -} - -fmi2Status fmi2SetInteger(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, const fmi2Integer value[]) -{ - for (size_t i = 0; i < nvr; i++) { - int* value_ref = storage_ref(c, vr[i], STORAGE_INT); - if (value_ref) *value_ref = value[i]; - } - return fmi2OK; -} - -fmi2Status fmi2SetBoolean(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, const fmi2Boolean value[]) -{ - for (size_t i = 0; i < nvr; i++) { - int* value_ref = storage_ref(c, vr[i], STORAGE_INT); - if (value_ref) *value_ref = value[i]; - } - return fmi2OK; -} - -fmi2Status fmi2SetString(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, const fmi2String value[]) -{ - for (size_t i = 0; i < nvr; i++) { - char** value_ref = storage_ref(c, vr[i], STORAGE_STRING); - if (value_ref) { - if (*value_ref) free(*value_ref); - *value_ref = strdup(value[i]); - } - } - return fmi2OK; -} - -fmi2Status fmi2SetBinary(fmi2Component c, const fmi2ValueReference vr[], - size_t nvr, const size_t valueSize[], const fmi2Binary value[], - size_t nValues) -{ - UNUSED(nValues); - for (size_t i = 0; i < nvr; i++) { - buffer_ref* value_ref = - (buffer_ref*)storage_ref(c, vr[i], STORAGE_BINARY); - uint32_t* size_ref = storage_ref(c, vr[i], STORAGE_BINARY_SIZE); - uint32_t* buffer_size_ref = - storage_ref(c, vr[i], STORAGE_BINARY_BUFFER_LENGTH); - if (value_ref == NULL) continue; - if (size_ref == NULL) continue; - if (buffer_size_ref == NULL) continue; - - dse_buffer_append( - *value_ref, size_ref, buffer_size_ref, value[i], valueSize[i]); - } - return fmi2OK; -} - - -/* STATUS Interface. */ -fmi2Status fmi2GetStatus( - fmi2Component c, const fmi2StatusKind s, fmi2Status* value) -{ - UNUSED(s); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2GetRealStatus( - fmi2Component c, const fmi2StatusKind s, fmi2Real* value) -{ - UNUSED(s); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2GetIntegerStatus( - fmi2Component c, const fmi2StatusKind s, fmi2Integer* value) -{ - UNUSED(s); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2GetBooleanStatus( - fmi2Component c, const fmi2StatusKind s, fmi2Boolean* value) -{ - UNUSED(s); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2GetStringStatus( - fmi2Component c, const fmi2StatusKind s, fmi2String* value) -{ - UNUSED(s); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2GetBinaryStatus( - fmi2Component c, const fmi2StatusKind s, fmi2Binary* value) -{ - UNUSED(s); - UNUSED(value); - assert(c); - return fmi2OK; -} - - -/* COSIM Interface. */ -fmi2Status fmi2SetRealInputDerivatives(fmi2Component c, - const fmi2ValueReference vr[], size_t nvr, const fmi2Integer order[], - const fmi2Real value[]) -{ - UNUSED(vr); - UNUSED(nvr); - UNUSED(order); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2GetRealOutputDerivatives(fmi2Component c, - const fmi2ValueReference vr[], size_t nvr, const fmi2Integer order[], - fmi2Real value[]) -{ - UNUSED(vr); - UNUSED(nvr); - UNUSED(order); - UNUSED(value); - assert(c); - return fmi2OK; -} - -fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, - fmi2Real communicationStepSize, - fmi2Boolean noSetFMUStatePriorToCurrentPoint) -{ - UNUSED(noSetFMUStatePriorToCurrentPoint); - - int rc = fmu_model_step(c, currentCommunicationPoint, communicationStepSize); - return (rc == 0 ? fmi2OK : fmi2Error); -} - -fmi2Status fmi2CancelStep(fmi2Component c) -{ - assert(c); - return fmi2OK; -} - - -/* Getting and setting the internal FMU state */ -fmi2Status fmi2GetFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) -{ - assert(c); - UNUSED(FMUstate); - return fmi2OK; -} - -fmi2Status fmi2SetFMUstate(fmi2Component c, fmi2FMUstate FMUstate) -{ - assert(c); - UNUSED(FMUstate); - return fmi2OK; -} - -fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) -{ - assert(c); - UNUSED(FMUstate); - return fmi2OK; -} - -fmi2Status fmi2SerializedFMUstateSize( - fmi2Component c, fmi2FMUstate FMUstate, size_t* size) -{ - assert(c); - UNUSED(FMUstate); - UNUSED(size); - return fmi2OK; -} - -fmi2Status fmi2SerializeFMUstate(fmi2Component c, fmi2FMUstate FMUstate, - fmi2Byte serializedState[], size_t size) -{ - assert(c); - UNUSED(FMUstate); - UNUSED(serializedState); - UNUSED(size); - return fmi2OK; -} - -fmi2Status fmi2DeSerializeFMUstate(fmi2Component c, - const fmi2Byte serializedState[], size_t size, fmi2FMUstate* FMUstate) -{ - assert(c); - UNUSED(serializedState); - UNUSED(size); - UNUSED(FMUstate); - return fmi2OK; -} - - -/* Getting partial derivatives */ -fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, - const fmi2ValueReference vUnknown_ref[], size_t nUnknown, - const fmi2ValueReference vKnown_ref[], size_t nKnown, - const fmi2Real dvKnown[], fmi2Real dvUnknown[]) -{ - assert(c); - UNUSED(vUnknown_ref); - UNUSED(nUnknown); - UNUSED(vKnown_ref); - UNUSED(nKnown); - UNUSED(dvKnown); - UNUSED(dvUnknown); - return fmi2OK; -} - - -/* Lifecycle interface. */ -fmi2Status fmi2Reset(fmi2Component c) -{ - assert(c); - return fmi2OK; -} - -fmi2Status fmi2Terminate(fmi2Component c) -{ - int rc = fmu_model_terminate(c); - return (rc == 0 ? fmi2OK : fmi2Error); -} - -void fmi2FreeInstance(fmi2Component c) -{ - fmu_model_destroy(c); - fmu_model_finalize(c); -} diff --git a/dse/clib/fmi/fmi2/fmi2importer.c b/dse/clib/fmi/fmi2/fmi2importer.c deleted file mode 100644 index 860ee6c..0000000 --- a/dse/clib/fmi/fmi2/fmi2importer.c +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define GENERAL_BUFFER_LEN 255 -#define FMU_LOG_BUFFER_LEN 2048 -#define UNUSED(x) ((void)x) - - -static void fmu2_logger_callback(fmi2ComponentEnvironment componentEnvironment, - fmi2String instanceName, fmi2Status status, fmi2String category, - fmi2String message, ...) -{ - UNUSED(componentEnvironment); - UNUSED(instanceName); - UNUSED(status); - - static char buffer[FMU_LOG_BUFFER_LEN]; - va_list ap; - va_start(ap, message); - vsnprintf(buffer, FMU_LOG_BUFFER_LEN, message, ap); - va_end(ap); - - log_debug("FMU LOG:%s:%s", category, buffer); -} - - -static void fmu2_step_finished_callback( - fmi2ComponentEnvironment componentEnvironment, fmi2Status status) -{ - UNUSED(componentEnvironment); - UNUSED(status); -} - - -int fmi2_load(FmuInstDesc* inst) -{ - /* Load the FMU Model. */ - // TODO load the fmu dll... - - /* Setup the FMI2 Model Descriptor, attach to model_desc. */ - Fmi2ModelDesc* fmi2_model_desc = calloc(1, sizeof(Fmi2ModelDesc)); - fmi2_model_desc->callbacks.allocateMemory = calloc; - fmi2_model_desc->callbacks.freeMemory = free; - fmi2_model_desc->callbacks.logger = fmu2_logger_callback; - fmi2_model_desc->callbacks.stepFinished = fmu2_step_finished_callback; - inst->model_desc = (void*)fmi2_model_desc; - - - /* Load functions from the FMU into the call table. */ - for (unsigned int i = 0; i < ARRAY_LENGTH(__fmi2_function_list); i++) { - log_notice(" Load symbol: %s ...", __fmi2_function_list[i].name); - fmi2_model_desc->func_table.table[i] = - dlsym(fmi2_model_desc->handle, __fmi2_function_list[i].name); - if (fmi2_model_desc->func_table.table[i] == NULL) { - if (__fmi2_function_list[i].required) { - log_fatal("Required symbol (%s) not found in FMU dll!", - __fmi2_function_list[i].name); - } else { - log_trace("(optional) symbol (%s) not found in FMU dll.", - __fmi2_function_list[i].name); - } - } else { - log_notice(" Loaded symbol: %s", __fmi2_function_list[i].name); - } - } - - /* Build the Vref<->Value map. */ - // FIXME implement this with a callback? So that any formatting can - // be used. SHould, parse some doc, call map_func and return Fmi2ValueRefMap list. - - for (int vt_idx = 0; vt_idx < __FMI2_VALUE_COUNT__; vt_idx++) { - // FIXME parse variables to storage ... can skip not used variables ... - // so advanced parsing. - - // FIXME generate Vr to Value mapping tables for each FMI type, - // consolidate by strategy type. - - // FIXME register each type with strategy. - } - - return 0; -} - - -int fmi2_set_var(FmuInstDesc* inst) -{ - assert(inst); - assert(inst->model_desc); - Fmi2ModelDesc* fmi2_model_desc = (Fmi2ModelDesc*)inst->model_desc; - __fmi2_func_table fmu = fmi2_model_desc->func_table.call; - fmi2Component comp = fmi2_model_desc->inst_handle; - Fmi2ValueRefMap* vm_p = fmi2_model_desc->value_map; - - while (vm_p && vm_p->vr) { - switch (vm_p->value_type) { - case FMI2_VALUE_BOOLEAN: // FMI_VALUE_TYPE_INTEGER|STORAGE_INT - { - fmi2Boolean _value[vm_p->count]; - for (size_t i = 0; i < vm_p->count; i++) { - _value[i] = *(int*)vm_p->values[i]; - } - fmu.SetBoolean(comp, vm_p->vr, vm_p->count, _value); - } break; - case FMI2_VALUE_INTEGER: // FMI_VALUE_TYPE_INTEGER|STORAGE_INT - { - fmi2Integer _value[vm_p->count]; - for (size_t i = 0; i < vm_p->count; i++) { - _value[i] = *(int*)vm_p->values[i]; - } - fmu.SetInteger(comp, vm_p->vr, vm_p->count, _value); - } break; - case FMI2_VALUE_REAL: // FMI_VALUE_TYPE_REAL|STORAGE_DOUBLE - { - fmi2Real _value[vm_p->count]; - for (size_t i = 0; i < vm_p->count; i++) { - _value[i] = *(double*)vm_p->values[i]; - } - fmu.SetReal(comp, vm_p->vr, vm_p->count, _value); - } break; - default: - break; - } - - // Next map. - vm_p++; - } - - return 0; -} - -int fmi2_get_var(FmuInstDesc* inst) -{ - assert(inst); - assert(inst->model_desc); - Fmi2ModelDesc* fmi2_model_desc = (Fmi2ModelDesc*)inst->model_desc; - fmi2Component comp = fmi2_model_desc->inst_handle; - __fmi2_func_table fmu = fmi2_model_desc->func_table.call; - Fmi2ValueRefMap* vm_p = fmi2_model_desc->value_map; - - while (vm_p && vm_p->vr) { - switch (vm_p->value_type) { - case FMI2_VALUE_BOOLEAN: // FMI_VALUE_TYPE_INTEGER|STORAGE_INT - { - fmi2Boolean _value[vm_p->count]; - fmu.GetBoolean(comp, vm_p->vr, vm_p->count, _value); - for (size_t i = 0; i < vm_p->count; i++) { - *(int*)vm_p->values[i] = _value[i]; - } - } break; - case FMI2_VALUE_INTEGER: // FMI_VALUE_TYPE_INTEGER|STORAGE_INT - { - fmi2Integer _value[vm_p->count]; - fmu.GetInteger(comp, vm_p->vr, vm_p->count, _value); - for (size_t i = 0; i < vm_p->count; i++) { - *(int*)vm_p->values[i] = _value[i]; - } - } break; - case FMI2_VALUE_REAL: // FMI_VALUE_TYPE_REAL|STORAGE_DOUBLE - { - fmi2Real _value[vm_p->count]; - fmu.GetReal(comp, vm_p->vr, vm_p->count, _value); - for (size_t i = 0; i < vm_p->count; i++) { - _value[i] = *(int*)vm_p->values[i]; - *(double*)vm_p->values[i] = _value[i]; - } - } break; - default: - break; - } - - // Next map. - vm_p++; - } - - return 0; -} - -int fmi2_init(FmuInstDesc* inst) -{ - assert(inst); - assert(inst->model_desc); - Fmi2ModelDesc* fmi2_model_desc = (Fmi2ModelDesc*)inst->model_desc; - __fmi2_func_table fmu = fmi2_model_desc->func_table.call; - fmi2Status fmu_rc; - YamlNode* node; - - /* Locate the GUID. */ - const char* guid = "GUID NOT DEFINE IN MODEL ANNOTATIONS!"; - node = dse_yaml_find_node( - inst->model_doc, "metadata/annotations/mcl_fmi_guid"); - if (node && node->scalar) { - guid = node->scalar; - } - /* Locate the resource dir. */ - node = dse_yaml_find_node( - inst->model_doc, "metadata/annotations/mcl_fmi_resource_dir"); - if (node && node->scalar) { - char buffer[GENERAL_BUFFER_LEN]; - getcwd(buffer, GENERAL_BUFFER_LEN - 1); - fmi2_model_desc->resource_dir = dse_path_cat(buffer, node->scalar); - } else { - fmi2_model_desc->resource_dir = dse_path_cat("/tmp", ""); - } - - /* Create the instance of the FMU. */ - log_debug("Call fmu.Instantiate():"); - log_debug(" instance name = %s", inst->name); - log_debug(" guid = %s", guid); - log_debug(" resource dir = %s", fmi2_model_desc->resource_dir); - fmi2Component comp = fmu.Instantiate(inst->name, fmi2CoSimulation, guid, - fmi2_model_desc->resource_dir, &(fmi2_model_desc->callbacks), fmi2False, - fmi2False); - fmi2_model_desc->inst_handle = comp; - - /* Can call Set() here. No sure if this call will be needed*/ - // __marshal_data_to_fmu_variables(model, inst); - - /* Push the FMU to the ready/operational state. */ - fmu_rc = fmu.SetupExperiment(comp, fmi2False, 0, 0, fmi2False, 0); - if (fmu_rc > fmi2Warning) log_fatal("FMU SetupExperiment call failed!"); - fmu_rc = fmu.EnterInitializationMode(comp); - if (fmu_rc > fmi2Warning) - log_fatal("FMU EnterInitializationMode call failed!"); - - fmi2_get_var(inst); - - fmu_rc = fmu.ExitInitializationMode(comp); - if (fmu_rc > fmi2Warning) - log_fatal("FMU ExitInitializationMode call failed!"); - - return 0; -} - - -int fmi2_step(FmuInstDesc* inst, double* model_time, double stop_time) -{ - assert(inst); - assert(inst->model_desc); - - fmi2Status fmu_rc; - Fmi2ModelDesc* fmi2_model_desc = (Fmi2ModelDesc*)inst->model_desc; - fmi2Component comp = fmi2_model_desc->inst_handle; - __fmi2_func_table fmu = fmi2_model_desc->func_table.call; - assert(comp); - - /* Complete the FMU step. */ - log_debug(" Call FMU DoStep ..."); - fmu_rc = fmu.DoStep(comp, *model_time, (stop_time - *model_time), fmi2True); - if (fmu_rc != fmi2OK) log_fatal("FMU DoStep call did not return OK!"); - // TODO consider model request to end simulation. fmu.GetBooleanStatus - // fmi2Terminated. - - /* Indicate the step completed. */ - *model_time = stop_time; - return 0; -} - - -int fmi2_unload(FmuInstDesc* inst) -{ - assert(inst); - - /* Only release/free resources created by this module. */ - - /* Release any FMI2 model specific data. */ - if (inst->model_desc) { - Fmi2ModelDesc* fmi2_model_desc = (Fmi2ModelDesc*)inst->model_desc; - __fmi2_func_table fmu = fmi2_model_desc->func_table.call; - - /* Release the FMU. */ - if (fmi2_model_desc->inst_handle) { - fmu.Terminate(fmi2_model_desc->inst_handle); - fmu.FreeInstance(fmi2_model_desc->inst_handle); - fmi2_model_desc->inst_handle = NULL; - } - /* Release runtime properties. */ - if (fmi2_model_desc->resource_dir) free(fmi2_model_desc->resource_dir); - - /* Release the value map. */ - Fmi2ValueRefMap* vm_p = fmi2_model_desc->value_map; - while (vm_p && vm_p->vr) { - if (vm_p->vr) free(vm_p->vr); - if (vm_p->values) free(vm_p->values); - - // Next map. - vm_p++; - } - if (fmi2_model_desc->value_map) free(fmi2_model_desc->value_map); - - /* Unload the DLL. */ - if (fmi2_model_desc->handle) { - dlclose(fmi2_model_desc->handle); - fmi2_model_desc->handle = NULL; - } - - free(inst->model_desc); - inst->model_desc = NULL; - } - - - return 0; -} diff --git a/dse/clib/fmi/fmi2/fmi2importer.h b/dse/clib/fmi/fmi2/fmi2importer.h deleted file mode 100644 index f7625a9..0000000 --- a/dse/clib/fmi/fmi2/fmi2importer.h +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#ifndef DSE_CLIB_FMI_FMI2_FMI2IMPORTER_H_ -#define DSE_CLIB_FMI_FMI2_FMI2IMPORTER_H_ - -#include -#include -#include -#include -#include - - -#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0])) - - -/* FMI2 Function List */ -typedef struct __fmi2_func_spec { - const char* name; - bool required; /* Defaults to false (0). */ -} __fmi2_func_spec; - - -static __fmi2_func_spec __fmi2_function_list[] = { - /* Common Functions. */ - { - .name = "fmi2GetTypesPlatform", - }, - { - .name = "fmi2GetVersion", - }, - { - .name = "fmi2SetDebugLogging", - }, - { - .name = "fmi2Instantiate", - }, - { - .name = "fmi2FreeInstance", - }, - { - .name = "fmi2SetupExperiment", - }, - { - .name = "fmi2EnterInitializationMode", - }, - { - .name = "fmi2ExitInitializationMode", - }, - { - .name = "fmi2Terminate", - }, - { - .name = "fmi2Reset", - }, - { - .name = "fmi2GetReal", - }, - { - .name = "fmi2GetInteger", - }, - { - .name = "fmi2GetBoolean", - }, - { - .name = "fmi2GetString", - }, - { - .name = "fmi2SetReal", - }, - { - .name = "fmi2SetInteger", - }, - { - .name = "fmi2SetBoolean", - }, - { - .name = "fmi2SetString", - }, - { - .name = "fmi2GetFMUstate", - }, - { - .name = "fmi2SetFMUstate", - }, - { - .name = "fmi2FreeFMUstate", - }, - { - .name = "fmi2SerializedFMUstateSize", - }, - { - .name = "fmi2SerializeFMUstate", - }, - { - .name = "fmi2DeSerializeFMUstate", - }, - { - .name = "fmi2GetDirectionalDerivative", - }, - /* Functions for FMI2 for Co-Simulation. */ - { - .name = "fmi2SetRealInputDerivatives", - }, - { - .name = "fmi2GetRealOutputDerivatives", - }, - { - .name = "fmi2DoStep", - .required = true, - }, - { - .name = "fmi2CancelStep", - }, - { - .name = "fmi2GetStatus", - }, - { - .name = "fmi2GetRealStatus", - }, - { - .name = "fmi2GetIntegerStatus", - }, - { - .name = "fmi2GetBooleanStatus", - }, - { - .name = "fmi2GetStringStatus", - }, - /* Functions for Binary Strings (optional). - * see : - * https://github.com/boschglobal/dse.standards/blob/main/modelica/fmi-ls-binary-string/README.md - */ - { - .name = "fmi2GetBinary", - }, - { - .name = "fmi2SetBinary", - }, - { - .name = "fmi2GetBinaryStatus", - }, -}; - - -/* FMI" Function Call Table. */ -typedef struct __fmi2_func_table { - /* Common Functions. */ - fmi2GetTypesPlatformTYPE* GetTypesPlatform; - fmi2GetVersionTYPE* GetVersionTYPE; - fmi2SetDebugLoggingTYPE* SetDebugLogging; - fmi2InstantiateTYPE* Instantiate; - fmi2FreeInstanceTYPE* FreeInstance; - fmi2SetupExperimentTYPE* SetupExperiment; - fmi2EnterInitializationModeTYPE* EnterInitializationMode; - fmi2ExitInitializationModeTYPE* ExitInitializationMode; - fmi2TerminateTYPE* Terminate; - fmi2ResetTYPE* Reset; - fmi2GetRealTYPE* GetReal; - fmi2GetIntegerTYPE* GetInteger; - fmi2GetBooleanTYPE* GetBoolean; - fmi2GetStringTYPE* GetString; - fmi2SetRealTYPE* SetReal; - fmi2SetIntegerTYPE* SetInteger; - fmi2SetBooleanTYPE* SetBoolean; - fmi2SetStringTYPE* SetString; - fmi2GetFMUstateTYPE* GetFMUstate; - fmi2SetFMUstateTYPE* SetFMUstate; - fmi2FreeFMUstateTYPE* FreeFMUstate; - fmi2SerializedFMUstateSizeTYPE* SerializedFMUstateSize; - fmi2SerializeFMUstateTYPE* SerializeFMUstate; - fmi2DeSerializeFMUstateTYPE* DeSerializeFMUstate; - fmi2GetDirectionalDerivativeTYPE* GetDirectionalDerivative; - /* Functions for FMI2 for Co-Simulation. */ - fmi2SetRealInputDerivativesTYPE* SetRealInputDerivatives; - fmi2GetRealOutputDerivativesTYPE* GetRealOutputDerivatives; - fmi2DoStepTYPE* DoStep; - fmi2CancelStepTYPE* CancelStep; - fmi2GetStatusTYPE* GetStatus; - fmi2GetRealStatusTYPE* GetRealStatus; - fmi2GetIntegerStatusTYPE* GetIntegerStatus; - fmi2GetBooleanStatusTYPE* GetBooleanStatus; - fmi2GetStringStatusTYPE* GetStringStatus; - /* Functions for Binary Strings (optional). */ - fmi2GetBinaryTYPE* GetBinary; - fmi2SetBinaryTYPE* SetBinary; - fmi2GetBinaryStatusTYPE* GetBinaryStatus; -} __fmi2_func_table; - - -typedef int (*__fmi2_generic_func)(void); - - -typedef union { - __fmi2_func_table call; - __fmi2_generic_func table[ARRAY_LENGTH(__fmi2_function_list)]; -} Fmi2FuncCallTable; - - -typedef enum { - FMI2_VALUE_BOOLEAN, - FMI2_VALUE_INTEGER, - FMI2_VALUE_REAL, - __FMI2_VALUE_COUNT__, -} Fmi2Value; - - -typedef struct Fmi2ValueRefMap { - Fmi2Value value_type; - size_t count; - fmi2ValueReference* vr; // Allocated vr table. - void** values; // Allocated storage references. -} Fmi2ValueRefMap; - - -typedef struct Fmi2ModelDesc { - void* handle; - - char* resource_dir; - - Fmi2FuncCallTable func_table; - fmi2Component inst_handle; - fmi2CallbackFunctions callbacks; - Fmi2ValueRefMap* value_map; // Null terminated list. -} Fmi2ModelDesc; - - -/* fmi2importer.c */ -DLL_PUBLIC int fmi2_load(FmuInstDesc* inst); -DLL_PUBLIC int fmi2_init(FmuInstDesc* inst); -DLL_PUBLIC int fmi2_step( - FmuInstDesc* inst, double* model_time, double stop_time); -DLL_PUBLIC int fmi2_unload(FmuInstDesc* inst); -DLL_PUBLIC int fmi2_set_var(FmuInstDesc* inst); -DLL_PUBLIC int fmi2_get_var(FmuInstDesc* inst); - - - -#endif // DSE_CLIB_FMI_FMI2_FMI2IMPORTER_H_ diff --git a/dse/clib/fmi/fmi3/fmi3fmu.c b/dse/clib/fmi/fmi3/fmi3fmu.c deleted file mode 100644 index 4dc7147..0000000 --- a/dse/clib/fmi/fmi3/fmi3fmu.c +++ /dev/null @@ -1,1016 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define UNUSED(x) ((void)x) - - -typedef void** buffer_ref; - -typedef struct Fmu3InstanceData { - /* FMI Instance Data. */ - const char* instance_name; - const char* resource_location; - const char* guid; - bool log_enabled; -} Fmu3InstanceData; - - -/* Inquire version numbers and setting logging status */ - -const char* fmi3GetVersion() -{ - return fmi3Version; -} - -fmi3Status fmi3SetDebugLogging(fmi3Instance instance, fmi3Boolean loggingOn, - size_t nCategories, const fmi3String categories[]) -{ - assert(instance); - UNUSED(loggingOn); - UNUSED(nCategories); - UNUSED(categories); - - return fmi3OK; -} - -/* Creation and destruction of FMU instances and setting debug status */ - -fmi3Instance fmi3InstantiateModelExchange(fmi3String instanceName, - fmi3String instantiationToken, fmi3String resourcePath, fmi3Boolean visible, - fmi3Boolean loggingOn, fmi3InstanceEnvironment instanceEnvironment, - fmi3LogMessageCallback logMessage) -{ - UNUSED(instanceName); - UNUSED(instantiationToken); - UNUSED(resourcePath); - UNUSED(visible); - UNUSED(loggingOn); - UNUSED(instanceEnvironment); - UNUSED(logMessage); - - return NULL; -} - -fmi3Instance fmi3InstantiateCoSimulation(fmi3String instanceName, - fmi3String instantiationToken, fmi3String resourcePath, fmi3Boolean visible, - fmi3Boolean loggingOn, fmi3Boolean eventModeUsed, - fmi3Boolean earlyReturnAllowed, - const fmi3ValueReference requiredIntermediateVariables[], - size_t nRequiredIntermediateVariables, - fmi3InstanceEnvironment instanceEnvironment, - fmi3LogMessageCallback logMessage, - fmi3IntermediateUpdateCallback intermediateUpdate) -{ - UNUSED(visible); - UNUSED(eventModeUsed); - UNUSED(earlyReturnAllowed); - UNUSED(requiredIntermediateVariables); - UNUSED(nRequiredIntermediateVariables); - UNUSED(instanceEnvironment); - UNUSED(logMessage); - UNUSED(intermediateUpdate); - - /* Create the FMU Model Instance Data. */ - Fmu3InstanceData* fmu_inst = calloc(1, sizeof(Fmu3InstanceData)); - fmu_inst->instance_name = instanceName; - fmu_inst->resource_location = resourcePath; - fmu_inst->guid = instantiationToken; - fmu_inst->log_enabled = loggingOn; - - /** - * Calculate the offset needed to trim/correct the resource location. - * The resource location may take the forms: - * - * file:///tmp/MyFMU/resources - * file:/tmp/MyFMU/resources - * /tmp/MyFMU/resources - */ - int resource_path_offset = 0; - if (strstr(resourcePath, FILE_URI_SCHEME)) { - resource_path_offset = strlen(FILE_URI_SCHEME); - } else if (strstr(resourcePath, FILE_URI_SHORT_SCHEME)) { - resource_path_offset = strlen(FILE_URI_SHORT_SCHEME); - } - - /* Create the Model. */ - FmuModelDesc* model_desc = fmu_model_create(fmu_inst, calloc, free, - resourcePath + resource_path_offset); - - return (fmi3Instance)model_desc; -} - -fmi3Instance fmi3InstantiateScheduledExecution(fmi3String instanceName, - fmi3String instantiationToken, fmi3String resourcePath, fmi3Boolean visible, - fmi3Boolean loggingOn, fmi3InstanceEnvironment instanceEnvironment, - fmi3LogMessageCallback logMessage, fmi3ClockUpdateCallback clockUpdate, - fmi3LockPreemptionCallback lockPreemption, - fmi3UnlockPreemptionCallback unlockPreemption) -{ - UNUSED(instanceName); - UNUSED(instantiationToken); - UNUSED(resourcePath); - UNUSED(visible); - UNUSED(loggingOn); - UNUSED(instanceEnvironment); - UNUSED(logMessage); - UNUSED(clockUpdate); - UNUSED(lockPreemption); - UNUSED(unlockPreemption); - - return NULL; -} - -void fmi3FreeInstance(fmi3Instance instance) -{ - assert(instance); - fmu_model_destroy(instance); - fmu_model_finalize(instance); -} - -/* Enter and exit initialization mode, enter event mode, terminate and reset */ - -fmi3Status fmi3EnterInitializationMode(fmi3Instance instance, - fmi3Boolean toleranceDefined, fmi3Float64 tolerance, fmi3Float64 startTime, - fmi3Boolean stopTimeDefined, fmi3Float64 stopTime) -{ - assert(instance); - UNUSED(toleranceDefined); - UNUSED(tolerance); - UNUSED(startTime); - UNUSED(stopTimeDefined); - UNUSED(stopTime); - - return fmi3OK; -} - -fmi3Status fmi3ExitInitializationMode(fmi3Instance instance) -{ - assert(instance); - int rc = fmu_model_init(instance); - return (rc == 0 ? fmi3OK : fmi3Error); -} - -fmi3Status fmi3EnterEventMode(fmi3Instance instance, - fmi3EventQualifier stepEvent, fmi3EventQualifier stateEvent, - const fmi3Int32 rootsFound[], size_t nEventIndicators, - fmi3EventQualifier timeEvent) -{ - assert(instance); - UNUSED(stepEvent); - UNUSED(stateEvent); - UNUSED(rootsFound); - UNUSED(nEventIndicators); - UNUSED(timeEvent); - - return fmi3OK; -} - -fmi3Status fmi3Terminate(fmi3Instance instance) -{ - assert(instance); - - int rc = fmu_model_terminate(instance); - return (rc == 0 ? fmi3OK : fmi3Error); -} - -fmi3Status fmi3Reset(fmi3Instance instance) -{ - assert(instance); - - return fmi3OK; -} - -/* Getting and setting variable values */ - -fmi3Status fmi3GetFloat32(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Float32 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetFloat64(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Float64 values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - double* value_ref = - storage_ref(instance, valueReferences[i], STORAGE_DOUBLE); - if (value_ref) values[i] = *value_ref; - } - - return fmi3OK; -} - -fmi3Status fmi3GetInt8(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Int8 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetUInt8(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3UInt8 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetInt16(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Int16 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetUInt16(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3UInt16 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetInt32(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Int32 values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - int* value_ref = storage_ref(instance, valueReferences[i], STORAGE_INT); - if (value_ref) *value_ref = values[i]; - } - - return fmi3OK; -} - -fmi3Status fmi3GetUInt32(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3UInt32 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetInt64(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Int64 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetUInt64(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3UInt64 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3GetBoolean(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Boolean values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - int* value_ref = storage_ref(instance, valueReferences[i], STORAGE_INT); - if (value_ref) values[i] = (*value_ref) ? fmi3True : fmi3False; - } - - return fmi3OK; -} - -fmi3Status fmi3GetString(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3String values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - const char** value_ref = - storage_ref(instance, valueReferences[i], STORAGE_STRING); - if (value_ref) { - values[i] = strdup(*value_ref); - } - } - - return fmi3OK; -} - -fmi3Status fmi3GetBinary(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - size_t valueSizes[], fmi3Binary values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - buffer_ref* value_ref = (buffer_ref*)storage_ref( - instance, valueReferences[i], STORAGE_BINARY); - uint32_t* size_ref = - storage_ref(instance, valueReferences[i], STORAGE_BINARY_SIZE); - - if (value_ref == NULL || **value_ref == NULL || size_ref == NULL) { - values[i] = NULL; - valueSizes[i] = 0; - continue; - } - - fmi3Binary buffer = malloc(*size_ref); - memcpy((void*)buffer, **value_ref, *size_ref); - values[i] = buffer; // Importer will call free(). - valueSizes[i] = *size_ref; - } - - return fmi3OK; -} - -fmi3Status fmi3GetClock(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Clock values[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - - return fmi3OK; -} - -fmi3Status fmi3SetFloat32(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Float32 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetFloat64(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Float64 values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - double* value_ref = - storage_ref(instance, valueReferences[i], STORAGE_DOUBLE); - if (value_ref) *value_ref = values[i]; - } - - return fmi3OK; -} -fmi3Status fmi3SetInt8(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Int8 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} -fmi3Status fmi3SetUInt8(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3UInt8 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetInt16(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Int16 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetUInt16(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3UInt16 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetInt32(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Int32 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetUInt32(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3UInt32 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetInt64(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Int64 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3SetUInt64(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3UInt64 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} -fmi3Status fmi3SetBoolean(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Boolean values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - int* value_ref = storage_ref(instance, valueReferences[i], STORAGE_INT); - if (value_ref) *value_ref = values[i]; - } - - return fmi3OK; -} - -fmi3Status fmi3SetString(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3String values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - char** value_ref = - storage_ref(instance, valueReferences[i], STORAGE_STRING); - if (value_ref) { - if (*value_ref) free(*value_ref); - *value_ref = strdup(values[i]); - } - } - - return fmi3OK; -} - -fmi3Status fmi3SetBinary(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const size_t valueSizes[], const fmi3Binary values[], size_t nValues) -{ - UNUSED(nValues); - - for (size_t i = 0; i < nValueReferences; i++) { - buffer_ref* value_ref = (buffer_ref*)storage_ref( - instance, valueReferences[i], STORAGE_BINARY); - uint32_t* size_ref = - storage_ref(instance, valueReferences[i], STORAGE_BINARY_SIZE); - uint32_t* buffer_size_ref = storage_ref( - instance, valueReferences[i], STORAGE_BINARY_BUFFER_LENGTH); - if (value_ref == NULL) continue; - if (size_ref == NULL) continue; - if (buffer_size_ref == NULL) continue; - - dse_buffer_append( - *value_ref, size_ref, buffer_size_ref, values[i], valueSizes[i]); - } - - return fmi3OK; -} - -fmi3Status fmi3SetClock(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Clock values[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(values); - - return fmi3OK; -} - -/* Getting Variable Dependency Information */ - -fmi3Status fmi3GetNumberOfVariableDependencies(fmi3Instance instance, - fmi3ValueReference valueReference, size_t* nDependencies) -{ - assert(instance); - UNUSED(valueReference); - UNUSED(nDependencies); - - return fmi3OK; -} - -fmi3Status fmi3GetVariableDependencies(fmi3Instance instance, - fmi3ValueReference dependent, size_t elementIndicesOfDependent[], - fmi3ValueReference independents[], size_t elementIndicesOfIndependents[], - fmi3DependencyKind dependencyKinds[], size_t nDependencies) -{ - assert(instance); - UNUSED(dependent); - UNUSED(elementIndicesOfDependent); - UNUSED(independents); - UNUSED(elementIndicesOfIndependents); - UNUSED(dependencyKinds); - UNUSED(nDependencies); - - return fmi3OK; -} - -/* Getting and setting the internal FMU state */ - -fmi3Status fmi3GetFMUState(fmi3Instance instance, fmi3FMUState* FMUState) -{ - assert(instance); - UNUSED(FMUState); - - return fmi3OK; -} - -fmi3Status fmi3SetFMUState(fmi3Instance instance, fmi3FMUState FMUState) -{ - assert(instance); - UNUSED(FMUState); - - return fmi3OK; -} - -fmi3Status fmi3FreeFMUState(fmi3Instance instance, fmi3FMUState* FMUState) -{ - assert(instance); - UNUSED(FMUState); - - return fmi3OK; -} - -fmi3Status fmi3SerializedFMUStateSize( - fmi3Instance instance, fmi3FMUState FMUState, size_t* size) -{ - assert(instance); - UNUSED(FMUState); - UNUSED(size); - - return fmi3OK; -} - -fmi3Status fmi3SerializeFMUState(fmi3Instance instance, fmi3FMUState FMUState, - fmi3Byte serializedState[], size_t size) -{ - assert(instance); - UNUSED(FMUState); - UNUSED(serializedState); - UNUSED(size); - - return fmi3OK; -} - -fmi3Status fmi3DeserializeFMUState(fmi3Instance instance, - const fmi3Byte serializedState[], size_t size, fmi3FMUState* FMUState) -{ - assert(instance); - UNUSED(serializedState); - UNUSED(size); - UNUSED(FMUState); - - return fmi3OK; -} - -/* Getting partial derivatives */ - -fmi3Status fmi3GetDirectionalDerivative(fmi3Instance instance, - const fmi3ValueReference unknowns[], size_t nUnknowns, - const fmi3ValueReference knowns[], size_t nKnowns, const fmi3Float64 seed[], - size_t nSeed, fmi3Float64 sensitivity[], size_t nSensitivity) -{ - assert(instance); - UNUSED(unknowns); - UNUSED(nUnknowns); - UNUSED(knowns); - UNUSED(nKnowns); - UNUSED(seed); - UNUSED(nSeed); - UNUSED(sensitivity); - UNUSED(nSensitivity); - - return fmi3OK; -} - -fmi3Status fmi3GetAdjointDerivative(fmi3Instance instance, - const fmi3ValueReference unknowns[], size_t nUnknowns, - const fmi3ValueReference knowns[], size_t nKnowns, const fmi3Float64 seed[], - size_t nSeed, fmi3Float64 sensitivity[], size_t nSensitivity) -{ - assert(instance); - UNUSED(unknowns); - UNUSED(nUnknowns); - UNUSED(knowns); - UNUSED(nKnowns); - UNUSED(seed); - UNUSED(nSeed); - UNUSED(sensitivity); - UNUSED(nSensitivity); - - return fmi3OK; -} - -/* Entering and exiting the Configuration or Reconfiguration Mode */ - -fmi3Status fmi3EnterConfigurationMode(fmi3Instance instance) -{ - assert(instance); - - return fmi3OK; -} - -fmi3Status fmi3ExitConfigurationMode(fmi3Instance instance) -{ - assert(instance); - - return fmi3OK; -} - -fmi3Status fmi3GetIntervalDecimal(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Float64 intervals[], fmi3IntervalQualifier qualifiers[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(intervals); - UNUSED(qualifiers); - - return fmi3OK; -} - -fmi3Status fmi3GetIntervalFraction(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3UInt64 counters[], fmi3UInt64 resolutions[], - fmi3IntervalQualifier qualifiers[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(counters); - UNUSED(resolutions); - UNUSED(qualifiers); - - return fmi3OK; -} - -fmi3Status fmi3GetShiftDecimal(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3Float64 shifts[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(shifts); - - return fmi3OK; -} - -fmi3Status fmi3GetShiftFraction(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - fmi3UInt64 counters[], fmi3UInt64 resolutions[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(counters); - UNUSED(resolutions); - - return fmi3OK; -} - -fmi3Status fmi3SetIntervalDecimal(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Float64 intervals[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(intervals); - - return fmi3OK; -} - -fmi3Status fmi3SetIntervalFraction(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3UInt64 counters[], const fmi3UInt64 resolutions[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(counters); - UNUSED(resolutions); - - return fmi3OK; -} - -fmi3Status fmi3SetShiftDecimal(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Float64 shifts[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(shifts); - - return fmi3OK; -} - -fmi3Status fmi3SetShiftFraction(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3UInt64 counters[], const fmi3UInt64 resolutions[]) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(counters); - UNUSED(resolutions); - - return fmi3OK; -} - -fmi3Status fmi3EvaluateDiscreteStates(fmi3Instance instance) -{ - assert(instance); - - return fmi3OK; -} - -fmi3Status fmi3UpdateDiscreteStates(fmi3Instance instance, - fmi3Boolean* discreteStatesNeedUpdate, fmi3Boolean* terminateSimulation, - fmi3Boolean* nominalsOfContinuousStatesChanged, - fmi3Boolean* valuesOfContinuousStatesChanged, - fmi3Boolean* nextEventTimeDefined, fmi3Float64* nextEventTime) -{ - assert(instance); - UNUSED(discreteStatesNeedUpdate); - UNUSED(terminateSimulation); - UNUSED(nominalsOfContinuousStatesChanged); - UNUSED(valuesOfContinuousStatesChanged); - UNUSED(nextEventTimeDefined); - UNUSED(nextEventTime); - - return fmi3OK; -} - -fmi3Status fmi3EnterContinuousTimeMode(fmi3Instance instance) -{ - assert(instance); - - return fmi3OK; -} - -fmi3Status fmi3CompletedIntegratorStep(fmi3Instance instance, - fmi3Boolean noSetFMUStatePriorToCurrentPoint, fmi3Boolean* enterEventMode, - fmi3Boolean* terminateSimulation) -{ - assert(instance); - UNUSED(noSetFMUStatePriorToCurrentPoint); - UNUSED(enterEventMode); - UNUSED(terminateSimulation); - - return fmi3OK; -} - -/* Providing independent variables and re-initialization of caching */ - -fmi3Status fmi3SetTime(fmi3Instance instance, fmi3Float64 time) -{ - assert(instance); - UNUSED(time); - - return fmi3OK; -} - -fmi3Status fmi3SetContinuousStates(fmi3Instance instance, - const fmi3Float64 continuousStates[], size_t nContinuousStates) -{ - assert(instance); - UNUSED(continuousStates); - UNUSED(nContinuousStates); - - return fmi3OK; -} - -/* Evaluation of the model equations */ - -fmi3Status fmi3GetContinuousStateDerivatives( - fmi3Instance instance, fmi3Float64 derivatives[], size_t nContinuousStates) -{ - assert(instance); - UNUSED(derivatives); - UNUSED(nContinuousStates); - - return fmi3OK; -} - -fmi3Status fmi3GetEventIndicators(fmi3Instance instance, - fmi3Float64 eventIndicators[], size_t nEventIndicators) -{ - assert(instance); - UNUSED(eventIndicators); - UNUSED(nEventIndicators); - - return fmi3OK; -} - -fmi3Status fmi3GetContinuousStates(fmi3Instance instance, - fmi3Float64 continuousStates[], size_t nContinuousStates) -{ - assert(instance); - UNUSED(continuousStates); - UNUSED(nContinuousStates); - - return fmi3OK; -} - -fmi3Status fmi3GetNominalsOfContinuousStates( - fmi3Instance instance, fmi3Float64 nominals[], size_t nContinuousStates) -{ - assert(instance); - UNUSED(nominals); - UNUSED(nContinuousStates); - - return fmi3OK; -} - -fmi3Status fmi3GetNumberOfEventIndicators( - fmi3Instance instance, size_t* nEventIndicators) -{ - assert(instance); - UNUSED(nEventIndicators); - - return fmi3OK; -} - -fmi3Status fmi3GetNumberOfContinuousStates( - fmi3Instance instance, size_t* nContinuousStates) -{ - assert(instance); - UNUSED(nContinuousStates); - - return fmi3OK; -} - -/* Simulating the FMU */ - -fmi3Status fmi3EnterStepMode(fmi3Instance instance) -{ - assert(instance); - - return fmi3OK; -} - -fmi3Status fmi3GetOutputDerivatives(fmi3Instance instance, - const fmi3ValueReference valueReferences[], size_t nValueReferences, - const fmi3Int32 orders[], fmi3Float64 values[], size_t nValues) -{ - assert(instance); - UNUSED(valueReferences); - UNUSED(nValueReferences); - UNUSED(orders); - UNUSED(values); - UNUSED(nValues); - - return fmi3OK; -} - -fmi3Status fmi3DoStep(fmi3Instance instance, - fmi3Float64 currentCommunicationPoint, fmi3Float64 communicationStepSize, - fmi3Boolean noSetFMUStatePriorToCurrentPoint, - fmi3Boolean* eventHandlingNeeded, fmi3Boolean* terminateSimulation, - fmi3Boolean* earlyReturn, fmi3Float64* lastSuccessfulTime) -{ - UNUSED(noSetFMUStatePriorToCurrentPoint); - UNUSED(eventHandlingNeeded); - UNUSED(terminateSimulation); - UNUSED(earlyReturn); - UNUSED(lastSuccessfulTime); - - int rc = - fmu_model_step(instance, currentCommunicationPoint, communicationStepSize); - return (rc == 0 ? fmi3OK : fmi3Error); - - return fmi3OK; -} - -fmi3Status fmi3ActivateModelPartition(fmi3Instance instance, - fmi3ValueReference clockReference, fmi3Float64 activationTime) -{ - assert(instance); - UNUSED(clockReference); - UNUSED(activationTime); - - return fmi3OK; -} diff --git a/dse/clib/fmi/fmu.c b/dse/clib/fmi/fmu.c deleted file mode 100644 index f305898..0000000 --- a/dse/clib/fmi/fmu.c +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define UNUSED(x) ((void)x) - - -/* FMU Spec (YAML). */ -#define FMU_SPEC_FILENAME "resources/fmu.yaml" -#define VR_INDEX_LEN 10 - - -static void _load_storage_spec( - FmuModelDesc* model_desc, YamlNode* model_doc, const char* spec) -{ - size_t var_count = 0; - YamlNode* spec_vars_node = dse_yaml_find_node(model_doc, spec); - if (spec_vars_node && spec_vars_node->node_type == YAML_MAPPING_NODE) { - var_count = hashmap_number_keys(spec_vars_node->mapping); - } - log_debug(" count : %d", var_count); - - char** _keys = hashmap_keys(&spec_vars_node->mapping); - for (unsigned int i = 0; i < var_count; i++) { - /* variable (node/dict) */ - YamlNode* var_node = hashmap_get(&spec_vars_node->mapping, _keys[i]); - if (!var_node) continue; - const char* name = var_node->name; - /* ref */ - unsigned int ref = 0; - if (dse_yaml_get_uint(var_node, "ref", &ref)) continue; - /* type */ - int type = -1; - const char* _scalar = dse_yaml_get_scalar(var_node, "type"); - if (_scalar == NULL) continue; - if (strcmp(_scalar, "bool") == 0) { - type = STORAGE_INT; - } else if (strcmp(_scalar, "int32") == 0) { - type = STORAGE_INT; - } else if (strcmp(_scalar, "uint32") == 0) { - type = STORAGE_INT; - } else if (strcmp(_scalar, "float") == 0) { - type = STORAGE_DOUBLE; - } else if (strcmp(_scalar, "double") == 0) { - type = STORAGE_DOUBLE; - } else if (strcmp(_scalar, "char") == 0) { - type = STORAGE_CHAR; - } else if (strcmp(_scalar, "string") == 0) { - type = STORAGE_STRING; - } else if (strcmp(_scalar, "binary") == 0) { - type = STORAGE_BINARY; - } else { - continue; - } - /* array */ - unsigned int array = 0; - dse_yaml_get_uint(var_node, "array", &array); - - log_info(" Variable: %s", name); - log_info(" ref: %d", ref); - log_info(" type: %d", type); - log_info(" array: %d", array); - - if ((type < 0) | (type >= __STORAGE_COUNT__)) continue; - storage_bucket* bucket = storage_get_bucket(model_desc, type); - if (bucket == NULL) continue; - - char _vr_index[VR_INDEX_LEN]; - snprintf(_vr_index, VR_INDEX_LEN - 1, "%d", ref); - - switch (type) { - case STORAGE_DOUBLE: - hashmap_set_double(&bucket->index, _vr_index, 0.0); - break; - case STORAGE_INT: - case STORAGE_CHAR: - hashmap_set_long(&bucket->index, _vr_index, 0); - break; - case STORAGE_STRING: - hashmap_set_string( - &bucket->index, _vr_index, calloc(1, sizeof(char))); - break; - case STORAGE_BINARY: { - storage_bucket* size_bucket = - storage_get_bucket(model_desc, STORAGE_BINARY_SIZE); - storage_bucket* length_bucket = - storage_get_bucket(model_desc, STORAGE_BINARY_BUFFER_LENGTH); - hashmap_set_ref( - &bucket->index, _vr_index, calloc(1, sizeof(void*))); - hashmap_set_long(&size_bucket->index, _vr_index, 0); - hashmap_set_long(&length_bucket->index, _vr_index, 0); - } break; - default: - break; - } - } -} - - -static int storage_index_on_fmu(FmuModelDesc* model_desc, const char* file) -{ - YamlNode* model_doc = dse_yaml_load_single_doc(file); - if (!model_doc) return 1; - - log_debug("Load variable list from file: %s", file); - _load_storage_spec(model_desc, model_doc, "spec/variables"); - - log_debug("Load parameter list from file: %s", file); - _load_storage_spec(model_desc, model_doc, "spec/parameters"); - - return 0; -} - - -/** -fmu_model_create -================ - -Creates an FMU Model Descriptor object and performs any necessary -initialisation of the FMU Model. - -Called by `fmi2Instantiate()`. - -Called by `fmi3InstantiateCoSimulation()`. - -Parameters ----------- -fmu_inst (void*) -: FMU provided instance data. - -mem_alloc (FmuMemAllocFunc) -: Function pointer for the memory allocation function which the Model should - use. Recommend using calloc(). - -mem_free (FmuMemFreeFunc) -: Function pointer for the memory free function which the Model should use. - Typically free(). - -resource_location (const char*) -: A string referencing the path to the resource directory. - -Returns -------- -FmuModelDesc* -: A new FMU Model Descriptor object. -*/ -__attribute__((weak)) FmuModelDesc* fmu_model_create( - void* fmu_inst, FmuMemAllocFunc mem_alloc, FmuMemFreeFunc mem_free, - const char* resource_location) -{ - assert(mem_alloc); - assert(mem_free); - - /* Create the Model Descriptor. */ - FmuModelDesc* model_desc = mem_alloc(1, sizeof(FmuModelDesc)); - model_desc->instance_data = fmu_inst; - model_desc->mem_alloc = mem_alloc; - model_desc->mem_free = mem_free; - model_desc->external_binary_free = false; - model_desc->resource_location = resource_location; - - /* Configure the Model: storage/variables. */ - storage_init(model_desc); - storage_index_on_fmu(model_desc, FMU_SPEC_FILENAME); - - return model_desc; -} - - -/** -fmu_model_init -============== - -Called by `fmi2ExitInitializationMode()` as the FMU exits initialisation mode. - -Called by `fmi3ExitInitializationMode()` as the FMU exits initialisation mode. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -Returns -------- -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. -*/ -__attribute__((weak)) int fmu_model_init(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - return 0; -} - - -/** -fmu_model_step -============== - -Called by `fmi2DoStep()`. - -Called by `fmi3DoStep()`. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -Returns -------- -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. -*/ -__attribute__((weak)) int fmu_model_step( - FmuModelDesc* model_desc, double model_time, double stop_time) -{ - UNUSED(model_desc); - UNUSED(model_time); - UNUSED(stop_time); - - return 0; -} - - -/** -fmu_model_terminate -=================== - -Called by `fmi2Terminate()`. - -Called by `fmi3Terminate()`. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -Returns -------- -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. -*/ -__attribute__((weak)) int fmu_model_terminate(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - return 0; -} - - -/** -fmu_model_destroy -================= - -Called by `fmi2FreeInstance()`. - -Called by `fmi3FreeInstance()`. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. - -Returns -------- -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. -*/ -__attribute__((weak)) void fmu_model_destroy(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); -} - - -/** -fmu_model_finalize -================== - -Releases the resources created by `fmu_model_create()`. - -Called by `fmi2FreeInstance()`. - -Called by `fmi3FreeInstance()`. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor, references various runtime functions and data. -*/ -__attribute__((weak)) void fmu_model_finalize(FmuModelDesc* model_desc) -{ - storage_destroy(model_desc); - model_desc->mem_free(model_desc->instance_data); - model_desc->mem_free(model_desc); -} diff --git a/dse/clib/fmi/fmu.h b/dse/clib/fmi/fmu.h deleted file mode 100644 index cf74e4c..0000000 --- a/dse/clib/fmi/fmu.h +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#ifndef DSE_CLIB_FMI_FMU_H_ -#define DSE_CLIB_FMI_FMU_H_ - -#include -#include -#include - - -/** -FMU Model API -============= - -The FMU Model API (a part of the DSE C Lib) provides a simplified interface for -developing Models which adhere to the Modelica Association FMI Standard. It has -the following notable capabilities: - -* Models are compatible with either FMI 2 or FMI 3 (selected via linker). -* Simple model lifecycle: - * `fmu_model_init()` - * `fmu_model_step()` - only function needed for a minimal FMU implementation! - * ... -* Storage system with fast hash based index for all FMI Variable types, including binary data. -* Integration with [DSE Network Codec API](https://github.com/boschglobal/dse.standards/tree/main/dse/ncodec) - which provides a MIMEtype selected (and configured) CAN Virtual Buses. The Network Codec has a simple - to use programming interface: - * `ncodec_write()` / `ncodec_flush()` - to send CAN frames - * `ncodec_read()` - to receive CAN frames. - - -Component Diagram ------------------ - - -![](fmu-model.png) - - -Example -------- - -The following example shows a minimal model implementation which simply -increments a counter. - -{{< readfile file="../examples/counter.c" code="true" lang="c" >}} - - -Linking -------- -When building an FMU, link the following files: - -- fmu.c : generic implementation parts -- storage.c : storage mechanism -- fmi2/fmi2fmu.c : version specific parts -- model.c : model specific parts - -*/ - -typedef void* (*FmuMemAllocFunc)(size_t number, size_t size); -typedef void (*FmuMemFreeFunc)(void* obj); - - -typedef struct FmuModelDesc { - /* Callback functions. */ - FmuMemAllocFunc mem_alloc; - FmuMemFreeFunc mem_free; - /* Resource Location (corrected for OS URI Schema). */ - const char* resource_location; - /* FMU Instance Data (indirect, from importer). */ - void* instance_data; - void* private; - /* Data flags. */ - bool external_binary_free; -} FmuModelDesc; - - -typedef enum storage_type { - STORAGE_DOUBLE, - STORAGE_INT, - STORAGE_CHAR, - STORAGE_STRING, - STORAGE_BINARY, - STORAGE_BINARY_SIZE, - STORAGE_BINARY_BUFFER_LENGTH, - __STORAGE_COUNT__, -} storage_type; - - -typedef struct storage_bucket { - storage_type type; - HashMap index; -} storage_bucket; - - -/* fmu.c */ -DLL_PRIVATE FmuModelDesc* fmu_model_create( - void* fmu_inst, FmuMemAllocFunc mem_alloc, FmuMemFreeFunc mem_free, - const char *working_dir); -DLL_PRIVATE void fmu_model_finalize(FmuModelDesc* model_desc); -/* Model API (implemented by the Model). */ -DLL_PRIVATE int fmu_model_init(FmuModelDesc* model_desc); -DLL_PRIVATE int fmu_model_step( - FmuModelDesc* model_desc, double model_time, double stop_time); -DLL_PRIVATE int fmu_model_terminate(FmuModelDesc* model_desc); -DLL_PRIVATE void fmu_model_destroy(FmuModelDesc* model_desc); - - -/* storage.c */ -DLL_PRIVATE int storage_init(FmuModelDesc* model_desc); -DLL_PRIVATE storage_bucket* storage_get_bucket( - FmuModelDesc* model_desc, storage_type type); -DLL_PRIVATE void* storage_ref( - FmuModelDesc* model_desc, unsigned int vr, storage_type type); -DLL_PRIVATE void storage_set_string( - FmuModelDesc* model_desc, unsigned int vr, char* source); -DLL_PRIVATE int storage_destroy(FmuModelDesc* model_desc); - - -/* Value Types supported by the FMI Importer (related to storage types). */ -typedef enum { - FMI_VALUE_TYPE_INTEGER, - FMI_VALUE_TYPE_REAL, - __FMI_VALUE_TYPE_COUNT__, -} FmiValueType; - -typedef unsigned int fmi_value_ref; // Generic type instance of fmi_value_ref. -typedef double fmi_real; // Generic type instance of fmi2Real. -typedef int fmi_integer; // Generic type instance of fmi2Integer. - - -typedef enum { - FMU_STRATEGY_ACTION_NONE = 0, - /* These strategy actions are implemented by a Adapter. */ - FMU_STRATEGY_ACTION_LOAD, - FMU_STRATEGY_ACTION_INIT, - FMU_STRATEGY_ACTION_STEP, - FMU_STRATEGY_ACTION_UNLOAD, - /* These strategy actions are implemented by a Strategy. */ - FMU_STRATEGY_ACTION_MARSHALL_OUT, - FMU_STRATEGY_ACTION_MARSHALL_IN, - /* Count of all actions. */ - __FMU_STRATEGY_ACTION_COUNT__ -} FmuStrategyAction; - - -typedef struct FmuInstDesc FmuInstDesc; - - -/* Strategy - defines an execution strategy to be applied to an imported FMU. */ -typedef int (*FmuStrategyExecuteFunc)( - FmuInstDesc* inst, FmuStrategyAction action); -typedef void (*FmuStrategyMapVariables)(FmuInstDesc* inst, - FmiValueType value_type, char** names, void** values, size_t count); -typedef void (*FmuStrategyToVariables)(FmuInstDesc* inst); -typedef void (*FmuStrategyFromVariables)(FmuInstDesc* inst); -typedef void (*FmuStrategyMapDestroy)(FmuInstDesc* inst); - - -typedef struct FmuStrategyDesc { - const char* name; - /* Strategy methods. */ - FmuStrategyExecuteFunc exec_func; - FmuStrategyMapVariables map_func; - FmuStrategyToVariables marshal_to_var_func; - FmuStrategyFromVariables marshal_from_var_func; - FmuStrategyMapDestroy map_destroy_func; - /* Time tracking for the strategy. */ - double step_size; - double model_time; - double stop_time; - double model_time_correction; -} FmuStrategyDesc; - - -/* Adapter - defines a specific FMI Importer Interface implementation. */ -typedef int (*FmuLoadHandler)(FmuInstDesc* inst); -typedef int (*FmuInitHandler)(FmuInstDesc* inst); -typedef int (*FmuStepHandler)( - FmuInstDesc* inst, double* model_time, double stop_time); -typedef int (*FmuUnloadHandler)(FmuInstDesc* inst); -typedef int (*FmuSetVarHandler)(FmuInstDesc* inst); -typedef int (*FmuGetVarHandler)(FmuInstDesc* inst); - -typedef struct FmuAdapterDesc { - const char* name; - /* Adapter methods. */ - FmuLoadHandler load_func; - FmuInitHandler init_func; - FmuStepHandler step_func; - FmuUnloadHandler unload_func; - FmuSetVarHandler set_var_func; - FmuGetVarHandler get_var_func; -} FmuAdapterDesc; - - -/* Instance - represents an imported instance of an FMU. */ -typedef struct FmuInstDesc { - const char* name; - const char* path; - void* model_doc; - /* Importer specific data. */ - FmuAdapterDesc* adapter; - FmuStrategyDesc* strategy; - void* inst_data; - /* FMU version specific data. */ - void* model_desc; -} FmuInstDesc; - - -/* importer.c - Generalised Importer Interface. */ -DLL_PUBLIC int fmu_load(FmuInstDesc* inst); -DLL_PUBLIC int fmu_init(FmuInstDesc* inst); -DLL_PUBLIC int fmu_step( - FmuInstDesc* inst, double* model_time, double stop_time); -DLL_PUBLIC int fmu_unload(FmuInstDesc* inst); -DLL_PUBLIC void fmu_map_variables(FmuInstDesc* inst, FmiValueType value_type, - char** names, void** values, size_t count); -DLL_PUBLIC void fmu_marshal_to_variables(FmuInstDesc* inst); -DLL_PUBLIC void fmu_marshal_from_variables(FmuInstDesc* inst); -DLL_PUBLIC void fmu_map_destroy(FmuInstDesc* inst); - - -/* strategy.c */ -DLL_PUBLIC int fmi2_cosim_execute(FmuInstDesc* inst, FmuStrategyAction action); - - -#endif // DSE_CLIB_FMI_FMU_H_ diff --git a/dse/clib/fmi/importer.c b/dse/clib/fmi/importer.c deleted file mode 100644 index fa5d5f7..0000000 --- a/dse/clib/fmi/importer.c +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - - -#include -#include -#include -#include - - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -#define UNUSED(x) ((void)x) - - -/* - * FMU Importer - Strategy Interface - * ================================= - */ - -int fmu_load(FmuInstDesc* inst) -{ - assert(inst); - assert(inst->strategy); - assert(inst->strategy->exec_func); - - return inst->strategy->exec_func(inst, FMU_STRATEGY_ACTION_LOAD); -} - - -int fmu_init(FmuInstDesc* inst) -{ - assert(inst); - assert(inst->strategy); - assert(inst->strategy->exec_func); - - return inst->strategy->exec_func(inst, FMU_STRATEGY_ACTION_INIT); -} - - -int fmu_step(FmuInstDesc* inst, double* model_time, double stop_time) -{ - assert(inst); - assert(inst->strategy); - assert(inst->strategy->exec_func); - UNUSED(model_time); - UNUSED(stop_time); - - // TODO set model time, stop time. - - inst->strategy->exec_func(inst, FMU_STRATEGY_ACTION_MARSHALL_OUT); - int rc = inst->strategy->exec_func(inst, FMU_STRATEGY_ACTION_STEP); - inst->strategy->exec_func(inst, FMU_STRATEGY_ACTION_MARSHALL_IN); - return rc; -} - -int fmu_unload(FmuInstDesc* inst) -{ - assert(inst); - assert(inst->strategy); - assert(inst->strategy->exec_func); - - return inst->strategy->exec_func(inst, FMU_STRATEGY_ACTION_UNLOAD); -} - - -/* - * FMU Importer - Scalar Variable Map - * ================================== - */ - -typedef struct VariableMap { - FmiValueType value_type; - void** values; - size_t count; - size_t offset; -} VariableMap; - - -typedef struct SignalMap { - char** names; - double* signals; - size_t count; - VariableMap* var_map; // Null terminated list; -} SignalMap; - - -void fmu_map_variables(FmuInstDesc* inst, FmiValueType value_type, char** names, - void** values, size_t count) -{ - assert(inst); - UNUSED(value_type); - - if (count == 0) return; - if (inst->inst_data == NULL) { - inst->inst_data = calloc(1, sizeof(SignalMap)); - } - SignalMap* signal_map = inst->inst_data; - - /* Extend the variable map. */ - VariableMap* vm_p = signal_map->var_map; - uint vm_count = 0; - while (vm_p && vm_p->values) { - vm_count++; - vm_p++; - } - signal_map->var_map = - realloc(signal_map->var_map, (vm_count + 1 + 1) * sizeof(VariableMap)); - vm_p = signal_map->var_map; - while (vm_p && vm_p->values) - vm_p++; - /* vm_p is the new VariableMap object (next is terminator). */ - assert(vm_p); - assert(vm_p->values == NULL); - - /* Complete the variable map. */ - vm_p->values = calloc(count, sizeof(void*)); - memcpy(vm_p->values, values, count * sizeof(void*)); - vm_p->offset = signal_map->count; // Offset to the signal_map->signals. - vm_p->count = count; - - /* Extend the signal map. */ - signal_map->count += count; - signal_map->signals = - realloc(signal_map->signals, signal_map->count * sizeof(double)); - signal_map->names = - realloc(signal_map->names, signal_map->count * sizeof(char*)); - for (size_t i = 0; i < count; i++) { - signal_map->names[vm_p->offset + i] = strdup(names[i]); - } -} - - -void fmu_marshal_to_variables(FmuInstDesc* inst) -{ - assert(inst); - if (inst->inst_data == NULL) return; - SignalMap* signal_map = inst->inst_data; - VariableMap* vm_p = signal_map->var_map; - - while (vm_p && vm_p->values) { - switch (vm_p->value_type) { - case FMI_VALUE_TYPE_INTEGER: - for (size_t i = 0; i < vm_p->count; i++) { - int* _v = (int*)vm_p->values[i]; - *_v = (int)signal_map->signals[vm_p->offset + i]; - } - break; - case FMI_VALUE_TYPE_REAL: - for (size_t i = 0; i < vm_p->count; i++) { - double* _v = (double*)vm_p->values[i]; - *_v = signal_map->signals[vm_p->offset + i]; - } - break; - default: - break; - } - // Next var_map. - vm_p++; - } -} - - -void fmu_marshal_from_variables(FmuInstDesc* inst) -{ - assert(inst); - if (inst->inst_data == NULL) return; - SignalMap* signal_map = inst->inst_data; - VariableMap* vm_p = signal_map->var_map; - - while (vm_p && vm_p->values) { - switch (vm_p->value_type) { - case FMI_VALUE_TYPE_INTEGER: - for (size_t i = 0; i < vm_p->count; i++) { - signal_map->signals[vm_p->offset + i] = - (double)*(int*)vm_p->values[i]; - } - break; - case FMI_VALUE_TYPE_REAL: - for (size_t i = 0; i < vm_p->count; i++) { - signal_map->signals[vm_p->offset + i] = - *(double*)vm_p->values[i]; - } - break; - default: - break; - } - // Next var_map. - vm_p++; - } -} - - -void fmu_map_destroy(FmuInstDesc* inst) -{ - assert(inst); - if (inst->inst_data == NULL) return; - SignalMap* signal_map = inst->inst_data; - - /* Release the variable map part. */ - VariableMap* vm_p = signal_map->var_map; - while (vm_p && vm_p->values) { - free(vm_p->values); - /* Next var_map. */ - vm_p++; - } - if (signal_map->var_map) free(signal_map->var_map); - - /* Release the signal part. */ - if (signal_map->names) { - for (size_t i = 0; i < signal_map->count; i++) { - if (signal_map->names[i]) free(signal_map->names[i]); - } - free(signal_map->names); - } - if (signal_map->signals) free(signal_map->signals); - - /* Release the container (and make the pointer safe). */ - free(signal_map); - inst->inst_data = NULL; -} diff --git a/dse/clib/fmi/storage.c b/dse/clib/fmi/storage.c deleted file mode 100644 index 6c1901a..0000000 --- a/dse/clib/fmi/storage.c +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - - -#define UNUSED(x) ((void)x) -#define VR_INDEX_LEN 11 - - -static storage_bucket __buckets[__STORAGE_COUNT__]; -static char __vr_index[VR_INDEX_LEN]; - - -static inline void _set_vr_index(unsigned int vr) -{ - snprintf(__vr_index, VR_INDEX_LEN, "%d", vr); -} - - -/** -storage_init -============ - -Initialise the storage subsystem for an FMU. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor. - -Returns -------- -0 (int) -: Success. - -+ve (int) -: Failure, inspect errno for the failing condition. -*/ -int storage_init(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - for (unsigned int i = 0; i < __STORAGE_COUNT__; i++) { - __buckets[i].type = i; - hashmap_init(&__buckets[i].index); - } - - return 0; -} - - -/** -storage_get_bucket -================== - -Returns a reference/pointer to the requested storage bucket. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor. - -type (storage_type) -: Indicate the storage type bucket which should be retrieved. - -Returns -------- -storage_bucket* -: Reference to the requested storage bucket. - -NULL -: The specified storage bucket is not provisioned. -*/ -storage_bucket* storage_get_bucket(FmuModelDesc* model_desc, storage_type type) -{ - UNUSED(model_desc); - - if (type >= __STORAGE_COUNT__) return NULL; - return &(__buckets[type]); -} - - -/** -storage_ref -=========== - -Get a reference (pointer to) the specified storage value. The returned -reference must be cast to the provided storage_type by the caller before -accessing the storage value. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor. - -vr (unsigned int) -: FMU Variable Reference. - -type (storage_type) -: Indicate the storage type bucket from which the storage reference should - be retrieved. - -Returns -------- -void* -: Reference to a storage value (caller must cast to storage_type). - -NULL -: A reference to the storage value could not be retrieved. - -Example -------- - -```c -#include - -static FmuModelDesc* model_desc; - -int set_int_value(unsigned int vr, int value) -{ - int *ref = (int*)storage_ref(model_desc, vr, STORAGE_INT); - if (ref == NULL) return 1; - *ref = value; - return 0; -} -``` -*/ -inline void* storage_ref( - FmuModelDesc* model_desc, unsigned int vr, storage_type type) -{ - UNUSED(model_desc); - - if ((type < 0) | (type >= __STORAGE_COUNT__)) return NULL; - - storage_bucket* bucket = &__buckets[type]; - _set_vr_index(vr); - void* ref = hashmap_get(&bucket->index, __vr_index); - - return ref; -} - - -void _free_ref(void* map_item, void* data) -{ - UNUSED(data); - void** pointer_ref = (void**)map_item; - - if (pointer_ref && *pointer_ref) free(*pointer_ref); -} - - -/** -storage_destroy -=============== - -Destroy any allocated storage. - -Parameters ----------- -model_desc (FmuModelDesc*) -: Model Descriptor. - -Returns -------- -0 (int) -: Success. - -+ve (int) -: Failure, inspect errno for the failing condition. -*/ -int storage_destroy(FmuModelDesc* model_desc) -{ - UNUSED(model_desc); - - for (unsigned int i = 0; i < __STORAGE_COUNT__; i++) { - storage_bucket* bucket = &__buckets[i]; - switch (i) { - case STORAGE_STRING: - hashmap_destroy_ext(&bucket->index, _free_ref, NULL); - break; - case STORAGE_BINARY: - if (model_desc->external_binary_free) { - hashmap_destroy(&bucket->index); - } else { - hashmap_destroy_ext(&bucket->index, _free_ref, NULL); - } - break; - default: - hashmap_destroy(&bucket->index); - } - } - - return 0; -} diff --git a/dse/clib/fmi/strategy.c b/dse/clib/fmi/strategy.c deleted file mode 100644 index 4d531ca..0000000 --- a/dse/clib/fmi/strategy.c +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2023 Robert Bosch GmbH -// -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - - -/** -fmi2_cosim_execute -================== - -Applies an action (load, init, step etc) from an FMI2 CoSim execution strategy -to the specified FMU instance. The strategy action will call FMU methods -according to the FMI Standard. - -Parameters ----------- -inst (FmuInstDesc*) -: Model Descriptor, references various runtime functions and data. - -action (FmuStrategyAction) -: The action which should be executed by the strategy. - -Returns -------- -0 -: Success, an equivalent status is passed to the FMU Importer. - -!0 -: Failure, an equivalent status is passed to the FMU Importer. -*/ -int fmi2_cosim_execute(FmuInstDesc* inst, FmuStrategyAction action) -{ - switch (action) { - case FMU_STRATEGY_ACTION_LOAD: - /* Call the FMU Adapter Load method. */ - if ((inst->adapter) && (inst->adapter->load_func)) { - inst->adapter->load_func(inst); - } - break; - - case FMU_STRATEGY_ACTION_INIT: - if ((inst->adapter) && (inst->adapter->init_func)) { - inst->adapter->init_func(inst); - } - /* Marshall any initialised variables to the Channel vector. */ - if (inst->strategy->marshal_from_var_func) - inst->strategy->marshal_from_var_func(inst); - break; - - case FMU_STRATEGY_ACTION_STEP: - /* - * Progress time for each model contained within this MCL. - * - * for each model, - * if the model time <= MCL time, - * and the model time + step size <= the next MCL time, - * step the model for its configured step size, - * until all models have stepped as far as they can. - * - * Its possible, when the model step is greater than the MCL step, that - * a model will not be stepped on/in individual calls to ACTION_STEP. - */ - { - /* Determine times. */ - double model_time = inst->strategy->model_time; - double model_stop_time = inst->strategy->stop_time; - if (model_time >= model_stop_time) { - break; - } - if (inst->strategy->step_size) { - /** - * Use the annotated step size. - * Increment via Kahan summation. - * - * model_stop_time = model_time + model->step_size; - */ - double y = inst->strategy->step_size - - inst->strategy->model_time_correction; - double t = model_time + y; - inst->strategy->model_time_correction = (t - model_time) - y; - model_stop_time = t; - - if (model_stop_time < inst->strategy->model_time) { - /* Fast forward this model. */ - double _ff_model_time = inst->strategy->model_time; - log_debug("Model fast forward: %f -> %f) (%s)", model_time, - _ff_model_time, inst->name); - model_time = _ff_model_time; - /* Recalculate the stop time. */ - double y = inst->strategy->step_size - - inst->strategy->model_time_correction; - double t = model_time + y; - inst->strategy->model_time_correction = - (t - model_time) - y; - model_stop_time = t; - } - } - if (model_stop_time <= inst->strategy->stop_time) { - /* Step this Model. */ - log_trace("CALL model->adapter->step_func @ %f (et=%f) (%s)", - model_time, model_stop_time, inst->name); - inst->adapter->step_func(inst, &model_time, model_stop_time); - inst->strategy->model_time = model_time; - } else { - /* Model stop time past MCL stop time. */ - log_debug("Model stop time past MCL stop time: %f>>%f (%s)", - model_stop_time, inst->strategy->stop_time, inst->name); - } - } - break; - - case FMU_STRATEGY_ACTION_UNLOAD: - if ((inst->adapter) && (inst->adapter->unload_func)) { - /* Call the FMU Adapter Unload method. */ - inst->adapter->unload_func(inst); - /* Call the Strategy Destroy method. */ - if (inst->strategy->map_destroy_func) - inst->strategy->map_destroy_func(inst); - } - break; - - case FMU_STRATEGY_ACTION_MARSHALL_OUT: - if (inst->strategy->marshal_to_var_func) - inst->strategy->marshal_to_var_func(inst); - break; - - case FMU_STRATEGY_ACTION_MARSHALL_IN: - if (inst->strategy->marshal_from_var_func) - inst->strategy->marshal_from_var_func(inst); - break; - - case FMU_STRATEGY_ACTION_NONE: - default: - log_debug("FMI CoSim Strategy NOP (action=%d)", action); - break; - } - - return 0; -}