Compile a Simulink generated C code using Python (ctypes)

202 Views Asked by At

Thanks everyone for your swift replies. I should have mentioned Im not that good with C programming, but from what I got based on Embedded coder (Simulink) documentation is that : ert_main.c (code below) is an example of how to use the model.c

  • In the ert_main.c file those variables are declared like:
static RT_MODEL_NAME_T Model_NAME_M_;
static RT_MODEL_NAME_T *const Model_NAME_M = &Model_NAME_M_;/* Real-time 
model */
static DW_Model_NAME_T Model_NAME_DW;/* Observable states */

In the model.c, model_initialize is defined as :

void model_initialize(RT_MODEL_model_T *const model_M, real_T *model_U_reference,
                      real_T *model_Y_measure)
{
}

I tried to mimic this structure :

typedef struct {
 real_T state1_DSTATE; /* '<S8>/state1 measure' */
 real_T state2_DSTATE; /* '<S3>/state2 measure' */
 real_T DiscreteTimeIntegrator1_DSTATE;/* '<S4>/Discrete-Time Integrator1' */
 uint8_T DiscreteTimeIntegrator_LOAD;/* '<S27>/Discrete-Time Integrator' */
 boolean_T G1_PreviousInput; /* '<S39>/G1' */
} DW_Model_NAME_T;
...
struct tag_RTM_Model_NAME_T { /*Just holding the pointer in this case*/
 DW_Model_NAME_T *dwork;
};

and here is part of my python code (I tried only 3 arguments but same error): (according to

from ctypes import *  # Import ctypes library

libc = CDLL("./test.so")  # Load library

# Rename main functions for readibility
initialize = libc.model_initialize
step = libc.model_step
terminate = libc.model_terminate



# Create both ctypes structures of both state variables
class DW_model_T(Structure):
    _fields_ = [("state1_DSTATE", c_double),
                ("state2_DSTATE", c_double),
                ("DiscreteTimeIntegrator1_DSTATE", c_double),
                ("DiscreteTimeIntegrator_LOAD", c_ubyte),
                ("G1_PreviousInput", c_ubyte)]


class RT_MODEL_model_T(Structure):
    _fields_ = [("dwork", POINTER(DW_model_T))]


# Now mimic their declaration in ert_main.c
model_DW = DW_model_T()
model_M_ = RT_MODEL_model_T()
model_M = pointer(model_M_)
model_M_.dwork = pointer(model_DW)

# Also declare inputs and outputs before initializing
model_U_ref = c_double()
model_Y_measure = c_double()
# Initialize model
initialize(model_M_,
           byref(model_U_ref),
           byref(model_Y_measure))

I hope its well explained now

1

There are 1 best solutions below

0
On

Problem resolved. The problem was in the structure definition. I defined mine same as the tutoriel I was following whereas my generated C code was not exactly the same (probably due to different compiler or Matlab version). So here is the structure in my model.h :

typedef struct {
  real_T DiscreteTimeIntegrator_DSTATE;/* '<Root>/Discrete-Time Integrator' */
} DW_model_T;

/* Real-time Model Data Structure */
struct tag_RTM_model_T {
  const char_T * volatile errorStatus;
  DW_model_T *dwork;
};

and here how it should be declared/defined in python :

class DW_model_T(Structure):
    _fields_ = [("DiscreteTimeIntegrator_DSTATE", c_double)]


class RT_MODEL_model_T(Structure):
    _fields_ = [("errorStatus", c_char_p),
                ("dwork", POINTER(DW_model_T))]

the rest is the same (only 3 arguments in calling each function) Thanks everyone, you've been such a great help <3