Issue with Inlining S-Functions with TLC wrapper

Hello!
I have some troubles to reproduce the exemple described in the https://nl.mathworks.com/help/rtw/tlc/inlining-s-functions.html
I've wrote the TCL wrapper for my S-Function but I still get the error during building:
Error using tlc_c
Block 'test_lib/sfunc_calcCRC32/S-Function' is a
non-inlined S-function, which is not supported with the current configuration. Select Support non-inlined
I could not change the configuration by internal rools so I need to deal with inlined s-function.
I've made a simple exemple that reproduce the error (see mode.zip).
To sum up, I have a main file:
sfunc_calcCRC32.c
#define S_FUNCTION_NAME sfunc_calcCRC32
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
#include "calcCRC32.h"
/******
inspired by
github.com/vedderb/FaultCheck_QuickCheck/tree/master/Examples/AUTOSAR_E2E_QuickCheck
The CRC module shall implement the CRC32 routine based on the
IEEE- 802.3 CRC32 Ethernet Standard:
CRC result width : 32 bits
Polynomial : 04C11DB7h
Initial value : FFFFFFFFh
Input data reflected : Yes
Result data reflected : Yes
XOR value : FFFFFFFFh
Check : CBF43926h
Magic check : DEBB20E3h (Reflection must be considered!)
******/
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, 0); // Number of expected parameters
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
return; // Parameter mismatch will be reported by Simulink
}
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetInputPortDataType(S, 0, SS_UINT32);
ssSetInputPortDirectFeedThrough(S, 0, 1);
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetOutputPortDataType(S, 0, SS_UINT32);
ssSetNumSampleTimes(S, 1);
ssSetOptions(S, 0);
}
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
InputUInt32PtrsType uPtrs = (InputUInt32PtrsType)ssGetInputPortSignalPtrs(S, 0);
const int_T len = ssGetInputPortWidth(S, 0);
uint32_T *y = (uint32_T *)ssGetOutputPortSignal(S, 0);
y[0] = calcCRC32(uPtrs, len);
}
static void mdlTerminate(SimStruct *S)
{
// No termination needed
}
#ifdef MATLAB_MEX_FILE
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif
it calls the function calcCRC32(uPtrs, len), described in calcCRC32.c and calcCRC32.h (see in zip)
and the TLC-wrapper sfunc_calcCRC32.tlc
%%This code is the TLC file sfunc_calcCRC32.tlc that inlines sfunc_calcCRC32.c:
%% File : sfunc_calcCRC32.tlc
%% Abstract:
%% Example inlined tlc file for S-function sfunc_calcCRC32.c
%%
%implements "sfunc_calcCRC32" "C"
%% Function: BlockTypeSetup ====================================================
%% Abstract:
%% Create function prototype in model.h as:
%% "extern uint32_T calcCRC32(uint32_T *inPtr, uint32_T numEls);"
%%
%% Function: Start ======================================================
%function Start(block, system) Output
%<LibAddToCommonIncludes("calcCRC32.h")>
%endfunction
%function BlockTypeSetup(block, system) void
%openfile buffer
extern uint32_T calcCRC32(uint32_T *inPtr, uint32_T numEls); /* This line is placed in calcCRC32.h */
%closefile buffer
%<LibCacheFunctionPrototype(buffer)>
%endfunction %% BlockTypeSetup
%% Function: Outputs ===========================================================
%% Abstract:
%% %<y> = calcCRC32( %<inPtr>, %<numEls> );
%%
%function Outputs(block, system) Output
/* %<Type> Block: %<Name> */
%assign y = LibBlockInputSignal(0, "", "", 0)
%assign inPtr = LibBlockInputSignalAddr(0, "", "",0)
%assign numEls = LibBlockOutputSignalWidth(0)
%% PROVIDE THE CALLING STATEMENT FOR "algorithm"
%% The following line is expanded and placed in mdlOutputs within sfunc_calcCRC32.c
{
%<y> = calcCRC32( %<inPtr>, %<numEls> );
}
%endfunction %% Outputs
Thanks in advance for any suggestion!

 采纳的回答

Hi Dimitri,
This error usually indicates that the TLC file for the S-Function is not being detected or used during code generation, so the block is treated as a non-inlined S-Function. You can try the following general troubleshooting steps:
  • Ensure the TLC file name matches the S-Function name exactly. Simulink uses this naming convention to automatically associate the wrapper during code generation.
  • Verify that the TLC file and related source/header files are on the MATLAB path before building the model so the code generator can locate them.
  • Clear any previous build artifacts (slprj, rtw, etc.) and rebuild the model to ensure the updated TLC file is used.
  • Confirm that the %implements statement in the TLC file matches the S-Function name and that required includes or function prototypes are added correctly so the generated code can call the external function.
  • Make sure any external C source files used by the S-Function are included in the build, either through the S-Function implementation or via Simulation Target / Custom Code settings in the model configuration.
  • Check the generated code or build report to verify that the block is being expanded inline rather than referenced as a separate S-Function call.
More details on how Simulink associates TLC files with S-Functions and how to implement inlining are described here:

更多回答(0 个)

类别

帮助中心File Exchange 中查找有关 Target Language Compiler 的更多信息

产品

版本

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by