PWork loses data in S-function
4 次查看(过去 30 天)
显示 更早的评论
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?
0 个评论
采纳的回答
Mark McBroom
2021-2-20
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 个评论
Mark McBroom
2021-2-21
You should initialize the memory in mdlStart() because this gets called at the beginning of a simulation. mdlInitializeSizes gets called at the start of simulation, but also gets called when updating the simulation model. You don't want to allocate the memory if the model is only being updated and not simulated.
If you were able share data via the stack it was just lucky that it worked. Stack data can be reused by the operating system for other purposes when returning from the function.
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Block and Blockset Authoring 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!