Why does the mdlOutputs block in S-functions only execute when there is a change in the input values?
Show older comments
I am working on creating a frequency sweep function in Simulink, where all operations need to be defined within the S-Function. Since one of the dependencies of the function is the time variable, I initially set up my implementation to receive time as an external input, and the S-Function worked correctly. This is because the time data increases in the same manner as the discrete simulation time, so a value that changes at each cycle tick is passed into the S-Function.
In my subsequent work, I modified the setup to receive only a rising edge trigger as the function input and count the time internally within the S-Function. However, in this case, the mdlOutputs block only updates once when the trigger input changes from 0 to 1, and it doesn't execute again unless there is another change in the input. I explored the ssSetOptions function block but couldn't achieve a positive result.

From what I understand in the above image, mdlCheckParameters calls the mdlOutputs function when there is a change, but I haven't fully grasped how it works. Could you assist me with this? Thank you in advance.
Here is my code for initialization and for output block.
static void mdlInitializeSizes(SimStruct* S)
{
static char_T msg[256];
/* Set Function Arguments */
ssSetNumSFcnParams(S, N_ARGS);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
sprintf(msg, "Wrong number of input arguments passed.\n%d arguments are expected\n", N_ARGS);
ssSetErrorStatus(S, msg);
return;
}
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
/* Set Input Ports */
if (!ssSetNumInputPorts(S, N_PORT_IN)) return;
ssSetInputPortWidth(S, PORT_IN_ARRAY, WIDTH_OF_INPORT);
ssSetInputPortDataType(S, PORT_IN_ARRAY, SS_DOUBLE);
ssSetInputPortRequiredContiguous(S, PORT_IN_ARRAY, 1);
ssSetInputPortDirectFeedThrough(S, PORT_IN_ARRAY, 1);
ssSetInputPortWidth(S, PORT_IN_TIME, WIDTH_OF_INPORT_2);
ssSetInputPortDataType(S, PORT_IN_TIME, SS_DOUBLE);
ssSetInputPortRequiredContiguous(S, PORT_IN_TIME, 1);
ssSetInputPortDirectFeedThrough(S, PORT_IN_TIME, 1);
/* Set Output Ports */
if (!ssSetNumOutputPorts(S, N_PORT_OUT)) return;
ssSetOutputPortWidth(S, PORT_OUT_ELEM_1, WIDTH_OF_OUTPORT);
ssSetOutputPortDataType(S, PORT_OUT_ELEM_1, SS_DOUBLE);
ssSetOutputPortWidth(S, PORT_OUT_ELEM_2, WIDTH_OF_OUTPORT);
ssSetOutputPortDataType(S, PORT_OUT_ELEM_2, SS_UINT8);
/* Set Number of Sample Times, this should be >1 when there are different rate inputs */
ssSetNumSampleTimes(S, 1);
/* Set Number Work Vectors */
ssSetNumDWork(S, N_DWORK);
ssSetNumRWork(S, N_IWORK);
ssSetNumIWork(S, N_RWORK);
ssSetNumPWork(S, N_PWORK);
/* specify the sim state compliance to be same as a built-in block */
ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);
/* Set this S-function as runtime thread-safe for multicore execution */
ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE);
/* None of the parameters are tunable */
ssSetSFcnParamTunable(S, 0, 0);
/* Set S-function Options */
ssSetOptions(S, SS_OPTION_WORKS_WITH_CODE_REUSE |
SS_OPTION_ASYNC_RATE_TRANSITION |
SS_OPTION_EXCEPTION_FREE_CODE);
}
static void mdlOutputs(SimStruct* S, int_T tid)
{
/* Retrieve C++ object object */
LinearSweep* sweepGenerator = (LinearSweep*)ssGetPWork(S)[P_WORK_SWEEP];
real_T* params = (real_T*)ssGetInputPortSignal(S, PORT_IN_ARRAY);
real_T* t = (real_T*)ssGetInputPortSignal(S, PORT_IN_TIME);
//double t = ssGetT(S); //this function can be used if the functionwill be triggered by a flag
real_T* wave_output = (real_T*)ssGetOutputPortSignal(S, 0); // Output signal
uint8_T* bdone = (uint8_T*)ssGetOutputPortSignal(S, 1); // Done flag
// Call the freqSweep function on the instance
sweepGenerator->freqSweep(params, *t, wave_output, bdone);
/* Unused Argument */
UNUSED_ARG(tid);
}

Normally time output is used from "Time trigger source" to s-function. Thus, inputs are changing at each time step, but I changed the code as trigger will be input. But at this time s-func doesn't work properly.
Accepted Answer
More Answers (0)
Categories
Find more on Configure C/C++ S-Function Features in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!