README.md 8.35 KB
Newer Older
Jean Meurice's avatar
Jean Meurice committed
1
# Hardware Emulator
Evgeny Kusmenko's avatar
Evgeny Kusmenko committed
2

3 4 5 6
- Dynamic Interface
- SoftwareSimulator
- HardwareEmulator
- Controller
Jean Meurice's avatar
Jean Meurice committed
7

8

Jean Meurice's avatar
Jean Meurice committed
9
## Overview
10
This project allows to run **EmbeddedMontiArc** models that have a **DynamicInterface** and let them communicate with the MontiSim simulation. It allows the time evaluation of the model execution using a parametric computer model.
11

Jean Meurice's avatar
Jean Meurice committed
12

Jean Meurice's avatar
Jean Meurice committed
13

Jean Meurice's avatar
Jean Meurice committed
14 15 16 17
## Building
The project contains a **C++ CMake project** and a **Maven project**. 
The C++ project contains the logic of the Hardware Emulator.
The Maven project takes this C++ library and wraps it in a Jar alongside its Java Interfaces. The resulting Jar is avaiable as dependency in the **nexus**.
18

19
### C++ Project
Jean Meurice's avatar
Jean Meurice committed
20
To compile the C++ project (under the [hardware_emulator](hardware_emulator) folder), use the `build_emulator` script for your system (located in the [scripts](scripts) folder).
Jean Meurice's avatar
Jean Meurice committed
21

Jean Meurice's avatar
Jean Meurice committed
22 23 24
> For Visual Studio, the script has to be started inside the Visual Studio **Developer Command Prompt**.
> 
> With Visual Studio, the library can also be compiled directly from within the Visual Studio project generated by CMake (in the `build` folder).
Jean Meurice's avatar
Jean Meurice committed
25

Jean Meurice's avatar
Jean Meurice committed
26
The `build_emulator` script will directly install the compiled library inside the [resources](src/main/resources) folder of the Maven project.
Jean Meurice's avatar
Jean Meurice committed
27

Jean Meurice's avatar
Jean Meurice committed
28
_**NOTE:** Any changes to the C++ project **MUST** be compiled and installed under both **Linux and Windows** before being merged into the Master branch so that both updated versions are included in the maven artifact._
Jean Meurice's avatar
Jean Meurice committed
29

30
### Maven Project
Jean Meurice's avatar
Jean Meurice committed
31

Jean Meurice's avatar
Jean Meurice committed
32 33 34 35
Simply use the `mvn install` command in the main directory to compile the maven project. 

> The project uses the [LibraryService](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/commons/blob/master/src/main/java/commons/utils/LibraryService.java) system to make libraries stored inside the jar resources available at runtime (depending on the system).

36
### C++ dependencies
Jean Meurice's avatar
Jean Meurice committed
37

Jean Meurice's avatar
Jean Meurice committed
38
The libraries required by the C++ project are pre-compiled under [hardware_emulator/libs](hardware_emulator/libs). They can be recompiled using the `build_dependencies` scripts.
Jean Meurice's avatar
Jean Meurice committed
39

Jean Meurice's avatar
Jean Meurice committed
40
> *(For MinGW, the [Unicorn](unicorn) library has to be compiled under MSYS.)*
Jean Meurice's avatar
Jean Meurice committed
41 42 43 44


## Test

Jean Meurice's avatar
Jean Meurice committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
The `hardware-emulator-test` can be executed in the hardware_emulator/bin folder locally to test the emulation of sample programs and a basic autopilot emulation.


## Usage

To use the Hardware Emulator inside another Maven project add the following dependency to the `pom.xml`:
```xml
<dependency>
    <groupId>montisim</groupId>
    <artifactId>hardware_emulator</artifactId>
    <version>${montisim.hardware_emulator.version}</version>
</dependency>
```
Where `montisim.hardware_emulator.version` specifies the artifact version.

60
The main interface for a simulator is [SoftwareSimulator](src/main/java/de/rwth/monticore/EmbeddedMontiArc/simulators/hardware_emulator/interfaces/SoftwareSimulator.java).
Jean Meurice's avatar
Jean Meurice committed
61

62 63 64 65 66 67 68 69 70 71 72 73 74 75
Depending on whether the usage of the SoftwareSimulator is remote or not, it has to be allocated through a different instance of a [SoftwareSimulatorManager](src/main/java/de/rwth/monticore/EmbeddedMontiArc/simulators/hardware_emulator/interfaces/SoftwareSimulatorManager.java): `DirectSoftwareSimulatorManager` or `RemoteSoftwareSimulatorManager`. The remote version will return a RMI reference to the remote simulator.

