/* Copyright (C) 2012 Modelon AB This program is free software: you can redistribute it and/or modify it under the terms of the BSD style license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the FMILIB_License.txt file for more details. You should have received a copy of the FMILIB_License.txt file along with this program. If not, contact Modelon AB . */ #include #include #include #include #include char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) { char* dir_path; size_t len; assert( fmu_unzipped_path && callbacks); len = strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP) + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP) + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1; dir_path = (char*)callbacks->malloc(len); if (dir_path == NULL) { jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory."); return NULL; } sprintf(dir_path, "%s%s%s%s%s%s", fmu_unzipped_path, FMI_FILE_SEP, FMI_BINARIES, FMI_FILE_SEP, FMI_PLATFORM, FMI_FILE_SEP);/*safe */ return dir_path; } char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) { char* fname; size_t len; assert(callbacks && model_identifier); len = strlen(dll_dir_name) + strlen(model_identifier) + strlen(FMI_DLL_EXT) + 1; fname = (char*)callbacks->malloc(len); if (fname == NULL) { jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory."); return NULL; } sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */ return fname; } //// #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif typedef struct { char *name; long vr; } FMIL_Variable; __declspec(dllexport) void* FMI1_CS_LOAD(const char *zipFilePath, const char *unzipFolder); __declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu); __declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count); __declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu); __declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu); __declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize); __declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value); __declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr); __declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count); #ifdef __cplusplus } #endif #define BUFFER 4096 /* Logger function used by the C-API */ void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message) { printf("module = %s, log level = %d: %s\n", module, log_level, message); } /* Logger function used by the FMU internally */ void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...) { char msg[BUFFER]; int len; va_list argp; va_start(argp, message); /*len=jm_vsnprintf(msg, BUFFER, message, argp); printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg); if(len > BUFFER) { printf("Warning: message was trancated"); }*/ } void *FMI1_CS_LOAD(char *zipFilePath, char *unzipFolder) { fmi1_callback_functions_t callBackFunctions; fmi_import_context_t* context; fmi1_fmu_kind_enu_t standard = fmi1_fmu_kind_enu_cs_standalone; fmi_version_enu_t version; jm_status_enu_t status; fmi1_import_t *fmu; jm_callbacks* callbacks; callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks)); callbacks->malloc = malloc; callbacks->calloc = calloc; callbacks->realloc = realloc; callbacks->free = free; callbacks->logger = importlogger; callbacks->log_level = jm_log_level_debug; callbacks->context = 0; callBackFunctions.logger = fmilogger; callBackFunctions.allocateMemory = calloc; callBackFunctions.freeMemory = free; context = fmi_import_allocate_context(callbacks); version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder); fmu = fmi1_import_parse_xml(context, unzipFolder); status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0); fmi_import_free_context(context); return fmu; } int FMI1_CS_UNLOAD(void *fmu_) { fmi1_import_t *fmu = (fmi1_import_t *)fmu_; fmi1_import_destroy_dllfmu(fmu); fmi1_import_free(fmu); return 1; } FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count) { int i; FMIL_Variable *result; fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu); count[0] = fmi1_import_get_variable_list_size(vl); result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable)); for(i = 0; i < count[0]; i++) { fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i); if(!var) { printf("Something wrong with variable %d \n",i); return 0; } else { fmi1_base_type_enu_t bt; result[i].name = fmi1_import_get_variable_name(var); result[i].vr = fmi1_import_get_variable_vr(var); } } fmi1_import_free_variable_list(vl); return result; } #define INSTANCE_NAME "kekkeli" int FMI1_CS_INSTANTIATE(void *fmu) { fmi1_string_t fmuLocation; fmi1_string_t mimeType; fmi1_real_t timeout; fmi1_boolean_t visible; fmi1_boolean_t interactive; fmi1_boolean_t loggingOn; fmuLocation = ""; mimeType = ""; timeout = 0; visible = fmi1_false; interactive = fmi1_false; loggingOn = fmi1_true; if (fmi1_import_instantiate_slave(fmu, INSTANCE_NAME, NULL, NULL, timeout, fmi1_false, fmi1_false) == NULL) { printf("fmi1_capi_instantiate_slave: Failed\n"); return 0; } else { printf("fmi1_capi_instantiate_slave: Success\n"); } return 0; } int FMI1_CS_INITIALIZE(void *fmu) { fmi1_status_t status; fmi1_real_t tStart; fmi1_real_t tStop; fmi1_boolean_t StopTimeDefined; tStart = 0; tStop = 10; StopTimeDefined = fmi1_false; status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop); if (status == fmi1_status_error || status == fmi1_status_fatal) { printf("fmi1_capi_initialize_slave: Failed\n"); return 0; } else { printf("fmi1_capi_initialize_slave: Success\n"); } return 0; } int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize) { fmi1_status_t status; status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true); if (status == fmi1_status_error || status == fmi1_status_fatal) { printf("fmi1_capi_do_step: Failed\n"); return 0; } else { printf("fmi1_capi_do_step: Success\n"); } return 0; } int FMI1_CS_SET_REAL(void *fmu, long valueId, double value) { fmi1_value_reference_t vr = valueId; fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value); return 0; } double FMI1_CS_GET_REAL(void *fmu, int valueReference) { fmi1_value_reference_t vr = valueReference; fmi1_real_t value; fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value); return value; } int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count) { fmi1_value_reference_t *vrs = valueReferences; fmi1_real_t value; fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result); return 1; }