MATLAB Answers

PWork loses data in S-function

19 views (last 30 days)
Steradiant
Steradiant on 18 Feb 2021
Commented: Steradiant on 3 Mar 2021
Hello,
I want to read out the data (which are structures) from the S-functions parameter dialog at Startup and use them in every cycle. Therefore, I wrote the following MWE
#define S_FUNCTION_NAME s_fun_paratest /* Defines and Includes */
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#define MDL_START
struct myStruct1{
mxDouble data1, data2;
};
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 1); /* Number of expected parameters */
#if defined(MATLAB_MEX_FILE)
if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
// mdlCheckParameters(S);
if (ssGetErrorStatus(S) != NULL) {
return;
}
} else {
return; /* Parameter mismatch reported by the Simulink engine*/
}
#endif
ssSetNumPWork(S, 1);
// ssSetSFcnParamTunable(S,0,false);
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);
/* Take care when specifying exception free code - see sfuntmpl.doc */
ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}
static void mdlStart(SimStruct *S)
{
struct myStruct1 st1, *st2;
mxArray *tmp;
tmp = mxGetField(ssGetSFcnParam(S,0),0,"maxIter");
if (tmp == NULL)
mexErrMsgIdAndTxt("MATLAB:SIMULINK","maxIter not existing.");
st1.data1 = *mxGetDoubles(tmp);
ssGetPWork(S)[0] = &st1;
mexPrintf("\nst1.data1: %f", st1.data1); // <- outputs the correct value
st2 = ssGetPWork(S)[0];
mexPrintf("\nst2.data1: %f", st2->data1); // <- outputs the correct value
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
struct myStruct1 *st2;
st2 = ssGetPWork(S)[0];
mexPrintf("\nst2.data1: %f", st2->data1); // <- outputs 0
}
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
I marked the problem in the mdlOutputs . I've already checked the addresses of ssGetPWork(S) and ssGetPWork(S)[0] and they are the same in mdlStart and mdlOutputs. Do you have any ideas what i'm missing?

Accepted Answer

Mark McBroom
Mark McBroom on 20 Feb 2021
st1 is an autmomatic variable, so its memory location can get reused after leaving mdlStart(). YOu need to allocation memory for st1 in mdlStart and save this malloc'd address in PWork.
  3 Comments
Steradiant
Steradiant on 3 Mar 2021
I see. Thanks for the information. Regarding the pointers, the difference is, that I have a main function, the mexFunction in the MEX C-Code from where I call the subprograms. In these function calls I use pointers created in the mexFunction. For S-functions on the other hand, there is obviously nothing like a main function. Depending on the current stage of the simulink Simulation, a different routine is carried out.

Sign in to comment.

More Answers (0)

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by