Generate Code for Atomic Subsystems
This example shows a model designed and configured for deploying embedded system component code that is generated from a model that is partitioned into multiple atomic subsystems. The subsystems execute at different rates. The multirate top model is configured for C data interface code generation. You integrate the generated source code for each subsystem with other code, including an external scheduler, that runs in a target environment.
Atomic Subsystem Model
Open the example model.
open_system("AtomicSubsystem");
The model is configured to display color-coded sample times with annotations. To see them, after opening the model, update the diagram by pressing Ctrl+D. To display the legend, press Ctrl+J.
This model partitions an algorithm into two atomic subsystems: Rate1s
and Rate2s
. Subsystem Rate1s
is configured with a sample time of 1 second. Subsystem Rate2s
is configured with a sample time of 2 seconds.
Relevant Model Configuration Parameter Settings
Type set to
Fixed-step
.Solver set to
discrete (no continuous states)
.Treat each discrete rate as a separate task cleared.
Scheduling
Simulink® simulates the model based on the model configuration. Simulink propagates and uses the Inport block sample times to order block execution based on a single-core, single-tasking execution platform.
For this example, the sample time legend shows implicit rate grouping. Red represents the fastest discrete rate. Green represents the second fastest discrete rate.
Based on rate-monotonic scheduling, your application code (execution framework) must transfer data between subsystems Rate2s
and Rate1s
at a frequency of 2 seconds with the priority of 1 second. That is, the generated function transfers data in the 1 second task every other time prior to executing code for subsystem Rate1s
.
Your execution framework must schedule the generated function code and handle the data transfers between them. This is an advantage for multirate models because the generated code does not assume scheduling or data transfer semantics. However, the execution framework must handle data transfers explicitly.
Generate Code and Report
Generate a single callable function for each subsystem without connections between them. Multiple ways are available to generate code for a subsystem, including from the subsystem context menu.
Open the Embedded Coder app.
Right-click a subsystem block.
Click C/C++ Code > Build This Subsystem.
The example model generates a report.
Review Generated Code
Review the generated code in the Code view or the code generation report.
ert_main.c
is an example main program (execution framework) for the subsystem. This code controls model code execution by calling entry-point functionRate1s_step
orRate2s_step
. Use this file as a starting point for coding your execution framework.Rate1s.c
andRate2s.c
contain entry points for the code that implements subsystemRate1s
andRate2s
, respectively. This file includes the rate and task scheduling code.Rate1s.h
andRate2s.h
declare model data structures and a public interface to subsystem entry points and data structures.rtwtypes.h
defines data types, structures, and macros that the generated code requires.
Code Interface
Open and review the Code Interface Report. Use the information in that report to write the interface code for your execution framework:
Include the generated header file by adding directive
#include AtomicSubsystem.h
.Write input data to the generated code for model Inport blocks.
Call the generated entry-point functions.
Read data from the generated code for model Outport blocks.
Input ports, Rate1s
:
rtU.In1
of typereal_T
with dimension of 1rtU.In2
of typereal_T
with dimension of 1
Entry-point functions, Rate1s
:
Initialize entry-point function,
void Rate1s_initialize(void)
. At startup, call this function once.Output and update entry-point (step) function,
void Rate1s_step(void)
. Call this function periodically, every second.Termination function,
void Rate1s_terminate(void)
. Call this function once from your shutdown code.
Output ports, Rate1s
:
rtY.Out1
of typereal_T
with dimension of 1rtY.Out2
of typereal_T
with dimension of 1
Input ports, Rate2s
:
rtU.In1
of typereal_T
with dimension of 1
Entry-point functions, Rate2s
:
Initialize entry-point function,
void Rate2s_initialize(void)
. Call this function once at startup.Output and update entry-point (step),
void Rate2s_step(void)
. Call this function periodically, every 2 seconds.Termination function,
void Rate2s_terminate(void)
. Call this function once from your shutdown code.
Output ports, Rate2s
:
rtY.Out1
of typereal_T
with dimension of 1