IP Protect using static/shared library
Contents
Workflow
We support importing Dymola FMU into SimWB. To run the FMU in SimWB, we need binary for Linux 64-bit or 32-bit depending on the SimWB server. Dymola is currently only available in Windows and they are working towards having a Linux version as well. Meanwhile we need to follow the steps below to get a working FMU in SimWB. Following steps assume you are using Dymola 2015.
Steps for Suppliers
The 'Suppliers' do not need to purchase SimWB or custom hardware to make this work. All they have to so is create a static library in say Centos 64-bit system if the SimWB is a 64-bit system. The idea is to have the supplier send two different static libraries for Windows and Linux. Assuming the supplier has a S-Function that he wants to protect, see below for the steps:
Example S-Function
/* * File : timesthree.c * Abstract: * An example C-file S-function for multiplying an input by 3, * y = 3*u * */ #define S_FUNCTION_NAME timesthree #define S_FUNCTION_LEVEL 2 #include "simstruc.h" /*================* * Build checking * *================*/ /* Function: mdlInitializeSizes =============================================== * Abstract: * Setup sizes of the various vectors. */ static void mdlInitializeSizes(SimStruct *S) { ssSetNumSFcnParams(S, 0); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { return; /* Parameter mismatch will be reported by Simulink */ } if (!ssSetNumInputPorts(S, 1)) return; ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetInputPortDirectFeedThrough(S, 0, 1); if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetNumSampleTimes(S, 1); /* specify the sim state compliance to be same as a built-in block */ ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE); ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE | SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_USE_TLC_WITH_ACCELERATOR); } /* Function: mdlInitializeSampleTimes ========================================= * Abstract: * Specifiy that we inherit our sample time from the driving block. */ static void mdlInitializeSampleTimes(SimStruct *S) { ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); ssSetModelReferenceSampleTimeDefaultInheritance(S); } /* Function: mdlOutputs ======================================================= * Abstract: * y = 2*u */ static void mdlOutputs(SimStruct *S, int_T tid) { int_T i; InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); int_T width = ssGetOutputPortWidth(S,0); for (i=0; i<width; i++) { /* * This example does not implement complex signal handling. * To find out see an example about how to handle complex signal in * S-function, see sdotproduct.c for details. */ *y++ = 2.0 *(*uPtrs[i]); } } /* Function: mdlTerminate ===================================================== * Abstract: * No termination needed, but we are required to have this routine. */ static void mdlTerminate(SimStruct *S) { } #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ #include "simulink.c" /* MEX-file interface mechanism */ #else #include "cg_sfun.h" /* Code generation registration function */ #endif
Move the S-Function logic to external source file
/* * File : timesthree.c * Abstract: * An example C-file S-function for multiplying an input by 3, * y = 3*u * */ #define S_FUNCTION_NAME timesthree #define S_FUNCTION_LEVEL 2 #include "simstruc.h" #include "externallogic.h" /*================* * Build checking * *================*/ /* Function: mdlInitializeSizes =============================================== * Abstract: * Setup sizes of the various vectors. */ static void mdlInitializeSizes(SimStruct *S) { ssSetNumSFcnParams(S, 0); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { return; /* Parameter mismatch will be reported by Simulink */ } if (!ssSetNumInputPorts(S, 1)) return; ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetInputPortDirectFeedThrough(S, 0, 1); if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED); ssSetNumSampleTimes(S, 1); /* specify the sim state compliance to be same as a built-in block */ ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE); ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE | SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_USE_TLC_WITH_ACCELERATOR); } /* Function: mdlInitializeSampleTimes ========================================= * Abstract: * Specifiy that we inherit our sample time from the driving block. */ static void mdlInitializeSampleTimes(SimStruct *S) { ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); ssSetOffsetTime(S, 0, 0.0); ssSetModelReferenceSampleTimeDefaultInheritance(S); } /* Function: mdlOutputs ======================================================= * Abstract: * y = 2*u */ static void mdlOutputs(SimStruct *S, int_T tid) { int_T i; InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0); real_T *y = ssGetOutputPortRealSignal(S,0); int_T width = ssGetOutputPortWidth(S,0); compute(y,width); /* The above call to 'compute' is implemented in externallogic.c and it has the following code for (i=0; i<width; i++) { */ /* * This example does not implement complex signal handling. * To find out see an example about how to handle complex signal in * S-function, see sdotproduct.c for details. */ /* *y++ = 2.0 *(*uPtrs[i]); } */ } /* Function: mdlTerminate ===================================================== * Abstract: * No termination needed, but we are required to have this routine. */ static void mdlTerminate(SimStruct *S) { } #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */ #include "simulink.c" /* MEX-file interface mechanism */ #else #include "cg_sfun.h" /* Code generation registration function */ #endif
Compile external source file
- Compile the external source file into static or shared library for
- Windows
- Linux
- To run in SimWB, the library needs to be a Linux 64-bit binary. You can use GCC on a freely available Centos OS.