Simulink Buses with Pointer and Reflection inspect

Simulink Buses with Pointer and Reflection inspect

Inhalt


Topic:.Smlk.


1 SmlkMexCpp

Topic:.SmlkMexCpp.


1.1 Using the Microsoft C++ compiler for C sources instead C compilation

Topic:.SmlkMexCpp..

Reason:

The Microsoft Visual Studio Compiler compiles source.c with C compilation and source.cpp with C++ compilation. But the option

/TP

switches the C++ compilation for source.c -files too. Often the lightweigth C++ sources are written in source.c files. Using the Integrated Development Environment you can set this option in the Project Settings.

But for mex compilation you should touch the follwing files:

Matlab 2016 a:

c:\Users\NAME\AppData\Roaming\MathWorks\MATLAB\R2016a\mex_C_win64.xml

This file on this location is created with

mex -setup

from the Matlab command line.

To set the /TP option I have edited this file as text and change the following XML line:

<config
 ...
  <vars
  ...
    COMPILER="cl"
    COMPFLAGS="/Zp8 /GR /W3 /EHs /nologo /MD /TP /EHa"

The attribute COMPFLAGS contains the string which is used on invocation of the compiler cl. The /TP /EHa option is added to that flags.

The /EHa option switches that any kind of exception can be catched with catch(...). It is


2 Working with Buses and Pointer in Simulink

Topic:.Smlk..

Sometimes the same algorithms should be uses in traditional C / C++-programming and for models designed with Matlab-Simulink. For the model simulation level that C-sources can be used in form of Simulink S-Functions. If the model was translated to C-code with the Simulink-Codegen feature, the core routines of the S-function are immediately invoked in the translated code of the model.

What about Object Oriented Programming, which is usual in C++, which can be used in C-algorithm too. The C-algorithm which are traditionally used in C may be Object-Oriented. Object Orientation in its core (substantial) meaning is the binding of routines (C-functions, methods, operations) to its data. The data can be structured in C in struct { ...}. If a method respectively C-function works with its specific data, it is Object-Oriented. Associations, Aggregations and Compositions between classes are built with pointer (references) to other struct. The abstraction respectively inheritance is a important feature of Object Orientation, but not the substantial one. Abstraction in C can be done with reference types to a head struct type inside the derived structures, see the example.

Is there any commonality between a Simulink model and Object Orientation? A Simulink model presents a data flow thinking. Data are provided from one block and processed from another block (or module) in the calculation order. Object Orientation does not show the data flow (may be in sequence diagrams). Object model diagrams show the dependency between classes or moduls, the knowledge of the other data. But both worlds are able to join together. The Simulink model shows the data flow and calculation order of routines. Some Simulink blocks which uses the same bus inputs and outputs can be conceived as methods of the data which are presented in the bus types. The buses are the data structs or classes, and the using blocks are the methods or operations in Object Orientation.

Why this topic? Conventional Programming is a common practice, Object Orientation is an important style of conventional Programming. Embedded Software is often programmed in C or a lightweight C++. Simulink modelling with Code generation is a good idea of programming of embedded systems which can or should replace the conventional programming step by step, but not totally, more conglomerating. Both thinking areas should be joined therefore.


2.1 Buses in Simulink, presented in C with struct, provided as pointer type

Topic:.Smlk..bus_struct_ptr.

Lets present an example:

TODO image

It is possible to deal with pointer in Simulink Buses which can be used in C in generated code, or in S-functions, not in pure Simulink.

The last one, I think simulink has a paradigm: Data flow from input to output. Pointers offers the possibility to set data backward, from an output bus into the module. That is not desired, therefore pointers in buses are not firstly supported. But for solutions in the C-environment pointers may be a point of interest.

In the header file you should define a union:

typedef struct MyBus_t {
  /*unnamed union*/
  union { int32 myRefBus_int[2]; MyRefBus* myRefBus; };
  //... some more elements;
} MyBus;

The Simulink Bus definition should contain only the myRefBus_int element as int32 array of 2 dimensions. The next topic is a S-function which converts any desired Bus to the int32[]. S-functions have pointers as input if the input is a bus at model level. Arrays are also presented as pointners. Therefore the S-function "Bus2ptr" has the following definition in the mex.c file:

static void mdlInitializeSizes(SimStruct *simstruct) {
 ...
 ssSetInputPortWidth(simstruct, 0, 1);
 ssSetInputPortDataType(simstruct, 0, DYNAMICALLY_TYPED);
 ssSetOutputPortDataType(simstruct, 0, SS_INT32);
 ssSetOutputPortWidth(simstruct, 0, 2);
}
static void mdlOutputs(SimStruct *simstruct, int_T tid)
{
 void const*const* ptrs = ssGetInputPortSignalPtrs(simstruct, 0);  //InputPtrsType, InputRealPtrsType etc.
 void const* x = ptrs[0];
 int32* y = (int32*)ssGetOutputPortSignal(simstruct, 0);
 int64 ptr = (int64)(x);
 y[0] = (int32)ptr;
 y[1] = (int32)(ptr >>32);  //assume little endian. It is proper for all PC processors.
}

There are used two int32 because it should run on a 64 bit PC. The tlc-file contains the line:

%function Outputs(block, system) Output
 %assign u1_ptr = LibBlockInputSignalAddr(0, "", "", 0)
 %assign y1_ptr = LibBlockOutputSignalAddr(0, "", "", 0)
 //Assign only y1_ptr[0] because the target for code generation is 32 bit, let y1_ptr[1] = 0.
 *(int32*)(%<y1_ptr>) = (int32)(%<u1_ptr>);
%endfunction

For a 32-bit target system you need only 1 element. With this S-function you can convert any bus to int32-array and store the int32 values which is the address in the bus structure. From C level you can use the other union element in the bus header struct.