static void fmi2_capi_get_fcn_with_flag(fmi2_capi_t* fmu, const char* function_name,
													jm_dll_function_ptr* dll_function_ptrptr,
													unsigned int capabilities[],
													fmi2_capabilities_enu_t flag) {
	jm_status_enu_t status = jm_status_success;
	if(capabilities[flag]) {
		fmi2_capi_get_fcn(fmu, function_name, dll_function_ptrptr, &status);
		if(status != jm_status_success) {
			jm_log_warning(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Resetting flag '%s'", fmi2_capability_to_string(flag));
			capabilities[flag] = 0;
		}
	}
}
Exemple #2
0
/* Load FMI 1.0 Co-Simulation functions */
static jm_status_enu_t fmi1_capi_load_cs_fcn(fmi1_capi_t* fmu)
{
	jm_status_enu_t jm_status = jm_status_success;

	jm_log_verbose(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Loading functions for the co-simulation interface"); 

	/* Workaround for Dymola 2012 and SimulationX 3.x */
	if (fmi1_capi_get_fcn(fmu, "fmiGetTypesPlatform",(jm_dll_function_ptr*)&fmu->fmiGetTypesPlatform) == jm_status_error) {
		jm_log_warning(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function 'fmiGetTypesPlatform'. %s. Trying to load fmiGetModelTypesPlatform instead.", jm_portability_get_last_dll_error());
		jm_status = jm_status_warning;
		if (fmi1_capi_get_fcn(fmu, "fmiGetModelTypesPlatform", (jm_dll_function_ptr*)&fmu->fmiGetTypesPlatform) == jm_status_error) {
			jm_log_error(fmu->callbacks, FMI_CAPI_MODULE_NAME, "Could not load the FMI function 'fmiGetModelTypesPlatform'. %s", jm_portability_get_last_dll_error());
			jm_status = jm_status_error;
		}
	}

	LOAD_DLL_FUNCTION(fmiInstantiateSlave);
	LOAD_DLL_FUNCTION(fmiInitializeSlave);
	LOAD_DLL_FUNCTION(fmiTerminateSlave);
	LOAD_DLL_FUNCTION(fmiResetSlave);
	LOAD_DLL_FUNCTION(fmiFreeSlaveInstance);
	LOAD_DLL_FUNCTION(fmiSetRealInputDerivatives);
	LOAD_DLL_FUNCTION(fmiGetRealOutputDerivatives);
	LOAD_DLL_FUNCTION(fmiCancelStep);
	LOAD_DLL_FUNCTION(fmiDoStep);
	LOAD_DLL_FUNCTION(fmiGetStatus);
	LOAD_DLL_FUNCTION(fmiGetRealStatus);
	LOAD_DLL_FUNCTION(fmiGetIntegerStatus);
	LOAD_DLL_FUNCTION(fmiGetBooleanStatus);
	LOAD_DLL_FUNCTION(fmiGetStringStatus);

	LOAD_DLL_FUNCTION(fmiGetVersion);
	LOAD_DLL_FUNCTION(fmiSetDebugLogging);
	LOAD_DLL_FUNCTION(fmiSetReal);
	LOAD_DLL_FUNCTION(fmiSetInteger);
	LOAD_DLL_FUNCTION(fmiSetBoolean);
	LOAD_DLL_FUNCTION(fmiSetString);
	LOAD_DLL_FUNCTION(fmiGetReal);
	LOAD_DLL_FUNCTION(fmiGetInteger);
	LOAD_DLL_FUNCTION(fmiGetBoolean);
	LOAD_DLL_FUNCTION(fmiGetString);
	return jm_status; 
}
/* Load and destroy functions */
jm_status_enu_t fmi2_import_create_dllfmu(fmi2_import_t* fmu, fmi2_fmu_kind_enu_t fmuKind, const fmi2_callback_functions_t* callBackFunctions) {

	char curDir[FILENAME_MAX + 2];
	char* dllDirPath = 0;
	char* dllFileName = 0;
	const char* modelIdentifier;
	fmi2_callback_functions_t defaultCallbacks;

	if (fmu == NULL) {
		assert(0);
		return jm_status_error;
	}

	if(fmu -> capi) {
		if(fmi2_capi_get_fmu_kind(fmu -> capi) == fmuKind) {
			jm_log_warning(fmu->callbacks, module, "FMU binary is already loaded"); 
			return jm_status_success;
		}
		else
			fmi2_import_destroy_dllfmu(fmu);		
	}

	if(fmuKind == fmi2_fmu_kind_me)
		modelIdentifier = fmi2_import_get_model_identifier_ME(fmu);
	else 	if(fmuKind == fmi2_fmu_kind_cs)
		modelIdentifier = fmi2_import_get_model_identifier_CS(fmu);
	else {
		assert(0);
		return jm_status_error;
	}

	if (modelIdentifier == NULL) {
		jm_log_error(fmu->callbacks, module, "No model identifier given");
		return jm_status_error;
	}

	if( jm_portability_get_current_working_directory(curDir, FILENAME_MAX+1) != jm_status_success) {
		jm_log_warning(fmu->callbacks, module, "Could not get current working directory (%s)", strerror(errno));
		curDir[0] = 0;
	};

	dllDirPath = fmi_construct_dll_dir_name(fmu->callbacks, fmu->dirPath);
	dllFileName = fmi_construct_dll_file_name(fmu->callbacks, dllDirPath, modelIdentifier);

	if (!dllDirPath ||!dllFileName) {
		fmu->callbacks->free(dllDirPath);
		return jm_status_error;
	}

	if(!callBackFunctions) {
		jm_callbacks* cb = fmu->callbacks;
		defaultCallbacks.allocateMemory = cb->calloc;
		defaultCallbacks.freeMemory = cb->free;
		defaultCallbacks.componentEnvironment = fmu;
		defaultCallbacks.logger = fmi2_log_forwarding;
		defaultCallbacks.stepFinished = 0;
		callBackFunctions = &defaultCallbacks;
	}

	if(jm_portability_set_current_working_directory(dllDirPath) != jm_status_success) {
		jm_log_fatal(fmu->callbacks, module, "Could not change to the DLL directory %s", dllDirPath);
		if(ENOENT == errno)
			jm_log_fatal(fmu->callbacks, module, "No binary for this platform?");
		else
			jm_log_fatal(fmu->callbacks, module, "System error: %s", strerror(errno));
	}
	else {
		/* Allocate memory for the C-API struct */
		fmu -> capi = fmi2_capi_create_dllfmu(fmu->callbacks, dllFileName, modelIdentifier, callBackFunctions, fmuKind);
	}


	/* Load the DLL handle */
	if (fmu -> capi) {
		jm_log_info(fmu->callbacks, module, 
			"Loading '" FMI_PLATFORM "' binary with '%s' platform types", fmi2_get_types_platform() );

		if(fmi2_capi_load_dll(fmu -> capi) == jm_status_error) {		
			fmi2_capi_destroy_dllfmu(fmu -> capi);
			fmu -> capi = NULL;
		}
	}

	if(curDir[0] && (jm_portability_set_current_working_directory(curDir) != jm_status_success)) {
		jm_log_error(fmu->callbacks, module, "Could not restore current working directory (%s)", strerror(errno));
	}

	fmu->callbacks->free((jm_voidp)dllDirPath);
	fmu->callbacks->free((jm_voidp)dllFileName);

	if (fmu -> capi == NULL) {
		return jm_status_error;
	}


	/* Load the DLL functions */
	if (fmi2_capi_load_fcn(fmu -> capi, fmi2_xml_get_capabilities(fmu->md)) == jm_status_error) {
		fmi2_capi_free_dll(fmu -> capi);			
		fmi2_capi_destroy_dllfmu(fmu -> capi);
		fmu -> capi = NULL;
		return jm_status_error;
	}
	jm_log_verbose(fmu->callbacks, module, "Successfully loaded all the interface functions"); 

	return jm_status_success;
}