hans
hans

Reputation: 5

How to give a structure with arrays in simulink to a custom C code function?

I'm trying to give a structure to a C function in Simulink. My steps so far:

If I run the code I get a long error from the code generation that indicates that it can't be compiled in c-code. The error is:

   c2_Test2.c 
   c2_Test2.c(57) : error C2143: syntax error : missing ')' before '*' 
   c2_Test2.c(57) : error C2081: 'cs_size' : name in formal parameter   list illegal 
   c2_Test2.c(57) : error C2143: syntax error : missing '{' before '*' 
   c2_Test2.c(57) : error C2059: syntax error : ')' 
   c2_Test2.c(60) : error C2143: syntax error : missing ')' before '*'   
   ....

This only happens if I declare the two variables i and x as Pointers. If I declare them as scalar in the header and MATLAB function it works. Does any one see what I'm doing wrong?

Upvotes: 0

Views: 2497

Answers (2)

Ryan Livingston
Ryan Livingston

Reputation: 1928

Getting the Code to Compile

To get the code to compile I added:

#include "mystruct.h"

in the Simulation Target->Custom Code->Header File section. Adding the required include paths on that pane may be necessary as well.

Compatibility Concerns

After doing the above, the code crashes when running. The issue is that the definition of mystruct is not what MATLAB Coder is expecting.

When you define a MATLAB structure with fixed-size arrays inside of it, the type generated by MATLAB Coder uses static arrays inside of the C struct like:

typedef struct {
  int32_T m;
  int32_T i[10];
  real_T x[10];
} mystruct;

You can see this in the code in the slprj directory if you remove the 'extern' from the coder.cstructname call.

A struct with inline arrays already has memory allocated for the arrays by the C compiler. However, when the fields are pointers, someone needs to allocate the space for the data, which has not been done here.

I see a few options:

  • Omit the 'extern' and allow MATLAB Coder/Simulink to generate the type definition
  • Declare your external structure with arrays rather than pointers for i and x
  • Before writing to or reading from the struct, pass it to another C function that allocates memory for the fields:

    function y = fcn(u)
    %#codegen
    m=int32(1);
    i=zeros(10,1,'int32');
    x=zeros(10,1);
    s = coder.nullcopy(struct('m',m,'i',i,'x',x));
    coder.cstructname(s,'mystruct');
    coder.ceval('initmystruct',coder.wref(s),int32(numel(i)),int32(numel(x)));
    s.m=m;
    s.i=i;
    s.x=x;
    

    And in C:

    /* Example of initmystruct with no error checking */
    /* int is the size type assuming it matches int32 */
    /* in the MATLAB coder.ceval call                 */
    void initmystruct (mystruct *s, int szi, int szx)
    {
        s->i = malloc(szi*sizeof(*s->i));
        s->x = malloc(szx*sizeof(*s->x));
    }
    

Upvotes: 2

Phil Goddard
Phil Goddard

Reputation: 10782

According to the doc for cstructname the header file needs to be specified using the 'Headerfile' input argument.

Upvotes: 0

Related Questions