## Details

This project is build from the following main components:

![Project Structure](docs/Structure.svg)

The components used to discover the ports of a *DynamicInterface* software and responsible for the communication between the MontiSim simulator and the software are shown in the following:

![Port Structure](docs/PortStructureVert.svg)

The main idea is to discover the name and types of the ports (performed by the `DynamicInterfaceResolver`), to store these informations in `PortInformation` structures, then depending on the actual simulator implementation used, allocate actual `Port` instances that can store and transfer the specific data type (`PortSimpleIntDirect`, `PortArrayIntEmu`, ...).

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
The templated `PortSimple` and `PortArray` implementations already define how the port communicates with the Java simulator (through JNI), but how the port data is given to the software is depending on how the software is loaded (as native library or in the Computer emulation), which is specified in the variants `Port...Emu` and `Port...Direct`.






# TODO Adapt

# Dev Documentation

## Emulator configuration

The [emulator_configuration](docs/emulator_configuration.pdf) document shows the configuration possibilities for the autopilot emulators.

## HardwareEmulator JNI interface

The interface of between the RMIModelServer and the HardwareEmulator works with _Java Native Interface (JNI)_. In case of an update
of the interface (file: [src/main/java/simulator/integration/HardwareEmulatorInterface.java](src/main/java/simulator/integration/HardwareEmulatorInterface.java)),
the corresponding C header has to be generated.

Currently, this happens in the [hardware_emulator](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/simulators/hardware_emulator) project under the `jni` folder,
where the HardwareEmulatorInterface.java has to be copied. `generate.bat` shows how to update the interface on Windows.

The java file has to be adapted to compile without its dependencies, since the JNI header will only
be generated from compilable java files. Since the actual header file only depends on the `native` functions from the java file, the other dependencies can
be safely deleted. The resulting header file then has to be renamed `emulator_server.h` and placed in the `hardware_emulator/src/emulator` source folder.
The corresponding implementations of the C interface have to be updated in `hardware_emulator/src/emulator/emulator_server.cpp`.

A better approach would be a script in the RMIModelServer project generating the header and copying it to the *hardware_emulator* project.

## New autopilot EMA port types

To communicate with the ports from the autopilot, an _AutopilotAdapter_ encapsulates the EMA model. For new port data types,
the *EMAM2CPP* generator and the *hardware_emulator* have to be updated to handle the new data type.

In the EMAM2CPP project, the `de.monticore.lang.monticar.generator.cpp.viewmodel.AutopilotAdapterDataModel` class is responsible to create the _AutopilotAdapter_.
In its `addInput` and `addOutput` functions, the new function definition and declarations for the data type have to be defined.

In the *hardware_emulator* projects, three places require updates for new data types.
 1. The `hardware_emulator/src/emulator/function_values.h / .cpp` files need to updated with the new data type (`enum class VALUE_TYPE`), buffer entry (`struct FunctionValue`) and type name (`FunctionValue::get_type()`).
 2. The `call_input()` and `call_output()` functions from the `HardwareEmulator` structure (`hardware_emulator/src/emulator/hardware_emulator.h`) must be updated. They need to know how to pass the arguments to the emulated autopilots.
 3. The `Java_simulator_integration_HardwareEmulatorInterface_add_1one_1input()` and `Java_simulator_integration_HardwareEmulatorInterface_query_1outputs()` functions need to know how to pass and read port data to and from Java. (`hardware_emulator/src/emulator/emulator_server.h`)
 
## Unsupported autopilot functionalities.

The emulator used in this RMIModelServer only implements features encountered in previous autopilots.

New autopilots might trigger new unsupported features:
 * Unsupported system calls (enable `debug=unsupported_syscalls` flag for the autopilot emulator). These are operating system functions for which no current emulation is implemented. These have to be added and registered in the `hardware_emulator/src/os_linux/linux_calls.h / .cpp` files for Linux and in the `hardware_emulator/src/os_windows/windows_calls.h / .cpp` files for Windows.
 * Unsupported instruction time value. The time table (currently `hardware_emulator/src/timetable/skylake.txt`) describing the number of CPU cycles for every instruction is manually filled. It currently only contains entries (!=0) for encountered instructions. It can be filled with elements from the `hardware_emulator/docs/instruction_time.txt` file (which contains entries from the instruction_tables.pdf file).
 
To make sure the autopilot emulation is correct, allocate an autopilot emulator with the `test_real` flag. When loading an autopilot with the same OS as the RMIModelServer, the emulator will compare the outputs of the emulated autopilot with the outputs of the actual autopilot program.