OSMPDummySensor which is written in FMI 2.0 and handles binary data (serialised and deserealised using OSI), has workaround for handling binary data using integers hi,lo,size, as FMI 2.0 doesnt support binary data handling directly.

I wish to refactor the above example for FMI 3.0 and make the dummy sensor handle binary data directly (without the workaround).

After refactoring the example, fmu was successfully built but it is giving an error "The thread tried to read from or write to a virtual address for which it does not have the appropriate access" in the co-simulation software.

It will be kind of you if you could help me resolve this issue. I am attaching a few code snippets of the refactored code which handles binary data:

OSMPDummySensor.h

/* Binary Variables */
#define FMI_BINARY_SENSORVIEW_IN_IDX 0
#define FMI_BINARY_SENSORDATA_OUT_IDX 1
#define FMI_BINARY_SENSORVIEW_CONFIG_REQUEST_IDX 2
#define FMI_BINARY_SENSORVIEW_CONFIG_IDX 3
#define FMI_BINARY_LAST_IDX FMI_BINARY_SENSORVIEW_CONFIG_IDX
#define FMI_BINARY_VARS (FMI_BINARY_LAST_IDX+1)

/* Binary Data Handling struct */

` struct BinaryData {

fmi3Byte* data; // Mutable pointer to binary data. Not using fmi3Binary as its a const.

//fmi3Binary data;

size_t size; // Size of the binary data

BinaryData() : data(nullptr), size(0) {} // default constructor

~BinaryData() { delete[] data; } // destructor

};`

/* Binary vars definition: an array of BinaryData with size of FMI_BINARY_VARS*/

BinaryData binary_vars[FMI_BINARY_VARS];

OSMPDummySensor.cpp

`fmi3Status COSMPDummySensor::doInit() { DEBUGBREAK();

/* Booleans */
for (int i = 0; i<FMI_BOOLEAN_VARS; i++)
    boolean_vars[i] = fmi3False;

/* Integers */
for (int i = 0; i<FMI_INTEGER_VARS; i++)
    integer_vars[i] = 0;

/* Float64 */
for (int i = 0; i<FMI_FLOAT64_VARS; i++)
    float64_vars[i] = 0.0;

/* Strings */
for (int i = 0; i<FMI_STRING_VARS; i++)
    string_vars[i] = "";
/* Binary */
// Initialize Binary Variables
for (int i = 0; i < FMI_BINARY_VARS; i++) {
    if (binary_vars[i].data != nullptr) {
        delete[] binary_vars[i].data; // Free existing data if any
    }
    binary_vars[i].data = nullptr;
    binary_vars[i].size = 0;}

set_fmi_nominal_range(135.0);
return fmi3OK;

}`

`fmi3Status COSMPDummySensor::GetBinary(const fmi3ValueReference vr[], size_t nvr, size_t valueSizes[], fmi3Binary value[], size_t nValues) { fmi_verbose_log("fmi3GetBinary(...)");

// Ensure not to access more values than are available
size_t numValuesToProcess = std::min(nvr, nValues);

for (size_t i = 0; i < numValuesToProcess; i++) {
    if (vr[i] < FMI_BINARY_VARS) {
        // Check if the provided buffer is large enough
        if (valueSizes[i] >= binary_vars[vr[i]].size && binary_vars[vr[i]].data != nullptr) {
            std::memcpy((void*)value[i], binary_vars[vr[i]].data, binary_vars[vr[i]].size); // copy from binary_vars[vr[i]].data to value[i] 
        } else {
            return fmi3Error;  // Buffer too small or binary data is null
        }
    } else {
        return fmi3Error;  // Invalid value reference
    }
}
return fmi3OK;

}

fmi3Status COSMPDummySensor::SetBinary(const fmi3ValueReference vr[], size_t nvr, const size_t size[], const fmi3Binary value[], size_t nValues) { fmi_verbose_log("fmi3SetBinary(...)");

// Ensure not to set more values than are available or expected
size_t numValuesToSet = std::min(nvr, nValues);

for (size_t i = 0; i < numValuesToSet; i++) {
    if (vr[i] < FMI_BINARY_VARS) {
        auto& binaryVar = binary_vars[vr[i]]; // referencing

        // Deallocate any existing data
        delete[] binaryVar.data;

        // Allocate new memory for the binary data and copy the provided data into it
        binaryVar.size = size[i];
        binaryVar.data = new fmi3Byte[binaryVar.size];
        // std::memcpy(const_cast<fmi3Byte*>(binaryVar.data), value[i], binaryVar.size);

        // introducing a buffer for memcpy function args
        //void* tempBuffer = new fmi3Byte[binaryVar.size];
        std::memcpy((void*)binaryVar.data, value[i], binaryVar.size);

        // Cast the temporary buffer to fmi3Binary and assign it to binaryVar.data
        // binaryVar.data = static_cast<fmi3Byte*>(tempBuffer);
    } else {
        return fmi3Error;  // Invalid value reference
    }
}
return fmi3OK;

}`

0

There are 0 best solutions below