diff --git a/Makefile b/Makefile index 4a8f716..800c0ab 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ TOOL_DIRS = simer ################ ## DSE Projects. DSE_CLIB_REPO ?= https://github.com/boschglobal/dse.clib -DSE_CLIB_VERSION ?= 1.0.17 +DSE_CLIB_VERSION ?= 1.0.21 export DSE_CLIB_URL ?= $(DSE_CLIB_REPO)/archive/refs/tags/v$(DSE_CLIB_VERSION).zip DSE_SCHEMA_REPO ?= https://github.com/boschglobal/dse.schemas diff --git a/dse/modelc/mcl.h b/dse/modelc/mcl.h index 48ba2fc..2736ef4 100644 --- a/dse/modelc/mcl.h +++ b/dse/modelc/mcl.h @@ -86,14 +86,19 @@ typedef struct MclDesc { double model_time_correction; /* References for Signal Vector marshalling. */ struct { - size_t* count; + size_t count; const char** signal; - double** scalar; + union { + double* scalar; + void** binary; + }; + uint32_t* binary_len; + MarshalKind* kind; } source; MarshalSignalMap* msm; // NULL terminated list /* Reserved. */ - uint64_t __reserved__[3]; + uint64_t __reserved__[4]; } MclDesc; diff --git a/dse/modelc/model/checks.c b/dse/modelc/model/checks.c index 3e98b41..44aef7c 100644 --- a/dse/modelc/model/checks.c +++ b/dse/modelc/model/checks.c @@ -15,6 +15,9 @@ __attribute__((unused)) static void __compile_time_checks(void) // char(*___)[sizeof(ModelGatewayDesc)] = 1; // char(*___)[sizeof(MclDesc)] = 1; + // char(*___)[sizeof(MarshalGroup)] = 1; + // char(*___)[sizeof(MarshalStruct)] = 1; + // char(*___)[sizeof(MarshalMapSpec)] = 1; // char(*___)[sizeof(MarshalSignalMap)] = 1; // Compile-time type size check. Get actual size with: @@ -29,8 +32,11 @@ __attribute__((unused)) static void __compile_time_checks(void) #if defined(__x86_64__) #if __SIZEOF_POINTER__ == 8 _Static_assert(sizeof(ModelGatewayDesc) == 80, "Compatibility FAIL!"); - _Static_assert(sizeof(MclDesc) == 272, "Compatibility FAIL!"); - _Static_assert(sizeof(MarshalSignalMap) == 56, "Compatibility FAIL!"); + _Static_assert(sizeof(MclDesc) == 296, "Compatibility FAIL!"); + _Static_assert(sizeof(MarshalGroup) == 128, "Compatibility FAIL!"); + _Static_assert(sizeof(MarshalStruct) == 128, "Compatibility FAIL!"); + _Static_assert(sizeof(MarshalMapSpec) == 88, "Compatibility FAIL!"); + _Static_assert(sizeof(MarshalSignalMap) == 112, "Compatibility FAIL!"); _Static_assert(sizeof(SimulationSpec) == 104, "Compatibility FAIL!"); _Static_assert(sizeof(ModelInstanceSpec) == 160, "Compatibility FAIL!"); _Static_assert(sizeof(ModelDesc) == 112, "Compatibility FAIL!"); diff --git a/dse/modelc/model/mcl.c b/dse/modelc/model/mcl.c index 16a9d82..a3edb38 100644 --- a/dse/modelc/model/mcl.c +++ b/dse/modelc/model/mcl.c @@ -58,6 +58,79 @@ model (ModelDesc*) extern void mcl_destroy(MclDesc* model); +static void _match_block(MclDesc* model, HashList* msm_list, size_t offset, + size_t count, MarshalKind kind) +{ + if (count == 0) return; + + /* Construct the source references. */ + MarshalMapSpec source; + switch (kind) { + case MARSHAL_KIND_PRIMITIVE: + source = (MarshalMapSpec){ + .count = count, + .is_binary = false, + .signal = &model->source.signal[offset], + .scalar = &model->source.scalar[offset], + }; + break; + case MARSHAL_KIND_BINARY: + source = (MarshalMapSpec){ + .count = count, + .is_binary = true, + .signal = &model->source.signal[offset], + .binary = &model->source.binary[offset], + .binary_len = &model->source.binary_len[offset], + }; + break; + default: + return; + } + + for (SignalVector* sv = model->model.sv; sv && sv->name; sv++) { + if (sv->is_binary != source.is_binary) continue; + /* Construct the signal reference. */ + MarshalMapSpec signal; + if (sv->is_binary) { + signal = (MarshalMapSpec){ + .name = sv->name, + .count = sv->count, + .is_binary = true, + .signal = sv->signal, + .binary = sv->binary, + .binary_len = sv->length, + .binary_buffer_size = sv->buffer_size, + }; + } else { + signal = (MarshalMapSpec){ + .name = sv->name, + .count = sv->count, + .signal = sv->signal, + .scalar = sv->scalar, + }; + } + /* Generate the map. */ + errno = 0; + MarshalSignalMap* msm = + marshal_generate_signalmap(signal, source, NULL, sv->is_binary); + if (errno != 0) { + if (msm) free(msm); + return; + } + hashlist_append(msm_list, msm); + + /* Logging. */ + log_notice("FMU <-> SignalVector mapping for: %s", msm->name); + for (uint32_t i = 0; i < msm->count; i++) { + log_notice(" Variable: %s (%d) <-> %s (%d)", + sv->signal[msm->signal.index[i]], msm->signal.index[i], + model->source.signal[msm->source.index[i]], + msm->source.index[i]); + } + } +} + + /** mcl_load ======== @@ -86,42 +159,27 @@ int32_t mcl_load(MclDesc* model) HashList msm_list; hashlist_init(&msm_list, 64); - MarshalMapSpec source = { - .count = *model->source.count, - .scalar = model->source.scalar, - .signal = model->source.signal, - }; - for (SignalVector* sv = model->model.sv; sv && sv->name; sv++) { - MarshalMapSpec signal = { - .count = sv->count, - .name = sv->name, - .scalar = &(sv->scalar), - .signal = sv->signal, - }; - MarshalSignalMap* msm = marshal_generate_signalmap( - signal, source, NULL, sv->is_binary); - if (errno != 0) return errno; - hashlist_append(&msm_list, msm); - - /* Logging. */ - log_notice("FMU <-> SignalVector mapping for: %s", msm->name); - for (uint32_t i = 0; i < msm->count; i++) { - log_notice(" Variable: %s (%d) <-> %s (%d)", - sv->signal[msm->signal.index[i]], msm->signal.index[i], - model->source.signal[msm->source.index[i]], - msm->source.index[i]); + /* Parse the source for blocks of similar Kind. */ + MarshalKind kind = MARSHAL_KIND_NONE; + size_t offset = 0; + size_t count = 0; + for (size_t i = 0; i < model->source.count; i++) { + if (model->source.kind[i] != kind) { + /* New block detected, emit the previous block. */ + _match_block(model, &msm_list, offset, count, kind); + /* Setup for the new block (this item). */ + offset = i; + count = 1; + kind = model->source.kind[i]; + } else { + /* Current block. */ + count++; } } - + _match_block(model, &msm_list, offset, count, kind); /* Convert to a NTL. */ - size_t count = hashlist_length(&msm_list); - model->msm = calloc(count + 1, sizeof(MarshalSignalMap)); - for (uint32_t i = 0; i < count; i++) { - memcpy(&model->msm[i], hashlist_at(&msm_list, i), - sizeof(MarshalSignalMap)); - free(hashlist_at(&msm_list, i)); - } - hashlist_destroy(&msm_list); + model->msm = + hashlist_ntl(&msm_list, sizeof(MarshalSignalMap), true); } return model->vtable.load(model);