Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ tests/Rectifier/

# generated documentation
_build
native/remoting/.vs
69 changes: 38 additions & 31 deletions native/remoting/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,48 @@ if (WIN32)
set(FMI_PLATFORM win32)
endif ()
else ()
set(FMI_PLATFORM linux64)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

include(CheckFunctionExists)
check_function_exists(semtimedop HAVE_SEMTIMEDOP)

if (APPLE)
set(FMI_PLATFORM darwin64)
# Compilation in 32 bits mode is no longer supported in MacOS
else ()
if (BUILD_32)
set(FMI_PLATFORM linux32)
set(BITNESS "-m32")
else ()
set(FMI_PLATFORM linux64)
endif ()
endif()
endif ()

message("FMI_PLATFORM: ${FMI_PLATFORM}")

# Version.h creation
find_package(Git QUIET)
if(NOT Git_FOUND)
message(WARNING "Git not found")
set(GIT_TAG, "LOCAL Version")
else()
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_RESULT
)
endif()
message("--- Version: ${GIT_TAG}")
configure_file(
${CMAKE_SOURCE_DIR}/version.h.in
${CMAKE_CURRENT_BINARY_DIR}/version.h
)


if (MSVC)
# link statically against the the Visual C runtime
set(variables
Expand Down Expand Up @@ -142,7 +179,6 @@ if (WIN32)
add_executable(server_sm
communication.c communication.h
process.c process.h
remote.c remote.h
server.c server.h
${CMAKE_CURRENT_BINARY_DIR}/config.h
)
Expand All @@ -164,7 +200,6 @@ if (WIN32)
client.c client.h
communication.c communication.h
process.c process.h
remote.c remote.h
${CMAKE_CURRENT_BINARY_DIR}/config.h
)

Expand Down Expand Up @@ -195,31 +230,3 @@ target_include_directories(client_test PUBLIC
target_link_libraries(client_test
${CMAKE_DL_LIBS}
)

if (BUILD_TESTER)

add_executable(test_sizeof
${CMAKE_CURRENT_SOURCE_DIR}/test_sizeof.c
remote.h
)

target_include_directories(test_sizeof PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../src/fmpy/c-code
)

add_custom_command(OUTPUT test_sizeof.c
COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/gen_sizeof.py
DEPENDS gen_sizeof.py
)

add_executable(test_server
${CMAKE_CURRENT_SOURCE_DIR}/test_server.c
)
target_include_directories(test_server PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../src/fmpy/c-code)

target_include_directories(test_sizeof PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../src/fmpy/c-code
)

endif ()
71 changes: 45 additions & 26 deletions native/remoting/README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,60 @@
## Purpose
# FMU-Remoting

Run model contained inside FMU (which is a shared library) into a separate process.
The calling process may be in different bitness than the model (shared library).
## Rationale

Some OS can support 32-bits and 64-bits. Remoting feature adds a new interface to a existing FMU and let
the user mix bitness between fmi-importer and the DLL contained into the FMU.

## Implementation

Current implementation relies on Shared Memory and is available on Windows, Linux and MacOS only.
Current implementation relies on Shared Memory and Semaphore. It is available on Windows and Linux only.
Primary OS is Windows.

This version supports:
- ONLY FMI 2.0, ONLY for co-simulation mode
- Strings are NOT supported

### Sequence Diagram

```mermaid
sequenceDiagram
participant env as Simulation Environment
participant importer as FMI-importer
participant client as client.dll
participant server as server.exe
participant dll as model.dll
Note over env,dll: Initialization
env->>client: fmi2Initialize
Note over importer,dll: Initialization
importer->>client: fmi2Initialize
client->>+server: spawn
server->>-client: acknowledge
client->>server:fmi2Initialize
client->>server:RPC_fmi2Initialize
server->>dll: load
server->>+dll: fmi2Initialize
dll->>-server: fmi2Component (server_t *)
server->>client: status
client->>env: fmi2Component (client_t*)
Note over env,dll: Main loop until fmi2FreeInstance
env->>client: fmi2 function
client->>server: fmi2 function
server->>+dll: fmi2 function
client->>importer: fmi2Component (client_t*)
Note over importer,dll: Main loop until fmi2FreeInstance
importer->>+client: fmi2SetXXX
client->>-importer: status
importer->>+client: fmi2GetXXX
client->>-importer: values
importer->>client: fmi2DoStep
client->>server: values
client->>server: RPC_fmi2DoStep
server->>+dll: fmiSetXXX
server->>+dll: fmi2DoStep
dll->>-server: status
server->>+dll: fmiGetXXX
server->>client: values
server->>client: status
client->>env: status
client->>importer: status
```

### Performances

To improve performance, this implementation minimize the number of Inter Process Communication calls. So that,
values of signal of the DLL are cached on client side in local buffers.


### How it's work ?

Considering win64 FMU, only the `binaries/win64` folder is populated. It contains `model.dll`.
Expand All @@ -47,30 +70,26 @@ When Simulation Enviroment will use the FMU on 32 bits OS:

#### Add remoting win64: simulate 32 bits FMU 64 bits OS
1. Copy `client_sm.dll` (64 bits) as `model.dll` in `binaries/win64`
3. Copy `server_sm.exe` (32 bits) in `binaries/win32`
2. Copy `server_sm.exe` (32 bits) in `binaries/win32`

When Simulation Enviroment will use the FMU on 64bits kernel:
1. it will load `win64/model.dll` (which is a copy of `client_sm.dll`)
2. which will communicate with `win32/server_exe`.
3. which will load `win32/model.dll`


## TODO List
## Usage with `fmutool`

- [X] Unique name for event/memory
- [X] Deep tests for Stings getters/setters
- [X] Perfomances tests (and improvement if needed)
- [X] Support for more fmi2 function
- [ ] Support for fmi3
- [ ] network communication (multi-OS communication)
This feature is available easily with `fmutool` command line or with its graphical user interface:
```fmutool -input model64.fmu -add-remoting32 -output model64+32.fmu```


## LICENSE

The remoting code is written by Nicolas.LAURENT@Renault.com. It is based on FMPy original ideas.
This code is released under the 2-Clause BSD license:
The remoting code is part of [fmu-manipulation-toolbox](https://github.com/grouperenault/fmu_manipulation_toolbox)
It is released under the 2-Clause BSD license:

Copyright 2023 Renault SAS
Copyright 2023-2026 Renault SAS

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
Expand All @@ -82,7 +101,7 @@ provided that the following conditions are met:
and the following disclaimer in the documentation and/or other materials provided with
the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Expand Down
Loading