When using Embedded Coder® to generate code for an embedded system architecture, it is important to design your Simulink® models with code generation in mind from the very beginning of the design process. Think about relevant design factors and issues such as:
Use Simulink to design models that represent application algorithms and run-time environments from which you intend to generate deployable code. Depending on your application, you might deploy code to an execution environment that consists of a combination of:
Execution Environment Components | Choices |
---|---|
Hardware |
|
Cores |
|
Operating system |
|
Scheduling |
|
Application algorithm code |
|
As you design models to generate C or C++ code for rapid prototyping or production deployment, keep in mind the execution environment. Generate code that meets implementation requirements and avoids potential design rework. As the preceding table reflects, the execution environment for code that you generate can range from relatively simple to complex. For example, a simple case is code that you generate from a single, single-tasking model that runs on a single-core microprocessor. A complex case is code that generate from a model partitioned to run as a distributed system on a multicore microprocessor and an FPGA.
Part of an application execution environment is the software execution framework that is responsible for scheduling and running the generated code. That software can preexist, as in the case of an operating system and its scheduler, or you can code the software manually. The level of complexity varies depending on which of the following modeling and code generation scenarios applies:
Generate code from a single top model, which represents the algorithms intended to run in the execution environment.
Generate code from a model, which represents part of an overall algorithm. You can mix the generated code with code written manually and code generated from other sources or releases of MathWorks® products.
For a single top model, the software execution framework is responsible for running generated code the same way that Simulink simulates the model. Functions in the generated code are highly coordinated and optimized because Simulink is aware of dependencies. The framework interfaces with code generated for the top model only. Code generated for a top model handles interfacing with code for referenced Model blocks.
Consider the following example, where a single top model is mapped to tasks that run on a single-core CPU.
For this system, you map model clock rates to tasks that run on the hardware. You can choose for Simulink to map the rates implicitly or you can map them explicitly in your model. You can model latency effects resulting from how you map rates in a model to single-tasking or multitasking execution environments. Simulink schedules the tasks properly based on rates in the model and data dependencies between tasks. The code generator implements the same dependencies in the code that it generates. The software execution framework invokes generated entry-point functions at rates based on system timers and interrupts. The generated code executes in the same manner that Simulink simulates the model, and contains code dedicated to communicating data between functions running at different rates.
When you generate code from multiple top models separately and mix that code with code acquired in other ways, the execution environment of the application takes on more software execution framework responsibility. For this modeling scenario, you generate code for standalone, atomic reusable components.
With this scenario, Simulink is not aware of model dependencies. Functions in code generated from the different models are minimally coordinated and optimized. For example, the models might share generated utility functions. Potential optimizations that cross model boundaries are not possible. You must design the software execution framework taking into account dependencies between units of code, including execution order. For an application that requires concurrent execution across multiple cores, you must consider data latency effects across the cores.
The code generator helps you address software execution framework challenges, such as sharing global data and avoiding identifier conflicts. The code generated for a each model handles the interfacing for referenced Model blocks.
When mapping an embedded system architecture to the Simulink modeling environment, think about the model design.
Modeling Algorithms | Given initial state and input, a set of tasks or instructions that efficiently produce the results that you want. |
Modeling Interfaces | Mechanisms that enable algorithm components to communicate and exchange information across component boundaries. |
Modeling Systems | Collection of algorithm components that achieve a higher-level, domain-specific goal or result. Components often share resources. |
Modeling Run-Time Environments | Framework that handles scheduling of system algorithm resources and execution. |
Consider the following questions regarding an embedded system architecture with corresponding modeling capabilities and links to related information. Use the information as a guide for mapping your architecture details to the Simulink modeling environment. Designing a model architecture with your specific embedded system architecture in mind can help you avoid rework and future conversion and maintenance costs.
Architecture Considerations | Modeling Considerations | Related Information |
---|---|---|
What is the system domain? | Product prerequisites (based on domains of components) | |
Does the system involve physical domains, such as mechanical, electrical, or hydraulic domains? | Physical systems | |
What aspects of your algorithm can you represent with blocks provided by MathWorks products? What blocks do you need to create? | Block usage, creation, and customization | |
Does the architecture include state machine components? | Event-driven system | Model Reactive Systems in Stateflow (Stateflow) |
Is there a need to standardize code that the code generator produces from multiple models? | Custom code definitions for data and functions |
Architecture Considerations | Modeling Considerations | Related Information |
---|---|---|
| Data representation | |
Where and how is data pulled into the system and pulled within the system? | Input | |
| Output | |
| Functions and function calls | |
Can you benefit from setting up default code generation configurations for categories of data and functions? | Data and function configuration | |
Do you need to export functions that are invoked by controlling logic that is outside the model? | Function export | |
Does the system monitor signals or log data (for example, for calibration)? | C API and ASAP2 data exchange interfaces | |
Do you need to replace code generated for functions or operators, for example, to optimize the code for specific hardware? | Code replacement | |
Do you need to control the placement of data or functions in memory? | Memory sections | |
Is there a requirement for elaboration and future considerations? | Elaboration and future considerations |
Architecture Considerations | Modeling Considerations | Related Information |
---|---|---|
| Componentization |
|
| Model referencing | |
Are you modeling a client-server architecture? | Simulink Function and Caller blocks | |
Is relevant legacy or custom code available? | External code integration | External Code Integration |
Can you apply a reference architecture or reference components? | Model and project templates | |
Do you need to export functions that are invoked by controlling logic that is outside a model? | Export-function models | Export-Function Models Overview |
Is there a need to package the source code for a component as a shared object library to simplify distribution or sharing? | Shared object libraries (dynamic link libraries) | Package Generated Code as Shared Libraries |
Can you reuse functions? | Function reuse | |
| Shared data | |
Do you need to control placement of data or functions in memory? | Memory sections | |
Are you required to apply the AUTOSAR standard? If yes, what aspects of the architecture involve AUTOSAR? | AUTOSAR | AUTOSAR Blockset |
Does your system need to meet other standards or guidelines? | Standards and guidelines | Support for Standards and Guidelines |
Architecture Considerations | Modeling Considerations | Related Information |
---|---|---|
| Runtime interfacing |
|
Is the system partitioned into concurrent components to maximize parallelism? Which components? | Concurrency | |
| Clocks and clock rates | |
| Time-based scheduling | |
| Event-based scheduling | |
Does the system need to handle initialization, reset, or terminate events? | Initialization, reset, termination | |
| Task execution | |
| Processing platforms | Multicore Processor Targets |
| Kernel, operating system |
Embedded Coder provides a set of built-in templates to use as a starting point to create models for common application designs. Use the templates to create models that are preconfigured to generate code for embedded system applications.
Template | Description |
---|---|
Code Generation System | Basic model consisting of an Inport block and Output block. |
Exported functions | Model for generating code from function-call subsystems. You can export each function-call subsystem separately by right-clicking a subsystem, selecting C/C++ Code > Export Functions, and clicking Build. |
Fixed-step, multirate | Fixed-step model that uses multiple rates and consists of Inport blocks, an Outport block,
and a Sum block. The model is configured to use a fixed-step discrete solver
and to use two rates with model configuration parameter Periodic
sample time constraint set to
Unconstrained and parameter Treat
each discrete rate as a separate task selected. Simulink inserts a Rate Transition block to handle the two sample
rates. |
Fixed-step, single rate | Fixed-step model that uses a single rate and consists of Inport blocks, an Outport block, and a Sum block. The model is configured to use a fixed-step discrete solver. |
To create a model from a template:
On the MATLAB® home tab, click Simulink.
In the Simulink start page, expand Embedded Coder.
Hover over a template and click Create Model. A new model that uses the template contents and settings appears in the Simulink Editor window.
For more information, for example to create and use a template as a reference design, see Create a Template from a Model.