Using array input and output for simulink S-function C code block

I'm having a tough time attempting to use a C code block that needs uint8 array input and output . I've tried starting from a number of legacy code examples but encounter crashes every time my C code actually tries to access the incoming memory. If someone can point me to a working example (I've already tried everything that looked relevant here) I'd appreciate it. In my latest attempt I gave up on using the legacy code functions and took code from this example Create a Basic C MEX S-Function - MATLAB & Simulink (mathworks.com) which at least runs without crashing, and started to change it to take uint8 in/out as below. However I've no idea where to find the equivalent of InputRealPtrsType for unit8_T . If I use InputPtrsType instead of InputRealPtrsType I get the error error C2100: you cannot dereference an operand of type const void`
static void mdlOutputs(SimStruct *S, int_T tid)
{
int_T i;
// replced ssGetInputPortRealSignalPtrs(S,0) with ssGetInputPortSignalPtrs
InputRealPtrsType uPtrs = ssGetInputPortSignalPtrs(S,0);
// replaced ssGetOutputPortRealSignal(S,0) with ssGetOutputPortSignal
real_T *y = ssGetOutputPortSignal(S,0);
int_T width = ssGetOutputPortWidth(S,0);
for (i=0; i<width; i++) {
*y++ = 2.0 *(*uPtrs[i]);
}
}

 採用された回答

Gojo
Gojo 2024 年 9 月 10 日

1 投票

Hey Jeremy
I understand you wish to implement a C code block that accepts uint8 array input and perform some operations upon it.
I have tried out a simple example using "InputPtrsType" and it works as intended. If you are facing any issues upon its usage, I suggest you to share the model and code files to reproduce the issue.
Meanwhile you can refer to my model where I have modified the "mdlOutputs" as following:
static void mdlOutputs(SimStruct *S, int_T tid)
{
InputPtrsType uPtrs = ssGetInputPortSignalPtrs(S, 0);
uint8_T *y = (uint8_T *)ssGetOutputPortSignal(S, 0);
int_T width = ssGetOutputPortWidth(S, 0);
for (int_T i = 0; i < width; i++) {
y[i] = 2 * (*(uint8_T *)uPtrs[i]);
}
}
I am attaching "times_two" file for your reference. You can change the file extension from .txt to .c and build it using the following command:
mex times_two.c
I have created a simple Simulink model where I have used the constant block to create an input signal array and modified the Signal Attributes of the block to output uint8 data type. The S-function block is just used to double the values of the input signal.
I hope this helps!

3 件のコメント

Jeremy
Jeremy 2024 年 9 月 10 日
編集済み: Jeremy 2024 年 9 月 10 日
Thanks 10^6 that did the trick. For completeness what was missing was setting input/output data types with ssSetInputPortDataType(S, 0, SS_UINT8) and ssSetOutputPortDataType(S, 0, SS_UINT8) and then using casting to (uint8_T *) for the pointer dereferences to avoid error C2100. One thing that does puzzle me is that the width is determined by using
int_T width = ssGetOutputPortWidth(S,0)
as opposed to checking the input port width ; maybe the output is assumed to be the same size as the input? What if I wanted output of a different size?
Gojo
Gojo 2024 年 9 月 10 日
Yes Jeremy, I assumed the output to be as the same size as the input and this is true for most of the models/blocks I work with. If you want the output to be of different size then surely you can use the input port width and perform the computations accordingly. Anyways, I was using it as a terminating condition for the loop as done by you in your code snippet.
Happy to know that your query is resolved!
Jeremy
Jeremy 2024 年 9 月 11 日
It still puzzles me since the output port width is defined only as DYNAMICALLY_SIZED , so where is this size coming from? For an input I can understand that its size would be determined by the incoming size of the input but this is an output...

サインインしてコメントする。

その他の回答 (0 件)

製品

リリース

R2023b

質問済み:

2024 年 9 月 9 日

コメント済み:

2024 年 9 月 11 日

Community Treasure Hunt

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

Start Hunting!

Translated by