Error trying to build an s-function in C

4 views (last 30 days)
Hi,
I try to make a simulink model working with s-function written in C and here's my main file ( main.c ):
#include "Reservoir.h"
void Reservoir(double q1,
double q2,
double qe,
double qo,
double *y1,
double *y2,
double *y3,
double *y4)
{
*y1 = q1 + q2 + qe - qo;
*y2 = 1875.0 * q1 + 1667.0 * q2 + 1000.0 * qe - 1468.48 * qo;
*y3 = sqrt(*y1 + 1) - 1;
*y4 = ((3000.0) * (1 - 1000.0)) / ((3000.0 - 1000.0) * (*y2 / *y1));
}
And here's my header file ( Reservoir.h ):
#ifndef RESERVOIR_H
#define RESERVOIR_H
#include "tmwtypes.h"
extern void Reservoir(double q1, double q2, double qe, double qo, double *y1, double *y2, double *y3, double *y4);
#endif
And when I execute my file :
def = legacy_code('initialize');
def.SFunctionName = 'S_function1';
def.OutputFcnSpec = 'Reservoir(double u1, double u2, double u3, double u4, double y1, double y2, double y3, double y4)';
def.HeaderFiles = {'Reservoir.h'};
def.SourceFiles = {'main.c'};
legacy_code('sfcn_cmex_generate', def)
legacy_code('compile', def)
legacy_code('sfcn_tlc_generate', def)
I get this error :
Error using mex
C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c: In function 'mdlOutputs':
C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:229:35: error: incompatible type for argument 5 of
'Reservoir'
Reservoir(*u1, *u2, *u3, *u4, *y1, *y2, *y3, *y4);
^
In file included from C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:39:0:
C:\Users\PODES7\Desktop\Reservoir_sfunc\Reservoir.h:5:13: note: expected 'double *' but argument is of type
'real_T {aka double}'
extern void Reservoir(double q1, double q2, double qe, double qo, double *y1, double *y2, double *y3, double
*y4);
^~~~~~~~~
C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:229:40: error: incompatible type for argument 6 of
'Reservoir'
Reservoir(*u1, *u2, *u3, *u4, *y1, *y2, *y3, *y4);
^
In file included from C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:39:0:
C:\Users\PODES7\Desktop\Reservoir_sfunc\Reservoir.h:5:13: note: expected 'double *' but argument is of type
'real_T {aka double}'
extern void Reservoir(double q1, double q2, double qe, double qo, double *y1, double *y2, double *y3, double
*y4);
^~~~~~~~~
C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:229:45: error: incompatible type for argument 7 of
'Reservoir'
Reservoir(*u1, *u2, *u3, *u4, *y1, *y2, *y3, *y4);
^
In file included from C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:39:0:
C:\Users\PODES7\Desktop\Reservoir_sfunc\Reservoir.h:5:13: note: expected 'double *' but argument is of type
'real_T {aka double}'
extern void Reservoir(double q1, double q2, double qe, double qo, double *y1, double *y2, double *y3, double
*y4);
^~~~~~~~~
C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:229:50: error: incompatible type for argument 8 of
'Reservoir'
Reservoir(*u1, *u2, *u3, *u4, *y1, *y2, *y3, *y4);
^
In file included from C:\Users\PODES7\Desktop\Reservoir_sfunc\S_function1.c:39:0:
C:\Users\PODES7\Desktop\Reservoir_sfunc\Reservoir.h:5:13: note: expected 'double *' but argument is of type
'real_T {aka double}'
extern void Reservoir(double q1, double q2, double qe, double qo, double *y1, double *y2, double *y3, double
*y4);
^~~~~~~~~
Error in legacycode.LCT/compile
Error in legacycode.LCT.legacyCodeImpl
Error in legacy_code (line 103)
[varargout{1:nargout}] = legacycode.LCT.legacyCodeImpl(action, varargin{1:end});
Error in demarches (line 13)
legacy_code('compile', def)
Can somebody help me please ?

Answers (1)

Rajanya
Rajanya on 16 Sep 2024
I understand that you are trying to make a Simulink model with S-function in C. I was able to reproduce your issue, and the error messages essentially signify that there is a type mismatch between the "Reservoir" function signature defined in the ‘main.c’ and the signature defined in the ‘def.OutputFcnSpec’ during execution.
The “Reservoir” function demands ‘y1’, ‘y2’, ‘y3’, ‘y4’ as pointers since they are meant to be called by addresses. The current caller definition does not specify the same, declaring them as double scalars and hence the errors occur. Changing the “OutputFcnSpec” property of the definition to the following during execution will solve the issue.
def.OutputFcnSpec = 'Reservoir(double u1, double u2, double u3, double u4, double y1[1], double y2[1], double y3[1], double y4[1])';
In general, while dealing with pointer variables and calling by addresses, the syntax of [1] is used to specify that the variable is a pointer. You can read more about inputs passed by value or address to legacy Functions here:
Hope this helps.

Categories

Find more on Simulink Coder in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!