2 Copyright (C) 2012 Modelon AB
\r
4 This program is free software: you can redistribute it and/or modify
\r
5 it under the terms of the BSD style license.
\r
7 This program is distributed in the hope that it will be useful,
\r
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
10 FMILIB_License.txt file for more details.
\r
12 You should have received a copy of the FMILIB_License.txt file
\r
13 along with this program. If not, contact Modelon AB <http://www.modelon.com>.
\r
19 #include <FMI/fmi_util.h>
\r
20 #include <FMI/fmi_zip_unzip.h>
\r
22 char* fmi_construct_dll_dir_name(jm_callbacks* callbacks, const char* fmu_unzipped_path) {
\r
26 assert( fmu_unzipped_path && callbacks);
\r
29 strlen(fmu_unzipped_path) + strlen(FMI_FILE_SEP)
\r
30 + strlen(FMI_BINARIES) + strlen(FMI_FILE_SEP)
\r
31 + strlen(FMI_PLATFORM) + strlen(FMI_FILE_SEP) + 1;
\r
33 dir_path = (char*)callbacks->malloc(len);
\r
34 if (dir_path == NULL) {
\r
35 jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
\r
39 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 */
\r
44 char* fmi_construct_dll_file_name(jm_callbacks* callbacks, const char* dll_dir_name, const char* model_identifier) {
\r
47 assert(callbacks && model_identifier);
\r
49 strlen(dll_dir_name) +
\r
50 strlen(model_identifier)
\r
51 + strlen(FMI_DLL_EXT) + 1;
\r
52 fname = (char*)callbacks->malloc(len);
\r
53 if (fname == NULL) {
\r
54 jm_log_fatal(callbacks, "FMIUT", "Failed to allocate memory.");
\r
57 sprintf(fname, "%s%s%s", dll_dir_name, model_identifier, FMI_DLL_EXT);/*safe */
\r
101 __declspec(dllexport) void* FMI1_CS_LOAD(const char *zipFilePath, const char *unzipFolder);
\r
102 __declspec(dllexport) int FMI1_CS_UNLOAD(void* fmu);
\r
103 __declspec(dllexport) FMIL_Variable *FMI1_CS_GET_VARIABLES(void* fmu, int *count);
\r
104 __declspec(dllexport) int FMI1_CS_INSTANTIATE(void* fmu);
\r
105 __declspec(dllexport) int FMI1_CS_INITIALIZE(void* fmu);
\r
106 __declspec(dllexport) int FMI1_CS_STEP(void* fmu, double masterTime, double stepSize);
\r
107 __declspec(dllexport) int FMI1_CS_SET_REAL(void* fmu, int vr, double value);
\r
108 __declspec(dllexport) double FMI1_CS_GET_REAL(void* fmu, int vr);
\r
109 __declspec(dllexport) int FMI1_CS_GET_REALS(void* fmu, int *vrs, double *values, int count);
\r
115 #define BUFFER 4096
\r
117 /* Logger function used by the C-API */
\r
118 void importlogger(jm_callbacks* c, jm_string module, jm_log_level_enu_t log_level, jm_string message)
\r
120 printf("module = %s, log level = %d: %s\n", module, log_level, message);
\r
123 /* Logger function used by the FMU internally */
\r
124 void fmilogger(fmi1_component_t c, fmi1_string_t instanceName, fmi1_status_t status, fmi1_string_t category, fmi1_string_t message, ...)
\r
129 va_start(argp, message);
\r
130 /*len=jm_vsnprintf(msg, BUFFER, message, argp);
\r
131 printf("fmiStatus = %d; %s (%s): %s\n", status, instanceName, category, msg);
\r
133 printf("Warning: message was trancated");
\r
137 void *FMI1_CS_LOAD(char *zipFilePath, char *unzipFolder) {
\r
139 fmi1_callback_functions_t callBackFunctions;
\r
140 fmi_import_context_t* context;
\r
141 fmi1_fmu_kind_enu_t standard = fmi1_fmu_kind_enu_cs_standalone;
\r
142 fmi_version_enu_t version;
\r
143 jm_status_enu_t status;
\r
144 fmi1_import_t *fmu;
\r
145 jm_callbacks* callbacks;
\r
147 callbacks = (jm_callbacks *)calloc(1, sizeof(jm_callbacks));
\r
149 callbacks->malloc = malloc;
\r
150 callbacks->calloc = calloc;
\r
151 callbacks->realloc = realloc;
\r
152 callbacks->free = free;
\r
153 callbacks->logger = importlogger;
\r
154 callbacks->log_level = jm_log_level_debug;
\r
155 callbacks->context = 0;
\r
157 callBackFunctions.logger = fmilogger;
\r
158 callBackFunctions.allocateMemory = calloc;
\r
159 callBackFunctions.freeMemory = free;
\r
161 context = fmi_import_allocate_context(callbacks);
\r
163 version = fmi_import_get_fmi_version(context, zipFilePath, unzipFolder);
\r
165 fmu = fmi1_import_parse_xml(context, unzipFolder);
\r
167 status = fmi1_import_create_dllfmu(fmu, callBackFunctions, 0);
\r
169 fmi_import_free_context(context);
\r
175 int FMI1_CS_UNLOAD(void *fmu_) {
\r
177 fmi1_import_t *fmu = (fmi1_import_t *)fmu_;
\r
179 fmi1_import_destroy_dllfmu(fmu);
\r
181 fmi1_import_free(fmu);
\r
188 FMIL_Variable *FMI1_CS_GET_VARIABLES(void *fmu, int *count) {
\r
191 FMIL_Variable *result;
\r
192 fmi1_import_variable_list_t* vl = fmi1_import_get_variable_list((fmi1_import_t *)fmu);
\r
194 count[0] = fmi1_import_get_variable_list_size(vl);
\r
196 result = (FMIL_Variable *)malloc(count[0]*sizeof(FMIL_Variable));
\r
198 for(i = 0; i < count[0]; i++) {
\r
200 fmi1_import_variable_t* var = fmi1_import_get_variable(vl, i);
\r
203 printf("Something wrong with variable %d \n",i);
\r
208 result[i].name = fmi1_import_get_variable_name(var);
\r
209 result[i].description = fmi1_import_get_variable_description(var);
\r
211 switch (fmi1_import_get_variability(var)) {
\r
212 case fmi1_variability_enu_constant:
\r
213 result[i].variability = 0;
\r
215 case fmi1_variability_enu_parameter:
\r
216 result[i].variability = 1;
\r
218 case fmi1_variability_enu_discrete:
\r
219 result[i].variability = 2;
\r
221 case fmi1_variability_enu_continuous:
\r
222 result[i].variability = 3;
\r
224 case fmi1_variability_enu_unknown:
\r
225 result[i].variability = 4;
\r
229 switch (fmi1_import_get_causality(var)) {
\r
230 case fmi1_causality_enu_input:
\r
231 result[i].causality = 0;
\r
233 case fmi1_causality_enu_output:
\r
234 result[i].causality = 1;
\r
236 case fmi1_causality_enu_internal:
\r
237 result[i].causality = 2;
\r
239 case fmi1_causality_enu_none:
\r
240 result[i].causality = 3;
\r
242 case fmi1_causality_enu_unknown:
\r
243 result[i].causality = 4;
\r
247 switch (fmi1_import_get_variable_base_type(var)) {
\r
248 case fmi1_base_type_real:
\r
249 result[i].type = 0;
\r
251 case fmi1_base_type_int:
\r
252 result[i].type = 1;
\r
254 case fmi1_base_type_bool:
\r
255 result[i].type = 2;
\r
257 case fmi1_base_type_str:
\r
258 result[i].type = 3;
\r
260 case fmi1_base_type_enum:
\r
261 result[i].type = 4;
\r
265 result[i].vr = fmi1_import_get_variable_vr(var);
\r
271 fmi1_import_free_variable_list(vl);
\r
277 #define INSTANCE_NAME "kekkeli"
\r
279 int FMI1_CS_INSTANTIATE(void *fmu) {
\r
281 fmi1_string_t fmuLocation;
\r
282 fmi1_string_t mimeType;
\r
283 fmi1_real_t timeout;
\r
284 fmi1_boolean_t visible;
\r
285 fmi1_boolean_t interactive;
\r
286 fmi1_boolean_t loggingOn;
\r
291 visible = fmi1_false;
\r
292 interactive = fmi1_false;
\r
293 loggingOn = fmi1_true;
\r
295 if (fmi1_import_instantiate_slave(fmu, INSTANCE_NAME, NULL, NULL, timeout, fmi1_false, fmi1_false) == NULL) {
\r
296 printf("fmi1_capi_instantiate_slave: Failed\n");
\r
299 printf("fmi1_capi_instantiate_slave: Success\n");
\r
305 int FMI1_CS_INITIALIZE(void *fmu) {
\r
307 fmi1_status_t status;
\r
308 fmi1_real_t tStart;
\r
310 fmi1_boolean_t StopTimeDefined;
\r
314 StopTimeDefined = fmi1_false;
\r
316 status = fmi1_import_initialize_slave((fmi1_import_t *)fmu, tStart, StopTimeDefined, tStop);
\r
317 if (status == fmi1_status_error || status == fmi1_status_fatal) {
\r
318 printf("fmi1_capi_initialize_slave: Failed\n");
\r
321 printf("fmi1_capi_initialize_slave: Success\n");
\r
327 int FMI1_CS_STEP(void *fmu, double masterTime, double stepSize) {
\r
329 fmi1_status_t status;
\r
331 status = fmi1_import_do_step((fmi1_import_t *)fmu, (fmi1_real_t)masterTime, (fmi1_real_t)stepSize, fmi1_true);
\r
332 if (status == fmi1_status_error || status == fmi1_status_fatal) {
\r
333 printf("fmi1_capi_do_step: Failed\n");
\r
336 printf("fmi1_capi_do_step: Success\n");
\r
343 int FMI1_CS_SET_REAL(void *fmu, long valueId, double value) {
\r
345 fmi1_value_reference_t vr = valueId;
\r
346 fmi1_import_set_real((fmi1_import_t *)fmu, &vr, 1, &value);
\r
352 double FMI1_CS_GET_REAL(void *fmu, int valueReference) {
\r
354 fmi1_value_reference_t vr = valueReference;
\r
356 fmi1_import_get_real((fmi1_import_t *)fmu, &vr, 1, &value);
\r
361 int FMI1_CS_GET_REALS(void *fmu, int *valueReferences, double *result, int count) {
\r
363 fmi1_value_reference_t *vrs = valueReferences;
\r
365 fmi1_import_get_real((fmi1_import_t *)fmu, vrs, count, result);
\r