How can I create an S-Function with dynamically typed inputs that support uint64 in Simulink

2 views (last 30 days)
Hi,
I am trying to create an S-Function block in Simulink Real-Time that has a dynamically typed input port and also supports uint64. Something like this:
However, I always get following error when building the model:
dyn_64bit_input_port_model.cpp:429: undefined reference to `ssRegisterDataTypeFxpFSlopeFixExpBias'
I can set the input port fixed to uint64, and the model builds without an issue:
[...]
#include "simstruc.h"
#include "fixedpoint.h"
static void mdlInitializeSizes(SimStruct *S)
{
[...]
// Register uint64 data type
DTypeId uint64TypeId = INVALID_DTYPE_ID;
#ifdef MATLAB_MEX_FILE
uint64TypeId = ssRegisterDataTypeInteger(S, 0, 64, 0);
if (uint64TypeId == INVALID_DTYPE_ID) {
ssSetErrorStatus(S, "Failed to register 64-bit integer type");
return;
}
#endif
ssSetInputPortDataType(S, 0, uint64TypeId);
[...]
}
[...]
#ifdef MATLAB_MEX_FILE
#include "simulink.c" /* Mex glue */
#include "fixedpoint.c"
#else
#include "cg_sfun.h" /* Code generation glue */
#endif
If I configure the port data type to be dynamic, the model builds fine with an uint32 on the input:
static void mdlInitializeSizes(SimStruct *S)
{
[...]
ssSetInputPortDataType(S, 0, DYNAMICALLY_TYPED);
[...]
}
#ifdef MATLAB_MEX_FILE
#define MDL_SET_INPUT_PORT_DATA_TYPE
static void mdlSetInputPortDataType(SimStruct *S, int port, DTypeId dataType)
{
ssSetInputPortDataType(S, port, dataType);
}
#define MDL_SET_DEFAULT_PORT_DATA_TYPES
static void mdlSetDefaultPortDataTypes(SimStruct *S)
{
// Set input ports to default data type
int numInputPorts = ssGetNumInputPorts(S);
for (int i = 0; i < numInputPorts; i++) {
if (ssGetInputPortDataType(S, i) == DYNAMICALLY_TYPED) {
ssSetInputPortDataType(S, i, SS_UINT32);
}
}
}
#endif // MATLAB_MEX_FILE
But when I connect an uint64 to the input port, no matter whether I register the uint64 or not, Simulink always adds this call to ssRegisterDataTypeFxpFSlopeFixExpBias() to the generated code, which then fails to build because it cannot find it.
More detailed error message:
### Creating standalone executable C:/f/dyn_64bit_input_port/dyn_64bit_input_port_model_slrealtime_rtw/dyn_64bit_input_port_model ...
q++ -Vgcc_ntox86_64 -g -std=gnu++14 -stdlib=libstdc++ -o C:/f/dyn_64bit_input_port/dyn_64bit_input_port_model_slrealtime_rtw/dyn_64bit_input_port_model rt_matrx.o rt_printf.o dyn_64bit_input_port_model.o dyn_64bit_input_port_model_cal.o rtGetInf.o rtGetNaN.o rt_nonfinite.o slrealtime_datatype_ground.o rte_dyn_64bit_input_port_model_parameters.o main.o dyn_64bit_input_port_sfunc.o host_timer_x86.o slrealtime_code_profiling_utility_functions.o -LC:/PROGRA~1/MATLAB/R2022a/toolbox/slrealtime/target/win64/target/lib -ltraceparser -lpps -lslrealtime_kernel -lslrealtime_platform -lslrealtime_rtps -lsocket -lboost_system -lboost_log -lpci -lopenblas -lpcap
C:\ProgramData\MATLAB\SupportPackages\R2022a\toolbox\slrealtime\target\supportpackage\qnx710\\host\win64\x86_64\usr\bin\x86_64-pc-nto-qnx7.1.0-ld: dyn_64bit_input_port_model.o: in function `dyn_64bit_input_port_model_initialize':
C:/f/dyn_64bit_input_port/dyn_64bit_input_port_model_slrealtime_rtw/dyn_64bit_input_port_model.cpp:429: undefined reference to `ssRegisterDataTypeFxpFSlopeFixExpBias'
cc: C:/ProgramData/MATLAB/SupportPackages/R2022a/toolbox/slrealtime/target/supportpackage/qnx710//host/win64/x86_64/usr/bin/x86_64-pc-nto-qnx7.1.0-ld caught signal 1
dyn_64bit_input_port_model.mk:235: recipe for target 'C:/f/dyn_64bit_input_port/dyn_64bit_input_port_model_slrealtime_rtw/dyn_64bit_input_port_model' failed
make: *** [C:/f/dyn_64bit_input_port/dyn_64bit_input_port_model_slrealtime_rtw/dyn_64bit_input_port_model] Error 1
C:\f\dyn_64bit_input_port\dyn_64bit_input_port_model_slrealtime_rtw\instrumented>echo The make command returned an error of 2
The make command returned an error of 2
C:\f\dyn_64bit_input_port\dyn_64bit_input_port_model_slrealtime_rtw\instrumented>exit /B 1

Accepted Answer

Andy Bartlett
Andy Bartlett on 6 Jun 2022
S-Functions work with features that utilize code generation in a variety of ways.
The way I'm familiar with to get the fullest support for C/C++ code generation based features is to provide a companion TLC file.
If there is no TLC file, then some feature can work around this by using the DLL for the S-Function block and generating code for everything else. Simulink accelerator feature can do this.
If there is no TLC file, then some other features will try to reuse the S-Function's C code source file if it is available. There are restrictions to this support especially for situations like rapid accelerator that are designed to execute without MATLAB or Simulink exe or DLL services. I believe Simulink Real-Time usage has similar restrictions to rapid accelerator. This means that calls to functions exported by the fixedpoint DLL will not work. I believe that is the root of the problem you are facing.
I've attached a trivial TLC companion file for your example. I tested it with rapid accelerator and it worked fine.
The examples I previously mentioned like
edit([matlabroot,'\toolbox\simulink\fixedandfloat\fxpdemos\sfun_user_fxp_asr.c'])
edit([matlabroot,'\toolbox\simulink\fixedandfloat\fxpdemos\sfun_user_fxp_prodsum.c'])
have companion tlc files like
edit([matlabroot,'\toolbox\simulink\fixedandfloat\fxpdemos\tlc_c\sfun_user_fxp_asr.tlc'])
edit([matlabroot,'\toolbox\simulink\fixedandfloat\fxpdemos\tlc_c\sfun_user_fxp_prodsum.tlc'])
The example sfun_user_fxp_prodsum may be interesting in that the core computation uses the same C code for the S-Functions C and TLC. The C code does extra work to register the interface. The TLC just does wrapper work to get the C text that represents the inputs and outputs.

More Answers (2)

Andy Bartlett
Andy Bartlett on 3 Jun 2022
Hi Daniel,
Providing one extra argument
-lfixedpoint
when mex'ing your SFunction should solve the linker issue.
An example from this folder
toolbox\simulink\fixedandfloat\fxpdemos
would be mex'd like so
mex sfun_user_fxp_asr.c -lfixedpoint;
If you have additional trouble with data type propagation, this set of videos may help.
Regards,
Andy

Daniel Meer
Daniel Meer on 3 Jun 2022
Hi Andy,
Thanks for the info about mexing. I didn't mention it in my original question, but I already provide the -lfixedpoint when mexing and there is no issue during that step.
The error occurs later, when I try to build the model.
I've attached a minimal example to this post. I will also have a look at the YouTube videos.
Regards,
Daniel
  1 Comment
Andy Bartlett
Andy Bartlett on 6 Jun 2022
Ah, great you had mex'd with -lfixedpoint linker option.
I misunderstood where the issue was coming from.
Please see my second answer instead.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!