IP Protect using static/shared library
Contents
Workflow
The modern OEMs depend on multiple vendors to supply the parts of the OEM's final product. To integrate and test those parts, the OEM often require the model of the individual parts. In this situation, it is possible that individual part supplier wants to protect their Intellectual Property (IP). This means that they usually supply a precompiled binary to the OEM. Suppose if the integration platform is Simulink, the individual part supplier/vendor might just supply an S-Function. This means that the OEM will only be able to use this S-Function only on the Simulation platform which is usually Windows. In such a situation, the OEM will not be able to take advantage Hardware-In-the-Loop (HIL) simulation of the part. The following instructions show a way where the suppliers can still protect their IP while providing the OEMs with the ability to run HIL simulations. In the long run, we envision everyone embracing the FMI standard which is designed for this exact purpose and is supported by SimWB.
Steps for Suppliers/Vendors
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.