Print Preview C:\TEMP\Apdf_2541_3068\home\AppData\Local\PTC\Arbortext\Editor\.aptcache\ae1qwjtr/tf1qwcnj Simulink Coder User's Guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 1365

DownloadPrint Preview - C:\TEMP\Apdf_2541_3068\home\AppData\Local\PTC\Arbortext\Editor\.aptcache\ae1qwjtr/tf1qwcnj Simulink Coder User's Guide
Open PDF In BrowserView PDF
Simulink® Coder™
User’s Guide

R2012b

How to Contact MathWorks

Web
Newsgroup
www.mathworks.com/contact_TS.html Technical Support
www.mathworks.com

comp.soft-sys.matlab

suggest@mathworks.com
bugs@mathworks.com
doc@mathworks.com
service@mathworks.com
info@mathworks.com

Product enhancement suggestions
Bug reports
Documentation error reports
Order status, license renewals, passcodes
Sales, pricing, and general information

508-647-7000 (Phone)
508-647-7001 (Fax)
The MathWorks, Inc.
3 Apple Hill Drive
Natick, MA 01760-2098
For contact information about worldwide offices, see the MathWorks Web site.
Simulink® Coder™ User’s Guide
© COPYRIGHT 2011–2012 by The MathWorks, Inc.
The software described in this document is furnished under a license agreement. The software may be used
or copied only under the terms of the license agreement. No part of this manual may be photocopied or
reproduced in any form without prior written consent from The MathWorks, Inc.
FEDERAL ACQUISITION: This provision applies to all acquisitions of the Program and Documentation
by, for, or through the federal government of the United States. By accepting delivery of the Program
or Documentation, the government hereby agrees that this software or documentation qualifies as
commercial computer software or commercial computer software documentation as such terms are used
or defined in FAR 12.212, DFARS Part 227.72, and DFARS 252.227-7014. Accordingly, the terms and
conditions of this Agreement and only those rights specified in this Agreement, shall pertain to and govern
the use, modification, reproduction, release, performance, display, and disclosure of the Program and
Documentation by the federal government (or other entity acquiring for or through the federal government)
and shall supersede any conflicting contractual terms or conditions. If this License fails to meet the
government’s needs or is inconsistent in any respect with federal procurement law, the government agrees
to return the Program and Documentation, unused, to The MathWorks, Inc.

Trademarks

MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See
www.mathworks.com/trademarks for a list of additional trademarks. Other product or brand
names may be trademarks or registered trademarks of their respective holders.
Patents

MathWorks products are protected by one or more U.S. patents. Please see
www.mathworks.com/patents for more information.
Revision History

April 2011
September 2011
March 2012
September 2012

Online
Online
Online
Online

only
only
only
only

New for Version 8.0 (Release 2011a)
Revised for Version 8.1 (Release 2011b)
Revised for Version 8.2 (Release 2012a)
Revised for Version 8.3 (Release 2012b)

Check Bug Reports for Issues and Fixes

Software is inherently complex and is not free of errors. The output of a code generator
might contain bugs, some of which are not detected by a compiler. MathWorks
reports critical known bugs brought to its attention on its Bug Report system at
www.mathworks.com/support/bugreports/. Use the Saved Searches and Watched Bugs tool
with the search phrase ‘‘Incorrect Code Generation’’ to obtain a report of known bugs that
produce code that might compile and execute, but still produce wrong answers.
The bug reports are an integral part of the documentation for each release. Examine
periodically all bug reports for a release, as such reports may identify inconsistencies between
the actual behavior of a release you are using and the behavior described in this documentation.
In addition to reviewing bug reports, you should implement a verification and validation
strategy to identify potential bugs in your design, code, and tools.

Contents
Model Architecture and Design
Modeling

1
.............

1-2

Scheduling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Scheduling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Single-Tasking and Multitasking Execution Modes . . . . . .
Handle Rate Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Single-Tasking and Multitasking Model Execution . . . . . .
Handle Asynchronous Events . . . . . . . . . . . . . . . . . . . . . . . .
Timers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Configure Scheduling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1-4
1-4
1-5
1-13
1-27
1-34
1-79
1-90

Configure a Model for Code Generation

Supported Products and Block Usage . . . . . . . . . . . . . . . 1-92
Related Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-92
Simulink Built-In Blocks That Support Code Generation . . 1-94
Block Set Support for Code Generation . . . . . . . . . . . . . . . . 1-116
Fixed-Point Tool Data Type Override . . . . . . . . . . . . . . . . . 1-116
Data Type Overrides Unavailable for Most Blocks in
Embedded Targets and Desktop Targets . . . . . . . . . . . . 1-116
Modeling Semantic Considerations . . . . . . . . . . . . . . . . . .
Data Propagation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Sample Time Propagation . . . . . . . . . . . . . . . . . . . . . . . . . .
Latches for Subsystem Blocks . . . . . . . . . . . . . . . . . . . . . . .
Block Execution Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Algebraic Loops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1-117
1-117
1-119
1-120
1-120
1-122

v

Subsystems

2
Code Generation of Subsystems . . . . . . . . . . . . . . . . . . . . .
Subsystem Code Dependence . . . . . . . . . . . . . . . . . . . . . . . .

2-2
2-3

Generate Code and Executables for Individual
Subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Subsystem Build Limitations . . . . . . . . . . . . . . . . . . . . . . . .

2-4
2-6

Inline Subsystem Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Configure Subsystem to Inline Code . . . . . . . . . . . . . . . . . .
Exceptions to Inlining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2-7
2-7
2-8

Generate Subsystem Code as Separate Function and
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2-10

Generate Reusable Function for Identical Subsystems
Within a Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-11
Considerations for Function Packaging Options Auto and
Reusable function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-13
Optimize Code for Identical Nested Subsystems . . . . . .

2-14

Generate Reusable Code for Subsystems Containing
S-Function Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2-15

Generate Reusable Code from Stateflow Charts . . . . . .

2-16

Code Reuse Limitations for Subsystems . . . . . . . . . . . . .
Blocks That Prevent Code Reuse . . . . . . . . . . . . . . . . . . . . .
Code Reuse Limitations for Subsystems Shared Across
Referenced Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2-17
2-17

Code Reuse For Subsystems Shared Across Referenced
Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2-19

.......................

2-20

Reusable Library Subsystem

vi

Contents

2-18

Code Generation of a Reusable Library Subsystem . . . . . .
Reusable Library Subsystem Code Placement and
Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Reusable Library Subsystem in the Top Model . . . . . . . . . .
Reusable Library Subsystem Connected to Root Outport . .

2-20

Code Generation of Constant Parameters . . . . . . . . . . . .

2-22

Shared Constant Parameters for Code Reuse . . . . . . . .
Shared Constant Parameters Limitations . . . . . . . . . . . . . .

2-23
2-24

Generate Reusable Code for Subsystems Shared Across
Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2-25

Determine Why Subsystem Code Is Not Reused . . . . . .
Review the Subsystems Section of the HTML Code
Generation Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Compare Subsystem Checksum Data . . . . . . . . . . . . . . . . .

2-21
2-21
2-21

2-32
2-32
2-32

Referenced Models

3
Code Generation for Referenced Models . . . . . . . . . . . . .

3-2

Generate Code for Referenced Models . . . . . . . . . . . . . . .
About Generating Code for Referenced Models . . . . . . . . . .
Create and Configure the Subsystem . . . . . . . . . . . . . . . . .
Convert Model to Use Model Referencing . . . . . . . . . . . . . .
Generate Model Reference Code for a GRT Target . . . . . . .
Work with Project Folders . . . . . . . . . . . . . . . . . . . . . . . . . .

3-4
3-4
3-4
3-7
3-11
3-14

Project Folder Structure for Model Reference
Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3-16

Configure Referenced Models . . . . . . . . . . . . . . . . . . . . . . .

3-17

Build Model Reference Targets . . . . . . . . . . . . . . . . . . . . .

3-18

vii

Reduce Change Checking Time . . . . . . . . . . . . . . . . . . . . . .

3-18

Simulink Coder Model Referencing Requirements . . . .
Configuration Parameter Requirements . . . . . . . . . . . . . . .
Naming Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Custom Target Requirements . . . . . . . . . . . . . . . . . . . . . . .

3-19
3-19
3-23
3-24

Storage Classes for Signals Used with Model Blocks . .
Storage Classes for Parameters Used with Model Blocks . .
Effects of Signal Name Mismatches . . . . . . . . . . . . . . . . . . .

3-25
3-26
3-27

Inherited Sample Time for Referenced Models . . . . . . .

3-29

Customize Library File Suffix and File Type . . . . . . . . .

3-31

Reusable Code and Referenced Models . . . . . . . . . . . . . .
General Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Code Reuse and Model Blocks with Root Inport or Outport
Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3-32
3-32

Simulink Coder Model Referencing Limitations . . . . . .
Customization Limitations . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Logging Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . .
State Initialization Limitation . . . . . . . . . . . . . . . . . . . . . . .
Reusability Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . .
S-Function Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Simulink Tool Limitations . . . . . . . . . . . . . . . . . . . . . . . . . .
Subsystem Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Target Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Other Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3-36
3-36
3-36
3-37
3-38
3-39
3-39
3-39
3-39
3-40

3-33

Combined Models

4

viii

Contents

Combined Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4-2

Use GRT Malloc to Combine Models . . . . . . . . . . . . . . . . .

4-4

Share Data Across Models . . . . . . . . . . . . . . . . . . . . . . . . . .
Timing Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Logging and External Mode Support . . . . . . . . . . . . .

4-4
4-4
4-5

Configure Model Parameters

5
Platform Options for Development and Deployment . .
Configure Emulation and Embedded Target
Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Identify the Device Vendor . . . . . . . . . . . . . . . . . . . . . . . . . .
Identify the Device Type . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Register Additional Device Vendor and Device Type
Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Set Native Word Size for the Device . . . . . . . . . . . . . . . . . .
Set Byte Ordering Used By Device . . . . . . . . . . . . . . . . . . .
Set Quotient Rounding Technique for Signed Integer
Division . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Set Arithmetic Right Shift Behavior for Signed Integers . .

5-2

5-3
5-4
5-5
5-5
5-9
5-10
5-11
5-12

Configure Embedded Hardware Characteristics . . . . . .

5-13

Configure Emulation Hardware Characteristics . . . . . .
Update Release 14 Hardware Configuration . . . . . . . . . . . .

5-15
5-17

Control the Location for Generated Files . . . . . . . . . . . .

5-18

Control Generated Files Location Used for
Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5-20

Control the Location for Code Generation Files . . . . . .

5-22

Override Build Folder Settings for Current Session . . .

5-24

ix

Model Protection

6
Protect a Referenced Model . . . . . . . . . . . . . . . . . . . . . . . .
Requirements for Protecting a Model . . . . . . . . . . . . . . . . .

6-2
6-3

....................................

6-4

Protected Model Report . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6-5

Code Generation Support in a Protected Model . . . . . .
Protected Model Requirements to Support Code
Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6-6

Protected Model File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6-8

..........................

6-9

Test the Protected Model . . . . . . . . . . . . . . . . . . . . . . . . . . .

6-13

Save Base Workspace Definitions . . . . . . . . . . . . . . . . . . .

6-15

Package a Protected Model . . . . . . . . . . . . . . . . . . . . . . . . .

6-16

Harness Model

Create a Protected Model

6-6

Data, Function, and File Definition
Data Representation

7
Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Enumerated Data Types . . . . . . . . . . . . . . . . . . . . . .
Default Code for an Enumerated Data Type . . . . . . . . . . . .
Type Casting for Enumerations . . . . . . . . . . . . . . . . . . . . . .
Override Default Methods (Optional) . . . . . . . . . . . . . . . . .
Enumerated Type Limitations . . . . . . . . . . . . . . . . . . . . . . .

x

Contents

7-2
7-2
7-2
7-3
7-4
7-7

Structure Parameters and Generated Code . . . . . . . . . .
About Structure Parameters and Generated Code . . . . . . .
Configure Structure Parameters for Generated Code . . . .
Control Name of Structure Parameter Type . . . . . . . . . . . .

7-8
7-8
7-8
7-9

Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Nontunable Parameter Storage . . . . . . . . . . . . . . . . . . . . . .
Tunable Parameter Storage . . . . . . . . . . . . . . . . . . . . . . . . .
Tunable Parameter Storage Classes . . . . . . . . . . . . . . . . . .
Declare Tunable Parameters . . . . . . . . . . . . . . . . . . . . . . . .
Tunable Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Linear Block Parameter Tunability . . . . . . . . . . . . . . . . . . .
Configuration Parameter Quick Reference Diagram . . . . .
Generated Code for Parameter Data Types . . . . . . . . . . . . .
Tunable Workspace Parameter Data Type
Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tune Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Parameter Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Structure Parameters and Generated Code . . . . . . . . . . . .

7-10
7-10
7-11
7-13
7-14
7-17
7-22
7-26
7-27
7-28

Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Signal Storage Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Signals with Auto Storage Class . . . . . . . . . . . . . . . . . . . . .
Signals with Test Points . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interface Signals to External Code . . . . . . . . . . . . . . . . . . .
Symbolic Naming Conventions for Signals . . . . . . . . . . . . .
Summary of Signal Storage Class Options . . . . . . . . . . . . .
Interfaces for Monitoring Signals . . . . . . . . . . . . . . . . . . . . .
Signal Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Initialize Signals and States Using Signal Objects . . . . . . .

7-52
7-52
7-53
7-55
7-59
7-60
7-62
7-63
7-64
7-65
7-74

States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
State Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
State Storage Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interface States to External Code . . . . . . . . . . . . . . . . . . . .
Symbolic Names for States . . . . . . . . . . . . . . . . . . . . . . . . . .
Control Code Generation for Block States . . . . . . . . . . . . . .
Summary of State Storage Class Options . . . . . . . . . . . . . .

7-83
7-83
7-83
7-84
7-85
7-87
7-90
7-91

7-34
7-36
7-38
7-49

xi

Data Stores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Data Stores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Storage Classes for Data Store Memory Blocks . . . . . . . . .
Generate Code for Data Store Memory Blocks . . . . . . . . . .
Nonscalar Data Stores in Generated Code . . . . . . . . . . . . .
Data Store Buffering in Generated Code . . . . . . . . . . . . . . .

7-93
7-93
7-93
7-96
7-97
7-99

Entry Point Functions and Scheduling

8
Entry Point Functions and Scheduling . . . . . . . . . . . . . .

8-2

............................

8-4

Non-Real-Time Single-Tasking Systems . . . . . . . . . . . . . .

8-6

Non-Real-Time Multitasking Systems . . . . . . . . . . . . . . . .

8-7

Real-Time Single-Tasking Systems . . . . . . . . . . . . . . . . . .

8-9

Real-Time Multitasking Systems . . . . . . . . . . . . . . . . . . . .

8-11

Multitasking Systems Using Real-Time Tasking
Primitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8-14

Program Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8-16

Program Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8-18

External Mode Communication . . . . . . . . . . . . . . . . . . . . .

8-19

Data Logging in Single-Tasking and Multitasking
Model Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8-20

About Model Execution

xii

Contents

Rapid Prototyping and Embedded Model Execution
Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8-22

Rapid Prototyping Model Functions . . . . . . . . . . . . . . . . .

8-23

Embedded Model Functions . . . . . . . . . . . . . . . . . . . . . . . .

8-30

Code Generation
Configuration

9
Configuring a Model for Code Generation . . . . . . . . . . .
Code Generation Configuration . . . . . . . . . . . . . . . . . . . . . .
Open the Model Configuration for Code Generation . . . . . .
Configure a Model Programmatically . . . . . . . . . . . . . . . . .

9-2
9-2
9-3
9-3

Application Objectives . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Code Generation Objectives . . . . . . . . . . . . . . . . . . . .
Configure Code Generation Objectives Using Code
Generation Advisor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9-6
9-6

Target . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Hardware Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Available Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Targets and Code Formats . . . . . . . . . . . . . . . . . . . .
Types of Target Code Formats . . . . . . . . . . . . . . . . . . . . . . .
Targets and Code Formats . . . . . . . . . . . . . . . . . . . . . . . . . .
Targets and Code Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Backwards Compatibility of Code Formats . . . . . . . . . . . . .
Selecting a Target . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Template Makefiles and Make Options . . . . . . . . . . . . . . . .
Custom Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Describing the Emulation and Embedded Targets . . . . . . .
Describing Embedded Hardware Characteristics . . . . . . . .
Describing Emulation Hardware Characteristics . . . . . . . .
Specifying Target Interfaces . . . . . . . . . . . . . . . . . . . . . . . . .
Selecting and Viewing Code Replacement Libraries . . . . .

9-9
9-9
9-10
9-15
9-16
9-29
9-29
9-31
9-34
9-38
9-44
9-45
9-54
9-55
9-58
9-61

9-7

xiii

Select the Target Language . . . . . . . . . . . . . . . . . . . . . . . . .

9-71

Code Appearance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Configure Code Comments . . . . . . . . . . . . . . . . . . . . . . . . . .
Configure Generated Identifiers . . . . . . . . . . . . . . . . . . . . .

9-72
9-72
9-73

Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9-80

Source Code Generation

10
Initiate Code Generation . . . . . . . . . . . . . . . . . . . . . . . . . . .

10-2

Reload Generated Code . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10-3

Generated Source Files and File Dependencies . . . . . . . 10-4
About Generated Files and File Dependencies . . . . . . . . . . 10-4
Header Dependencies When Interfacing Legacy/Custom
Code with Generated Code . . . . . . . . . . . . . . . . . . . . . . . . 10-6
Dependencies of the Generated Code . . . . . . . . . . . . . . . . . . 10-16
Specify Include Paths in Simulink Coder Generated Source
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-21
Files and Folders Created by Build Process . . . . . . . . . . 10-24
Files Created During the Build Process . . . . . . . . . . . . . . . 10-24
Folders Used During the Build Process . . . . . . . . . . . . . . . . 10-28
How Code Is Generated From a Model . . . . . . . . . . . . . . . 10-31
Model Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-31
Code Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-31
Code Generation of Matrices and Arrays . . . . . . . . . . . . . 10-33
Simulink Coder Matrix Parameters . . . . . . . . . . . . . . . . . . . 10-34
Internal Data Storage for Complex Number Arrays . . . . . . 10-36
Shared Utility Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-37
About Shared Utility Code . . . . . . . . . . . . . . . . . . . . . . . . . . 10-37

xiv

Contents

Controlling Shared Utility Code Placement . . . . . . . . . . . .
rtwtypes.h and Shared Utility Code . . . . . . . . . . . . . . . . . .
Incremental Shared Utility Code Generation and
Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Shared Utility Checksum . . . . . . . . . . . . . . . . . . . . . . . . . . .
Shared Fixed-Point Utility Functions . . . . . . . . . . . . . . . . .
Share User-Defined Data Types Across Models . . . . . . . . .
Generating Code Using Simulink Coder™

10-38
10-38
10-39
10-39
10-41
10-43

. . . . . . . . . . . 10-49

Report Generation

11
Reports for Code Generation . . . . . . . . . . . . . . . . . . . . . . .

11-2

HTML Code Generation Report Location . . . . . . . . . . . .

11-3

HTML Code Generation Report for Referenced
Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11-4

Generate a Code Generation Report . . . . . . . . . . . . . . . . .

11-5

Generate Code Generation Report After Build
Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11-6

Open Code Generation Report . . . . . . . . . . . . . . . . . . . . . .
Limitation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11-8
11-8

Generate Code Generation Report
Programmatically . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-10
Search in the Code Generation Report

. . . . . . . . . . . . . . 11-11

View Code Generation Report in Model Explorer . . . . . 11-12
Package and Share the Code Generation Report

. . . . . 11-14

xv

Package the Code Generation Report . . . . . . . . . . . . . . . . . 11-14
View the Code Generation Report . . . . . . . . . . . . . . . . . . . . 11-15
Document Generated Code with Simulink Report
Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Generate Code for the Model . . . . . . . . . . . . . . . . . . . . . . . .
Open the Report Generator . . . . . . . . . . . . . . . . . . . . . . . . .
Set Report Name, Location, and Format . . . . . . . . . . . . . . .
Include Models and Subsystems in a Report . . . . . . . . . . . .
Customize the Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Generate the Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11-16
11-17
11-18
11-20
11-21
11-22
11-23

Deployment
Desktops

12
Rapid Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2
About Rapid Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2
Rapid Simulation Performance . . . . . . . . . . . . . . . . . . . . . . 12-3
General Rapid Simulation Workflow . . . . . . . . . . . . . . . . . . 12-3
Identify Rapid Simulation Requirements . . . . . . . . . . . . . . 12-4
Configure Inports to Provide Simulation Source Data . . . . 12-6
Configure and Build Model for Rapid Simulation . . . . . . . . 12-6
Set Up Rapid Simulation Input Data . . . . . . . . . . . . . . . . . 12-9
Scripts for Batch and Monte Carlo Simulations . . . . . . . . . 12-19
Run Rapid Simulations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-20
Rapid Simulation Target Limitations . . . . . . . . . . . . . . . . . 12-33
Generated S-Function Block . . . . . . . . . . . . . . . . . . . . . . . .
About Object Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Create S-Function Blocks from a Subsystem . . . . . . . . . . .
Tunable Parameters in Generated S-Functions . . . . . . . . .
System Target File and Template Makefiles . . . . . . . . . . . .
Checksums and the S-Function Target . . . . . . . . . . . . . . . .
S-Function Target Limitations . . . . . . . . . . . . . . . . . . . . . . .

xvi

Contents

12-34
12-34
12-37
12-42
12-44
12-45
12-45

Real-Time Systems

13
Real-Time System Rapid Prototyping . . . . . . . . . . . . . . .
About Real-Time Rapid Prototyping . . . . . . . . . . . . . . . . . .
Goals of Real-Time Rapid Prototyping . . . . . . . . . . . . . . . . .
Refine Code With Real-Time Rapid Prototyping . . . . . . . . .

13-2
13-2
13-3
13-3

Hardware-In-the-Loop (HIL) Simulation . . . . . . . . . . . . .
About Hardware-In-the-Loop Simulation . . . . . . . . . . . . . .
Set Up and Run HIL Simulations . . . . . . . . . . . . . . . . . . . .

13-5
13-5
13-6

External Code Integration

14
Integration Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Integration Options . . . . . . . . . . . . . . . . . . . . . . . . . .
Types of External Code Integration . . . . . . . . . . . . . . . . . . .

14-2
14-2
14-2

Reuse Algorithmic Components in Generated Code . . . 14-5
Reusable Algorithmic Components . . . . . . . . . . . . . . . . . . . 14-5
Integrate External MATLAB Code . . . . . . . . . . . . . . . . . . . 14-5
Integrate External C or C++ Code . . . . . . . . . . . . . . . . . . . . 14-8
Integrate Fortran Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-11
Integration Considerations for Reusable Algorithmic
Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-11
Deploy Algorithm Code Within a Target
Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-14
Export Generated Algorithm Code for Embedded
Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-18
Export Algorithm Executables for System
Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-21
Modify External Code for Language Compatibility

. . . 14-22

xvii

Automate S-Function Generation . . . . . . . . . . . . . . . . . . . 14-23
Integrate External Code Using Legacy Code Tool . . . . .
Legacy Code Tool and Code Generation . . . . . . . . . . . . . . .
Generate Inlined S-Function Files for Code Generation . .
Apply Code Style Settings to Legacy Functions . . . . . . . . .
Address Dependencies on Files in Different Locations . . . .
Deploy S-Functions for Simulation and Code Generation . .

14-28
14-28
14-29
14-30
14-31
14-32

Configure Model for External Code Integration . . . . . . 14-33
Insert Custom Code Blocks . . . . . . . . . . . . . . . . . . . . . . . . .
Custom Code Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Embed Custom Code Directly Into MdlStart Function . . . .
Custom Code in Subsystems . . . . . . . . . . . . . . . . . . . . . . . .
Preserve User Files in Build Folder . . . . . . . . . . . . . . . . . . .

14-36
14-36
14-40
14-43
14-44

Insert S-Function Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About S-Functions and Code Generation . . . . . . . . . . . . . .
Write Noninlined S-Functions . . . . . . . . . . . . . . . . . . . . . . .
Write Wrapper S-Functions . . . . . . . . . . . . . . . . . . . . . . . . .
Write Fully Inlined S-Functions . . . . . . . . . . . . . . . . . . . . .
Write Fully Inlined S-Functions with mdlRTW Routine . .
Guidelines for Writing Inlined S-Functions . . . . . . . . . . . .
Write S-Functions That Support Expression Folding . . . . .
S-Functions That Specify Port Scope and Reusability . . . .
S-Functions That Specify Sample Time Inheritance
Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
S-Functions That Support Code Reuse . . . . . . . . . . . . . . . .
S-Functions for Multirate Multitasking Environments . . .
Build Support for S-Functions . . . . . . . . . . . . . . . . . . . . . . .

14-46
14-46
14-52
14-54
14-64
14-65
14-91
14-91
14-105
14-111
14-113
14-113
14-120

Program Building, Interaction, and Debugging

15
Compiler or IDE Selection and Configuration . . . . . . . .
Choose and Configure a Compiler . . . . . . . . . . . . . . . . . . . .
Troubleshoot Compiler Configurations . . . . . . . . . . . . . . . .

xviii

Contents

15-2
15-2
15-9

Program Builds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Configure the Build Process . . . . . . . . . . . . . . . . . . . . . . . . .
Initiate the Build Process . . . . . . . . . . . . . . . . . . . . . . . . . . .
Build a Generic Real-Time Program . . . . . . . . . . . . . . . . . .
Rebuild a Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Control Regeneration of Top Model Code . . . . . . . . . . . . . .
Reduce Build Time for Referenced Models . . . . . . . . . . . . .
Relocate Code to Another Development Environment . . . .
How Executable Programs Are Built From Models . . . . . .

15-12
15-12
15-14
15-14
15-27
15-27
15-28
15-33
15-38

Build and Run a Program . . . . . . . . . . . . . . . . . . . . . . . . . . 15-43
Profile Code Performance . . . . . . . . . . . . . . . . . . . . . . . . . .
About Profiling Code Performance . . . . . . . . . . . . . . . . . . . .
How to Profile Code Performance . . . . . . . . . . . . . . . . . . . .
Run Profiling Hooks for Generated Code . . . . . . . . . . . . . . .
Profiling Limitation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15-45
15-45
15-45
15-48
15-49

Data Exchange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Host/Target Communication . . . . . . . . . . . . . . . . . . . . . . . .
Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Parameter Tuning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Data Interchange Using the C API . . . . . . . . . . . . . . . . . . .
ASAP2 Data Measurement and Calibration . . . . . . . . . . . .
Direct Memory Access to Generated Code . . . . . . . . . . . . . .

15-50
15-50
15-105
15-119
15-137
15-174
15-189

Performance
Optimizations for Generated Code

16
Optimization Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . .

16-2

Advice About Optimizing Models for Code
Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16-5

Control Compiler Optimizations . . . . . . . . . . . . . . . . . . . .

16-6

xix

Optimization Tools and Techniques . . . . . . . . . . . . . . . . .

16-7

Control Memory Allocation for Time Counters . . . . . . .

16-9

Optimization Dependencies . . . . . . . . . . . . . . . . . . . . . . . . 16-10

Defensive Programming

17
Optimize Code for Floating-Point to Integer
Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Remove Code That Wraps Out-of-Range Values . . . . . . . . .
Remove Code That Maps NaN to Integer Zero . . . . . . . . . .

17-2
17-2
17-3

Disable Nonfinite Checks or Inlining for Math
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17-4

Data Copy Reduction

18

xx

Contents

Optimizing Generated Code . . . . . . . . . . . . . . . . . . . . . . . .
About Optimizing Generated Code . . . . . . . . . . . . . . . . . . .
Setting Up the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18-2
18-2
18-2

Generate Code Without Buffer Optimization . . . . . . . . .

18-4

Generate Code With Buffer Optimization . . . . . . . . . . . .

18-9

Minimize Computations and Storage for Intermediate
Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Expression Folding . . . . . . . . . . . . . . . . . . . . . . . . . . .
Expression Folding Example . . . . . . . . . . . . . . . . . . . . . . . .
Enable Expression Folding . . . . . . . . . . . . . . . . . . . . . . . . . .

18-11
18-11
18-12
18-15

Declare Signals as Local Function Data . . . . . . . . . . . . . . 18-17
Inline Invariant Signals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-18

Execution Speed

19
Inline Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Referenced Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19-2
19-3

Configure Loop Unrolling Threshold . . . . . . . . . . . . . . . .

19-4

Optimize Code Generated for Vector Assignments . . . .
Configure Model to Optimize Code Generated for Vector
Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Optimize Code Generated for Vector Assignments Using
memcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19-6
19-6
19-7

Generate Target Optimizations Within Algorithm
Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-10

Memory Usage

20
Minimize Memory Requirements During Code
Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

20-2

...........

20-3

Reduce Memory Requirements for Signals . . . . . . . . . . .

20-4

................

20-5

Implement Logic Signals as Boolean Data

Reuse Memory Allocated for Signals

xxi

Use Stack Space Allocation . . . . . . . . . . . . . . . . . . . . . . . . .

20-6

Verification
Simulation and Code Comparison

21
Comparing Output Data . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21-2

Configure Signal Data for Logging . . . . . . . . . . . . . . . . . .

21-3

Log Simulation Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21-5

Log Data from the Generated Program . . . . . . . . . . . . . .

21-7

Compare Numerical Results . . . . . . . . . . . . . . . . . . . . . . . .

21-9

Customization
Build Process Integration

22
Control Build Process Compiling and Linking . . . . . . . .

22-2

Cross-Compile Code Generated on Microsoft
Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22-4

Control Library Location and Naming During Build . . 22-7
Specify the Location of Precompiled Libraries . . . . . . . . . . 22-8
Control the Location of Model Reference Libraries . . . . . . . 22-9
Control the Suffix Applied to Library File Names . . . . . . . 22-10
Recompile Precompiled Libraries . . . . . . . . . . . . . . . . . . . 22-12

xxii

Contents

Customize Post-Code-Generation Build Processing . . .
Build Information Object . . . . . . . . . . . . . . . . . . . . . . . . . . .
Program a Post Code Generation Command . . . . . . . . . . . .
Define a Post Code Generation Command . . . . . . . . . . . . . .
Suppress Makefile Generation . . . . . . . . . . . . . . . . . . . . . . .

22-13
22-14
22-14
22-16
22-17

Configure Generated Code with TLC . . . . . . . . . . . . . . . .
About Configuring Generated Code with TLC . . . . . . . . . .
Assigning Target Language Compiler Variables . . . . . . . .
Set Target Language Compiler Options . . . . . . . . . . . . . . .

22-18
22-18
22-18
22-20

Customize Build Process with STF_make_rtw_hook
File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About the STF_make_rtw_hook File . . . . . . . . . . . . . . . . . .
Conventions for Using the STF_make_rtw_hook File . . . .
STF_make_rtw_hook.m Function Prototype and
Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Applications for STF_make_rtw_hook.m . . . . . . . . . . . . . . .
Control Code Regeneration Using
STF_make_rtw_hook.m . . . . . . . . . . . . . . . . . . . . . . . . . .
Use STF_make_rtw_hook.m for Your Build Procedure . . .
Customize Build Process with sl_customization.m . . . .
About sl_customization.m . . . . . . . . . . . . . . . . . . . . . . . . . . .
Register Build Process Hook Functions Using
sl_customization.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Variables Available for sl_customization.m Hook
Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example Build Process Customization Using
sl_customization.m . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Replace the STF_rtw_info_hook Mechanism

22-21
22-21
22-21
22-22
22-25
22-26
22-27
22-28
22-28
22-30
22-31
22-31

. . . . . . . . . 22-33

Customize Build to Use Shared Utility Code . . . . . . . . . 22-34
Modify Template Makefiles to Support Shared Utilities . . 22-35

xxiii

Run-Time Data Interface Extensions

23
Customize an ASAP2 File . . . . . . . . . . . . . . . . . . . . . . . . . . . 23-2
About ASAP2 File Customization . . . . . . . . . . . . . . . . . . . . 23-2
ASAP2 File Structure on the MATLAB Path . . . . . . . . . . . 23-2
Customize the Contents of the ASAP2 File . . . . . . . . . . . . . 23-3
ASAP2 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23-4
Use GROUP and SUBGROUP Hierarchies to Organize
Signals and Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . 23-6
Customize Computation Method Names . . . . . . . . . . . . . . . 23-12
Suppress Computation Methods for FIX_AXIS . . . . . . . . . . 23-13
Create a Transport Layer for External
Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
About Creating a Transport Layer for External
Communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Design of External Mode . . . . . . . . . . . . . . . . . . . . . . . . . . .
External Mode Communications Overview . . . . . . . . . . . . .
External Mode Source Files . . . . . . . . . . . . . . . . . . . . . . . . .
Implement a Custom Transport Layer . . . . . . . . . . . . . . . .

23-14
23-14
23-14
23-17
23-19
23-23

Custom Target Development

24

xxiv

Contents

About Embedded Target Development . . . . . . . . . . . . . . .
Custom Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Types of Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Recommended Features for Embedded Targets . . . . . . . . .

24-2
24-2
24-2
24-5

Sample Custom Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . .

24-9

Target Development Mechanics . . . . . . . . . . . . . . . . . . . . .
Folder and File Naming Conventions . . . . . . . . . . . . . . . . .
Components of a Custom Target . . . . . . . . . . . . . . . . . . . . .
Key Folders Under Target Root (mytarget) . . . . . . . . . . . . .
Key Files in Target Folder (mytarget/mytarget) . . . . . . . . .
Additional Files for Externally Developed Targets . . . . . . .

24-11
24-11
24-12
24-17
24-20
24-28

Target Development and the Build Process

. . . . . . . . . . . . 24-29

Customize System Target Files . . . . . . . . . . . . . . . . . . . . .
Control Code Generation With the System Target File . . .
System Target File Naming and Location Conventions . . .
System Target File Structure . . . . . . . . . . . . . . . . . . . . . . . .
Define and Display Custom Target Options . . . . . . . . . . . .
Tips and Techniques for Customizing Your STF . . . . . . . .
Create a Custom Target Configuration . . . . . . . . . . . . . . . .

24-36
24-36
24-37
24-37
24-46
24-54
24-61

Customize Template Makefiles . . . . . . . . . . . . . . . . . . . . . .
Template Makefiles and Tokens . . . . . . . . . . . . . . . . . . . . .
Invoke the make Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Structure of the Template Makefile . . . . . . . . . . . . . . . . . . .
Customize and Create Template Makefiles . . . . . . . . . . . . .

24-75
24-75
24-82
24-83
24-87

Support Optional Features . . . . . . . . . . . . . . . . . . . . . . . . .
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Support Model Referencing . . . . . . . . . . . . . . . . . . . . . . . . .
Support Compiler Optimization Level Control . . . . . . . . . .
Support firstTime Argument Control . . . . . . . . . . . . . . . . .
Support C Function Prototype Control . . . . . . . . . . . . . . . .
Support C++ Encapsulation Interface Control . . . . . . . . . .

24-100
24-100
24-101
24-115
24-117
24-119
24-121

Interface to Development Tools . . . . . . . . . . . . . . . . . . . . .
About Interfacing to Development Tools . . . . . . . . . . . . . . .
Makefile Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interface to an Integrated Development Environment . . . .

24-123
24-123
24-124
24-124

Device Drivers and Target Preferences . . . . . . . . . . . . . . 24-135
Integrate Device Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-135
Use Target Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24-135

xxv

Desktop IDEs and Desktop Targets
Project and Build Configurations for Desktop
Targets

25
Model Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25-2
Block Selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25-2
Target Preferences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25-3
Configuration Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . 25-7
Model Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25-14
IDE Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Support for Third Party Products . . . . . . . . . . . . . . . . . . . .
Third Party Product Setup . . . . . . . . . . . . . . . . . . . . . . . . . .
Code Generation and Build . . . . . . . . . . . . . . . . . . . . . . . . .
Automation of IDE Tasks and Processes . . . . . . . . . . . . . . .

25-16
25-16
25-16
25-16
25-17

Makefiles for Software Build Tool Chains . . . . . . . . . . . .
What is the XMakefile Feature . . . . . . . . . . . . . . . . . . . . . .
Using Makefiles to Generate and Build Software . . . . . . . .
Making an XMakefile Configuration Operational . . . . . . . .
Working with Microsoft Visual Studio . . . . . . . . . . . . . . . . .
Creating a New XMakefile Configuration . . . . . . . . . . . . . .
XMakefile User Configuration Dialog Box . . . . . . . . . . . . .

25-19
25-19
25-21
25-24
25-24
25-25
25-31

Verification Code Generated for Desktop
Targets

26
Processor-in-the-Loop (PIL) Simulation . . . . . . . . . . . . . 26-2
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26-2
PIL Approaches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26-3
Communications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26-8
Running Your PIL Application to Perform Simulation and
Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26-11
Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26-11

xxvi

Contents

PIL Issues and Limitations

. . . . . . . . . . . . . . . . . . . . . . . . . 26-12

Working with Eclipse IDE

27
Installing Third-Party Software for Eclipse . . . . . . . . . .
Tested Software Versions . . . . . . . . . . . . . . . . . . . . . . . . . . .
Installing Sun Java Runtime Environment (JRE) . . . . . . .
Installing Eclipse IDE for C/C++ Developers . . . . . . . . . . .
Verifying the GNU Tool Chain on Linux Host . . . . . . . . . .
Installing the GNU Tool Chain on Windows . . . . . . . . . . . .

27-2
27-2
27-3
27-5
27-6
27-7

Configuring Your MathWorks Software to Work with
Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27-10
Troubleshooting with Eclipse IDE . . . . . . . . . . . . . . . . . . .
SIGSEGV Segmentation Fault for GDB . . . . . . . . . . . . . . .
GDB Stops on Each Semaphore Post . . . . . . . . . . . . . . . . . .
Build Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Profiling Not Available for Intel x86/Pentium and AMD
K5/K6/Athlon Processors Running Windows or Linux
Operating Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Eclipse Message: “Can’t find a source file” . . . . . . . . . . . . .
Eclipse Message: “Cannot access memory at address” . . . .
Some Versions of Eclipse CDT Do Not Catch GCC
Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

27-14
27-14
27-14
27-15
27-15
27-15
27-16
27-16

Working with Linux Target

28
Disambiguation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28-2

Preparing Models to Run on Linux Target . . . . . . . . . . .

28-3

Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28-4

xxvii

Base Rate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Running Target Applications on Multicore Processors . . . .
Running Multirate, Multitasking Executables on the Linux
Desktop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Avoiding Lock-Up in Free-Running, Multirate, Multitasking
Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28-4
28-4
28-11
28-12

Working with Microsoft Windows Target

29
Preparing Models to Run on Windows . . . . . . . . . . . . . . .

29-2

Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29-3
Selecting the Operating System and Scheduling Mode . . . 29-3
Base Rate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29-4
Running Target Applications on Multicore Processors . . . . 29-4
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29-10

Examples

A

xxviii

Contents

Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-2

Timing Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-3

Model Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-4

Data Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-5

Custom Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-6

S-Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-7

Optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-8

External Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-9

Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-10

Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

A-11

Advanced Code Generation . . . . . . . . . . . . . . . . . . . . . . . . .

A-12

Code Generation Using Makefiles . . . . . . . . . . . . . . . . . . .

A-13

Index

xxix

xxx

Contents

Model Architecture and Design
• Chapter 1, “Modeling”
• Chapter 2, “Subsystems”
• Chapter 3, “Referenced Models”
• Chapter 4, “Combined Models”
• Chapter 5, “Configure Model Parameters”
• Chapter 6, “Model Protection”

1
Modeling
• “Configure a Model for Code Generation” on page 1-2
• “Scheduling” on page 1-4
• “Supported Products and Block Usage” on page 1-92
• “Modeling Semantic Considerations” on page 1-117

1

Modeling

Configure a Model for Code Generation
Model configuration parameters determine the method for generating the
code and the resulting format.
1 Open rtwdemo_throttlecntrl and save a copy as throttlecntrl in a

writable location on your MATLAB path.
Note This model uses Stateflow® software.
2 Open the Configuration Parameters dialog box Solver pane. To generate

code for a model, you must configure the model to use a fixed-step solver.
For this example, set the parameters as noted in the following table.

1-2

Parameter

Setting

Effect on Generated
Code

Type

Fixed-step

Maintains a constant
(fixed) step size, which
is required for code
generation

Solver

discrete (no
continuous states)

Applies a fixed-step
integration technique
for computing the state
derivative of the model

Fixed-step size

.001

Sets the base rate;
must be the lowest
common multiple of all
rates in the system

Configure a Model for Code Generation

3 Open the Code Generation pane and make sure that System target

file is set to grt.tlc.
Note The GRT (Generic Real-Time Target) configuration requires a
fixed-step solver. However, the rsim.tlc system target file supports
variable step code generation.
The system target file (STF) defines a target, which is an environment
for generating and building code for execution on a certain hardware or
operating system platform. For example, one property of a target is code
format. The grt configuration requires a fixed step solver and the rsim.tlc
supports variable step code generation.
4 Open the Code Generation > Custom Code pane, and under Include

list of additional, select Include directories. In the Include
directories text field, enter:
"$matlabroot$\toolbox\rtw\rtwdemos\EmbeddedCoderOverview\"

This directory includes files that are required to build an executable for
the model.
5 Apply your changes and close the dialog box.

1-3

1

Modeling

Scheduling
The following sections explain and illustrate how the Simulink® and
Simulink Coder™ products handle multirate (mixed-rate) models, depending
on whether code is being generated for single-tasking or multitasking
environments.
In this section...
“About Scheduling” on page 1-4
“Single-Tasking and Multitasking Execution Modes” on page 1-5
“Handle Rate Transitions” on page 1-13
“Single-Tasking and Multitasking Model Execution” on page 1-27
“Handle Asynchronous Events” on page 1-34
“Timers” on page 1-79
“Configure Scheduling” on page 1-90

About Scheduling
Simulink models run at one or more sample times. The Simulink product
provides considerable flexibility in building multirate systems, that is,
systems with more than one sample time. However, this same flexibility
also allows you to construct models for which the code generator cannot
generate real-time code for execution in a multitasking environment. To
make multirate models operate as expected in real time (that is, to give
the right answers), you sometimes must modify your model or instruct the
Simulink engine to modify the model for you. In general, the modifications
involve placing Rate Transition blocks between blocks that have unequal
sample times. The following sections discuss issues you must address to use
a multirate model in a multitasking environment. For a comprehensive
discussion of sample times, including rate transitions, see “What Is Sample
Time?”, “Sample Times in Subsystems”, “Sample Times in Systems”, “Resolve
Rate Transitions”, and associated topics.

1-4

Scheduling

Single-Tasking and Multitasking Execution Modes
• “About Tasking Modes” on page 1-5
• “Execute Multitasking Models” on page 1-6
• “Multitasking and Pseudomultitasking Modes” on page 1-8
• “Build a Program for Multitasking Execution” on page 1-10
• “Single-Tasking Mode” on page 1-10
• “Build a Program for Single-Tasking Execution” on page 1-11
• “Model Execution and Rate Transitions” on page 1-11
• “Simulate Models with the Simulink Product” on page 1-12
• “Execute Models in Real Time” on page 1-12
• “Single-Tasking Versus Multitasking Operation” on page 1-13

About Tasking Modes
There are two execution modes for a fixed-step Simulink model: single-tasking
and multitasking. These modes are available only for fixed-step solvers. To
select an execution mode, use the Tasking mode for periodic sample
times menu on the Solver pane of the Configuration Parameters dialog
box. Auto mode (the default) applies multitasking execution for a multirate
model, and otherwise selects single-tasking execution. You can also select
SingleTasking or MultiTasking execution explicitly.
Execution of models in a real-time system can be done with the aid of a
real-time operating system, or it can be done on a bare-board target, where
the model runs in the context of an interrupt service routine (ISR).
The fact that a system (such as The Open Group UNIX® or Microsoft®
Windows® systems) is multitasking does not imply that your program can
execute in real time. This is because the program might not preempt other
processes when required.
In operating systems (such as PC-DOS) where only one process can exist at
any given time, an interrupt service routine (ISR) must perform the steps of
saving the processor context, executing the model code, collecting data, and
restoring the processor context.

1-5

1

Modeling

Other operating systems, such as POSIX-compliant ones, provide automatic
context switching and task scheduling. This simplifies the operations
performed by the ISR. In this case, the ISR simply enables the model execution
task, which is normally blocked. The next figure illustrates this difference.

Real-Time Clock
Hardware
Interrupt

Interrupt Service
Routine
Save Context
Execute Model

Program execution using an
interrupt service routine
(bareboard, with no real-time
operating system). See the
grt target for an example.

Collect Data
Restore Context

Real-Time Clock
Hardware
Interrupt

Interrupt Service
Routine
semGive

Context
Switch

Model Execution
Task
semTake

Execute Model
Program execution using a real-time
operating system primitive. See the
Tornado raget for an example.

Collect Data

Execute Multitasking Models
In cases where the continuous part of a model executes at a rate that is
different from the discrete part, or a model has blocks with different sample

1-6

Scheduling

rates, the Simulink engine assigns each block a task identifier (tid) to
associate the block with the task that executes at the block’s sample rate.
You set sample rates and their constraints on the Solver pane of the
Configuration Parameters dialog box. To generate code with the Simulink
Coder software, you must select Fixed-step for the solver type. Certain
restrictions apply to the sample rates that you can use:
• The sample rate of any block must be an integer multiple of the base (that
is, the fastest) sample period.
• When Periodic sample time constraint is unconstrained, the base
sample period is determined by the Fixed step size specified on the
Solvers pane of the Configuration parameters dialog box.
• When Periodic sample time constraint is Specified, the base rate
fixed-step size is the first element of the sample time matrix that you
specify in the companion option Sample time properties. The Solver
pane from the example model rtwdemo_mrmtbb shows an example.

1-7

1

Modeling

• Continuous blocks always execute by using an integration algorithm that
runs at the base sample rate. The base sample period is the greatest
common denominator of all rates in the model only when Periodic sample
time constraint is set to Unconstrained and Fixed step size is Auto.
• The continuous and discrete parts of the model can execute at different
rates only if the discrete part is executed at the same or a slower rate than
the continuous part and is an integer multiple of the base sample rate.

Multitasking and Pseudomultitasking Modes
When periodic tasks execute in a multitasking mode, by default the blocks
with the fastest sample rates are executed by the task with the highest
priority, the next fastest blocks are executed by a task with the next higher
priority, and so on. Time available in between the processing of high-priority
tasks is used for processing lower priority tasks. This results in efficient
program execution.
Where tasks are asynchronous rather than periodic, there may not necessarily
be a relationship between sample rates and task priorities; the task with
the highest priority need not have the fastest sample rate. You specify
asynchronous task priorities using Async Interrupt and Task Sync blocks.
You can switch the sense of what priority numbers mean by selecting or
deselecting the Solver option Higher priority value indicates higher
task priority.
In multitasking environments (that is, under a real-time operating system),
you can define separate tasks and assign them priorities. In a bare-board
target (that is, no real-time operating system present), you cannot create
separate tasks. However, Simulink Coder application modules implement
what is effectively a multitasking execution scheme using overlapped
interrupts, accompanied by programmatic context switching.
This means an interrupt can occur while another interrupt is currently
in progress. When this happens, the current interrupt is preempted, the
floating-point unit (FPU) context is saved, and the higher priority interrupt
executes its higher priority (that is, faster sample rate) code. Once complete,
control is returned to the preempted ISR.

1-8

Scheduling

The next figures illustrate how timing of tasks in multirate systems are
handled by the Simulink Coder software in multitasking, pseudomultitasking,
and single-tasking environments.

t0

t1

t2

t3

t4
rate 1

Highest Priority

rate 2

rate 3
Lowest Priority

Vertical arrows indicate sample time hits.
Dotted lines with downward pointing
arrows indicate the release of control
to a lower priority task.
Dotted lines with upward pointing
arrows indicate preemption by a
higher priority task.

Dark gray areas indicate task execution.
Hashed areas indicate task preemption
by a higher priority task.
Light gray areas indicate task execution
is pending.

The next figure shows how overlapped interrupts are used to implement
pseudomultitasking. In this case, Interrupt 0 does not return until after
Interrupts 1, 2, and 3.

1-9

1

Modeling

Interrupt 0
Begins
t0

Interrupt 1

t1

Interrupt 2
Begins

Interrupt 1
Ends
t2

Interrupt 3

t3

Interrupt 3
Ends
t4

Highest Priority
Interrupt 2
Ends

Interrupt 0
Ends

Lowest Priority

Build a Program for Multitasking Execution
To use multitasking execution, select Auto (the default) or MultiTasking from
the Tasking mode for periodic sample times menu on the Solver pane
of the Configuration Parameters dialog box. This menu is active only if you
select Fixed-step as the solver type. Auto mode results in a multitasking
environment if your model has two or more different sample times. A model
with a continuous and a discrete sample time runs in single-tasking mode if
the fixed-step size is equal to the discrete sample time.

Single-Tasking Mode
You can execute model code in a strictly single-tasking manner. While this
mode is less efficient with regard to execution speed, in certain situations,
it can simplify your model.
In single-tasking mode, the base sample rate must define a time interval that
is long enough to allow the execution of all blocks within that interval.

1-10

Scheduling

The next figure illustrates the inefficiency inherent in single-tasking
execution.

t0

t1

t2

t3

t4

Single-tasking system execution requires a base sample rate that is long
enough to execute one step through the entire model.

Build a Program for Single-Tasking Execution
To use single-tasking execution, select SingleTasking from the Tasking
mode for periodic sample times menu on the Solver pane of the
Configuration Parameters dialog box. If you select Auto, single-tasking is
used in the following cases:
• If your model contains one sample time
• If your model contains a continuous and a discrete sample time and the
fixed step size is equal to the discrete sample time

Model Execution and Rate Transitions
To generate code that executes as expected in real time, you (or the Simulink
engine) might need to identify and handle sample rate transitions within
the model. In multitasking mode, by default the Simulink engine flags
errors during simulation if the model contains invalid rate transitions,
although you can use the Multitask rate transition diagnostic to alter this
behavior. A similar diagnostic, called Single task rate transition, exists for
single-tasking mode.
To avoid raising rate transition errors, insert Rate Transition blocks between
tasks. You can request that the Simulink engine handle rate transitions
automatically by inserting hidden Rate Transition blocks. See “Automatic
Rate Transition” on page 1-20 for an explanation of this option.
To understand such problems, first consider how Simulink simulations differ
from real-time programs.

1-11

1

Modeling

Simulate Models with the Simulink Product
Before the Simulink engine simulates a model, it orders the blocks based upon
their topological dependencies. This includes expanding virtual subsystems
into the individual blocks they contain and flattening the entire model into a
single list. Once this step is complete, each block is executed in order.
The key to this process is the ordering of blocks. Any block whose output is
directly dependent on its input (that is, any block with direct feedthrough)
cannot execute until the block driving its input executes.
Some blocks set their outputs based on values acquired in a previous time
step or from initial conditions specified as a block parameter. The output of
such a block is determined by a value stored in memory, which can be updated
independently of its input. During simulation, computations are performed
prior to advancing the variable corresponding to time. In essence, this results
in computations occurring instantaneously (that is, no computational delay).

Execute Models in Real Time
A real-time program differs from a Simulink simulation in that the program
must execute the model code synchronously with real time. Every calculation
results in some computational delay. This means the sample intervals cannot
be shortened or lengthened (as they can be in a Simulink simulation), which
leads to less efficient execution.
Consider the following timing figure.

t0

t1

t2

Time
Note the processing inefficiency in the sample interval t1. That interval
cannot be compressed to increase execution speed because, by definition,
sample times are clocked in real time.

1-12

Scheduling

You can circumvent this potential inefficiency by using the multitasking
mode. The multitasking mode defines tasks with different priorities to
execute parts of the model code that have different sample rates.
See “Multitasking and Pseudomultitasking Modes” on page 1-8 for a
description of how this works. It is important to understand that section
before proceeding here.

Single-Tasking Versus Multitasking Operation
Single-tasking programs require longer sample intervals, because all
computations must be executed within each clock period. This can result in
inefficient use of available CPU time, as shown in the previous figure.
Multitasking mode can improve the efficiency of your program if the model is
large and has many blocks executing at each rate.
However, if your model is dominated by a single rate, and only a few blocks
execute at a slower rate, multitasking can actually degrade performance. In
such a model, the overhead incurred in task switching can be greater than the
time required to execute the slower blocks. In this case, it is more efficient to
execute all blocks at the dominant rate.
If you have a model that can benefit from multitasking execution, you might
need to modify your model by adding Rate Transition blocks (or instruct the
Simulink engine to do so) to generate expected results. The next section,
“Handle Rate Transitions” on page 1-13, discusses issues related to rate
transition blocks.

Handle Rate Transitions
• “About Rate Transitions” on page 1-14
• “Data Transfer Problems” on page 1-15
• “Data Transfer Assumptions” on page 1-16
• “Rate Transition Block Options” on page 1-17
• “Faster to Slower Transitions in a Simulink Model” on page 1-22
• “Faster to Slower Transitions in Real Time” on page 1-23

1-13

1

Modeling

• “Slower to Faster Transitions in a Simulink Model” on page 1-24
• “Slower to Faster Transitions in Real Time” on page 1-25

About Rate Transitions
Two periodic sample rate transitions can exist within a model:
• A faster block driving a slower block
• A slower block driving a faster block
The following sections concern models with periodic sample times with zero
offset only. Other considerations apply to multirate models that involve
asynchronous tasks. For details on how to generate code for asynchronous
multitasking, see “Handle Asynchronous Events” on page 1-34.
In single-tasking systems, there are no issues involving multiple sample
rates. In multitasking and pseudomultitasking systems, however, differing
sample rates can cause problems by causing blocks to be executed in the
wrong order. To prevent possible errors in calculated data, you must control
model execution at these transitions. When connecting faster and slower
blocks, you or the Simulink engine must add Rate Transition blocks between
them. Fast-to-slow transitions are illustrated in the next figure.

T = 1s
Faster
Block

T = 2s
Slower
Block

becomes

T = 1s
Faster
Block

1-14

Port-based:
Tin = 1s; Tout = 2s
Rate Transition

T = 2s
Slower
Block

Scheduling

Slow-to-fast transitions are illustrated in the next figure.

T = 2s

T = 1s

Slower
Block

Faster
Block

becomes

T = 2s
Slower
Block

Port-based:
Tin = 2s; Tout = 1s
Rate Transition

T = 1s
Faster
Block

Note Although the Rate Transition block offers a superset of the capabilities
of the Unit Delay block (for slow-to-fast transitions) and the Zero-Order Hold
block (for fast-to-slow transitions), you should use the Rate Transition block
instead of these blocks.

Data Transfer Problems
Rate Transition blocks deal with issues of data integrity and determinism
associated with data transfer between blocks running at different rates.
• Data integrity: A problem of data integrity exists when the input to a block
changes during the execution of that block. Data integrity problems can be
caused by preemption.
Consider the following scenario:

-

A faster block supplies the input to a slower block.
The slower block reads an input value V1 from the faster block and
begins computations using that value.

1-15

1

Modeling

-

The computations are preempted by another execution of the faster
block, which computes a new output value V2.

-

A data integrity problem now arises: when the slower block resumes
execution, it continues its computations, now using the “new” input
value V2.

Such a data transfer is called unprotected. “Faster to Slower Transitions in
Real Time” on page 1-23 shows an unprotected data transfer.
In a protected data transfer, the output V1 of the faster block is held until
the slower block finishes executing.
• Deterministic versus nondeterministic data transfer: In a deterministic
data transfer, the timing of the data transfer is completely predictable, as
determined by the sample rates of the blocks.
The timing of a nondeterministic data transfer depends on the availability
of data, the sample rates of the blocks, and the time at which the receiving
block begins to execute relative to the driving block.
You can use the Rate Transition block to protect data transfers in your
application and make them deterministic. These characteristics are
considered desirable in most applications. However, the Rate Transition
block supports flexible options that allow you to compromise data integrity
and determinism in favor of lower latency. The next section summarizes
these options.

Data Transfer Assumptions
When processing data transfers between tasks, the Simulink Coder software
assumes the following:
• Data transitions occur between a single reading task and a single writing
task.
• A read or write of a byte-sized variable is atomic.
• When two tasks interact through a data transition, only one of them can
preempt the other.
• For periodic tasks, the faster rate task has higher priority than the slower
rate task; the faster rate task always preempts the slower rate task.

1-16

Scheduling

• All tasks run on a single processor. Time slicing is not allowed.
• Processes do not crash or restart (especially while data is transferred
between tasks).

Rate Transition Block Options
Several parameters of the Rate Transition block are relevant to its use in code
generation for real-time execution, as discussed below. For a complete block
description, see Rate Transition in the Simulink documentation.
The Rate Transition block handles periodic (fast to slow and slow to fast) and
asynchronous transitions. When inserted between two blocks of differing
sample rates, the Rate Transition block automatically configures its input
and output sample rates for the type of transition; you do not need to specify
whether a transition is slow-to-fast or fast-to-slow (low-to-high or high-to-low
priorities for asynchronous tasks).
The critical decision you must make in configuring a Rate Transition block is
the choice of data transfer mechanism to be used between the two rates. Your
choice is dictated by considerations of safety, memory usage, and performance.
As the Rate Transition block parameter dialog box in the next figure shows,
the data transfer mechanism is controlled by two options.

1-17

1

Modeling

• Ensure data integrity during data transfer: When this option is on,
data transferred between rates maintains its integrity (the data transfer
is protected). When this option is off, the data might not maintain its
integrity (the data transfer is unprotected). By default, Ensure data
integrity during data transfer is on.
• Ensure deterministic data transfer (maximum delay): This option is
supported for periodic tasks with an offset of zero and fast and slow rates
that are multiples of each other. Enable this option for protected data
transfers (when Ensure data integrity during data transfer is on).
When this option is on, the Rate Transition block behaves like a Zero-Order
Hold block (for fast to slow transitions) or a Unit Delay block (for slow to
fast transitions). The Rate Transition block controls the timing of data
transfer in a completely predictable way. When this option is off, the data
transfer is nondeterministic. By default, Ensure deterministic data

1-18

Scheduling

transfer (maximum delay) is on for transitions between periodic rates
with an offset of zero; for asynchronous transitions, it cannot be selected.
Thus the Rate Transition block offers three modes of operation with respect to
data transfer. In order of level of safety:
• Protected/Deterministic (default): This is the safest mode. The
drawback of this mode is that it introduces deterministic latency into the
system for the case of slow-to-fast periodic rate transitions. For that case,
the latency introduced by the Rate Transition block is one sample period of
the slower task. For the case of fast-to-slow periodic rate transitions, the
Rate Transition block introduces no additional latency.
• Protected/NonDeterministic: In this mode, for slow-to-fast periodic rate
transitions, data integrity is protected by double-buffering data transferred
between rates. For fast-to-slow periodic rate transitions, a semaphore flag
is used. The blocks downstream from the Rate Transition block always use
the latest available data from the block that drives the Rate Transition
block. Maximum latency is less than or equal to one sample period of the
faster task.
The drawbacks of this mode are its nondeterministic timing. The advantage
of this mode is its low latency.
• Unprotected/NonDeterministic: This mode is not recommended for
mission-critical applications. The latency of this mode is the same as for
Protected/NonDeterministic mode, but memory requirements are reduced
since neither double-buffering nor semaphores are required. That is, the
Rate Transition block does nothing in this mode other than to pass signals
through; it simply exists to notify you that a rate transition exists (and can
cause generated code to compute incorrect answers). Selecting this mode,
however, generates the least amount of code.
Note In unprotected mode (Ensure data integrity during data
transfer option off), the Rate Transition block does nothing other than
allow the rate transition to exist in the model.

1-19

1

Modeling

Automatic Rate Transition. The Simulink engine can detect mismatched
rate transitions in a multitasking model and automatically insert Rate
Transition blocks to handle them. To instruct the engine to do this, select
Automatically handle rate transition for data transfer on the Solver
pane of the Configuration Parameters dialog box.
The Automatically handle rate transition for data transfer option is off
by default. When you select it,
• The Simulink engine handles transitions between periodic sample times
and asynchronous tasks.
• The Simulink engine inserts “hidden” Rate Transition blocks that are not
visible on the block diagram.
• The Simulink Coder software generates code for the automatically inserted
Rate Transition blocks that is identical to that generated for manually
inserted Rate Transition blocks.
• Automatically inserted Rate Transition blocks operate in protected mode
for periodic tasks and asynchronous tasks, which you cannot alter. For
periodic tasks, automatically inserted Rate Transition blocks operate
with the level of determinism specified by the Solver pane parameter
Deterministic data transfer. (The default setting is Whenever
possible, which enables determinism for data transfers between periodic
sample-times that are related by an integer multiple; for more information,
see “Deterministic data transfer” in the Simulink reference documentation.)
To use other modes, you must insert Rate Transition blocks and set their
modes manually.
For example, in the following model SineWave2 has a Sample time of 2, and
SineWave3 has a Sample time of 3.

1-20

Scheduling

If Automatically handle rate transition for data transfer is on, the
Simulink engine inserts an invisible Rate Transition block between each Sine
Wave block and the Product block. The inserted blocks have the parameter
values required to reconcile the Sine Wave block sample times.

Inserted Rate Transition Block HTML Report
When the Simulink engine has automatically inserted Rate Transition blocks
into a model, after code generation the optional HTML code generation report
includes a List of inserted blocks that describes the blocks. For example,
the following report describes the two Rate Transition blocks that the engine
automatically inserts into the previous model.

Only automatically inserted Rate Transition blocks appear in a List of
inserted blocks. If no such blocks exist in a model, the HTML code
generation report does not include a List of inserted blocks.

1-21

1

Modeling

Rate Transition Blocks and Continuous Time. The sample time at the
output port of a Rate Transition block can only be discrete or fixed in minor
time step. This means that when a Rate Transition block inherits continuous
sample time from its destination block, it treats the inherited sample time
as Fixed in Minor Time Step. Therefore, the output function of the Rate
Transition block runs only at major time steps. If the destination block
sample time is continuous, Rate Transition block output sample time is the
base rate sample time (if solver is fixed-step), or zero-order-hold-continuous
sample time (if solver is variable-step).
The next four sections describe cases in which Rate Transition blocks are
required for periodic sample rate transitions. The discussion and timing
diagrams in these sections are based on the assumption that the Rate
Transition block is used in its default (protected/deterministic) mode;
that is, the Ensure data integrity during data transfer and Ensure
deterministic data transfer (maximum delay) options are both on. These
are the settings used for automatically inserted Rate Transition blocks.

Faster to Slower Transitions in a Simulink Model
In a model where a faster block drives a slower block having direct
feedthrough, the outputs of the faster block are always computed first. In
simulation intervals where the slower block does not execute, the simulation
progresses more rapidly because there are fewer blocks to execute. The next
figure illustrates this situation.
t1

t0
T = 1s
Faster
Block

T = 2s
Slower
Block

T = 1s

T = 2s

t2

T = 1s T = 1s

t3
T = 2s

T = 1s

Time

A Simulink simulation does not execute in real time, which means that it is
not bound by real-time constraints. The simulation waits for, or moves ahead
to, whatever tasks are required to complete simulation flow. The actual time
interval between sample time steps can vary.

1-22

Scheduling

Faster to Slower Transitions in Real Time
In models where a faster block drives a slower block, you must compensate
for the fact that execution of the slower block might span more than one
execution period of the faster block. This means that the outputs of the faster
block can change before the slower block has finished computing its outputs.
The next figure shows a situation in which this problem arises (T = sample
time). Note that lower priority tasks are preempted by higher priority tasks
before completion.

T = 1s
Faster
Block

T = 2s
Slower
Block

2 Sec
Task
1 Sec
Task

1

T=1s

T=2s

2

1

T=1s

3

T=1s

T=2s

2

T=1s

3

Time
1 The faster task (T=1s) completes.
2 Higher priority preemption occurs.
3 The slower task (T=2s) resumes and its inputs
have changed. This leads to unpredictable results.
In the above figure, the faster block executes a second time before the slower
block has completed execution. This can cause unpredictable results because
the input data to the slow task is changing. Data might not maintain its
integrity in this situation.
To avoid this situation, the Simulink engine must hold the outputs of the 1
second (faster) block until the 2 second (slower) block finishes executing. The
way to accomplish this is by inserting a Rate Transition block between the 1
second and 2 second blocks. The input to the slower block does not change
during its execution, maintaining data integrity.

1-23

1

Modeling

T=1s
Faster Block

Tin = 1Tout = 2

T=2s

Rate Transition

Slower Block

It is assumed that the Rate Transition block is used in its default
(protected/deterministic) mode.
The Rate Transition block executes at the sample rate of the slower block, but
with the priority of the faster block.

t0

t2

2 Sec
Task

T=2s

t0
1 Sec
Task

T=2s

t1
T=1s

RT

t2
T=1s

t3
T=1s

RT

T=1s

Time
When you add a Rate Transition block, the block executes before the 2 second
block (its priority is higher) and its output value is held constant while the 2
second block executes (it executes at the slower sample rate).

Slower to Faster Transitions in a Simulink Model
In a model where a slower block drives a faster block, the Simulink engine
again computes the output of the driving block first. During sample intervals
where only the faster block executes, the simulation progresses more rapidly.
The next figure shows the execution sequence.

1-24

Scheduling

t1

t0
T = 2s

T = 1s

Slower
Block

T = 2s

Faster
Block

t2

T = 1s T = 1s

t3
T = 2s

T = 1s T = 1s

Time

As you can see from the preceding figures, the Simulink engine can simulate
models with multiple sample rates in an efficient manner. However, a
Simulink simulation does not operate in real time.

Slower to Faster Transitions in Real Time
In models where a slower block drives a faster block, the generated code
assigns the faster block a higher priority than the slower block. This means
the faster block is executed before the slower block, which requires special
care to avoid incorrect results.

t0
2 Sec
Task
T = 2s
Block

T = 1s
Faster
Block

T=2s

T=2s
1

t0
1 Sec
Task

t2

T=1s

2

t1
T=1s

1

t2
T=1s

t3

2
T=1s

t4
T=1s

Time
1 The faster block executes a second time prior
to the completion of the slower block.
2 The faster block executes before the slower block.
This timing diagram illustrates two problems:
• Execution of the slower block is split over more than one faster block
interval. In this case the faster task executes a second time before the

1-25

1

Modeling

slower task has completed execution. This means the inputs to the faster
task can have incorrect values some of the time.
• The faster block executes before the slower block (which is backward from
the way a Simulink simulation operates). In this case, the 1 second block
executes first; but the inputs to the faster task have not been computed.
This can cause unpredictable results.
To eliminate these problems, you must insert a Rate Transition block between
the slower and faster blocks.

T = 2s

T = 1s

Tin = 2 Tout = 1

Slower
Block

Faster
Block

Rate Transition

It is assumed that the Rate Transition block is used in its default
(protected/deterministic) mode.
The next figure shows the timing sequence that results with the added Rate
Transition block.

2
2 Sec
Task

RT
update

T=2s

t1

t0
1 Sec
Task

RT
output T=1s

T=1s

Time

1-26

t3

t2

1

1

1
3

RT
update

T=2s

RT
output T=1s

1
T=1s

Scheduling

Three key points about transitions in this diagram (refer to circled numbers):
1 The Rate Transition block output runs in the 1 second task, but at a slower

rate (2 seconds). The output of the Rate Transition block feeds the 1 second
task blocks.
2 The Rate Transition update uses the output of the 2 second task to update

its internal state.
3 The Rate Transition output in the 1 second task uses the state of the Rate

Transition that was updated in the 2 second task.
The first problem is alleviated because the Rate Transition block is updating
at a slower rate and at the priority of the slower block. The input to the Rate
Transition block (which is the output of the slower block) is read after the
slower block completes executing.
The second problem is alleviated because the Rate Transition block executes
at a slower rate and its output does not change during the computation of the
faster block it is driving. The output portion of a Rate Transition block is
executed at the sample rate of the slower block, but with the priority of the
faster block. Since the Rate Transition block drives the faster block and has
effectively the same priority, it is executed before the faster block.
Note This use of the Rate Transition block changes the model. The output
of the slower block is now delayed by one time step compared to the output
without a Rate Transition block.

Single-Tasking and Multitasking Model Execution
• “Introduction” on page 1-28
• “Single-Tasking Execution” on page 1-28
• “Multitasking Execution” on page 1-31

1-27

1

Modeling

Introduction
This section examines how a simple multirate model executes in both real
time and simulation, using a fixed-step solver. It considers the operation of
both SingleTasking and MultiTasking Solver pane tasking modes.
The example model is shown in the next figure. The discussion refers to the
six blocks of the model as A through F, as labeled in the block diagram.
The execution order of the blocks (indicated in the upper right of each block)
has been forced into the order shown by assigning higher priorities to blocks F,
E, and D. The ordering shown is one possible valid execution ordering for this
model. (See “Simulating Dynamic Systems” in the Simulink documentation.)
The execution order is determined by data dependencies between blocks.
In a real-time system, the execution order determines the order in which
blocks execute within a given time interval or task. This discussion treats the
model’s execution order as a given, because it is concerned with the allocation
of block computations to tasks, and the scheduling of task execution.

Note The discussion and timing diagrams in this section are based on
the assumption that the Rate Transition blocks are used in the default
(protected/deterministic) mode, with the Ensure data integrity during
data transfer and Ensure deterministic data transfer (maximum
delay) options on.

Single-Tasking Execution
This section considers the execution of the above model when the solver
Tasking mode is SingleTasking.

1-28

Scheduling

In a single-tasking system, if the Block reduction option on the
Optimization pane is on, fast-to-slow Rate Transition blocks are optimized
out of the model. The default case is shown (Block reduction on), so block B
does not appear in the timing diagrams in this section. For more information,
see “Block reduction”.
The following table shows, for each block in the model, the execution order,
sample time, and whether the block has an output or update computation.
Block A does not have discrete states, and accordingly does not have an
update computation.
Execution Order and Sample Times (Single-Tasking)
Blocks
(in Execution
Order)

Sample Time
(in Seconds)

Output

Update

F

0.1

Y

Y

E

0.1

Y

Y

D

1

Y

Y

A

0.1

Y

N

C

1

Y

Y

Real-Time Single-Tasking Execution. The next figure shows the
scheduling of computations when the generated code is deployed in a real-time
system. The generated program is shown running in real time, under control
of interrupts from a 10 Hz timer.

1-29

1

Modeling

Output:

FEDAC

FEA

(wait)
FEDC

Update:

FEDAC

FEA

(wait)
FE

FE

...

FEDC

...
Time:

0.0

0.1

0.2

...
1.0

At time 0.0, 1.0, and every second thereafter, both the slow and fast blocks
execute their output computations; this is followed by update computations
for blocks that have states. Within a given time interval, output and update
computations are sequenced in block execution order.
The fast blocks execute on every tick, at intervals of 0.1 second. Output
computations are followed by update computations.
The system spends some portion of each time interval (labeled “wait”) idling.
During the intervals when only the fast blocks execute, a larger portion
of the interval is spent idling. This illustrates an inherent inefficiency of
single-tasking mode.
Simulated Single-Tasking Execution. The next figure shows the execution
of the model during the Simulink simulation loop.

Output:

Update:

Time: 0.0

1-30

FEA

FEDAC

FEDC

0.1

FEA

FE

0.2

FEDAC

FE

..

...

F E D C ...

...

...

1.0

Scheduling

Because time is simulated, the placement of ticks represents the iterations
of the simulation loop. Blocks execute in exactly the same order as in the
previous figure, but without the constraint of a real-time clock. Therefore
there is no idle time between simulated sample periods.

Multitasking Execution
This section considers the execution of the above model when the solver
Tasking mode is MultiTasking. Block computations are executed under
two tasks, prioritized by rate:
• The slower task, which gets the lower priority, is scheduled to run every
second. This is called the 1 second task.
• The faster task, which gets higher priority, is scheduled to run 10 times
per second. This is called the 0.1 second task. The 0.1 second task can
preempt the 1 second task.
The following table shows, for each block in the model, the execution order,
the task under which the block runs, and whether the block has an output
or update computation. Blocks A and B do not have discrete states, and
accordingly do not have an update computation.
Task Allocation of Blocks in Multitasking Execution
Blocks
(in Execution
Order)

Task

Output

Update

F

0.1 second task

Y

Y

E

0.1 second task

Y

Y

1-31

1

Modeling

Task Allocation of Blocks in Multitasking Execution (Continued)
Blocks
(in Execution
Order)

Task

Output

Update

D

The Rate Transition block uses
port-based sample times.
Output runs at the output port
sample time under 0.1 second
task.
Update runs at input port sample
time under 1 second task.
For more information on
port-based sample times, see
“Inherit Sample Times” in the
Simulink documentation.

Y

Y

A

0.1 second task

Y

N

B

The Rate Transition block uses
port-based sample times.
Output runs at the output port
sample time under 0.1 second
task.
For more information on
port-based sample times, see
“Inherit Sample Times” in the
Simulink documentation.

Y

N

C

1 second task

Y

Y

Real-Time Multitasking Execution. The next figure shows the scheduling
of computations in MultiTasking solver mode when the generated code is
deployed in a real-time system. The generated program is shown running in
real time, as two tasks under control of interrupts from a 10 Hz timer.

1-32

Scheduling

1 SECOND
Output:

C

C

preemption

preemption

Update:

C

...

DC

...
Time: 0.0

1.0

0.1 SECOND
Output:

FEDAB

Update:

FEA

FE

FEA

FE

(wait)

FEA

FEDAB

FE

...

FE

...
Time: 0.0

0.1

0.2

1.0

1.1

Simulated Multitasking Execution. The next figure shows the Simulink
execution of the same model, in MultiTasking solver mode. In this case,
the Simulink engine runs the blocks in one thread of execution, simulating
multitasking. No preemption occurs.

1-33

1

Modeling

1 SECOND
BLOCKS
Output:

C

C

Update:

DC

DC

...
Time: 0.0

1.0

0.1 SECOND
BLOCKS
Output: F E D A B

Update:

FE

FE

F E DA

FEA

FEA

F

...

FEA

FE

...
Time: 0.0

0.1

0.2

1.0

Handle Asynchronous Events
• “About Asynchronous Events” on page 1-35
• “Handling Interrupts” on page 1-37
• “Rate Transitions and Asynchronous Blocks” on page 1-53
• “Use Timers in Asynchronous Tasks” on page 1-58
• “Create a Customized Asynchronous Library” on page 1-60
• “Import Asynchronous Event Data for Simulation” on page 1-69
• “Asynchronous Support Limitations” on page 1-74

1-34

1.1

Scheduling

About Asynchronous Events
• “Asynchronous Support” on page 1-35
• “Block Library for Wind River Systems VxWorks Real-Time Operating
System” on page 1-35
• “Access the VxWorks Block Library” on page 1-36
• “Generate Code with the VxWorks Library Blocks” on page 1-37
• “Examples and Additional Information” on page 1-37
Asynchronous Support. Simulink Coder models are normally timed from
a periodic interrupt source (for example, a hardware timer). Blocks in a
periodically clocked single-rate model run at a timer interrupt rate (the base
rate of the model). Blocks in a periodically clocked multirate model run at the
base rate or at submultiples of that rate.
Many systems must also support execution of blocks in response to events that
are asynchronous with respect to the periodic timing source of the system. For
example, a peripheral device might signal completion of an input operation
by generating an interrupt. The system must service such interrupts, for
example, by acquiring data from the interrupting device.
This chapter explains how to use blocks to model and generate code for
asynchronous event handling, including servicing of hardware-generated
interrupts, maintenance of timers, asynchronous read and write operations,
and spawning of asynchronous tasks under a real-time operating system
(RTOS). Although the blocks target the Wind River® Systems VxWorks®
Tornado® RTOS, this chapter provides source code analysis and other
information you can use to develop blocks that support asynchronous event
handling for an alternative target RTOS.
Block Library for Wind River Systems VxWorks Real-Time Operating
System. The next figure shows the blocks in the VxWorks block library
(vxlib1).

1-35

1

Modeling

The key blocks in the library are the Async Interrupt and Task Sync blocks.
These blocks are targeted for the VxWorks Tornado operating system. You
can use them, without modification, to support VxWorks applications.
If you want to implement asynchronous support for an RTOS other than
VxWorks RTOS, guidelines and example code are provided that will help
you to adapt the VxWorks library blocks to target your RTOS. This topic is
discussed in “Create a Customized Asynchronous Library” on page 1-60.
The VxWorks library includes blocks you can use to
• Generate interrupt-level code — Async Interrupt block
• Spawn a VxWorks task that calls a function call subsystem — Task Sync
block
• Enable data integrity when transferring data between blocks running as
different tasks — Protected RT block
• Use an unprotected/nondeterministic mode when transferring data
between blocks running as different tasks — Unprotected RT block
The use of protected and unprotected Rate Transition blocks in asynchronous
contexts is discussed in “Rate Transitions and Asynchronous Blocks” on page
1-53. For general information on rate transitions, see “Scheduling” on page
1-4.
Access the VxWorks Block Library. To access the VxWorks library, enter
the MATLAB® command vxlib1.

1-36

Scheduling

Generate Code with the VxWorks Library Blocks. To generate a
VxWorks compatible application from a model containing VxWorks library
blocks, select one of the following targets from the System Target File Browser
associated with the model:
• ert.tlc
Embedded Coder. This target is provided with the Embedded
Coder™ product.
When using the ERT target with VxWorks library blocks, you must
select the Generate an example main program option, and select
VxWorksExample from the Target operating system menu.
• tornado.tlc

Tornado (VxWorks) Real-Time Target.

Examples and Additional Information. Additional information relevant
to the topics in this chapter can be found in
• The rtwdemo_async model. To open this example, type rtwdemo_async
at the MATLAB command prompt.
• The rtwdemo_async_mdlreftop model. To open this example, type
rtwdemo_async_mdlreftop at the MATLAB command prompt.
• “Scheduling” on page 1-4, discusses general multitasking and rate
transition issues for periodic models.
• The Embedded Coder documentation discusses the Embedded Real-Time
(ERT) target, including task execution and scheduling.
• See your VxWorks system documentation for detailed information about
the VxWorks system calls mentioned in this chapter.

Handling Interrupts
• “Generate Interrupt Service Routines” on page 1-37
• “Spawn a Wind River Systems VxWorks Task” on page 1-46
Generate Interrupt Service Routines. To generate an interrupt service
routine (ISR) associated with a specific Wind River Systems VxWorks VME
interrupt level, use the Async Interrupt block. The Async Interrupt block
enables the specified interrupt level and installs an ISR that calls a connected
function call subsystem.

1-37

1

Modeling

You can also use the Async Interrupt block in a simulation. It provides an
input port that can be enabled and connected to a simulated interrupt source.

Connecting the Async Interrupt Block
To generate an ISR, connect an output of the Async Interrupt block to the
control input of
• A function call subsystem
• The input of a Task Sync block
• The input to a Stateflow chart configured for a function call input event
The next figure shows an Async Interrupt block configured to service two
interrupt sources. The outputs (signal width 2) are connected to two function
call subsystems.

Requirements and Restrictions
Note the following requirements and restrictions:
• The Async Interrupt block supports VME interrupts 1 through 7.

1-38

Scheduling

• The Async Interrupt block requires a VxWorks Board Support Package
(BSP) that supports the following VxWorks system calls:

-

sysIntEnable
sysIntDisable
intConnect
intLock
intUnlock
tickGet

Performance Considerations
Execution of large subsystems at interrupt level can have a significant impact
on interrupt response time for interrupts of equal and lower priority in the
system. As a general rule, it is best to keep ISRs as short as possible. Connect
only function call subsystems that contain a small number of blocks to an
Async Interrupt block.
A better solution for large subsystems is to use the Task Sync block to
synchronize the execution of the function call subsystem to a VxWorks
task. The Task Sync block is placed between the Async Interrupt block and
the function call subsystem. The Async Interrupt block then installs the
Task Sync block as the ISR. The ISR releases a synchronization semaphore
(performs a semGive) to the task, and returns immediately from interrupt
level. The task is then scheduled and run by the VxWorks RTOS. See “Spawn
a Wind River Systems VxWorks Task” on page 1-46 for more information.

Using the Async Interrupt Block in Simulation and Code Generation
This section describes a dual-model approach to the development and
implementation of real-time systems that include ISRs. In this approach, you
develop one model that includes a plant and a controller for simulation, and
another model that only includes the controller for code generation. Using a
Simulink library, you can implement changes to both models simultaneously.
The next figure shows how changes made to the plant or controller, both of
which are in a library, are propagated to the models.

1-39

1

Modeling

Plant

Controller

Library: Changes made here
affect both models.

Plant
Interrupt
Block
(Simulation
input enabled)

Interrupt
Block
Simulink Coder library

Interrupt
Block

Model
(for simulation)

Controller
Model
(for code generation)
Controller

Dual-Model Use of Async Interrupt Block for Simulation and Code Generation

A single-model approach is also possible. In this approach, the Plant
component of the model is active only in simulation. During code generation,
the Plant components are effectively switched out of the system and code is
generated only for the interrupt block and controller parts of the model. For
an example of this approach, see the rtwdemo_async model.

Dual-Model Approach: Simulation
The following block diagram shows a simple model that illustrates the
dual-model approach to modeling. During simulation, the Pulse Generator
blocks provide simulated interrupt signals.

1-40

Scheduling

The simulated interrupt signals are routed through the Async Interrupt
block’s input port. Upon receiving a simulated interrupt, the block calls the
connected subsystem.
During simulation, subsystems connected to Async Interrupt block outputs
are executed in order of their VxWorks priority. In the event that two or more
interrupt signals occur simultaneously, the Async Interrupt block executes
the downstream systems in the order specified by their interrupt levels (level
7 gets the highest priority). The first input element maps to the first output
element.
You can also use the Async Interrupt block in a simulation without enabling
the simulation input. In such a case, the Async Interrupt block inherits the
base rate of the model and calls the connected subsystems in order of their
VxWorks priorities. (In effect, in this case the Async Interrupt block behaves
as if all inputs received a 1 simultaneously.)

Dual-Model Approach: Code Generation
In the generated code for the sample model,
• Ground blocks provide input signals to the Environment Controller block
• The Async Interrupt block does not use its simulation input

1-41

1

Modeling

The Ground blocks drive control input of the Environment Controller block so
no code is generated for that signal path. The Simulink Coder code generator
does not generate code for blocks that drive the simulation control input to the
Environment Controller block because that path is not selected during code
generation. However, the sample times of driving blocks for the simulation
input to the Environment Controller block contribute to the sample times
supported in the generated code. To avoid including unnecessary sample
times in the generated code, use the sample times of the blocks driving the
simulation input in the model where generated code is intended.

Standalone functions are installed as ISRs and the interrupt vector table
is as follows:
Offset
192

&isr_num1_vec192()

193

&isr_num2_vec193()

Consider the code generated from this model, assuming that the Async
Interrupt block parameters are configured as shown in the next figure.

1-42

Scheduling

Initialization Code
In the generated code, the Async Interrupt block installs the code in the
Subsystem blocks as interrupt service routines. The interrupt vectors for
IRQ1 and IRQ2 are stored at locations 192 and 193 relative to the base of the
interrupt vector table, as specified by the VME interrupt vector offset(s)
parameter.
Installing an ISR requires two VxWorks calls, int_connect and
sysInt_Enable. The Async Interrupt block inserts these calls in the
model_initialize function, as shown in the following code excerpt.
/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Connect and enable ISR function: isr_num1_vec192 */
if( intConnect(INUM_TO_IVEC(192), isr_num1_vec192, 0) != OK) {
printf("intConnect failed for ISR 1.\n");
}
sysIntEnable(1);

1-43

1

Modeling

/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Connect and enable ISR function: isr_num2_vec193 */
if( intConnect(INUM_TO_IVEC(193), isr_num2_vec193, 0) != OK)
{
printf("intConnect failed for ISR 2.\n");
}
sysIntEnable(2);

The hardware that generates the interrupt is not configured by the Async
Interrupt block. Typically, the interrupt source is a VME I/O board, which
generates interrupts for specific events (for example, end of A/D conversion).
The VME interrupt level and vector are set up in registers or by using jumpers
on the board. You can use the mdlStart routine of a user-written device
driver (S-function) to set up the registers and enable interrupt generation on
the board. You must match the interrupt level and vector specified in the
Async Interrupt block dialog to the level and vector set up on the I/O board.

Generated ISR Code
The actual ISR generated for IRQ1 is listed below.
/* VxWorks Interrupt Block: '/Async Interrupt' */
void isr_num1_vec192(void)
{
int_T lock;
FP_CONTEXT context;
/* Use tickGet() as a portable tick counter example.
A much higher resolution can be achieved with a
hardware counter */
Async_Code_M->Timing.clockTick2 = tickGet();
/* disable interrupts (system is configured as non-ive) */
lock = intLock();
/* save floating point context */
fppSave(&context);

1-44

Scheduling

/* Call the system: /Subsystem A */
Count(0, 0);
/* restore floating point context */
fppRestore(&context);
/* re-enable interrupts */
intUnlock(lock);
}

There are several features of the ISR that should be noted:
• Because of the setting of the Preemption Flag(s) parameter, this ISR is
locked; that is, it cannot be preempted by a higher priority interrupt. The
ISR is locked and unlocked by the VxWorks int_lock and int_unlock
functions.
• The connected subsystem, Count, is called from within the ISR.
• The Count function executes algorithmic (model) code. Therefore, the
floating-point context is saved and restored across the call to Count.
• The ISR maintains its own absolute time counter, which is distinct from
other periodic base rate or subrate counters in the system. Timing data is
maintained for the use of any blocks executed within the ISR that require
absolute or elapsed time.
See “Use Timers in Asynchronous Tasks” on page 1-58 for details.

Model Termination Code
The model’s termination function disables the interrupts:
/* Model terminate function */
void Async_Code_terminate(void)
{
/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Disable interrupt for ISR system: isr_num1_vec192 */
sysIntDisable(1);

1-45

1

Modeling

/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Disable interrupt for ISR system: isr_num2_vec193 */
sysIntDisable(2);
}

Spawn a Wind River Systems VxWorks Task. To spawn an independent
VxWorks task, use the Task Sync block. The Task Sync block is a function
call subsystem that spawns an independent VxWorks task. The task calls the
function call subsystem connected to the output of the Task Sync block.
Typically, the Task Sync block is placed between an Async Interrupt block
and a function call subsystem block or a Stateflow chart. Another example
would be to place the Task Sync block at the output of a Stateflow chart that
has an event, Output to Simulink, configured as a function call.
The Task Sync block performs the following functions:
• An independent task is spawned, using the VxWorks system call
taskSpawn. When the task is activated, it calls the downstream function
call subsystem code. The task is deleted using taskDelete during model
termination.
• A semaphore is created to synchronize the connected subsystem to the
execution of the Task Sync block.
• The spawned task is wrapped in an infinite for loop. In the loop, the
spawned task listens for the semaphore, using semTake. When semTake is
first called, NO_WAIT is specified. This allows the task to determine whether
a second semGive has occurred prior to the completion of the function call
subsystem. This would indicate that the interrupt rate is too fast or the
task priority is too low.
• The Task Sync block generates synchronization code (for example,
semGive()). This code allows the spawned task to run; the task in turn
calls the connected function call subsystem code. The synchronization
code can run at interrupt level. This is accomplished by connecting the
Task Sync block to the output of an Async Interrupt block, which triggers
execution of the Task Sync block within an ISR.
• If blocks in the downstream algorithmic code require absolute time, it can
be supplied either by the timer maintained by the Async Interrupt block,

1-46

Scheduling

or by an independent timer maintained by the task associated with the
Task Sync block.
For an example of how to use the Task Sync block, see the rtwdemo_async
example. The block diagram for the model appears in the next figure. Before
reading the following discussion, open the example model and double-click
the Generate Code button. You can then examine the generated code in the
HTML code generation report produced by the example.

In this model, the Async Interrupt block is configured for VME interrupts 1
and 2, using interrupt vector offsets 192 and 193. Interrupt 2 is connected to
the Task Sync block, which in turn drives the Algorithm subsystem. Consider
the code generated from this model, assuming that the Task Sync block
parameters are configured as shown in the next figure.

1-47

1

Modeling

Initialization Code
The Task Sync block generates initialization code for initialization by
MdlStart, which itself creates and initializes the synchronization semaphore.
It also spawns an independent task (task0).
/* VxWorks Task Block: /S-Function (vxtask1) */
/* Spawn task: Task0 with priority 50 */
if ((*(SEM_ID *)rtwdemo_async_DWork.SFunction_PWORK.SemID =
semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == NULL) {
printf("semBCreate call failed for block Task0.\n");
}
if ((rtwdemo_async_DWork.SFunction_IWORK.TaskID = taskSpawn("Task0",
50.0, VX_FP_TASK, 8192.0, (FUNCPTR)Task0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0)) == ERROR) {
printf("taskSpawn call failed for block Task0.\n");
}

After spawning Task0, MdlStart connects and enables the ISR
(isr_num2_vec193) for interrupt 2:
/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Connect and enable ISR function: isr_num1_vec192 */

1-48

Scheduling

if( intConnect(INUM_TO_IVEC(192), isr_num1_vec192, 0) != OK) {
printf("intConnect failed for ISR 1.\n");
}
sysIntEnable(1);

The ordering of these operations is significant. The task must be spawned
before the interrupt that activates it can be enabled.

Task and Task Synchronization Code
The function Task0, generated by the Task Sync block, runs as a VxWorks
task. The task waits for a synchronization semaphore in an infinite for loop.
If it obtains the semaphore, it updates its task timer and calls the Algorithm
subsystem.
For this example, the Synchronize the data transfer of this task with
the caller task option of the Task Sync block is selected. Therefore, the
timer associated with the Task Sync block (rtM->Timing.clockTick2) is
updated with the value of the timer that is maintained by the Async Interrupt
block (rtM->Timing.clockTick3). Therefore, blocks within the Algorithm
subsystem use timer values based on the time of the most recent interrupt
(not the most recent activation of Task0).
/* VxWorks Task Block: /S-Function (vxtask1) */
/* Spawned with priority: 50 */
void Task0(void)
{
/* Wait for semaphore to be released by system:
rtwdemo_async/Task Sync */
for(;;) {
if (semTake(*(SEM_ID
*)rtwdemo_async_DWork.SFunction_PWORK.SemID,NO_WAIT) !=
ERROR) {
logMsg("Rate for Task Task0() too fast.\n",0,0,0,0,0,0);
#if STOPONOVERRUN
logMsg("Aborting real-time simulation.\n",0,0,0,0,0,0);
semGive(stopSem);
return(ERROR);
#endif

1-49

1

Modeling

} else {
semTake(*(SEM_ID
*)rtwdemo_async_DWork.SFunction_PWORK.SemID,
WAIT_FOREVER);
}
/* Use the upstream clock tick counter for this Task. */
rtwdemo_async_M->Timing.clockTick2 =
rtwdemo_async_M->Timing.clockTick3;

/* Call the system: /Algorithm */
{

/* Output and update for function-call system: '/Algorithm' */

{

uint32_T rt_currentTime = ((uint32_T)rtwdemo_async_M->Timing.clockTick2);
uint32_T rt_elapseTime = rt_currentTime rtwdemo_async_DWork.Algorithm_PREV_T;
rtwdemo_async_DWork.Algorithm_PREV_T = rt_currentTime;

{
int32_T i;

/* DiscreteIntegrator: '/Integrator' */
rtwdemo_async_B.Integrator = rtwdemo_async_DWork.Integrator_DSTATE;
for(i = 0; i < 60; i++) {

/* Sum: '/Sum' */
rtwdemo_async_B.Sum[i] = rtwdemo_async_B.ProtectedRT1[i] + 1.25;
}
}

/* Sum: '/Sum1' */
rtwdemo_async_B.Sum1 = rtwdemo_async_B.Sum[0];
{
int_T i1;

const real_T *u0 = &rtwdemo_async_B.Sum[1];

1-50

Scheduling

for (i1=0; i1 < 59; i1++) {
rtwdemo_async_B.Sum1 += u0[i1];
}
}

{
int32_T i;
if(rtwdemo_async_DWork.ProtectedRT2_ActiveBufIdx) {
for(i = 0; i < 60; i++) {
rtwdemo_async_DWork.ProtectedRT2_Buffer0[i] =
rtwdemo_async_B.Sum[i];
}
rtwdemo_async_DWork.ProtectedRT2_ActiveBufIdx = (boolean_T)0U;
} else {
for(i = 0; i < 60; i++) {
rtwdemo_async_DWork.ProtectedRT2_Buffer1[i] =
rtwdemo_async_B.Sum[i];
}
rtwdemo_async_DWork.ProtectedRT2_ActiveBufIdx = (boolean_T)1U;
}
}

/* Update for DiscreteIntegrator: '/Integrator' */
rtwdemo_async_DWork.Integrator_DSTATE = (real_T)rt_elapseTime *
1.6666666666666666E-002 * rtwdemo_async_B.Sum1 +
rtwdemo_async_DWork.Integrator_DSTATE;
}

The semaphore is granted by the function isr_num2_vec193, which is called
from interrupt level:
/* VxWorks Interrupt Block: '/Async Interrupt' */
void isr_num2_vec193(void)
{

/* Use tickGet() as a portable tick counter example. A much
higher resolution can be achieved with a hardware counter */
rtwdemo_async_M->Timing.clockTick3 = tickGet();

/* Call the system: /Subsystem */

1-51

1

Modeling

/* Output and update for function-call system:
'/Subsystem' */
{

{
int32_T i;
for(i = 0; i < 60; i++) {
if(rtwdemo_async_DWork.ProtectedRT1_ActiveBufIdx) {
rtwdemo_async_B.ProtectedRT1[i] =
rtwdemo_async_DWork.ProtectedRT1_Buffer1[i];
} else {
rtwdemo_async_B.ProtectedRT1[i] =
rtwdemo_async_DWork.ProtectedRT1_Buffer0[i];
}
}
}

/* VxWorks Task Block: /S-Function (vxtask1) */
/* Release semaphore for system task: Task0 */
semGive(*(SEM_ID *)rtwdemo_async_DWork.SFunction_PWORK.SemID);
}
}

The ISR maintains a timer that stores the tick count at the time of interrupt.
This timer is updated before releasing the semaphore that activates Task0.
As this example shows, the Task Sync block generates only a small amount of
interrupt-level code.

Task Termination Code
The Task Sync block also generates the following termination code.
/* Model terminate function */

void rtwdemo_async_terminate(void)
{

1-52

Scheduling

/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Disable interrupt for ISR system: isr_num1_vec192 */
sysIntDisable(1);

/* VxWorks Interrupt Block: '/Async Interrupt' */
/* Disable interrupt for ISR system: isr_num2_vec193 */
sysIntDisable(2);

/* Terminate for function-call system: '/Subsystem' */
/* VxWorks Task Block: /S-Function (vxtask1) */
/* Destroy task: Task0 */
taskDelete(rtwdemo_async_DWork.SFunction_IWORK.TaskID);
}

Rate Transitions and Asynchronous Blocks
• “About Rate Transitions and Asynchronous Blocks” on page 1-53
• “Handle Rate Transitions for Asynchronous Tasks” on page 1-55
• “Handle Multiple Asynchronous Interrupts” on page 1-56
About Rate Transitions and Asynchronous Blocks. Because an
asynchronous function call subsystem can preempt or be preempted by other
model code, an inconsistency arises when more than one signal element is
connected to an asynchronous block. The issue is that signals passed to and
from the function call subsystem can be in the process of being written to or
read from when the preemption occurs. Thus, some old and some new data
is used. This situation can also occur with scalar signals in some cases. For
example, if a signal is a double (8 bytes), the read or write operation might
require two machine instructions.
The Simulink Rate Transition block is designed to deal with preemption
problems that occur in data transfer between blocks running at different
rates. These issues are discussed in “Scheduling” on page 1-4.
You can handle rate transition issues automatically by selecting the
Automatically handle data transfers between tasks option on the Solver
pane of the Configuration Parameters dialog box. This saves you from having
to manually insert Rate Transition blocks to avoid invalid rate transitions,

1-53

1

Modeling

including invalid asynchronous-to-periodic and asynchronous-to-asynchronous
rate transitions, in multirate models. For asynchronous tasks, the Simulink
engine configures inserted blocks for data integrity but not determinism
during data transfers.
For asynchronous rate transitions, the Rate Transition block provides data
integrity, but cannot provide determinism. Therefore, when you insert Rate
Transition blocks explicitly, you must clear the Ensure data determinism
check box in the Block Parameters dialog box.
When you insert a Rate Transition block between two blocks to maintain
data integrity and priorities are assigned to the tasks associated with the
blocks, the Simulink Coder software assumes that the higher priority task can
preempt the lower priority task and the lower priority task cannot preempt
the higher priority task. If the priority associated with task for either block is
not assigned or the priorities of the tasks for both blocks are the same, the
Simulink Coder software assumes that either task can preempt the other task.
Priorities of periodic tasks are assigned by the Simulink engine, in accordance
with the options specified in the Solver options section of the Solver pane
of the Configuration Parameters dialog box. When the Periodic sample
time constraint option field of Solver options is set to Unconstrained, the
model base rate priority is set to 40. Priorities for subrates then increment or
decrement by 1 from the base rate priority, depending on the setting of the
Higher priority value indicates higher task priority option.
You can assign priorities manually by using the Periodic sample time
properties field. The Simulink engine does not assign a priority to
asynchronous blocks. For example, the priority of a function call subsystem
that connects back to an Async Interrupt block is assigned by the Async
Interrupt block.
The Simulink task priority field of the Async Interrupt block specifies
a priority level (required) for every interrupt number entered in the VME
interrupt number(s) field. The priority array sets the priorities of the
subsystems connected to each interrupt.
For the Task Sync block, if the Wind River Systems VxWorks RTOS is the
target, the Higher priority value indicates higher task priority option
should be deselected. The Simulink task priority field specifies the block

1-54

Scheduling

priority relative to connected blocks (in addition to assigning a VxWorks
priority to the generated task code).
The VxWorks library provides two types of rate transition blocks as a
convenience. These are simply preconfigured instances of the built-in
Simulink Rate Transition block:
• Protected Rate Transition block: Rate Transition block that is configured
with the Ensure data integrity during data transfers on and Ensure
deterministic data transfer off.
• Unprotected Rate Transition block: Rate Transition block that is configured
with the Ensure data integrity during data transfers option off.
Handle Rate Transitions for Asynchronous Tasks. For rate transitions
that involve asynchronous tasks, you can maintain data integrity. However,
you cannot achieve determinism. You have the option of using the Rate
Transition block or target-specific rate transition blocks.
Consider the following model, which includes a Rate Transition block.

You can use the Rate Transition block in either of the following modes:
• Maintain data integrity, no determinism
• Unprotected
Alternatively, you can use target-specific rate transition blocks. The following
blocks are available for the VxWorks RTOS:

1-55

1

Modeling

• Protected Rate Transition block (reader)
• Protected Rate Transition block (writer)
• Unprotected Rate Transition block
Handle Multiple Asynchronous Interrupts. Consider the following model,
in which two functions trigger the same subsystem.

The two tasks must have equal priorities. When priorities are the same, the
outcome depends on whether they are firing periodically or asynchronously,
and also on a diagnostic setting. The following table and notes describe
these outcomes:
Supported Sample Time and Priority for Function Call Subsystem with Multiple Triggers

Async
Priority = 1
Async
Priority = 1
Async
Priority = 2
Async
Priority
Unspecified

1-56

Async
Priority = 2

Async
Priority
Unspecified

Supported (1)
Supported (1)
Supported (2)

Periodic
Priority = 1

Periodic
Priority = 2

Scheduling

Supported Sample Time and Priority for Function Call Subsystem with Multiple Triggers
(Continued)

Async
Priority = 1
Periodic
Priority = 1
Periodic
Priority = 2

Async
Priority = 2

Async
Priority
Unspecified

Periodic
Priority = 1

Periodic
Priority = 2

Supported
Supported

1 Control these outcomes using the Tasks with equal priority option in

the Diagnostics pane of the Configuration Parameters dialog box; set this
diagnostic to none if tasks of equal priority cannot preempt each other
in the target system.
2 For this case, the following warning message is issued unconditionally:

The function call subsystem  has multiple asynchronous
triggers that do not specify priority. Data integrity will
not be maintained if these triggers can preempt one another.

Empty cells in the above table represent multiple triggers with differing
priorities, which are unsupported.
The Simulink Coder product provides absolute time management for a
function call subsystem connected to multiple interrupts in the case where
timer settings for TriggerA and TriggerB (time source, resolution) are the
same.
Assume that all of the following conditions are true for the model shown above:
• A function call subsystem is triggered by two asynchronous triggers
(TriggerA and TriggerB) having identical priority settings.
• Each trigger sets the source of time and timer attributes by calling the
functions ssSetTimeSource and ssSetAsyncTimerAttributes.

1-57

1

Modeling

• The triggered subsystem contains a block that needs elapsed or absolute
time (for example, a Discrete Time Integrator).
The asynchronous function call subsystem has one global variable,
clockTick# (where # is the task ID associated with the subsystem). This
variable stores absolute time for the asynchronous task. There are two ways
timing can be handled:
• If the time source is set to SS_TIMESOURCE_BASERATE, the Simulink Coder
code generator generates timer code in the function call subsystem,
updating the clock tick variable from the base rate clock tick. Data integrity
is maintained if the same priority is assigned to TriggerA and TriggerB.
• If the time source is SS_TIMESOURCE_SELF, generated code for both TriggerA
and TriggerB updates the same clock tick variable from the hardware clock.
The word size of the clock tick variable can be set directly or be established
according to the Application lifespan (days) setting and the timer
resolution set by the TriggerA and TriggerB S-functions (which must be the
same). See “Use Timers in Asynchronous Tasks” on page 1-58 and “Control
Memory Allocation for Time Counters” on page 16-9 for more information.

Use Timers in Asynchronous Tasks
An ISR can set a source for absolute time. This is done with the function
ssSetTimeSource, which has the following three options:
• SS_TIMESOURCE_SELF: Each generated ISR maintains its own absolute time
counter, which is distinct from any periodic base rate or subrate counters
in the system. The counter value and the timer resolution value (specified
in the Timer resolution (seconds) parameter of the Async Interrupt
block) are used by downstream blocks to determine absolute time values
required by block computations.
• SS_TIMESOURCE_CALLER: The ISR reads time from a counter maintained by
its caller. Time resolution is thus the same as its caller’s resolution.
• SS_TIMESOURCE_BASERATE: The ISR can read absolute time from the
model’s periodic base rate. Time resolution is thus the same as its base
rate resolution.

1-58

Scheduling

Note The function ssSetTimeSource cannot be called before
ssSetOutputPortWidth is called. If this occurs, the program will come to a
halt and generate an error message.
By default, the counter is implemented as a 32-bit unsigned integer member
of the Timing substructure of the real-time model structure. For any target
that supports the rtModel data structure, when the time data type is not set
by using ssSetAsyncTimeDataType, the counter word size is determined by
the Application lifespan (days) model parameter. As an example (from
ERT target code),
/* Real-time Model Data Structure */
struct _RT_MODEL_elapseTime_exp_Tag {
const char *errorStatus;
/*
* Timing:
* The following substructure contains information regarding
* the timing information for the model.
*/
struct {
uint32_T clockTick1;
uint32_T clockTick2;
} Timing;
};

The example omits unused fields in the Timing data structure (a feature of
ERT target code not found in GRT). For any target that supports the rtModel
data structure, the counter word size is determined by the Application
lifespan (days) model parameter.
By default, the library blocks for the Wind River Systems VxWorks RTOS
set the timer source to SS_TIMESOURCE_SELF and update their counters by
using the system call tickGet. tickGet returns a timer value maintained by
the VxWorks kernel. The maximum word size for the timer is UINT32. The
following VxWorks example for the shows a generated call to tickGet.
/* VxWorks Interrupt Block: '/Async Interrupt' */
void isr_num2_vec193(void)

1-59

1

Modeling

{
/* Use tickGet() as a portable tick counter example. A much
higher resolution can be achieved with a hardware counter */
rtM->Timing.clockTick2 = tickGet();
. . .

The tickGet call is supplied only as an example. It can (and in many
instances should) be replaced by a timing source that has better resolution. If
you are targeting the VxWorks RTOS, you can obtain better timer resolution
by replacing the tickGet call and accessing a hardware timer by using your
BSP instead.
If you are implementing a custom asynchronous block for an RTOS other than
the VxWorks RTOS, you should either generate an equivalent call to the
target RTOS, or generate code to read a timer register on the target hardware.
The default Timer resolution (seconds) parameter of your Async Interrupt
block implementation should be changed to match the resolution of your
target’s timing source.
The counter is updated at interrupt level. Its value represents the tick value
of the timing source at the most recent execution of the ISR. The rate of this
timing source is unrelated to sample rates in the model. In fact, typically it
is faster than the model’s base rate. Select the timer source and set its rate
and resolution based on the expected rate of interrupts to be serviced by the
Async Interrupt block.
For an example of timer code generation, see “Async Interrupt Block
Implementation” on page 1-61.

Create a Customized Asynchronous Library
• “About Implementing Asynchronous Blocks” on page 1-61
• “Async Interrupt Block Implementation” on page 1-61
• “Task Sync Block Implementation” on page 1-66
• “asynclib.tlc Support Library” on page 1-68

1-60

Scheduling

About Implementing Asynchronous Blocks. This section describes how
to implement asynchronous blocks for use with your target RTOS, using the
Async Interrupt and Task Sync blocks as a starting point. (Rate Transition
blocks are target-independent, so you do not need to develop customized rate
transition blocks.)
You can customize the asynchronous library blocks by modifying the block
implementation. These files are
• The block’s underlying S-function MEX-file
• The TLC files that control code generation of the block
In addition, you need to modify the block masks to remove references specific
to the Wind River Systems VxWorks RTOS and to incorporate parameters
required by your target RTOS.
Custom block implementation is an advanced topic, requiring familiarity with
the Simulink MEX S-function format and API, and with the Target Language
Compiler (TLC). These topics are covered in the following documents:
• Simulink topics “What Is an S-Function?”, “Use S-Functions in Models”,
“How S-Functions Work”, and “Implementing S-Functions” describe MEX
S-functions and the S-function API in general.
• The “Inlining S-Functions”, “Inlining C MEX S-Functions”, and “Insert
S-Function Code” on page 14-46 describe how to create a TLC block
implementation for use in code generation.
The following sections discuss the C/C++ and TLC implementations of the
asynchronous library blocks, including required SimStruct macros and
functions in the TLC asynchronous support library (asynclib.tlc).
Async Interrupt Block Implementation. The source files for the Async
Interrupt block are located in matlabroot/rtw/c/tornado/devices:
• vxinterrupt1.c: C MEX-file source code, for use in configuration and
simulation
• vxinterrupt1.tlc: TLC implementation, for use in code generation

1-61

1

Modeling

• asynclib.tlc: library of TLC support functions, called by the TLC
implementation of the block. The library calls are summarized in
“asynclib.tlc Support Library” on page 1-68.

C MEX Block Implementation
Most of the code in vxinterrupt1.c performs ordinary functions that are
not related to asynchronous support (for example, obtaining and validating
parameters from the block mask, marking parameters nontunable, and
passing parameter data to the model.rtw file).
The mdlInitializeSizes function uses special SimStruct macros and
SS_OPTIONS settings that are required for asynchronous blocks, as described
below.
Note that the following macros cannot be called before ssSetOutputPortWidth
is called:
• ssSetTimeSource
• ssSetAsyncTimerAttributes
• ssSetAsyncTimerResolutionEl
• ssSetAsyncTimerDataType
• ssSetAsyncTimerDataTypeEl
• ssSetAsyncTaskPriorities
• ssSetAsyncTaskPrioritiesEl
If any one of the above macros is called before ssSetOutputPortWidth, the
following error message will appear:
SL_SfcnMustSpecifyPortWidthBfCallSomeMacro {
S-function '%s' in '%'
must set output port %d width using
ssSetOutputPortWidth before calling macro %s
}

1-62

Scheduling

ssSetAsyncTimerAttributes
ssSetAsyncTimerAttributes declares that the block requires a timer,
and sets the resolution of the timer as specified in the Timer resolution
(seconds) parameter.

The function prototype is
ssSetAsyncTimerAttributes(SimStruct *S, double res)

where
• S is a Simstruct pointer.
• res is the Timer resolution (seconds) parameter value.
The following code excerpt shows the call to ssSetAsyncTimerAttributes.
/* Setup Async Timer attributes */
ssSetAsyncTimerAttributes(S,mxGetPr(TICK_RES)[0]);

ssSetAsyncTaskPriorities
ssSetAsyncTaskPriorities sets the Simulink task priority for blocks

executing at each interrupt level, as specified in the block’s Simulink task
priority field.
The function prototype is
ssSetAsyncTaskPriorities(SimStruct *S, int numISRs,
int *priorityArray)

where
• S is a SimStruct pointer.
• numISRs is the number of interrupts specified in the VME interrupt
number(s) parameter.
• priorityarray is an integer array containing the interrupt numbers
specified in the VME interrupt number(s) parameter.
The following code excerpt shows the call to ssSetAsyncTaskPriorities:

1-63

1

Modeling

/* Setup Async Task Priorities */
priorityArray = malloc(numISRs*sizeof(int_T));
for (i=0; i Input must be a
comma-separated list of tables, as described in “Enable Data Import”.
• The table corresponding to the input port outputting asynchronous events
must be a column vector containing time values for the asynchronous
events.

-

The time vector of the asynchronous events must be of double data type
and monotonically increasing.

-

All time data must be integer multiples of the model step size.
To specify multiple function calls at a given time step, you must repeat
the time value accordingly. In other words, if you wish to specify three
asynchronous events at t = 1 and two events at t = 9, then you must list 1
three times and 9 twice in your time vector. ( t = [1 1 1 9 9])

• The table corresponding to normal data input port can be of any other
supported format as described in “Enable Data Import”.
Example. In this model, a function-call subsystem is used to track the total
number of asynchronous events and to multiply a set of inputs by 2.

1-70

Scheduling

1-71

1

Modeling

1 To input data via the Configuration Parameters dialog box,
a Select Simulation > Configuration Parameters > Data

Import/Export.
b Select the Input parameter.
c For this example, enter the following command in the MATLAB window:

>> t = [1 1 5 9 9 9]', u = [[0:10]' [0:10]']

Alternatively, you can enter the data as t, tu in the Data Import/Export
pane:

1-72

Scheduling

Here, t is a column vector containing the times of asynchronous events
for Inport block In1 while tu is a table of input values versus time for
Inport block In2.
2 By default, the Time and Output options are selected and the output

variables are named tout and yout.
3 Simulate the model.
4 Display the output by entering [tout yout] at the MATLAB command

line and obtain:
ans =
0
1
2
3
4
5
6
7
8
9
10

0
2
2
2
2
3
3
3
3
6
6

-1
2
2
2
2
10
10
10
10
18
18

Here the first column contains the simulation times.

1-73

1

Modeling

The second column represents the output of Out1 — the total number of
asynchronous events. Since the function-call subsystem is triggered twice
at t = 1, the output is 2. It is not called again until t = 5, and so does not
increase to 3 until then. Finally, it is called three times at 9, so it increases
to 6.
The third column contains the output of Out2 obtained by multiplying the
input value at each asynchronous event time by 2. At any other time, the
output is held at its previous value

Asynchronous Support Limitations
• “Asynchronous Task Priority” on page 1-74
• “Convert an Asynchronous Subsystem into a Model Reference” on page 1-74
Asynchronous Task Priority. The Simulink product does not simulate
asynchronous task behavior. Although you can specify a task priority for an
asynchronous task represented in a model with the Task Sync block, the
priority setting is for code generation purposes only and is not honored during
simulation.
Convert an Asynchronous Subsystem into a Model Reference. You
can use the Asynchronous Task Specification block to specify an asynchronous
function-call input to a model reference. However, you must convert the
Async Interrupt and Function-Call blocks into a subsystem and then convert
the subsystem into a model reference.
Following is an example with step-by-step instructions for conversion.

1-74

Scheduling

1 Convert the Async Interrupt and Count blocks into a subsystem. Select

both blocks and right-click Count. From the menu, select Subsystem &
Model Reference > Create Subsystem from Selection.

2 To prepare for converting the new subsystem to a Model block, set

the following configuration parameters in the top model. Open the
Configuration Parameters dialog box.
• If you are simulating in Normal mode, then you must make the following
change. From the Optimization node, navigate to the Signals and
Parameters pane. Under Simulation and code generation, select the
Inline parameters option.
• From the Diagnostics node, navigate to the Sample Time pane. Then set
Multitask rate transition to error and Multitask conditionally
executed subsystem to error.
• Under Diagnostics, navigate to the Data Validity pane and set the
Multitask data store option to error and set the Underspecified
initialization detection to Simplified. If your model is large
or complex, in the Model Advisor, run the Check consistency of
initialization parameters for Outport and Merge blocks check and
make suggested changes.
• Under Diagnostics, navigate to the Connectivity pane. Set Mux
blocks used to create bus signals, Bus signal treated as

1-75

1

Modeling

vector, and Invalid function-call connection to error. Also set
Context-dependent inputs to Enable All.
3 Convert the subsystem to an atomic subsystem. Select Edit > Subsystem

Parameters > Treat as atomic unit.

4 Convert the subsystem to a Model block. Right-click the subsystem

and select Subsystem & Model Reference > Convert Subsystem
to > Referenced Model. A window opens with a model reference block
inside of it.
5 Replace the subsystem in the top model with the new model reference block.

6 Move the Async Interrupt block from the model reference to the top model,

before the model reference block.

1-76

Scheduling

7 Insert an Asynchronous Task Specification block in the model reference.

Set the priority of the Asynchronous Task Specification block. (For more
information on setting the priority, see Asynchronous Task Specification.)

8 In the model reference, double-click the input port to open its Source Block

Parameters dialog box. Click theSignal Attributes tab and select the
Output function call option. Click OK.

1-77

1

Modeling

9 Save your model and then perform Simulation > Update Diagram to

verify your settings.

1-78

Scheduling

Timers
• “Absolute and Elapsed Time Computation” on page 1-79
• “APIs for Accessing Timers” on page 1-81
• “Elapsed Timer Code Generation Example” on page 1-85
• “Limitations on the Use of Absolute Time” on page 1-88

Absolute and Elapsed Time Computation
• “About Timers” on page 1-79
• “Timers for Periodic and Asynchronous Tasks” on page 1-80
• “Allocation of Timers” on page 1-80
• “Integer Timers in Generated Code” on page 1-81
• “Elapsed Time Counters in Triggered Subsystems” on page 1-81
About Timers. Certain blocks require the value of either absolute time
(that is, the time from the start of program execution to the present time) or
elapsed time (for example, the time elapsed between two trigger events).
Targets that support the real-time model (rtModel) data structure provide
efficient time computation services to blocks that request absolute or elapsed
time. Absolute and elapsed timer features include
• Timers are implemented as unsigned integers in generated code.
• In multirate models, at most one timer is allocated per rate. If no blocks
executing at a given rate require a timer, no timer is allocated to that rate.
This minimizes memory allocated for timers and significantly reduces
overhead involved in maintaining timers.

1-79

1

Modeling

• Allocation of elapsed time counters for use of blocks within triggered
subsystems is minimized, further reducing memory usage and overhead.
• The Simulink Coder product provides S-function and TLC APIs that let
your S-functions access timers, in both simulation and code generation.
• The word size of the timers is determined by a user-specified maximum
counter value, Application lifespan (days). If you specify this value,
timers will not overflow. For more information, see “Control Memory
Allocation for Time Counters” on page 16-9.
See “Limitations on the Use of Absolute Time” on page 1-88 and “Blocks that
Depend on Absolute Time” on page 1-89 for more information about absolute
time and the restrictions that it imposes.
Timers for Periodic and Asynchronous Tasks. This chapter discusses
timing services provided for blocks executing within periodic tasks (that is,
tasks running at the model’s base rate or subrates).
The Simulink Coder product also provides timer support for blocks whose
execution is asynchronous with respect to the periodic timing source of the
model. See the following sections of the Asynchronous Support chapter:
• “Use Timers in Asynchronous Tasks” on page 1-58
• “Create a Customized Asynchronous Library” on page 1-60
Allocation of Timers. If you create or maintain an S-Function block that
requires absolute or elapsed time data, it must register the requirement (see
“APIs for Accessing Timers” on page 1-81). In multirate models, timers are
allocated on a per-rate basis. For example, consider a model structured as
follows:
• There are three rates, A, B, and C, in the model.
• No blocks running at rate B require absolute or elapsed time.
• Two blocks running at rate C register a requirement for absolute time.
• One block running at rate A registers a requirement for absolute time.
In this case, two timers are generated, running at rates A and C respectively.
The timing engine updates the timers as the tasks associated with rates A

1-80

Scheduling

and C execute. Blocks executing at rates A and C obtain time data from the
timers associated with rates A and C.
Integer Timers in Generated Code. In the generated code, timers for
absolute and elapsed time are implemented as unsigned integers. The default
size is 64 bits. This is the amount of memory allocated for a timer if you
specify a value of inf for the Application lifespan (days) parameter. For
an application with a sample rate of 1000 MHz, a 64-bit counter will not
overflow for more than 500 years. See “Use Timers in Asynchronous Tasks”
on page 1-58 and “Control Memory Allocation for Time Counters” on page
16-9 for more information.
Elapsed Time Counters in Triggered Subsystems. Some blocks, such
as the Discrete-Time Integrator block, perform computations requiring the
elapsed time (delta T) since the previous block execution. Blocks requiring
elapsed time data must register the requirement (see “APIs for Accessing
Timers” on page 1-81). A triggered subsystem then allocates and maintains a
single elapsed time counter if required. This timer functions at the subsystem
level, not at the individual block level. The timer is generated if the triggered
subsystem (or any unconditionally executed subsystem within the triggered
subsystem) contains one or more blocks requiring elapsed time data.
Note If you are using simplified initialization mode, elapsed time is always
reset on first execution after becoming enabled, whether or not the subsystem
is configured to reset on enable. For more information, see “Underspecified
initialization detection” in the Simulink documentation.

APIs for Accessing Timers
• “About Timer APIs” on page 1-82
• “C API for S-Functions” on page 1-82
• “TLC API for Code Generation” on page 1-84

1-81

1

Modeling

About Timer APIs. This section describes APIs that let your S-functions
take advantage of the efficiencies offered by the absolute and elapsed timers.
SimStruct macros are provided for use in simulation, and TLC functions are
provided for inlined code generation. Note that
• To generate and use the new timers as described above, your
S-functions must register the need to use an absolute or elapsed
timer by calling ssSetNeedAbsoluteTime or ssSetNeedElapseTime in
mdlInitializeSampleTime.
• Existing S-functions that read absolute time but do not register by using
these macros will continue to operate as expected, but will generate
old-style, less efficient code.
C API for S-Functions. The SimStruct macros described in this section
provide access to absolute and elapsed timers for S-functions during
simulation.
In the functions below, the SimStruct *S argument is a pointer to the
simstruct of the calling S-function.
• void ssSetNeedAbsoluteTime(SimStruct *S, boolean b): if b is TRUE,
registers that the calling S-function requires absolute time data, and
allocates an absolute time counter for the rate at which the S-function
executes (if such a counter has not already been allocated).
• int ssGetNeedAbsoluteTime(SimStruct *S): returns 1 if the S-function
has registered that it requires absolute time.
• double ssGetTaskTime(SimStruct *S, tid): read absolute time
for a given task with task identifier tid. ssGetTaskTime operates
transparently, regardless of whether or not you use the new timer features.
ssGetTaskTime is documented in the SimStruct Functions chapter of the
Simulink documentation.
• void ssSetNeedElapseTime(SimStruct *S, boolean b): if b is TRUE,
registers that the calling S-function requires elapsed time data, and
allocates an elapsed time counter for the triggered subsystem in which the
S-function executes (if such a counter has not already been allocated). See
also “Elapsed Time Counters in Triggered Subsystems” on page 1-81.

1-82

Scheduling

• int ssGetNeedElapseTime(SimStruct *S): returns 1 if the S-function
has registered that it requires elapsed time.
• void ssGetElapseTime(SimStruct *S, (double *)elapseTime):
returns, to the location pointed to by elapseTime, the value (as a double)
of the elapsed time counter associated with the S-function.
• void ssGetElapseTimeCounterDtype(SimStruct *S, (int *)dtype):
returns the data type of the elapsed time counter associated with the
S-function to the location pointed to by dtype. This function is intended for
use with the ssGetElapseTimeCounter function (see below).
• void ssGetElapseResolution(SimStruct *S, (double *)resolution):
returns the resolution (that is, the sample time) of the elapsed time counter
associated with the S-function to the location pointed to by resolution.
This function is intended for use with the ssGetElapseTimeCounter
function (see below).
• void ssGetElapseTimeCounter(SimStruct *S, (void *)elapseTime):
This function is provided for the use of blocks that require the elapsed time
values for fixed-point computations. ssGetElapseTimeCounter returns,
to the location pointed to by elapseTime, the integer value of the elapsed
time counter associated with the S-function. If the counter size is 64 bits,
the value is returned as an array of two 32-bit words, with the low-order
word stored at the lower address.
To determine how to access the returned counter value, obtain the data
type of the counter by calling ssGetElapseTimeCounterDtype, as in the
following code:
int
*y_dtype;
ssGetElapseTimeCounterDtype(S, y_dtype);
switch(*y_dtype) {
case SS_DOUBLE_UINT32:
{
uint32_T dataPtr[2];
ssGetElapseTimeCounter(S, dataPtr);
}
break;
case SS_UINT32:
{
uint32_T dataPtr[1];

1-83

1

Modeling

ssGetElapseTimeCounter(S, dataPtr);
}
break;
case SS_UINT16:
{
uint16_T dataPtr[1];
ssGetElapseTimeCounter(S, dataPtr);
}
break;
case SS_UINT8:
{
uint8_T dataPtr[1];
ssGetElapseTimeCounter(S, dataPtr);
}
break;
case SS_DOUBLE:
{
real_T dataPtr[1];
ssGetElapseTimeCounter(S, dataPtr);
}
break;
default:
ssSetErrorStatus(S, "Invalid data type for elaspe time
counter");
break;
}

If you want to use the actual elapsed time, issue a call to the
ssGetElapseTime function to access the elapsed time directly. You do not
need to get the counter value and then calculate the elapsed time.
double *y_elapseTime;
.
.
.
ssGetElapseTime(S, elapseTime)

TLC API for Code Generation. The following TLC functions support
elapsed time counters in generated code when you inline S-functions by
writing TLC scripts for them.

1-84

Scheduling

• LibGetTaskTimeFromTID(block): Generates code to read the absolute
time for the task in which block executes.
LibGetTaskTimeFromTID is documented with other sample time functions
in the TLC Function Library Reference pages of the Target Language
Compiler documentation.

Note Do not use LibGetT for this purpose. LibGetT always reads the base
rate (tid 0) timer. If LibGetT is called for a block executing at a subrate,
the wrong timer is read, causing serious errors.
• LibGetElapseTime(system): Generates code to read the elapsed time
counter for system. (system is the parent system of the calling block.) See
“Elapsed Timer Code Generation Example” on page 1-85 for an example
of code generated by this function.
• LibGetElapseTimeCounter(system): Generates code to read the integer
value of the elapsed time counter for system. (system is the parent system
of the calling block.) This function should be used in conjunction with
LibGetElapseTimeCounterDtypeId and LibGetElapseTimeResolution.
(See the discussion of ssGetElapseTimeCounter above.)
• LibGetElapseTimeCounterDtypeId(system): Generates code that returns
the data type of the elapsed time counter for system. (system is the parent
system of the calling block.)
• LibGetElapseTimeResolution(system): Generates code that returns the
resolution of the elapsed time counter for system. (system is the parent
system of the calling block.)

Elapsed Timer Code Generation Example
This section shows a simple model illustrating how an elapsed time counter is
generated and used by a Discrete-Time Integrator block within a triggered
subsystem. The following block diagrams show the model elapseTime_exp,
which contains subsystem Amplifier, which includes a Discrete-Time
Integrator block.

1-85

1

Modeling

elapseTime_exp Model

Amplifier Subsystem

A 32-bit timer for the base rate (the only rate in this model) is defined within
the rtModel structure, as follows, in model.h.
-/*
* Timing:
* The following substructure contains information regarding
* the timing information for the model.
*/
struct {
time_T stepSize;
uint32_T clockTick0;
uint32_T clockTickH0;
time_T stepSize0;
time_T tStart;
time_T tFinal;
time_T timeOfLastOutput;
void *timingData;
real_T *varNextHitTimesList;

1-86

Scheduling

SimTimeStep simTimeStep;
boolean_T stopRequestedFlag;
time_T *sampleTimes;
time_T *offsetTimes;
int_T *sampleTimeTaskIDPtr;
int_T *sampleHits;
int_T *perTaskSampleHits;
time_T *t;
time_T sampleTimesArray[1];
time_T offsetTimesArray[1];
int_T sampleTimeTaskIDArray[1];
int_T sampleHitArray[1];
int_T perTaskSampleHitsArray[1];
time_T tArray[1];
} Timing;

Had the target been ERT instead of GRT, the Timing structure would have
been pruned to contain only the data required by the model, as follows:
/* Real-time Model Data Structure */ (for ERT!)
struct _RT_MODEL_elapseTime_exp_Tag {
/*
* Timing:
* The following substructure contains information regarding
* the timing information for the model.
*/
struct {
uint32_T clockTick0;
} Timing;
};

Storage for the previous-time value of the Amplifier subsystem
(Amplifier_PREV_T) is allocated in the D_Work(states) structure in model.h.
typedef struct D_Work_elapseTime_exp_tag {
real_T DiscreteTimeIntegrator_DSTATE; /* '/Discrete-Time
Integrator' */
int32_T clockTickCounter;
/* '/Pulse Generator' */
uint32_T Amplifier_PREV_T;
/* '/Amplifier' */
} D_Work_elapseTime_exp;

1-87

1

Modeling

These structures are declared in model.c:
/* Block states (auto storage) */
D_Work_elapseTime_exp elapseTime_exp_DWork;
.
.
.
/* Real-time model */
rtModel_elapseTime_exp elapseTime_exp_M_;
rtModel_elapseTime_exp *elapseTime_exp_M = &elapseTime_exp_M_;

The elapsed time computation is performed as follows within the model_step
function:
/* Output and update for trigger system: '/Amplifier' */
uint32_T rt_currentTime =
((uint32_T)elapseTime_exp_M->Timing.clockTick0);
uint32_T rt_elapseTime = rt_currentTime elapseTime_exp_DWork.Amplifier_PREV_T;
elapseTime_exp_DWork.Amplifier_PREV_T = rt_currentTime;

As shown above, the elapsed time is maintained as a state of the triggered
subsystem. The Discrete-Time Integrator block finally performs its output
and update computations using the elapsed time.
/* DiscreteIntegrator: '/Discrete-Time Integrator' */
OUTPUT = elapseTime_exp_DWork.DiscreteTimeIntegrator_DSTATE;
/* Update for DiscreteIntegrator: '/Discrete-Time Integrator'*/
elapseTime_exp_DWork.DiscreteTimeIntegrator_DSTATE += 0.3 *
(real_T)rt_elapseTime * 1.5 ;

Because the triggered subsystem maintains the elapsed time, the TLC
implementation of the Discrete-Time Integrator block needs only a single call
to LibGetElapseTime to access the elapsed time value.

Limitations on the Use of Absolute Time
• “About Absolute Time Limitations” on page 1-89
• “Logging Absolute Time” on page 1-89

1-88

Scheduling

• “Absolute Time in Stateflow Charts” on page 1-89
• “Blocks that Depend on Absolute Time” on page 1-89
About Absolute Time Limitations. Absolute time is the time that has
elapsed from the beginning of program execution to the present time, as
distinct from elapsed time, the interval between two events. See “Absolute
and Elapsed Time Computation” on page 1-79 for more information.
When you design an application that is intended to run indefinitely, you must
take care when logging time values, or using charts or blocks that depend
on absolute time. If the value of time reaches the largest value that can
be represented by the data type used by the timer to store time, the timer
overflows and the logged time or block output is incorrect.
If your target uses rtModel, you can avoid timer overflow by specifying a
value for the Application life span parameter. See “Integer Timers in
Generated Code” on page 1-81 for more information.
Logging Absolute Time. If you log time values by opening the Configuration
Parameters dialog box and enabling Data Import/Export > Save to
workspace > Time, your model uses absolute time.
Absolute Time in Stateflow Charts. Every Stateflow chart that uses time
is dependent on absolute time. The only way to eliminate the dependency is to
change the Stateflow chart to not use time.
Blocks that Depend on Absolute Time. The following Simulink blocks
depend on absolute time:
• Backlash
• Chirp Signal
• Clock
• Derivative
• Digital Clock
• Discrete-Time Integrator (only when used in triggered subsystems)
• From File

1-89

1

Modeling

• From Workspace
• Pulse Generator
• Ramp
• Rate Limiter
• Repeating Sequence
• Signal Generator
• Sine Wave (only when the Sine type parameter is set to Time-based)
• Step
• To File
• To Workspace (only when logging to StructureWithTime format)
• Transport Delay
• Variable Time Delay
• Variable Transport Delay
In addition to the Simulink blocks above, blocks in other blocksets may depend
on absolute time. See the documentation for the blocksets that you use.

Configure Scheduling
• “Configure Start and Stop Times” on page 1-90
• “Configure the Solver Type” on page 1-91
• “Configure the Tasking Mode” on page 1-91
For details about solver options, see “Solver Pane” in the Simulink reference
documentation.

Configure Start and Stop Times
The Stop time must be greater than or equal to the Start time. If the stop
time is zero, or if the total simulation time (Stop minus Start) is less than
zero, the generated program runs for one step. If the stop time is set to inf,
the generated program runs indefinitely.

1-90

Scheduling

When using the GRT or Wind River Systems Tornado targets, you can
override the stop time when running a generated program from the Microsoft
Windows command prompt or UNIX1 command line. To override the stop
time that was set during code generation, use the -tf switch.
model -tf n

The program runs for n seconds. If n = inf, the program runs indefinitely.
Certain blocks have a dependency on absolute time. If you are designing a
program that is intended to run indefinitely (Stop time = inf), and your
generated code does not use the rtModel data structure (that is, it uses
simstructs instead), you must not use these blocks. See “Limitations on the
Use of Absolute Time” on page 1-88 for a list of blocks that can potentially
overflow timers.
If you know how long an application that depends on absolute time needs to
run, you can prevent the timers from overflowing and force the use of optimal
word sizes by specifying the Application lifespan (days) parameter on the
Optimization pane. See “Control Memory Allocation for Time Counters” on
page 16-9 for details.

Configure the Solver Type
For code generation, you must configure a model to use a fixed-step solver for
all targets except the S-function and RSim targets. You can configure the
S-function and RSim targets with a fixed-step or variable-step solver.

Configure the Tasking Mode
The Simulink Coder product supports both single-tasking and multitasking
modes for periodic sample times. See “Scheduling” on page 1-4 for details.

1. UNIX® is a registered trademark of The Open Group in the United States and other
countries.

1-91

1

Modeling

Supported Products and Block Usage
In this section...
“Related Products” on page 1-92
“Simulink Built-In Blocks That Support Code Generation” on page 1-94
“Block Set Support for Code Generation” on page 1-116
“Fixed-Point Tool Data Type Override” on page 1-116
“Data Type Overrides Unavailable for Most Blocks in Embedded Targets
and Desktop Targets” on page 1-116

Related Products
The following table summarizes MathWorks® products that extend and
complement Simulink Coder software. For information about these and other
MathWorks products, see www.mathworks.com.

1-92

Product

Extends Code Generation Capabilities for
...

Aerospace Blockset™

Aircraft, spacecraft, rocket, propulsion
systems, and unmanned airborne vehicles

Communications System Toolbox™

Physical layer of communication systems

Computer Vision System Toolbox™

Video processing, image processing, and
computer vision systems

Control System Toolbox™

Linear control systems

DSP System Toolbox™

Signal processing systems

Embedded Coder

Embedded systems, on-target rapid prototyping
boards, microprocessors in mass production,
and real-time simulators

Fuzzy Logic Toolbox™

System designs based on fuzzy logic

Gauges Blockset™

Linking generated code executing on a target
system with graphical instrumentation in a
Simulink model

Supported Products and Block Usage

Product

Extends Code Generation Capabilities for
...

Model-Based Calibration Toolbox™

Developing processes for systematically
identifying optimal balance of engine
performance, emissions, and fuel economy, and
reusing statistical models for control design,
hardware-in-the-loop testing, or powertrain
simulation

Model Predictive Control Toolbox™

Controllers that optimize performance of
multi-input and multi-output systems that are
subject to input and output constraints

Real-Time Windows Target™

Rapid prototyping or hardware-in-the-loop
simulation of control system and signal
processing algorithms

SimDriveline™

Driveline (drivetrain) systems

SimElectronics®

Electronic and electromechanical systems

SimHydraulics®

Hydraulic power and control systems

SimMechanics™

Three-dimensional mechanical systems

SimPowerSystems™

Systems that generate, transmit, distribute,
and consume electrical power

Simscape™

Systems spanning mechanical, electrical,
hydraulic, and other physical domains as
physical networks

Simulink Fixed Point™

Control and signal processing systems
implemented with fixed-point arithmetic

Simulink 3D Animation™

Systems with 3D visualizations

Simulink Design Optimization™

Systems requiring maximum overall system
performance

Simulink Report Generator™

Automatically generating project
documentation in a standard format

1-93

1

Modeling

Product

Extends Code Generation Capabilities for
...

Simulink Verification and Validation™

Applications requiring automated
requirements tracing, model standards
compliance checking, and test harness
generation

System Identification Toolbox™

Systems constructed from measured
input-output data
Support exceptions:
• Nonlinear IDNLGREY Model, IDDATA
Source, IDDATA Sink, and estimator blocks
• Nonlinear ARX models that contain custom
regressors
• neuralnet nonlinearities
• customnet nonlinearities

Vehicle Network Toolbox™

Support exception: CAN Configuration, CAN
Receive, and CAN Transmit blocks in the CAN
Communication library

xPC Target™

Rapid control prototyping,
hardware-in-the-loop (HIL) simulation, and
other real-time testing applications

xPC Target Embedded Option™

Deploying real-time embedded systems on a PC
for production, data acquisition, calibration,
and testing applications

Simulink Built-In Blocks That Support Code
Generation
The following tables summarize Simulink Coder and Embedded Coder
support for Simulink blocks. There is a table for each block library. For
each block, the second column indicates any support notes, which give
information about the block for code generation. For more detail, including

1-94

Supported Products and Block Usage

data types each block supports, in the MATLAB Command Window, type
showblockdatatypetable, or consult the block reference pages.
• Additional Math and Discrete: Additional Discrete on page 1-96
• Additional Math and Discrete: Increment/Decrement on page 1-97
• Continuous on page 1-97
• Discontinuities on page 1-98
• Discrete on page 1-99
• Logic and Bit Operations on page 1-101
• Lookup Tables on page 1-102
• Math Operations on page 1-103
• Model Verification on page 1-106
• Model-Wide Utilities on page 1-107
• Ports & Subsystems on page 1-107
• Signal Attributes on page 1-108
• Signal Routing on page 1-109
• Sinks on page 1-110
• Sources on page 1-112
• User-Defined on page 1-115

1-95

1

Modeling

Additional Math and Discrete: Additional Discrete
Block

Support Notes

Fixed-Point State-Space

The Simulink Coder software does not explicitly
group primitive blocks that constitute a
nonatomic masked subsystem block in the
generated code. This flexibility allows for more
efficient code generation. In certain cases, you
can achieve grouping by configuring the masked
subsystem block to execute as an atomic unit by
selecting the Treat as atomic unit option.

Transfer Fcn Direct Form II

• The Simulink Coder software does not
explicitly group primitive blocks that
constitute a nonatomic masked subsystem
block in the generated code. This flexibility
allows for more efficient code generation. In
certain cases, you can achieve grouping by
configuring the masked subsystem block to
execute as an atomic unit by selecting the
Treat as atomic unit option.

Transfer Fcn Direct Form II Time Varying
Unit Delay Enabled
Unit Delay Enabled External IC
Unit Delay Enabled Resettable
Unit Delay Enabled Resettable External IC
Unit Delay External IC
Unit Delay Resettable
Unit Delay Resettable External IC
Unit Delay With Preview Enabled
Unit Delay With Preview Enabled Resettable
Unit Delay With Preview Enabled Resettable
External RV
Unit Delay With Preview Resettable
Unit Delay With Preview Resettable
External RV

1-96

• Generated code might rely on memcpy or
memset (string.h).

Supported Products and Block Usage

Additional Math and Discrete: Increment/Decrement
Block

Support Notes

Decrement Real World

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Decrement Stored Integer

Decrement Time To Zero

Supports code generation.

Decrement To Zero

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Increment Real World
Increment Stored Integer

Continuous
Block

Support Notes

Derivative

Not recommended for production-quality code. Relates to resource
limits and restrictions on speed and memory often found in
embedded systems. The code generated can contain dynamic
allocation and freeing of memory, recursion, additional memory
overhead, and widely-varying execution times. While the code
is functionally valid and generally acceptable in resource-rich
environments, smaller embedded targets often cannot support
such code.

Integrator
Integrator Limited
PID Controller
PID Controller (2DOF)
Second-Order Integrator
Second-Order Integrator
Limited
State-Space
Transfer Fcn
Transport Delay
Variable Time Delay

In general, consider using the Simulink Model Discretizer to
map continuous blocks into discrete equivalents that support
production code generation. To start the Model Discretizer,
select Analysis > Control Design > Model Discretizer. One
exception is the Second-Order Integrator block because, for
this block, the Model Discretizer produces an approximate
discretization.

1-97

1

Modeling

Continuous (Continued)
Block

Support Notes

Variable Transport Delay
Zero-Pole
Discontinuities

1-98

Block

Support Notes

Backlash

Supports code generation.

Coulomb and Viscous
Friction

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Dead Zone

Supports code generation.

Dead Zone Dynamic

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Hit Crossing

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Quantizer

Supports code generation.

Rate Limiter

Cannot use inside a triggered subsystem hierarchy.

Supported Products and Block Usage

Discontinuities (Continued)
Block

Support Notes

Rate Limiter Dynamic

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Relay

Support code generation.

Saturation
Saturation Dynamic
Wrap To Zero

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Discrete
Block

Support Notes

Delay

Supports code generation.

Difference

• The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.
• Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code.

1-99

1

Modeling

Discrete (Continued)
Block

Support Notes
Usually, blocks evolve toward being suitable for production
code. Thus, blocks suitable for production code remain suitable.

Discrete Derivative

• Generated code might rely on memcpy or memset (string.h).
• Depends on absolute time when used inside a triggered
subsystem hierarchy.

Discrete Filter

Support code generation.

Discrete FIR Filter
PID Controller

• Generated code might rely on memcpy or memset (string.h).

PID Controller (2DOF)

• Depends on absolute time when used inside a triggered
subsystem hierarchy.

Discrete State-Space

Generated code might rely on memcpy or memset (string.h).

Discrete Transfer Fcn
Discrete Zero-Pole
Discrete-Time Integrator

Depends on absolute time when used inside a triggered subsystem
hierarchy.

First-Order Hold

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Memory

Support code generation.

Tapped Delay

1-100

Supported Products and Block Usage

Discrete (Continued)
Block

Support Notes

Transfer Fcn First Order
Transfer Fcn Real Zero

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Unit Delay

Generated code might rely on memcpy or memset (string.h).

Zero-Order Hold

Supports code generation.

Transfer Fcn Lead or Lag

Logic and Bit Operations
Block

Support Notes

Bit Clear

Support code generation.

Bit Set
Bitwise Operator
Combinatorial Logic
Compare to Constant
Compare to Zero
Detect Change

Generated code might rely on memcpy or memset (string.h).

Detect Decrease
Detect Fall Negative
Detect Fall Nonpositive
Detect Increase
Detect Rise Nonnegative
Detect Rise Positive

1-101

1

Modeling

Logic and Bit Operations (Continued)
Block

Support Notes

Extract Bits

Support code generation.

Interval Test
Interval Test Dynamic
Logical Operator
Relational Operator
Shift Arithmetic
Lookup Tables
Block

Support Notes

Cosine

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit check box.

Direct Lookup Table (n-D)

Support code generation.

Interpolation Using
Prelookup
1-D Lookup Table
2-D Lookup Table
n-D Lookup Table
Lookup Table Dynamic
Prelookup
Sine

1-102

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by

Supported Products and Block Usage

Lookup Tables (Continued)
Block

Support Notes
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Math Operations
Block

Support Notes

Abs

Support code generation.

Add
Algebraic Constraint

Ignored during code generation.

Assignment

Support code generation.

Bias
Complex to
Magnitude-Angle
Complex to Real-Imag
Divide
Dot Product
Find Nonzero Elements
Gain
Magnitude-Angle to
Complex
Math Function (10^u)
Math Function (conj)
Math Function (exp)
Math Function (hermitian)
Math Function (hypot)
Math Function (log)
Math Function (log10)

1-103

1

Modeling

Math Operations (Continued)
Block
Math Function
(magnitude^2)
Math Function (mod)
Math Function (pow)
Math Function (reciprocal)
Math Function (rem)
Math Function (square)
Math Function (transpose)
Matrix Concatenate
MinMax
MinMax Running
Resettable
Permute Dimensions
Polynomial
Product
Product of Elements
Real-Imag to Complex
Reciprocal Sqrt
Reshape
Rounding Function
Sign
Signed Sqrt

1-104

Support Notes

Supported Products and Block Usage

Math Operations (Continued)
Block

Support Notes

Sine Wave Function

• Does not refer to absolute time when configured for
sample-based operation. Depends on absolute time when in
time-based operation.
• Depends on absolute time when used inside a triggered
subsystem hierarchy.

Slider Gain

Support code generation.

Sqrt
Squeeze
Subtract
Sum
Sum of Elements
Trigonometric Function

Functions asinh, acosh, and atanh are not supported by all
compilers. If you use a compiler that does not support those
functions, the software issues a warning for the block and the
generated code fails to link.

Unary Minus

Support code generation.

Vector Concatenate
Weighted Sample Time
Math

1-105

1

Modeling

Model Verification
Block

Support Notes

Assertion

Supports code generation.

Check Discrete Gradient

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Check Dynamic Gap

Support code generation.

Check Dynamic Lower
Bound
Check Dynamic Range
Check Dynamic Upper
Bound
Check Input Resolution
Check Static Gap
Check Static Lower Bound
Check Static Range
Check Static Upper Bound

1-106

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Supported Products and Block Usage

Model-Wide Utilities
Block

Support Notes

Block Support Table

Ignored during code generation.

DocBlock

Uses the template symbol you specify for the Embedded Coder
Flag block parameter to add comments to generated code.
Requires an Embedded Coder license. For more information, see
“Use a Simulink DocBlock to Add a Comment”.

Model Info

Ignored during code generation.

Timed-Based Linearization
Trigger-Based
Linearization
Ports & Subsystems
Block

Support Notes

Atomic Subsystem

Support code generation.

CodeReuse Subsystem
Configurable Subsystem
Enable
Enabled Subsystem
Enabled and Triggered
Subsystem
For Each
For Each Subsystem
For Iterator Subsystem
Function-Call Generator
Function-Call Split
Function-Call Subsystem
If

1-107

1

Modeling

Ports & Subsystems (Continued)
Block

Support Notes

If Action Subsystem
Model
Subsystem
Switch Case
Switch Case Action
Subsystem
Triggered Subsystem
While Iterator Subsystem
Signal Attributes
Block

Support Notes

Bus to Vector

Support code generation.

Data Type Conversion
Data Type Conversion
Inherited
Data Type Duplicate
Data Type Propagation
Data Type Scaling Strip

1-108

IC

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Probe

Supports code generation.

Supported Products and Block Usage

Signal Attributes (Continued)
Block

Support Notes

Rate Transition

• Generated code might rely on memcpy or memset (string.h).
• Cannot use inside a triggered subsystem hierarchy.

Signal Conversion

Support code generation.

Signal Specification
Weighted Sample Time
Width
Signal Routing
Block

Support Notes

Bus Assignment

Support code generation.

Bus Creator
Bus Selector
Data Store Memory
Data Store Read
Data Store Write
Demux
Environment Controller

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

1-109

1

Modeling

Signal Routing (Continued)
Block

Support Notes

From

Support code generation.

Goto
Goto Tag Visibility
Index Vector
Manual Switch

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Merge

When multiple signals connected to a Merge block have a non-Auto
storage class, all non-Auto signals connected to that block must be
identically labeled and have the same storage class. When Merge
blocks connect directly to one another, these rules apply to all
signals connected to Merge blocks in the group.

Multiport Switch

Support code generation.

Mux
Selector
Switch

Generated code might rely on memcpy or memset (string.h).

Sinks
Block

Support Notes

Display

Ignored for code generation.

Floating Scope
Outport (Out1)

1-110

Supports code generation.

Supported Products and Block Usage

Sinks (Continued)
Block

Support Notes

Scope

Ignored for code generation.

Stop Simulation

• Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code.
Usually, blocks evolve toward being suitable for production
code. Thus, blocks suitable for production code remain suitable.
• Generated code stops executing when the stop condition is true.

Terminator

Supports code generation.

To File

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

To Workspace

Ignored for code generation.

XY Graph

1-111

1

Modeling

Sources
Block

Support Notes

Band-Limited White Noise

Cannot use inside a triggered subsystem hierarchy.

Chirp Signal

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Clock

Constant

Supports code generation.

Counter Free-Running

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Counter Limited

• The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.
• Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code.

1-112

Supported Products and Block Usage

Sources (Continued)
Block

Support Notes
Usually, blocks evolve toward being suitable for production
code. Thus, blocks suitable for production code remain suitable.

Digital Clock

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Enumerated Constant

Supports code generation.

From File

Ignored for code generation.

From Workspace
Ground

Support code generation.

Inport (In1)
Pulse Generator

Cannot use inside a triggered subsystem hierarchy. Does not refer
to absolute time when configured for sample-based operation.
Depends on absolute time when in time-based operation.

Ramp

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Random Number

Supports code generation.

1-113

1

Modeling

Sources (Continued)
Block

Support Notes

Repeating Sequence

• Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code.
Usually, blocks evolve toward being suitable for production
code. Thus, blocks suitable for production code remain suitable.
• Consider using the Repeating Sequence Stair or Repeating
Sequence Interpolated block instead.

Repeating Sequence
Interpolated

• The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.
• Cannot use inside a triggered subsystem hierarchy.

Repeating Sequence Stair

The Simulink Coder software does not explicitly group primitive
blocks that constitute a nonatomic masked subsystem block in
the generated code. This flexibility allows for more efficient
code generation. In certain cases, you can achieve grouping by
configuring the masked subsystem block to execute as an atomic
unit by selecting the Treat as atomic unit option.

Signal Builder

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Signal Generator

1-114

Supported Products and Block Usage

Sources (Continued)
Block

Support Notes

Sine Wave

• Depends on absolute time when used inside a triggered
subsystem hierarchy.
• Does not refer to absolute time when configured for
sample-based operation. Depends on absolute time when in
time-based operation.

Step

Not recommended for production code. Relates to resource limits
and restrictions on speed and memory often found in embedded
systems. Generated code can contain dynamic allocation and
freeing of memory, recursion, additional memory overhead, and
widely-varying execution times. While the code is functionally
valid and generally acceptable in resource-rich environments,
smaller embedded targets often cannot support such code. Usually,
blocks evolve toward being suitable for production code. Thus,
blocks suitable for production code remain suitable.

Uniform Random Number

Supports code generation.

User-Defined
Block

Support Notes

Fcn

Supports code generation.

Interpreted MATLAB
Function

Consider using the MATLAB Function block instead.

Level-2 MATLAB
S-Function

Ignored during code generation.

MATLAB Function

Supports code generation.

S-Function

S-functions that call into MATLAB are not supported for code
generation.

S-Function Builder

1-115

1

Modeling

Block Set Support for Code Generation
Several products that include blocks are available for you to consider for
code generation. However, before using the blocks for one of these products,
consult the documentation for that product to confirm whether any, all, or a
subset of blocks support code generation.

Fixed-Point Tool Data Type Override
SIL/PIL does not support signals with data types overridden by the
Fixed-Point Tool Data type override parameter at the SIL/PIL component
boundary.
You may see an exception message like the following:
Simulink.DataType object 'real_T' is not in scope
from 'mpil_mtrig_no_ic_preread/TmpSFcnForModelReference_unitInTopMdl'.
This error message is related to a hidden S-Function block.

There is no resolution for this issue.

Data Type Overrides Unavailable for Most Blocks in
Embedded Targets and Desktop Targets
When you attempt to perform a datatype override on a block, you may get an
error message similar to the following example:
Error reported by S-function 'sfun_can_frame_splitter' in
'c2000_host_CAN_monitor/CAN Message Unpacking/CAN Message
Unpacking': Incompatible DataType or Size specified.

Data type overrides using the Fixed point tool are not available for blocks
in Simulink Coder > Desktop Targets and Embedded Coder > Embedded
Targets libraries that support fixed-point.
There is no resolution for this issue.

1-116

Modeling Semantic Considerations

Modeling Semantic Considerations
In this section...
“Data Propagation” on page 1-117
“Sample Time Propagation” on page 1-119
“Latches for Subsystem Blocks” on page 1-120
“Block Execution Order” on page 1-120
“Algebraic Loops” on page 1-122

Data Propagation
The first stage of code generation is compilation of the block diagram. This
stage is analogous to that of a C or C++ program. The compiler carries out
type checking and preprocessing. Similarly, the Simulink engine verifies that
input/output data types of block ports are consistent, line widths between
blocks are of expected thickness, and the sample times of connecting blocks
are consistent.
The Simulink engine propagates data from one block to the next along signal
lines. The data propagated consists of
• Data type
• Line widths
• Sample times
You can verify what data types any given Simulink block supports by typing
showblockdatatypetable

at the MATLAB prompt, or (from the Help browser) clicking the command
above.
The Simulink engine typically derives signal attributes from a source block.
For example, the Inport block’s parameters dialog box specifies the signal
attributes for the block.

1-117

1

Modeling

In this example, the Inport block has a port width of 3, a sample time of .01
seconds, the data type is double, and the signal is complex.
This figure shows the propagation of the signal attributes associated with the
Inport block through a simple block diagram.

In this example, the Gain and Outport blocks inherit the attributes specified
for the Inport block.

1-118

Modeling Semantic Considerations

Sample Time Propagation
Inherited sample times in source blocks (for example, a root inport) can
sometimes lead to unexpected and unintended sample time assignments.
Since a block may specify an inherited sample time, information available at
the outset is often insufficient to compile a block diagram completely.
In such cases, the Simulink engine propagates the known or assigned sample
times to those blocks that have inherited sample times but that have not
yet been assigned a sample time. Thus, the engine continues to fill in the
blanks (the unknown sample times) until sample times have been assigned
to as many blocks as possible. Blocks that still do not have a sample time
are assigned a default sample time.
For a completely deterministic model (one where no sample times are set
using the above rules), you should explicitly specify the sample times of all
your source blocks. Source blocks include root inport blocks and any blocks
without input ports. You do not have to set subsystem input port sample
times. You might want to do so, however, when creating modular systems.
An unconnected input implicitly connects to ground. For ground blocks and
ground connections, the sample time is always constant (inf).
All blocks have an inherited sample time (Ts = -1). They are assigned a
sample time of (Tf - Ti)/50.

Constant Block Sample Times
You can specify a sample time for Constant blocks. This has certain
implications for code generation.
When a sample time of inf is selected for a Constant block,
• If Inline parameters is on, the block takes on a constant sample time,
and propagates a constant sample time downstream.
• If Inline parameters is off, the Constant block inherits its sample time –
which is nonconstant – and propagates that sample time downstream.
Generated code for any block differs when it has a constant sample time; its
outputs are represented in the constant block outputs structure instead of in

1-119

1

Modeling

the general block outputs structure. The generated code thus reflects that the
Constant block propagates a constant sample time downstream if a sample
time of inf is specified and Inline parameters is on.

Latches for Subsystem Blocks
When an Inport block is the signal source for a triggered or function-call
subsystem, you can use latch options to preserve input values while the
subsystem executes. The Inport block latch options include:
For...

You Can Use...

Triggered
subsystems

Latch input by delaying outside signal

Function-call
subsystems

Latch input for feedback signals of function-call
subsystem outputs

When you use Latch input for feedback signals of function-call
subsystem outputs for a function-call subsystem, the Simulink Coder code
generator
• Preserves latches in generated code regardless of any optimizations that
might be set
• Places the code for latches at the start of a subsystem’s output/update
function
For more information on these options, see the description of the Inport block
in the Simulink documentation.

Block Execution Order
Once the Simulink engine compiles the block diagram, it creates a model.rtw
file (analogous to an object file generated from a C or C++ file). The model.rtw
file contains the connection information of the model, as well as the signal
attributes. Thus, the timing engine in can determine when blocks with
different rates should be executed.
You cannot override this execution order by directly calling a block
(in handwritten code) in a model. For example, in the next figure the

1-120

Modeling Semantic Considerations

disconnected_trigger model on the left has its trigger port connected to

ground, which can lead to all blocks inheriting a constant sample time. Calling
the trigger function, f(), directly from user code does not work and should
never be done. Instead, you should use a function-call generator to specify the
rate at which f() should be executed, as shown in the connected_trigger
model on the right.

f0

1
In1

In1

f0

Out1

Triggered
Subsystem

Connected
Trigger

Function-call
Generator

Disconnected
Trigger
1
Out1

1
In1

In1

f0

Out1

1
Out1

Triggered
Subsystem

Instead of the function-call generator, you could use any other block that can
drive the trigger port. Then, you should call the model’s main entry point to
execute the trigger function.
For multirate models, a common use of the Simulink Coder product is to build
individual models separately and then manually code the I/O between the
models. This approach places the burden of data consistency between models
on the developer of the models. Another approach is to let the Simulink
and Simulink Coder products maintain data consistency between rates and
generate multirate code for use in a multitasking environment. The Simulink
Rate Transition block is able to interface both periodic and asynchronous
signals. For a description of the Simulink Coder libraries, see “Handle
Asynchronous Events” on page 1-34. For more information on multirate code
generation, see “Scheduling” on page 1-4.

1-121

1

Modeling

Algebraic Loops
Algebraic loops are circular dependencies between variables. This prevents
the straightforward direct computation of their values. For example, in the
case of a system of equations
• x = y + 2
• y = -x
the values of x and y cannot be directly computed.
To solve this, either repeatedly try potential solutions for x and y (in an
intelligent manner, for example, using gradient based search) or “solve” the
system of equations. In the previous example, solving the system into an
explicit form leads to
• 2x = 2
• y = -x
• x = 1
• y = -1
An algebraic loop exists whenever the output of a block having direct
feedthrough (such as Gain, Sum, Product, and Transfer Fcn) is fed back as an
input to the same block. The Simulink engine is often able to solve models
that contain algebraic loops, such as the next diagram.

1-122

Modeling Semantic Considerations

The Simulink Coder software does not produce code that solves algebraic
loops. This restriction includes models that use Algebraic Constraint blocks
in feedback paths. However, the Simulink engine can often eliminate all
or some algebraic loops that arise, by grouping equations in certain ways
in models that contain them. It does this by separating the update and
output functions to avoid circular dependencies. See “Algebraic Loops” in the
Simulink documentation for details.

Algebraic Loops in Triggered Subsystems
While the Simulink engine can minimize algebraic loops involving atomic
and enabled subsystems, a special consideration applies to some triggered
subsystems. An example for which code can be generated is shown in the
following model and triggered subsystem.

The default Simulink behavior is to combine output and update methods for
the subsystem, which creates an apparent algebraic loop, even though the
Unit Delay block in the subsystem has no direct feedthrough.
You can allow the Simulink engine to solve the problem by splitting the output
and update methods of triggered and enabled-triggered subsystems when
feasible. If you want the Simulink Coder code generator to take advantage of
this feature, select the Minimize algebraic loop occurrences check box in
the Subsystem Parameters dialog box. Select this option to avoid algebraic
loop warnings in triggered subsystems involved in loops.

1-123

1

Modeling

Note If you always check this box, the generated code for the subsystem
might contain split output and update methods, even if the subsystem is
not actually involved in a loop. Also, if a direct feedthrough block (such as a
Gain block) is connected to the inport in the above triggered subsystem, the
Simulink engine cannot solve the problem, and the Simulink Coder software
is unable to generate code.
A similar Minimize algebraic loop occurrences option appears on the
Model Referencing pane of the Configuration Parameters dialog box.
Selecting it enables the Simulink Coder software to generate code for models
containing Model blocks that are involved in algebraic loops.

1-124

2
Subsystems
• “Code Generation of Subsystems” on page 2-2
• “Generate Code and Executables for Individual Subsystem” on page 2-4
• “Inline Subsystem Code” on page 2-7
• “Generate Subsystem Code as Separate Function and Files” on page 2-10
• “Generate Reusable Function for Identical Subsystems Within a Model”
on page 2-11
• “Optimize Code for Identical Nested Subsystems” on page 2-14
• “Generate Reusable Code for Subsystems Containing S-Function Blocks”
on page 2-15
• “Generate Reusable Code from Stateflow Charts” on page 2-16
• “Code Reuse Limitations for Subsystems” on page 2-17
• “Code Reuse For Subsystems Shared Across Referenced Models” on page
2-19
• “Reusable Library Subsystem” on page 2-20
• “Code Generation of Constant Parameters” on page 2-22
• “Shared Constant Parameters for Code Reuse” on page 2-23
• “Generate Reusable Code for Subsystems Shared Across Models” on page
2-25
• “Determine Why Subsystem Code Is Not Reused” on page 2-32

2

Subsystems

Code Generation of Subsystems
For you to control how code is generated for any nonvirtual subsystem, the
Simulink Coder software provides subsystem parameters that you can use.
The categories of nonvirtual subsystems are:
• Conditionally executed subsystems. Execution depends upon a control
signal or control block. These subsystems include:

-

Triggered
Enabled
Action
Iterator

Function-call
For more information, see “About Conditional Subsystems”.

• Atomic subsystems: Any virtual subsystem can be declared atomic (and
therefore nonvirtual) by using the “Treat as atomic unit” parameter in the
Subsystem Parameters dialog box.
For more information on nonvirtual subsystems and atomic subsystems, see
“Systems and Subsystems” and run the sl_subsys_semantics model.
You can design and configure your model to control the code generated from
nonvirtual subsystems.

2-2

To...

See...

Generate inlined code from a selected
nonvirtual subsystem.

“Inline Subsystem Code” on page 2-7

Generate code for only a subsystem.

“Generate Code and Executables for
Individual Subsystem” on page 2-4

Generate separate functions with no
arguments, and optionally place the
subsystem code in a separate file.

“Generate Subsystem Code as
Separate Function and Files” on
page 2-10

Code Generation of Subsystems

To...

See...

Generate a single reentrant function
for a subsystem that is included in
multiple places within a model.

“Generate Reusable Function for
Identical Subsystems Within a
Model” on page 2-11

Generate a single reentrant function
for a subsystem that is included in
multiple places in a model reference
hierarchy.

“Generate Reusable Code for
Subsystems Shared Across Models”
on page 2-25 and “Code Reuse
For Subsystems Shared Across
Referenced Models” on page 2-19

Note If you generate code for a virtual subsystem, code generator treats the
subsystem as atomic and generates the code accordingly. The resulting code
can change the execution behavior of your model, for example, by applying
algebraic loops, and therefore introduce inconsistencies with the simulation
behavior. Declare virtual subsystems as atomic subsystems, which makes
simulation and execution behavior consistent for your model consistent.

Subsystem Code Dependence
Code generated from nonvirtual subsystems may or may not be completely
independent of the generating model. When generating code for a subsystem,
the code may reference global data structures of the model, even if the
subsystem code is in a separate file. Each subsystem code file contains
include directives and comments describing the dependencies. The Simulink
Coder software checks for cyclic file dependencies and warns about them
at build time. For descriptions of how generated code is packaged, see
“Generated Source Files and File Dependencies” on page 10-4.
To generate subsystem code that is independent of the generating model,
place the subsystem in a library and configure it as a reusable subsystem. For
more information, see “Code Reuse For Subsystems Shared Across Referenced
Models” on page 2-19.

2-3

2

Subsystems

Generate Code and Executables for Individual Subsystem
You can generate code and build an executable for a subsystem within a
model. The code generation and build process uses the code generation and
build parameters of the root model.
1 In the Configuration Parameters dialog box, set up the code generation and

build parameters, similar to setting up the code generation for a model.
2 Right-click the Subsystem block. From the context menu, select C/C++

Code > Build This Subsystem from the context menu.
Alternatively, in the current model, click a subsystem and then from the
Code menu, select C/C++ Code > Build Selected Subsystem.
Note When you select Build This Subsystem, if the model is operating in
external mode, the Simulink Coder build process automatically turns off
external mode for the duration of the build. Simulink Coder then restores
external mode upon completion of the build process.

2-4

Generate Code and Executables for Individual Subsystem

3 The Build code for Subsystem window displays a list of the subsystem

parameters. The upper pane displays the name, class, and storage class
of each variable (or data object) that is referenced as a block parameter in
the subsystem. When you select a parameter in the upper pane, the lower
pane shows all the blocks that reference the parameter and the parent
system of each block.
The Storage Class column contains a menu for each row. The menu
options set the storage class or inline the parameter. To declare a
parameter to be tunable, set the Storage Class to any value other than
Inlined.

For more information on tunable and inlined parameters and storage
classes, see “Parameters” on page 7-10.
4 After selecting tunable parameters, Build to initiate the code generation

and build process.

2-5

2

Subsystems

5 The build process displays status messages in the MATLAB Command

Window. When the build is complete, the generated executable is in your
working folder. The name of the generated executable is subsystem.exe
(on PC platforms) or subsystem (on The Open Group UNIX platforms).
subsystem is the name of the source subsystem block.
The generated code is in a build subfolder, named subsystem_target_rtw.
subsystem is the name of the source subsystem block and target is the
name of the target configuration.
When you generate code for a subsystem, you can generate an S-function
by selecting Code > C/C++ Code> Generate S-Function, or you can use
the right-click subsystem build. For more information on S-functions, see
“Automate S-Function Generation” on page 14-23 and in Embedded Coder,
“Generate S-Function Wrappers”.

Subsystem Build Limitations
The following limitations apply to building subsystems:
• When you right-click build a subsystem that includes an Outport block for
which the Data type parameter specifies a bus object, you must address
errors that result from setting signal labels. To configure the software to
display these errors, in the Configuration Parameters dialog box for the
parent model, on the Diagnostics > Connectivity pane, set the Signal
label mismatch parameter to error.
• When a subsystem is in a triggered or function-call subsystem, the
right-click build process might fail if the subsystem code is not sample-time
independent. To find out whether a subsystem is sample-time independent:
1 Copy all blocks in the subsystem to an empty model.
2 In the Configuration Parameters dialog box, on the Solver pane, set:

a. Type to Fixed-step.
b. Periodic sample time constraint to Ensure sample time
independent.
c. Click Apply.
3 Update the model. If the model is sample-time dependent, Simulink

generates an error in the process of updating the diagram.

2-6

Inline Subsystem Code

Inline Subsystem Code
You can configure a nonvirtual subsystem to inline the subsystem code
with the model code. In the Subsystem Parameters dialog box, setting the
Function packaging parameter to Auto or Inline inlines the generated
code of the subsystem.
The Auto option is the default. When there is only one instance of a subsystem
in the model, the Auto option inlines the subsystem code. When multiple
instances of a subsystem exist, the Auto option results in a single copy of the
function (as a reusable function). For function-call subsystems with multiple
callers, the subsystem code is generated as if you specified Function.
To always inline subsystem code, select Inline. The Inline option explicitly
directs the code generator to inline the subsystem unconditionally.

Configure Subsystem to Inline Code
To configure your subsystem for inlining:
1 Right-click the Subsystem block. From the context menu, select Block

Parameters (Subsystem).
2 In the Subsystem Parameters dialog box, if the subsystem is virtual, select

Treat as atomic unit. This option makes the subsystem nonvirtual.
On the Code Generation tab, the Function packaging option is now
available.
If the system is already nonvirtual, the Function packaging option is
already selected.
3 Click the Code Generation tab and select Auto or Inline from the

Function packaging parameter.

2-7

2

Subsystems

4 Click Apply and close the dialog box.

The border of the subsystem thickens, indicating that it is nonvirtual.
When you generate code from your model, the code generator inlines
subsystem code within model.c or model.cpp (or in its parent system’s source
file). You can identify this code by system/block identification tags, such as:
/* Atomic SubSystem Block: /AtomicSubsys1 */

Exceptions to Inlining
There are certain cases in which the code generator does not inline a
nonvirtual subsystem, even though the Inline option is selected.
• If the subsystem is a function-call subsystem that is called by a noninlined
S-function, the Inline option is ignored. Noninlined S-functions make calls

2-8

Inline Subsystem Code

by using function pointers. Therefore, the function-call subsystem must
generate a function with all arguments present.
• In a feedback loop involving function-call subsystems, the code generator
forces one of the subsystems to be generated as a function instead of
inlining it. Based on the order in which the subsystems are sorted
internally, the software selects the subsystem to be generated as a function.
• If a subsystem is called from an S-function block that sets the option
SS_OPTION_FORCE_NONINLINED_FCNCALL to TRUE, it is not inlined.
When user-defined Async Interrupt blocks or Task Sync blocks are
present, this result might occur. Such blocks must be generated as
functions. These blocks are located in the VxWorks block library
(vxlib1) shipped with the Simulink Coder product and use the
SS_OPTION_FORCE_NONINLINED_FCNCALL option.2

2. VxWorks® is a registered trademark of Wind River® Systems, Inc.

2-9

2

Subsystems

Generate Subsystem Code as Separate Function and Files
To generate both a separate subsystem function and a separate file for a
subsystem in a model:
1 Right-click a Subsystem block. From the context menu, select Block

Parameters (Subsystem).
2 In the Subsystem Parameters dialog box, if the subsystem is virtual, select

Treat as atomic unit. On the Code Generation tab, the Function
packaging parameter is now available.
3 Click the Code Generation tab and select Function from the Function

packaging parameter. The Function option enables two parameters:
• The “Function name options” parameter controls the naming of the
generated function.
• The “File name options” parameter controls the naming of the generated
file.
4 Set the Function name options parameter.
5 Set the File name options parameter to a value other than Auto. If you

are generating a reusable function for your subsystem, see “Generate
Reusable Function for Identical Subsystems Within a Model” on page
2-11 or “Generate Reusable Code for Subsystems Shared Across Models”
on page 2-25.
6 Click Apply and close the dialog box.

2-10

Generate Reusable Function for Identical Subsystems Within a Model

Generate Reusable Function for Identical Subsystems
Within a Model
In the Subsystem Parameters dialog box, the Function packaging
parameter option Function generates functions that use global data. The
Reusable function option generates reusable functions that have data
passed as arguments (enabling them to be reentrant). Selecting Reusable
function generates a function with arguments that allows the subsystem
code to be shared by other instances of it in the model. This action supports
less code instead of replicating the code for each instance of a subsystem or
each time it is called.
To determine reusability of the subsystem code, the code generator performs a
checksum to determine if subsystems are identical. The generated function
has arguments, for example, for block inputs and outputs (rtB_*), continuous
states (rtDW_*), parameters (rtP_*).
Note In the generated code, the call interface is subject to change from
release to release. Therefore, do not directly call reusable functions from
external code.
To generate one reusable function for identical subsystems within a model:
1 Right-click the Subsystem block. From the context menu, select Block

Parameters (Subsystem).
2 In the Subsystem Parameters dialog box, if the subsystem is virtual, select

Treat as atomic unit. On the Code Generation tab, the Function
packaging menu is now available.
If the subsystem is already nonvirtual, the Function packaging menu is
already selected.
3 Click the Code Generation tab and select Reusable function for the

Function packaging parameter.

2-11

2

Subsystems

For more information about this setting, see “Considerations for Function
Packaging Options Auto and Reusable function” on page 2-13.
4 Set the function name using the “Function name options” parameter.

Note If you do not choose Auto, for all other Subsystem blocks that
you want to share this code, specify the same function name for those
Subsystem blocks.
5 Set the file name using the “File name options” parameter to a value other

than Auto. If your generated code is under source control, a value other
than Auto prevents the generated file name from changing due to unrelated
model modifications.

2-12

Generate Reusable Function for Identical Subsystems Within a Model

Note For all other Subsystem blocks that you want to share this code,
specify the same file name for those Subsystem blocks.
6 Click Apply and close the dialog box.

For a summary of code reuse limitations, see “Code Reuse Limitations for
Subsystems” on page 2-17.

Considerations for Function Packaging Options Auto
and Reusable function
When you want multiple instances of a subsystem to be represented as one
reusable function, you can designate each one of them as Auto or as Reusable
function. Use one or the other, because using both creates two reusable
functions, one for each specification. The outcomes of these choices differ
only when reuse is not possible. Selecting Auto does not allow control of the
function or file name for the subsystem code.
The Reusable function and Auto options both try to determine if multiple
instances of a subsystem exist and if the code can be reused. When reuse is
not possible, there are differences in the options behavior:
• Auto yields inlined code. If circumstances prohibit inline, then the
generated code is separate functions without arguments for each subsystem
instance.
• Reusable function yields a separate function with arguments for each
subsystem instance in the model.

2-13

2

Subsystems

Optimize Code for Identical Nested Subsystems
The Function packaging parameter Auto option can optimize code in
situations in which identical subsystems contain other identical subsystems,
by both reusing and inlining generated code. Suppose a model, such as the
one shown in Reuse of Identical Nested Subsystems on page 2-14, contains
identical subsystems A1 and A2. A1 contains subsystem B1, and A2 contains
subsystem B2, which are identical. In such cases, the Auto option causes one
function to be generated which is called for both A1 and A2. This function
contains one piece of inlined code to execute B1 and B2. This optimization
generates less code which improves execution speed.

Reuse of Identical Nested Subsystems

2-14

Generate Reusable Code for Subsystems Containing S-Function Blocks

Generate Reusable Code for Subsystems Containing
S-Function Blocks
There are several requirements that need to be met in order for subsystems
containing S-function blocks to be reused. For the list of requirements, see
“S-Functions That Support Code Reuse” on page 14-113.
When you select the Reusable function option, two additional options are
enabled, Function name options and File name options. If you use
these fields to enter a function name and/or a file name, you must specify
exactly the same function name and file name for each instance of identical
subsystems for the code generator to reuse the subsystem code. For an
example, follow the procedure in “Generate Reusable Function for Identical
Subsystems Within a Model” on page 2-11.

2-15

2

Subsystems

Generate Reusable Code from Stateflow Charts
You can generate reusable code from a Stateflow chart, or from a subsystem
containing a chart, except in the following cases:
• The Stateflow chart contains exported graphical functions.
• The Stateflow model contains machine parented events.

2-16

Code Reuse Limitations for Subsystems

Code Reuse Limitations for Subsystems
The code generator uses a checksum to determine whether subsystems are
identical and reusable. Subsystem code is not reused, if:
• Multiple ports of a subsystem share the same source.
• A port used by multiple instances of a subsystem has different sample
times, data types, complexity, frame status, or dimensions across the
instances.
• The output of a subsystem is marked as a global signal.
• Subsystems contain identical blocks with different names or parameter
settings.
• The output of a subsystem is connected to a Merge block, and the output of
the Merge block is a custom storage class that is implemented in the C code
as memory that is nonaddressable (for example, BitField).
• The input of a subsystem is nonscalar and has a custom storage class that
is implemented in the C code as memory that is nonaddressable.
• A masked subsystem has a parameter that is nonscalar and has a custom
storage class that is implemented in the C code as memory that is
nonaddressable.
If you select Reusable function, and the code generator determines that
code for a subsystem cannot be reused, it generates a separate function that
is not reused. The code generation report might show that the separate
function is reusable, even if it is used by only one subsystem. If you prefer
that subsystem code be inlined in such circumstances rather than deployed as
functions, then choose Auto for the Function packaging option.

Blocks That Prevent Code Reuse
Use of the following blocks in a subsystem can also prevent the subsystem
code from being reused:
• Scope blocks (with data logging enabled)
• S-Function blocks that fail to meet certain criteria (see “S-Functions That
Support Code Reuse” on page 14-113)

2-17

2

Subsystems

• To File blocks (with data logging enabled)
• To Workspace blocks (with data logging enabled)

Code Reuse Limitations for Subsystems Shared
Across Referenced Models
The code generator uses a checksum to determine whether reusable library
subsystems are identical. The reusable library subsystem code is placed in
the shared utilities folder and is independent of the generated code of the top
model or the referenced model. For example, the reusable library subsystem
code does not include model.h or model_types.h.
Reusable code that is generated to the shared utilities folder and is dependent
on the model code does not compile. If the code generator determines that the
reusable library subsystem code is dependent on the model code, the reusable
subsystem code is not generated to the shared utilities folder. The following
cases might generate code that is dependent on the model code, when the
reusable library subsystem:
• Contains a block that uses time-related functionality, such as a Step block,
or continuous time or multirate blocks.
• Contains one or more Model blocks.
• Contains subsystems that are not inlined or a reusable library subsystem.
• Contains a For Each subsystem and the model configuration parameter,
Inline parameters, is cleared. In this case, types are defined in
model_types.h.
• Contains a signal that is not an Auto storage class. Variables of non-Auto
storage classes are generated to model.h.
• Contains a parameter that is not an Auto storage class.
• Contains a user-defined type where Data Scope is not set to Exported.
The code generator might place the type definition in model_types.h.
• Is a variant subsystem that generates preprocessor conditionals.
Preprocessor directives defining the variant objects are included in
model_types.h.

2-18

Code Reuse For Subsystems Shared Across Referenced Models

Code Reuse For Subsystems Shared Across Referenced
Models
To reuse common functionality, you can include multiple instances of a
subsystem within a model and across referenced models. To generate a
reusable function for a subsystem which is included in multiple referenced
models:
• If the subsystem is in a model reference hierarchy, set the configuration
parameter, Shared code placement to Auto. Otherwise, for each
model that uses the subsystem, set Shared code placement to Shared
location. The Shared code placement parameter is in the Configuration
Parameters dialog box, on the Code Generation > Interface pane.
• The subsystem must be defined in a library and configured for reuse.
This subsystem is referred to as a reusable library subsystem. For more
information, see “Reusable Library Subsystem” on page 2-20.
For an example, see “Generate Reusable Code for Subsystems Shared Across
Models” on page 2-25.
The code generator performs a checksum to determine reusability. There
are cases when the code generator cannot reuse subsystem code. For more
information, see “Code Reuse Limitations for Subsystems” on page 2-17.

2-19

2

Subsystems

Reusable Library Subsystem
A reusable library subsystem is a subsystem included in a library that is
configured for reuse. The Subsystem parameters must be set as follows:
• Treat as an atomic unit is selected.
• On the Code Generation tab:

-

Function packaging is set to Reusable function.
Function name options
and File name options are set to Auto or Use subsystem name.

For more information on creating a library, see “Libraries”. For an example
of creating a reusable library subsystem, see “Generate Reusable Code for
Subsystems Shared Across Models” on page 2-25.

Code Generation of a Reusable Library Subsystem
For incremental code generation, if the reusable library subsystem changes,
a rebuild of itself and its parents occurs. During the build, if a matching
function is not found, a new instance of the reusable function is generated
into the shared utilities folder. If a different matching function is found
from previous builds, that function is used, and a new reusable function is
not emitted.
For subsequent builds, unused files are not replaced or deleted from your
folder. During development of a model, when many obsolete shared functions
exist in the shared utilities folder, you can delete the folder and regenerate
the code. If all instances of a reusable library subsystem are removed from a
model reference hierarchy and you regenerate the code, the obsolete shared
functions remain in the shared utilities folder until you delete them.
If a model changes such that the change might cause different generated code
for the subsystem, a new reusable function is generated. For example, model
configuration parameters that modify code comments might cause different
generated code for the subsystem even if the reusable library subsystem did
not change.

2-20

Reusable Library Subsystem

Reusable Library Subsystem Code Placement and
Naming
The code generator uses checksums to determine reusability. The generated
code of a reusable library subsystem is independent of the generated code of
the model. Code for the reusable library subsystem is generated to the shared
utility folder, slprj/target/_sharedutils, instead of the model reference
hierarchy folders. The generated code for the supporting types, which are
generated to the .h file, are also in the shared utilities folder.
In the Subsystem Parameters dialog box, the Function name options
and File name options must be set to Auto or Use subsystem name. For
unique naming, reusable function names have a checksum string appended to
the reusable library subsystem name. For example, the code and files for a
subsystem, SS1, which links to a reusable library subsystem, RLS, might be:
• Function name: RLS_mgdjlngd
• File name: RLS_mgdjlnd.c and RLS_mgdjlnd.h

Reusable Library Subsystem in the Top Model
In a model reference hierarchy, if an instance of the reusable library
subsystem is in the top model, then on the Model Referencing pane of the
Configuration Parameters dialog box, you must select the Pass fixed-size
scalar root input by value for code generation parameter. If you do
not select the parameter, a separate shared function is generated for the
reusable library subsystem instance in the top model, and a reusable function
is generated for instances in the referenced models.

Reusable Library Subsystem Connected to Root
Outport
If a reusable library subsystem is connected to the root outport, reuse does not
happen with identical subsystems that are not connected to the root outport.
However, you can set Pass reusable system outputs as to Individual
arguments on the Optimizations > Signals and Parameters pane to make
sure that reuse occurs between these subsystems. This parameter requires
an Embedded Coder license.

2-21

2

Subsystems

Code Generation of Constant Parameters
The code generator attempts to generate constant parameters to the shared
utilities folder first. If constant parameters are not generated to the shared
utilities folder, they are defined in the top model in a global constant
parameter structure. The declaration of the structure, ConstParam_model, is
in model.h:
/* Constant parameters (auto storage) */
typedef struct {
/* Expression: [1 2 3 4 5 6 7]
* Referenced by: '/Constant'
*/
real_T Constant_Value[7];
/* Expression: [7 6 5 4 3 2 1]
* Referenced by: '/Gain'
*/
real_T Gain_Gain[7];
} ConstParam_model;

The definition of the constant parameters, model_constP, is in:
/* Constant parameters (auto storage) */
const ConstParam_model model_ConstP = {
/* Expression: [1 2 3 4 5 6 7]
* Referenced by: '/Constant'
*/
{ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 },
/* Expression: [7 6 5 4 3 2 1]
* Referenced by: '/Gain'
*/
{ 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 }
};

The model_constP is passed as an argument to referenced models. For more
information on how shared constants are generated, see “Shared Constant
Parameters for Code Reuse” on page 2-23.

2-22

Shared Constant Parameters for Code Reuse

Shared Constant Parameters for Code Reuse
You can share the generated code for constant parameters across models if:
• Constant parameters are shared in a model reference hierarchy, or
• On the Code Generation > Interface pane, the model configuration
parameter Shared code placement is set to Shared location.
The shared constant parameters are generated individually to the
const_params.c file, which is placed in the shared utilities folder
slprj/target/_sharedutils.

For example, if a constant has multiple uses within a model reference
hierarchy where the top model is named topmod, the code for the shared
constant is as follows:
• In the shared utility folder, slprj/grt/_sharedutils, the constant
parameters are defined in const_params.c and named rtCP_pooled_
appended to a unique checksum string:
extern const real_T rtCP_pooled_lfcjjmohiecj[7];
const real_T rtCP_pooled_lfcjjmohiecj[7] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0 };

extern const real_T rtCP_pooled_ppphohdbfcba[7];
const real_T rtCP_pooled_ppphohdbfcba[7] = { 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 };

• In top_model_private.h or in any referenced model,
ref_model_private.h, for better readability, the constants are
renamed as follows:
extern const real_T rtCP_pooled_lfcjjmohiecj[7];
extern const real_T rtCP_pooled_ppphohdbfcba[7];

#define rtCP_Constant_Value

rtCP_pooled_lfcjjmohiecj

/* Expression: [1 2 3 4 5 6 7]

#define rtCP_Gain_Gain

rtCP_pooled_ppphohdbfcba

/* Expression: [7 6 5 4 3 2 1]

* Referenced by: '/Constant'*/

* Referenced by: '/Gain' */

• In topmod.c or refmod.c, the call site might be:

2-23

2

Subsystems

for (i = 0; i < 7; i++) {
topmod_Y.Out1[i] = (topmod_U.In1 + rtCP_Constant_Value[i]) * rtCP_Gain_Gain[i];
}

The code generator attempts to generate all constants as individual constants
to the const_params.c file in the shared utilities folder. Otherwise, constants
are generated as described in “Code Generation of Constant Parameters”
on page 2-22.

Shared Constant Parameters Limitations
No shared constants or shared functions are generated for a model when:
• The model has a Code Replacement Library (CRL) that is specified for
data alignment.
• The model is specified to replace data type names in the generated code.
• The Memory Section for constants is MemVolatile or MemConstVolatile.
Individual constants are not shared, if:
• A constant is referenced by a non-inlined S-function.
• A constant has a user-defined type where Data Scope is not set to
Exported.

2-24

Generate Reusable Code for Subsystems Shared Across Models

Generate Reusable Code for Subsystems Shared Across
Models
This example shows you how to configure a reusable library subsystem and
generate a reusable function for a subsystem shared across referenced models.
The result is reusable code for the subsystem, which is generated to the
shared utility folder (slprj/target/_sharedutils). For more information
about a reusable library subsystem, see “Code Reuse For Subsystems Shared
Across Referenced Models” on page 2-19.
Create a reusable library subsystem.
1 In the Simulink Editor, select File > New > Library. Open

rtwdemo_ssreuse to copy and paste subsystem SS1 into the Library Editor.
This action loads the variables for SS1 into the base workspace. Rename
the subsystem block to RLS.

2 Click the Subsystem block and press Ctrl+U to view the contents of

subsystem RLS.

2-25

2

Subsystems

3 To configure the subsystem, in the Library editor, right-click RLS. In the

context menu, select Block Parameters(Subsystem). In the Subsystem
Parameters dialog box, choose the following options:
• Select Treat as an atomic unit.
• On the Code Generation tab:
– Set Function packaging to Reusable function.
– Set Function name options and File name options to Auto.
4 Click Apply and OK.
5 Save the reusable library subsystem as ssreuselib, which creates a file,

ssreuselib.slx.
Create the example model.
1 Create a model which includes one instance of RLS from ssreuselib. Name

this subsystem SS1. Add another subsystem and name it SS2. Name the
model ex_model1.

2-26

Generate Reusable Code for Subsystems Shared Across Models

2 Create another model which includes one instance of RLS from ssreuselib.

Name this subsystem SS1. Add another subsystem and name it SS3. Name
the model ex_model2.

2-27

2

Subsystems

3 Create a top model with two model blocks that reference ex_model1 and

ex_model2. Save the top model as ex_mdlref_ssreuse.

Set configuration parameters of the top model.

2-28

Generate Reusable Code for Subsystems Shared Across Models

1 With model ex_mdlref_ssreuse open in the Simulink Editor, select

Simulation > Model Configuration Parameters to open the
Configuration Parameters dialog box.
2 On the Optimization > Signals and Parameters pane, select Inline

parameters.
3 On the Solver pane, specify the Type as Fixed-step.
4 On the Code Generation > Report pane, select Create code generation

report and Open report automatically.
5 On the Code Generation > Interface pane, set the Shared code

placement to Shared location.
6 On the Code Generation > Symbols pane, set the Maximum identifier

length to 256. This step is optional.
7 Click Apply and OK.
Create and propagate a configuration reference.
1 In the Simulink Editor, select View > Model Explorer to open the Model

Explorer. In the left navigation column of the Model Explorer, expand the
ex_mdlref_ssreuse node.
2 Right-click Configuration and select Convert to Configuration

Reference.
3 In the Convert Active Configuration to Reference dialog box, click OK. This

action converts the model configuration set to a configuration reference,
Simulink.ConfigSetRef, and creates the configuration reference object,
configSetObj, in the base workspace.
4 In the left navigation column, right-click Reference (Active) and select

Propagate to Referenced Models.
5 In the Configuration Reference Propagation to Referenced Models dialog

box, select the referenced models in the list. Click Propagate.
Now, the top model and reference models all use the same configuration
reference, Reference (Active), which points to a model configuration

2-29

2

Subsystems

reference object, configSetObj, in the base workspace. When you save your
model, you also need to export the configSetObj to a MAT-file. For more
information, see “Save a Referenced Configuration Set”.
Generate and view the code.
1 To generate code, in the Simulink Editor, press Ctrl-B. After the code is

generated, the code generation report opens.
2 To view the code generation report for a referenced model, in the left

navigation pane, in the Referenced Models section, select ex_model1.
The code generation report displays the generated files for ex_model1.
3 In the left navigation pane, expand the Shared Utility files. The

code generator uses the reusable library subsystem name and a unique
string to name the reused function. The code for subsystem SS1 is in
RLS_aaaippph.c and RLS_aaaippph.h.

2-30

Generate Reusable Code for Subsystems Shared Across Models

4 Click Back and navigate to the ex_model2 code generation report.

ex_model2 uses the same source code, RLS_aaaippph.c and
RLS_aaaippph.h, as the code for ex_model1. Your subsystem function and

file names will be different.

Related
Examples

• “Determine Why Subsystem Code Is Not Reused” on page 2-32
• “Share a Configuration Across Referenced Models”
• “Generate Reusable Function for Identical Subsystems Within a Model”
on page 2-11

Concepts

• “Code Generation of Subsystems” on page 2-2
• “Code Reuse For Subsystems Shared Across Referenced Models” on page
2-19
• “Code Reuse Limitations for Subsystems” on page 2-17
• “Libraries”

2-31

2

Subsystems

Determine Why Subsystem Code Is Not Reused
Due to the limitations described in “Code Reuse Limitations for Subsystems”
on page 2-17, the code generator might not reuse generated code as you
expect. To determine why code generated for a subsystem is not reused, see
“Review the Subsystems Section of the HTML Code Generation Report” on
page 2-32. If you cannot determine why based on the report, see “Compare
Subsystem Checksum Data” on page 2-32.

Review the Subsystems Section of the HTML Code
Generation Report
If you determine that the code generator does not generate code for a
subsystem as reusable code, and you specified the subsystem as reusable,
examine the Subsystems section of the HTML code generation report (see
“Generate a Code Generation Report” on page 11-5). The Subsystems section
contains:
• A table that summarizes how nonvirtual subsystems were converted to
generated code.
• Diagnostic information that describes why the contents of some subsystems
were not generated as reusable code.
The Subsystems section also indicates the mapping of each noninlined
subsystem in the model to functions or reused functions in the generated code.
For an example, open and build the rtwdemo_atomic model.

Compare Subsystem Checksum Data
You can determine why subsystem code is not reused by accessing and
comparing subsystem checksum data. The code generator determines whether
subsystems are identical by comparing subsystem checksums, as noted in
“Code Reuse Limitations for Subsystems” on page 2-17. For subsystem reuse
across referenced models, this procedure might not catch every difference.
Consider the model, rtwdemo_ssreuse. SS1 and SS2 are instances of the
same subsystem. In both instances the subsystem parameter Function
packaging is set to Reusable function.

2-32

Determine Why Subsystem Code Is Not Reused

Use the method, Simulink.SubSystem.getChecksum, to get the checksum for
a subsystem. Compare the results to determine why code is not reused.
1 Open the model rtwdemo_ssreuse. Save a copy of the model in a folder

where you have write access.
2 In the model window, select subsystem SS1. In the command window, enter

SS1 = gcb;
3 In the model window, select subsystem SS2. In the command window, enter

SS2 = gcb;
4 Use the method, Simulink.SubSystem.getChecksum, to get the checksum

for each subsystem. This method returns two output values: the checksum
value and details on the input used to compute the checksum.
[chksum1, chksum1_details] = ...
Simulink.SubSystem.getChecksum(SS1);
[chksum2, chksum2_details] = ...
Simulink.SubSystem.getChecksum(SS2);
5 Compare the two checksum values. They should be equal based on the

subsystem configurations.
isequal(chksum1, chksum2)
ans =
1
6 To see how you can use Simulink.SubSystem.getChecksum to determine

why the checksums of two subsystems differ, change the data type mode of
the output port of SS1 so that it differs from that of SS2.
a Look under the mask of SS1. Right-click the subsystem. In the context

menu, select Mask > Look Under Mask.
b In the block diagram of the subsystem, double-click the Lookup Table

block to open the Subsystem Parameters dialog box.
c Click Data Types.

2-33

2

Subsystems

d Select Saturate on integer overflow and click OK.
7 Get the checksum for SS1. Compare the checksums for the two subsystems.

This time, the checksums are not equal.
[chksum1, chksum1_details] = ...
Simulink.SubSystem.getChecksum(SS1);
isequal(chksum1, chksum2)
ans =
0
8 After you determine that the checksums are different, find out why. The

Simulink engine uses information, such as signal data types, some block
parameter values, and block connectivity information, to compute the
checksums. To determine why checksums are different, you compare the
data used to compute the checksum values. You can get this information
from the second value returned by Simulink.SubSystem.getChecksum,
which is a structure array with four fields.
Look at the structure chksum1_details.
chksum1_details
chksum1_details =
ContentsChecksum:
InterfaceChecksum:
ContentsChecksumItems:
InterfaceChecksumItems:

[1x1 struct]
[1x1 struct]
[287x1 struct]
[53x1 struct]

ContentsChecksum and InterfaceChecksum are component

checksums of the subsystem checksum. The remaining two fields,
ContentsChecksumItems and InterfaceChecksumItems, contain the

checksum details.
9 Determine whether a difference exists in the subsystem contents, interface,

or both. For example:
isequal(chksum1_details.ContentsChecksum.Value,...
chksum2_details.ContentsChecksum.Value)
ans =
0

2-34

Determine Why Subsystem Code Is Not Reused

isequal(chksum1_details.InterfaceChecksum.Value,...
chksum2_details.InterfaceChecksum.Value)
ans =
1

In this case, differences exist in the contents.
10 Write a script like the following to find the differences.
idxForCDiffs=[];
for idx = 1:length(chksum1_details.ContentsChecksumItems)
if (~strcmp(chksum1_details.ContentsChecksumItems(idx).Identifier, ...
chksum2_details.ContentsChecksumItems(idx).Identifier))
disp(['Identifiers different for contents item ', num2str(idx)]);
idxForCDiffs=[idxForCDiffs, idx];
end
if (ischar(chksum1_details.ContentsChecksumItems(idx).Value))
if (~strcmp(chksum1_details.ContentsChecksumItems(idx).Value, ...
chksum2_details.ContentsChecksumItems(idx).Value))
disp(['String values different for contents item ', num2str(idx)]);
idxForCDiffs=[idxForCDiffs, idx];
end
end
if (isnumeric(chksum1_details.ContentsChecksumItems(idx).Value))
if (chksum1_details.ContentsChecksumItems(idx).Value ~= ...
chksum2_details.ContentsChecksumItems(idx).Value)
disp(['Numeric values different for contents item ', num2str(idx)]);
idxForCDiffs=[idxForCDiffs, idx];
end
end
end

11 Run the script. The following example assumes that you named the script

check_details.
check_details
String values different for contents item 202

The results indicate that differences exist for index item 202 in the
subsystem contents.

2-35

2

Subsystems

12 Use the returned index values to get the handle, identifier, and value

details for each difference found.
chksum1_details.ContentsChecksumItems(202)
ans =
Handle: 'rtwdemo_ssreuse/SS1/Lookup Table'
Identifier: 'SaturateOnIntegerOverflow'
Value: 'on'

The details identify the Lookup Table block parameter Saturate on
integer overflow as the focus for debugging a subsystem reuse issue.

2-36

3
Referenced Models

3

Referenced Models

Code Generation for Referenced Models
This section describes model referencing considerations that apply specifically
to code generation by the Simulink Coder. This section assumes that you
understand referenced models and related terminology and requirements, as
described in “Overview of Model Referencing” and associated topics.
When generating code for a referenced model hierarchy, the code generator
produces a stand-alone executable for the top model, and a library module
called a model reference target for each referenced model. When the code
executes, the top executable invokes the model reference targets to compute
the referenced model outputs. Model reference targets are sometimes called
Simulink Coder targets.
Be careful not to confuse a model reference target (Simulink Coder target)
with any of these other types of targets:
• Hardware target — A platform for which the Simulink Coder software
generates code
• System target — A file that tells the Simulink Coder software how to
generate code for particular purpose
• Rapid Simulation target (RSim) — A system target file supplied with the
Simulink Coder product
• Simulation target — A MEX-file that implements a referenced model that
executes with Simulink Accelerator™ software
The code generator places the code for the top model of a hierarchy in the
current working folder, and the code for submodels in a folder named slprj
within the current working folder. Subfolders in slprj provide separate
places for different types of files. See “Project Folder Structure for Model
Reference Targets” on page 3-16 for details.
By default, the product uses incremental code generation. When generating
code, it compares structural checksums of referenced model files with the
generated code files to determine whether to regenerate model reference
targets. To control when rebuilds occur, use the configuration parameter
Model Referencing > Rebuild. For details, see “Rebuild”.

3-2

Code Generation for Referenced Models

In addition to incremental code generation, the Simulink Coder software
uses incremental loading. The code for a referenced model is not loaded into
memory until the code for its parent model executes and needs the outputs of
the referenced model. The product then loads the referenced model target and
executes. Once loaded, the target remains in memory until it is no longer used.
Most code generation considerations are the same whether or not a model
includes any referenced models: the code generator handles the details
automatically insofar as possible. This chapter describes topics that you may
need to consider when generating code for a model reference hierarchy.
If you have a Embedded Coder license, custom targets must declare
themselves to be model reference compliant if they need to support Model
blocks. For more information, see “Support Model Referencing” on page
24-101.

3-3

3

Referenced Models

Generate Code for Referenced Models
In this section...
“About Generating Code for Referenced Models” on page 3-4
“Create and Configure the Subsystem” on page 3-4
“Convert Model to Use Model Referencing” on page 3-7
“Generate Model Reference Code for a GRT Target” on page 3-11
“Work with Project Folders” on page 3-14

About Generating Code for Referenced Models
To generated code for referenced models, you
1 Create a subsystem in an existing model.
2 Convert the subsystem to a referenced model (Model block).
3 Call the referenced model from the top model.
4 Generate code for the top model and referenced model.
5 Explore the generated code and the project folder.

You can accomplish some of these tasks automatically with a function called
Simulink.Subsystem.convertToModelReference.

Create and Configure the Subsystem
In the first part of this example, you define a subsystem for the vdp
example model, set configuration parameters for the model, and use the
Simulink.Subsystem.convertToModelReference function to convert it into
two new models — the top model (vdptop) and a referenced model vdpmultRM
containing a subsystem you created (vdpmult).

3-4

Generate Code for Referenced Models

1 In the MATLAB Command Window, create a new working folder wherever

you want to work and cd into it:
mkdir mrexample
cd mrexample
2 Open the vdp example model by typing:

vdp
3 Drag a box around the three blocks outlined in blue below:

4 ChooseCreate Subsystem from Selected from the model’s Diagram >

Subsystem & Model Reference menu.
A subsystem block replaces the selected blocks.
5 If the new subsystem block is not where you want it, move it to a preferred

location.
6 Rename the block vdpmult.

3-5

3

Referenced Models

7 Right-click the vdpmult block and select Subsystem Parameters.

The Function Block Parameters dialog box appears.
8 In the Function Block Parameters dialog box, select Treat as atomic

unit, then click OK.
The border of the vdpmult subsystem thickens to indicate that it is now
atomic. An atomic subsystem executes as a unit relative to the parent
model: subsystem block execution does not interleave with parent block
execution. This property makes it possible to extract subsystems for use as
stand-alone models and as functions in generated code.
The block diagram should now appear as follows:

You must set several properties before you can extract a subsystem for use as
a referenced model. To set the properties,
1 Open Model Explorer by selecting Model Explorer from the model’s

View menu.

3-6

Generate Code for Referenced Models

2 In the Model Hierarchy pane, click the symbol preceding the model name

to reveal its components.
3 Click Configuration (Active) in the left pane.
4 In the center pane, select Solver.
5 In the right pane, under Solver Options change the Type to Fixed-step,

then click Apply. You must use fixed-step solvers when generating code,
although referenced models can use different solvers than top models.
6 In the center pane, select Optimization. In the right pane, select

the Signals and Parameters tab, and under Simulation and code
generation, select Inline parameters. Click Apply.
7 In the center pane, select Diagnostics. In the right pane:
a Select the Data Validity tab. In the Signals area, set Signal

resolution to Explicit only.
b Select the Connectivity tab. In the Buses area, set Mux blocks used

to create bus signals to error.
8 Click Apply.

The model now has the properties that model referencing requires.
9 In the center pane, click Model Referencing. In the right pane, set

Rebuild to If any changes in known dependencies detected. Click
Apply. This setting prevents code regeneration when it is not required.
10 In the vdp model window, choose File > Save as. Save the model as

vdptop in your working folder. Leave the model open.

Convert Model to Use Model Referencing
In this portion of the example, you use the conversion function
Simulink.SubSystem.convertToModelReference to extract the subsystem
vdpmult from vdptop and convert vdpmult into a referenced model named
vdpmultRM. To see the complete syntax of the conversion function, type at
the MATLAB prompt:
help Simulink.SubSystem.convertToModelReference

3-7

3

Referenced Models

For additional information, type:
doc Simulink.SubSystem.convertToModelReference

If you want to see an example of
Simulink.SubSystem.convertToModelReference before using it

yourself, type:
sldemo_mdlref_conversion

Simulink also provides a menu command, Subsystem & Model
Reference > Convert Subsystem to > Referenced Model, that you
can use to convert a subsystem to a referenced model. The command calls
Simulink.SubSystem.convertToModelReference with default arguments.
For more information, see “Convert a Subsystem to a Referenced Model”.

Extract the Subsystem to a Referenced Model
To use Simulink.SubSystem.convertToModelReference to extract vdpmult
and convert it to a referenced model, type:
Simulink.SubSystem.convertToModelReference...
('vdptop/vdpmult', 'vdpmultRM',...
'ReplaceSubsystem', true, 'BuildTarget', 'Sim')

This command:
1 Extracts the subsystem vdpmult from vdptop.
2 Converts the extracted subsystem to a separate model named vdpmultRM

and saves the model to the working folder.
3 In vdptop, replaces the extracted subsystem with a Model block that

references vdpmultRM.
4 Creates a simulation target for vdptop and vdpmultRM.

The converter prints progress messages and terminates with
ans =
1

3-8

Generate Code for Referenced Models

The parent model vdptop now looks like this:

Note the changes in the appearance of the block vdpmult. These changes
indicate that it is now a Model block rather than a subsystem. As a Model
block, it has no contents of its own: the previous contents now exist in the
referenced model vdpmultRM, whose name appears at the top of the Model
block. Widen the Model block to expose the complete name of the referenced
model.
If the parent model vdptop had been closed at the time of conversion, the
converter would have opened it. Extracting a subsystem to a referenced model
does not automatically create or change a saved copy of the parent model. To
preserve the changes to the parent model, save vdptop.
Right-click the Model block vdpmultRM and choose Open Model
’vdpmultRM’ to open the referenced model. The model looks like this:

3-9

3

Referenced Models

Files Created and Changed by the Converter
The files in your working folder now consist of the following (not in this order).
File

Description

vdptop model file

Top model that contains a Model block
where the vdpmult subsystem was

vdpmultRM model file

Referenced model created for the vdpmult
subsystem

vdpmultRM_msf.mexw32

Static library file (Microsoft Windows
platforms only). The last three characters
of the suffix are system-dependent and may
differ. This file executes when the vdptop
model calls the Model block vdpmult. When
called, vdpmult in turn calls the referenced
model vdpmultRM.

/slprj

Project folder for generated model reference
code

Code for model reference simulation targets is placed in the slprj/sim
subfolder. Generated code for GRT, ERT, and other Simulink Coder targets is
placed in slprj subfolders named for those targets. You will inspect some
model reference code later in this example. For more information on project
folders, see “Work with Project Folders” on page 3-14.

3-10

Generate Code for Referenced Models

Run the Converted Model
Open the Scope block in vdptop if it is not visible. In the vdptop window, click
the Run tool or choose Run from the Simulation menu. The model calls the
vdpmultRM_msf simulation target to simulate. The output looks like this:

Generate Model Reference Code for a GRT Target
The function Simulink.SubSystem.convertToModelReference created the
model and the simulation target files for the referenced model vdpmultRM. In
this part of the example, you generate code for that model and the vdptop
model, and run the executable you create:
1 Verify that you are still working in the mrexample folder.
2 If the model vdptop is not open, open it. Make sure it is the active window.
3 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
4 In the Model Hierarchy pane, click the symbol preceding the vdptop

model to reveal its components.
5 Click Configuration (Active) in the left pane.
6 In the center pane, select Data Import/Export.

3-11

3

Referenced Models

7 In the Save to workspace section of the right pane, check Time and

Output and clear Data stores. Click Apply. The pane shows the following
information:

These settings instruct the model vdptop (and later its executable) to log
time and output data to MAT-files for each time step.
8 Generate GRT code (the default) and an executable for the top model and

the referenced model by selecting Code Generation in the center pane
and then clicking the Build button.

3-12

Generate Code for Referenced Models

The Simulink Coder build process generates and compiles code. The current
folder now contains a new file and a new folder:
File

Description

vdptop.exe

The executable created by the build
process

vdptop_grt_rtw/

The build folder, containing
generated code for the top model

The build process also generated GRT code for the referenced model, and
placed it in the slprj folder.
To view a model’s generated code in Model Explorer, the model must be
open. To use the Model Explorer to inspect the newly created build folder,
vdptop_grt_rtw:
1 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
2 In the Model Hierarchy pane, click the symbol preceding the model name

to reveal its components.
3 Click the symbol preceding Code for vdptop to reveal its components.
4 Directly under Code for vdptop, click This Model.

A list of generated code files for vdptop appears in the Contents pane:
rtmodel.h
vdptop.c
vdptop.h
vdptop.mk
vdptop_private.h
vdptop_types.h

3-13

3

Referenced Models

You can browse code in any of these files by selecting a file of interest in
the Contents pane.
To open a file in a text editor, click a filename, and then click the hyperlink
that appears in the gray area at the top of the Document pane. The
figure below illustrates viewing code for vdptop.c, in a text editor. Your
code may differ.

To view the generated code in the HTML code generation report, see
“Generate a Code Generation Report” on page 11-5.

Work with Project Folders
When you view generated code in Model Explorer, the files listed in the
Contents pane can exist either in a build folder or a project folder. Model
reference project folders (always rooted under slprj), like build folders, are
created in your current working folder, and this implies certain constraints on
when and where model reference targets are built, and how they are accessed.
The models referenced by Model blocks can be stored anywhere. A given
top model can include models stored on different file systems or in different
folders. The same is not true for the simulation targets derived from these
models; under most circumstances, all models referenced by a given top model
must be set up to simulate and generate model reference target code in a
single project folder. The top and referenced models can exist anywhere on
your path, but the project folder is assumed to exist in your current folder.
This means that, if you reference the same model from several top models,
each stored in a different folder, you must either

3-14

Generate Code for Referenced Models

• Always work in the same folder and be sure that the models are on your
path
• Allow separate project folders, simulation targets, and Simulink Coder
targets to be generated in each folder in which you work
The files in such multiple project folders are generally quite redundant.
Therefore, to minimize code regeneration for referenced models, choose a
specific working folder and remain in it for all sessions.
As model reference code generated for Simulink Coder targets as well as
for simulation targets is placed in project folders, the same considerations
as above apply even if you are generating target applications only. That is,
code for all models referenced from a given model ends up being generated
in the same project folder, even if it is generated for different targets and at
different times.

3-15

3

Referenced Models

Project Folder Structure for Model Reference Targets
Code for models referenced by using Model blocks is generated in project
folders within the current working folder. The top-level project folder is
always named /slprj. The next level within slprj contains parallel build
area subfolders.
The following table lists principal project folders and files. In the paths listed,
model is the name of the model being used as a referenced model, and target
is the system target file acronym (for example, grt, ert, rsim, and so on).

Folders and Files

Description

slprj/sim/model/

Simulation target files for referenced
models

slprj/sim/model/tmwinternal

MAT-files used during code generation

slprj/target/model/referenced_model_includes Header files from models referenced by

this model
slprj/target/model

Model reference target files

slprj/target/model/tmwinternal

MAT-files used during code generation

slprj/sl_proj.tmw

Marker file

slprj/target/_sharedutils

Utility functions for model reference
targets, shared across models

slprj/sim/_sharedutils

Utility functions for simulation targets,
shared across models

If you are building code for more than one referenced model within the same
working folder, model reference files for all such models are added to the
existing slprj folder.

3-16

Configure Referenced Models

Configure Referenced Models
Minimize occurrences of algebraic loops by selecting the Minimize algebraic
loop occurrences parameter on the Model Reference pane. The setting
of this option affects only generation of code from the model. See “Hardware
Targets” on page 9-9 in the Simulink Coder documentation for information
on how this option affects code generation. For more information, see “Model
Blocks and Direct Feedthrough”.
Use the Integer rounding mode parameter on your model’s blocks to
simulate the rounding behavior of the C compiler that you intend to use to
compile code generated from the model. This setting appears on the Signal
Attributes pane of the parameter dialog boxes of blocks that can perform
signed integer arithmetic, such as the Product and n-D Lookup Table blocks.
For most blocks, the value of Integer rounding mode completely defines
rounding behavior. For blocks that support fixed-point data and the Simplest
rounding mode, the value of Signed integer division rounds to also affects
rounding. For details, see “Rounding”.
When models contain Model blocks, all models that they reference must be
configured to use identical hardware settings. For information on the Model
Referencing pane options, see “Model Referencing Pane” and “Configuration
Parameter Requirements”.

3-17

3

Referenced Models

Build Model Reference Targets
By default, the Simulink engine rebuilds simulation targets before the
Simulink Coder software generates model reference targets. You can change
the rebuild criteria or specify that the engine always or never rebuilds targets.
See “Rebuild” for details.
The Simulink Coder software generates a model reference target directly from
the Simulink model. The product automatically generates or regenerates
model reference targets, for example, when they require an update.
You can command the Simulink and Simulink Coder products to generate a
simulation target for an Accelerator mode referenced model, and a model
reference target for any referenced model, by executing the slbuild command
with arguments in the MATLAB Command Window.
The Simulink Coder software generates only one model reference target for
all instances of a referenced model. See “Reusable Code and Referenced
Models” on page 3-32 for details.

Reduce Change Checking Time
You can reduce the time that the Simulink and Simulink Coder products
spend checking whether any or all simulation targets and model reference
targets need to be rebuilt by setting configuration parameter values as follows:
• In the top model, consider setting the model configuration parameter Model
Referencing > Rebuild to If any changes in known dependencies
detected. (See “Rebuild”.)
• In all referenced models throughout the hierarchy, set the configuration
parameter Diagnostics > Data Validity > Signal resolution to
Explicit only. (See “Signal resolution”.)
These parameter values exist in a referenced model’s configuration set, not
in the individual Model block, so setting either value for any instance of a
referenced model sets it for all instances of that model.

3-18

Simulink® Coder™ Model Referencing Requirements

Simulink Coder Model Referencing Requirements
A model reference hierarchy must satisfy various Simulink Coder
requirements, as described in this section. In addition to these requirements,
a model referencing hierarchy to be processed by the Simulink Coder software
must satisfy:
• The Simulink requirements listed in:

-

“Configuration Requirements for All Referenced Model Simulation”
“Model Structure Requirements”

• The Simulink limitations listed in “Limitations on All Model Referencing”
• The Simulink Coder limitations listed in “Simulink® Coder™ Model
Referencing Limitations” on page 3-36

Configuration Parameter Requirements
A referenced model uses a configuration set in the same way that any other
model does, as described in “Manage a Configuration Set”. By default, every
model in a hierarchy has its own configuration set, which it uses in the same
way that it would if the model executed independently.
Because each model can have its own configuration set, configuration
parameter values can be different in different models. Furthermore, some
parameter values are intrinsically incompatible with model referencing. The
response of the Simulink Coder software to an inconsistent or unusable
configuration parameter depends on the parameter:
• Where an inconsistency has no significance, or a trivial resolution exists
that carries no risk, the product ignores or resolves the inconsistency
without posting a warning.
• Where a nontrivial and possibly acceptable solution exists, the product
resolves the conflict silently; resolves it with a warning; or generates an
error. See “Model configuration mismatch” for details.
• Where no acceptable resolution is possible, the product generates an
error. You must then change some or all parameter values to eliminate
the problem.

3-19

3

Referenced Models

When a model reference hierarchy contains many submodels that have
incompatible parameter values, or a changed parameter value must propagate
to many submodels, manually eliminating all configuration parameter
incompatibilities can be tedious. You can control or eliminate such overhead
by using configuration references to assign an externally-stored configuration
set to multiple models. See “Manage a Configuration Reference” for details.
The following tables list configuration parameters that can cause problems if
set in certain ways, or if set differently in a referenced model than in a parent
model. Where possible, the Simulink Coder software resolves violations of
these requirements automatically, but most cases require changes to the
parameters in some or all models.
Configuration Requirements for Model Referencing with All System
Targets
Dialog Box
Pane

Option

Requirement

Solver

Start time

Some system
targets require
the start time of
all models to be
zero.

Hardware
Emulation hardware options
Implementation

3-20

All values
must be the
same for top
and referenced
models.

Simulink® Coder™ Model Referencing Requirements

Configuration Requirements for Model Referencing with All System
Targets (Continued)
Dialog Box
Pane

Option

Requirement

Code
Generation

System target file

Must be the
same for top
and referenced
models.

Language

Must be the
same for top
and referenced
models.

Generate code only

Must be the
same for top
and referenced
models.

Symbols

Maximum identifier length

Cannot be longer
for a referenced
model than for
its parent model.

Interface

Code replacement library

Must be the
same for top
and referenced
models.

Data
C API
exchange > Interface

The C API check
boxes for signals,
parameters, and
states must be
the same for top
and referenced
models.

ASAP2

Can be on or off
in a top model,
but must be off
in a referenced

3-21

3

Referenced Models

Configuration Requirements for Model Referencing with All System
Targets (Continued)
Dialog Box
Pane

Option

Requirement

model. If it is
not, the Simulink
Coder software
temporarily sets
it to off during
code generation.
Configuration Requirements for Model Referencing with ERT System
Targets (Requires Embedded Coder License)
Dialog
Box Pane

3-22

Option

Requirement

Ignore custom storage
Code
Generation classes

Must be the same for top and
referenced models.

Symbols

Global variables
Global types
Subsystem methods
Local temporary variables
Constant macros

$R token must appear.

Signal naming

Must be the same for top and
referenced models.

M-function

If specified, must be the same
for top and referenced models.

Parameter naming

Must be the same for top and
referenced models.

#define naming

Must be the same for top and
referenced models.

Simulink® Coder™ Model Referencing Requirements

Configuration Requirements for Model Referencing with ERT System
Targets (Requires Embedded Coder License) (Continued)
Dialog
Box Pane

Option

Requirement

Interface

Support floating-point
numbers

Must be the same for both top
and referenced models

Support non-finite
numbers

If off for top model, must be
off for referenced models.

Support complex numbers

If off for top model, must be
off for referenced models.

Suppress error status in
real-time model

If on for top model, must be
on for referenced models.

Templates Target operating system

Must be the same for top and
referenced models.

Data
Module Naming
Placement

Must be the same for top and
referenced models.

Module Name (if specified)

If set, must be the same for
top and referenced models.

Signal display level

Must be the same for top and
referenced models.

Parameter tune level

Must be the same for top and
referenced models.

Naming Requirements
Within a model that uses model referencing, there can be no collisions
between the names of the constituent models. When you generate code from
a model that uses model referencing, the Maximum identifier length
parameter must be large enough to accommodate the root model name and
the name mangling string. A code generation error occurs if Maximum
identifier length is not large enough.
When a name conflict occurs between a symbol within the scope of a
higher-level model and a symbol within the scope of a referenced model, the

3-23

3

Referenced Models

symbol from the referenced model is preserved. Name mangling is performed
on the symbol from the higher-level model.

Embedded Coder Naming Requirements
The Embedded Coder product provides a Symbol format field that lets you
control the formatting of generated symbols in much greater detail. When
generating code with an ERT target from a model that uses model referencing:
• The $R token must be included in the Identifier format control
parameter specifications (in addition to the $M token).
• The Maximum identifier length must be large enough to accommodate
full expansions of the $R and $M tokens.
See “Code Generation Pane: Symbols” for more information.

Custom Target Requirements
If you have an Embedded Coder license, a custom target must meet various
requirements to support model referencing. For details, see “Support Model
Referencing” on page 24-101.

3-24

Storage Classes for Signals Used with Model Blocks

Storage Classes for Signals Used with Model Blocks
Models containing Model blocks can use signals of storage class Auto without
restriction. However, when you declare signals to be global, you must be
aware of how the signal data will be handled.
A global signal is a signal with a storage class other than Auto:
• ExportedGlobal
• ImportedExtern
• ImportedExternPointer
• Custom
The above are distinct from SimulinkGlobal signals, which are treated as
test points with Auto storage class.
Global signals are declared, defined, and used as follows:
• An extern declaration is generated by all models that use any given global
signal.
As a result, if a signal crosses a Model block boundary, the top model and
the referenced model both generate extern declarations for the signal.
• For any exported signal, the top mode is responsible for defining (allocating
memory for) the signal, whether or not the top model itself uses the signal.
• All global signals used by a referenced model are accessed directly (as
global memory). They are not passed as arguments to the functions that
are generated for the referenced models.
Custom storage classes also follow the above rules. However, certain custom
storage classes are not currently supported for use with model reference. See
“Custom Storage Class Limitations” for details.

3-25

3

Referenced Models

Storage Classes for Parameters Used with Model
Blocks
All storage classes are supported for both simulation and code generation, and
all except Auto are tunable. The supported storage classes thus include
• SimulinkGlobal
• ExportedGlobal
• ImportedExtern
• ImportedExternPointer
• Custom
Note the following restrictions on parameters in referenced models:
• Tunable parameters are not supported for noninlined S-functions.
• Tunable parameters set using the Model Parameter Configuration dialog
box are ignored.
Note the following considerations concerning how global tunable parameters
are declared, defined, and used in code generated for targets:
• A global tunable parameter is a parameter in the base workspace with a
storage class other than Auto.
• An extern declaration is generated by all models that use any given
parameter.
• If a parameter is exported, the top model is responsible for defining
(allocating memory for) the parameter (whether it uses the parameter
or not).
• All global parameters are accessed directly (as global memory). They are
not passed as arguments to any of the functions that are generated for
any of the referenced models.
• Symbols for SimulinkGlobal parameters in referenced models are
generated using unstructured variables (rtP_xxx) instead of being written
into the model_P structure. This is so that each referenced model can be
compiled independently.

3-26

Storage Classes for Signals Used with Model Blocks

Certain custom storage classes for parameters are not currently supported for
model reference. See “Custom Storage Class Limitations” for details.
Parameters used as Model block arguments must be defined in the referenced
model’s workspace. See “Parameterize Model References” in the Simulink
documentation for specific details.

Effects of Signal Name Mismatches
Within a parent model, the name and storage class for a signal entering or
leaving a Model block might not match those of the signal attached to the root
inport or outport within that referenced model. Because referenced models
are compiled independently without regard to any parent model, they cannot
adapt to all possible variations in how parent models label and store signals.
The Simulink Coder software accepts all cases where input and output signals
in a referenced model have Auto storage class. When such signals are test
pointed or are global, as described above, certain restrictions apply. The
following table describes how mismatches in signal labels and storage classes
between parent and referenced models are handled:
Relationships of Signals and Storage Classes Between Parent and
Referenced Models

Signal Passing
Method

Signal
Mismatch
Checking

Referenced
Model

Parent Model

Auto

Any

Function
argument

None

SimulinkGlobal
or resolved to
Signal Object

Any

Function
argument

Label Mismatch
Diagnostic (none
/ warning / error)

3-27

3

Referenced Models

Relationships of Signals and Storage Classes Between Parent and
Referenced Models (Continued)

Referenced
Model

Parent Model

Signal Passing
Method

Signal
Mismatch
Checking

Global

Auto or
SimulinkGlobal

Global variable

Label Mismatch
Diagnostic (none
/ warning / error)

Global

Global

Global variable

Labels and
storage classes
must be identical
(else error)

To summarize, the following signal resolution rules apply to code generation:
• If the storage class of a root input or output signal in a referenced model is
Auto (or is SimulinkGlobal), the signal is passed as a function argument.

-

When such a signal is SimulinkGlobal or resolves to a Simulink.Signal
object, the Signal Mismatch diagnostic is applied.

• If a root input or output signal in a referenced model is global, it is
communicated by using direct memory access (global variable). In addition,

-

If the corresponding signal in the parent model is also global, the names
and storage classes must match exactly.

-

If the corresponding signal in the parent model is not global, the Signal
Mismatch diagnostic is applied.

You can set the Signal Mismatch diagnostic to error, warning, or none in
the Diagnostics > Connectivity pane of the Configuration Parameters
dialog box.

3-28

Inherited Sample Time for Referenced Models

Inherited Sample Time for Referenced Models
See “Inherit Sample Times” in the Simulink documentation for
information about Model block sample time inheritance. In
generated code, you can control inheriting sample time by using
ssSetModelReferenceSampleTimeInheritanceRule in different ways:
• An S-function that precludes inheritance: If the sample time is used
in the S-function’s run-time algorithm, then the S-function precludes a
model from inheriting a sample time. For example, consider the following
mdlOutputs code:
static void mdlOutputs(SimStruct *S, int_T tid)
{
const real_T *u = (const real_T*)
ssGetInputPortSignal(S,0);
real_T
*y = ssGetOutputPortSignal(S,0);
y[0] = ssGetSampleTime(S,tid) * u[0];
}

This mdlOutputs code uses the sample time in its algorithm, and the
S-function therefore should specify
ssSetModelReferenceSampleTimeInheritanceRule
(S, DISALLOW_SAMPLE_TIME_INHERITANCE);

• An S-function that does not preclude Inheritance: If the sample time
is only used for determining whether the S-function has a sample hit,
then it does not preclude the model from inheriting a sample time. For
example, consider the mdlOutputs code from the S-function example
sfun_multirate.c:
static void mdlOutputs(SimStruct *S, int_T tid)
{
InputRealPtrsType enablePtrs;
int
*enabled = ssGetIWork(S);
if (ssGetInputPortSampleTime
(S,ENABLE_IPORT)==CONTINUOUS_SAMPLE_TIME &&
ssGetInputPortOffsetTime(S,ENABLE_IPORT)==0.0) {

3-29

3

Referenced Models

if (ssIsMajorTimeStep(S) &&
ssIsContinuousTask(S,tid)) {
enablePtrs =
ssGetInputPortRealSignalPtrs(S,ENABLE_IPORT);
*enabled = (*enablePtrs[0] > 0.0);
}
} else {
int enableTid =
ssGetInputPortSampleTimeIndex(S,ENABLE_IPORT);
if (ssIsSampleHit(S, enableTid, tid)) {
enablePtrs =
ssGetInputPortRealSignalPtrs(S,ENABLE_IPORT);
*enabled = (*enablePtrs[0] > 0.0);
}
}
if (*enabled) {
InputRealPtrsType uPtrs =
ssGetInputPortRealSignalPtrs(S,SIGNAL_IPORT);
real_T
signal = *uPtrs[0];
int
i;
for (i = 0; i < NOUTPUTS; i++) {
if (ssIsSampleHit(S,
ssGetOutputPortSampleTimeIndex(S,i), tid)) {
real_T *y = ssGetOutputPortRealSignal(S,i);
*y = signal;
}
}
}
} /* end mdlOutputs */

The above code uses the sample times of the block, but only for determining
whether there is a hit. Therefore, this S-function should set
ssSetModelReferenceSampleTimeInheritanceRule
(S, USE_DEFAULT_FOR_DISCRETE_INHERITANCE);

3-30

Customize Library File Suffix and File Type

Customize Library File Suffix and File Type
You can control the library file suffix and file type extension that the Simulink
Coder code generator uses to name generated model reference libraries. Use
the model configuration parameter TargetLibSuffix to specify the string for
the suffix and extension. The string must include a period (.). If you do not set
this parameter, the Simulink Coder software names the libraries as follows:
• On Windows systems, model_rtwlib.lib
• On UNIX or Linux® systems, model_rtwlib.a

3-31

3

Referenced Models

Reusable Code and Referenced Models
Models that employ model referencing might require special treatment when
generating and using reusable code. The following sections identify general
restrictions and discuss how reusable functions with inputs or outputs
connected to a referenced model’s root Inport or Outport blocks can affect
code reuse.

General Considerations
You can generate code for subsystems that contain referenced models
using the same procedures and options described in “Code Generation of
Subsystems” on page 2-2. However, the following restrictions apply to such
builds:
• A top model that uses single-tasking mode and that has a submodel that
uses multi-tasking mode executes for blocks with the different rates that
are not connected. However, you get an error if the blocks with different
rates are connected by Rate Transition block (inserted either manually
or by Simulink).
• ERT S-functions do not support subsystems that contain a continuous
sample time.
• The Simulink Coder S-function target is not supported.
• The Tunable parameters table (set by using the Model Parameter
Configuration dialog box) is ignored; to make parameters tunable, you
must define them as Simulink parameter objects in the base workspace.
• All other parameters are inlined into the generated code and S-function.
Note You can generate subsystem code using any target configuration
available in the System Target File Browser. However, if the S-function
target is selected, Build This Subsystem and Build Selected
Subsystem behaves identically to Generate S-Function. (See “Automate
S-Function Generation” on page 14-23.)

3-32

Reusable Code and Referenced Models

Code Reuse and Model Blocks with Root Inport or
Outport Blocks
Reusable functions with inputs or outputs connected to a referenced model’s
root Inport or Outport block can affect code reuse. This means that code for
certain atomic subsystems cannot be reused in a model reference context the
same way it is reused in a standalone model.
For example, suppose you create the following subsystem and make the
following changes to the subsystem’s block parameters:
• Select Treat as an atomic unit
• Go to the Code Generation tab and set Function packaging to
Reusable function

Suppose you then create the following model, which includes three instances
of the preceding subsystem.

With the Inline parameters option enabled in this stand-alone model, the
Simulink Coder code generator can optimize the code by generating a single
copy of the function for the reused subsystem, as shown below.
void reuse_subsys1_Subsystem1(
real_T rtu_0,
rtB_reuse_subsys1_Subsystem1 *localB)
{

3-33

3

Referenced Models

/* Gain: '/Gain' */
localB->Gain_k = rtu_0 * 3.0;
}

When generated as code for a Model block (into an slprj project folder), the
subsystems have three different function signatures:
/* Output and update for atomic system: '/Subsystem1' */
void reuse_subsys1_Subsystem1(const real_T *rtu_0,
rtB_reuse_subsys1_Subsystem1
*localB)
{
/* Gain: '/Gain' */
localB->Gain_w = (*rtu_0) * 3.0;
}
/* Output and update for atomic system: '/Subsystem2' */
void reuse_subsys1_Subsystem2(real_T rtu_In1,
rtB_reuse_subsys1_Subsystem2
*localB)
{
/* Gain: '/Gain' */
localB->Gain_y = rtu_In1 * 3.0;
}
/* Output and update for atomic system: '/Subsystem3' */
void reuse_subsys1_Subsystem3(real_T rtu_In1, real_T *rty_0)
{
/* Gain: '/Gain' */
(*rty_0) = rtu_In1 * 3.0;
}

One way to make all the function signatures the same for code reuse, is
to insert Signal Conversion blocks. Place one between the Inport and
Subsystem1 and another between Subsystem3 and the Outport of the
referenced model.

3-34

Reusable Code and Referenced Models

The result is a single reusable function:
void reuse_subsys2_Subsystem1(real_T rtu_In1,
rtB_reuse_subsys2_Subsystem1 *localB)
{
/* Gain: '/Gain' */
localB->Gain_g = rtu_In1 * 3.0;
}

You can achieve the same result (reusable code) with only one Signal
Conversion block. You can omit the Signal Conversion block connected to the
Inport block if you select the Pass fixed-size scalar root inputs by value
check box at the bottom of the Model Referencing pane of the Configuration
Parameters dialog box. When you do this, you still need to insert a Signal
Conversion block before the Outport block.

3-35

3

Referenced Models

Simulink Coder Model Referencing Limitations
The following Simulink Coder limitations apply to model referencing. In
addition to these limitations, a model reference hierarchy used for code
generation must satisfy:
• The Simulink requirements listed in:

-

“Configuration Requirements for All Referenced Model Simulation”
“Model Structure Requirements”

• The Simulink limitations listed in “Model Referencing Limitations”.
• The Simulink Coder requirements applicable to the code generation target,
as listed in “Configuration Parameter Requirements” on page 3-19.

Customization Limitations
• The code generator ignores custom code settings in the Configuration
Parameter dialog box and custom code blocks when generating code for
a referenced model.
• Referenced models do not support custom storage classes if the parent
model has inline parameters off.
• This release does not include Stateflow target custom code in simulation
targets generated for referenced models.
• Data type replacement is not supported for simulation target code
generation for referenced models.
• Simulation targets do not include Stateflow target custom code.
• If you have an Embedded Coder license, some restrictions exist on grouped
custom storage classes in referenced models. For details, see “Custom
Storage Class Limitations”.

Data Logging Limitations
• To Workspace blocks, Scope blocks, and all types of runtime display,
such as the display of port values and signal values, are ignored when
the Simulink Coder software generates code for a referenced model. The
resulting code is the same as if the constructs did not exist.

3-36

Simulink® Coder™ Model Referencing Limitations

• Code generated for referenced models cannot log data to MAT-files. If data
logging is enabled for a referenced model, the Simulink Coder software
disables the option before code generation and re-enables it afterwards.
• If you log states for a model that contains referenced models, the ordering
of the states in the output is determined by block sorted order, and might
not match between simulation output and generated code MAT-file logging
output.

State Initialization Limitation
When a top model uses the Load from workspace > Initial state option
to specify initial conditions, the Simulink Coder software does not initialize
the states of any referenced models.

3-37

3

Referenced Models

Reusability Limitations
If a referenced model used for code generation has any of the following
properties, the model must specify the configuration parameter Model
Referencing > Total number of instances allowed per top model as
One, and no other instances of the model can exist in the hierarchy. If you do
not set the parameter to One, or more than one instance of the model exists in
the hierarchy, an error occurs. The properties are:
• The model references another model which has been set to single instance
• The model contains a state or signal with non-auto storage class
• The model uses any of the following Stateflow constructs:

-

Machine-parented data
Machine-parented events
Stateflow graphical functions

• The model contains a subsystem that is marked as function
• The model contains an S-function that is:

-

Inlined but has not set the option SS_OPTION_WORKS_WITH_CODE_REUSE
Not inlined

• The model contains a function-call subsystem that:

-

3-38

Has been forced by the Simulink engine to be a function
Is called by a wide signal

Simulink® Coder™ Model Referencing Limitations

S-Function Limitations
• If a referenced model contains an S-function that should be inlined using a
Target Language Compiler file, the S-function must use the ssSetOptions
macro to set the SS_OPTION_USE_TLC_WITH_ACCELERATOR option in its
mdlInitializeSizes method. The simulation target will not inline the
S-function unless this flag is set.
• A referenced model cannot use noninlined S-functions generated by the
Simulink Coder software.
• The Simulink Coder S-function target does not support model referencing.
For additional information, in the Simulink documentation, see “S-Functions
with Model Referencing”.

Simulink Tool Limitations
• Simulink tools that require access to a model’s internal data or
configuration (including the Model Coverage tool, the Simulink Report
Generator product, the Simulink debugger, and the Simulink profiler) have
no effect on code generated by the Simulink Coder software for a referenced
model, or on the execution of that code. Specifications made and actions
taken by such tools are ignored and effectively do not exist.

Subsystem Limitations
• If a subsystem contains Model blocks, you cannot build a subsystem module
by right-clicking the subsystem (or by using Code > C/C++ Code > Build
Selected Subsystem) unless the model is configured to use an ERT target.
• If you generate code for an atomic subsystem as a reusable function, inputs
or outputs that connect the subsystem to a referenced model can affect code
reuse, as described in “Reusable Code and Referenced Models” on page 3-32.

Target Limitations
• Simulink Coder grt_malloc targets do not support model reference.
• The Simulink Coder S-function target does not support model referencing.

3-39

3

Referenced Models

Other Limitations
• Errors or unexpected behavior can occur if a Model block is part of a cycle,
the Model block is a direct feedthrough block, and an algebraic loop results.
For details, see “Model Blocks and Direct Feedthrough”.
• The External mode option is not supported. If it is enabled, it is ignored
during code generation.

3-40

4
Combined Models

4

Combined Models

Combined Models
If you want to combine several models (or several instances of the same model)
into a single executable, the Simulink Coder product offers several options.
The most powerful solution is to use Model blocks. Each instance of a
Model block represents another model, called a referenced model. For code
generation, the referenced model effectively replaces the Model block that
references it. For details, see “Overview of Model Referencing” and “Generate
Code for Referenced Models” on page 3-4.
When developing embedded systems using the Embedded Coder product, you
can interface the code for several models to a common harness program by
directly calling the entry points to each model. However, the Embedded Coder
target has certain restrictions, relating to embedded processing, that might
not be compatible with your application.
The GRT malloc target is a another possible solution. Use it in situations
where you want to:
• Selectively control calls to more than one model
• Use dynamic memory allocation
• Include models that employ continuous states
• Log data to multiple files
• Run one of the models in external mode
For more information, see “Use GRT Malloc to Combine Models” on page 4-4.
To summarize by target, your options are as follows:

4-2

Target

Support for Combining Multiple
Models?

Generic Real-Time Target (grt.tlc)

Yes (using Model blocks)

Generic Real-Time Target with
dynamic memory allocation
(grt_malloc.tlc)

Yes

Combined Models

Target

Support for Combining Multiple
Models?

Embedded Coder (ert.tlc)

Yes

S-function Target (rtwsfcn.tlc)

No

4-3

4

Combined Models

Use GRT Malloc to Combine Models
This section discusses how to use the GRT malloc target to combine models
into a single program.
Building a multiple-model executable is fairly straightforward:
1 Generate and compile code from each of the models that are to be combined.
2 Combine the makefiles for each of the models into one makefile for creating

the final multimodel executable.
3 Create a combined simulation engine by modifying grt_malloc_main.c to

initialize and call the models.
4 Run the combination makefile to link the object files from the models and

the main program into an executable.

Share Data Across Models
Use unidirectional signal connections between models. This affects the order
in which models are called. For example, if an output signal from modelA is
used as input to modelB, modelA's output computation should be called first.

Timing Issues
You must generate all the models you are combining with the same solver
mode (either all single-tasking or all multitasking.) In addition, if the models
employ continuous states, the same solver should be used for all models.
Because each model has its own model-specific definition of the rtModel
data structure, you must use an alternative mechanism to control model
execution, as follows:
• The file rtw/c/src/rtmcmacros.h provides an rtModel API clue that can
be used to call the rt_OneStep procedure.
• The rtmcmacros.h header file defines the rtModelCommon data structure,
which has the minimum common elements in the rtModel structure
required to step a model forward one time step.

4-4

Use GRT Malloc to Combine Models

• The rtmcsetCommon macro populates an object of type rtModelCommon by
copying the respective similar elements in the model’s rtModel object. Your
main routine must create one rtModelCommon structure for each model
being called by the main routine.
• The main routine will subsequently invoke rt_OneStep with a pointer to
the rtModelCommon structure instead of a pointer to the rtModel structure.
If the base rates for the models are not the same, the main program (such as
grt_malloc_main) must set up the timer interrupt to occur at the greatest
common divisor rate of the models. The main program calls each model at
a time interval.

Data Logging and External Mode Support
A multiple-model program can log data to separate MAT-files for each model.
Only one of the models in a multiple-model program can use external mode.

4-5

4

4-6

Combined Models

5
Configure Model
Parameters
• “Hardware Targets” on page 9-9
• “Describing the Emulation and Embedded Targets” on page 9-45
• “Describing Embedded Hardware Characteristics” on page 9-54
• “Describing Emulation Hardware Characteristics” on page 9-55
• “Control the Location for Generated Files” on page 5-18
• “Control Generated Files Location Used for Simulation” on page 5-20
• “Control the Location for Code Generation Files” on page 5-22
• “Override Build Folder Settings for Current Session” on page 5-24

5

Configure Model Parameters

Platform Options for Development and Deployment
When you use Simulink software to create and execute a model, and Simulink
Coder software to generate code, you may need to consider up to three
platforms, often called hardware targets:
• MATLAB Host — The platform that runs MathWorks® software during
application development
• Embedded Target — The platform on which an application will be deployed
when it is put into production
• Emulation Target — The platform on which an application under
development is tested before deployment
The same platform might serve in two or possibly all three capacities, but they
remain conceptually distinct. Often the MATLAB host and the emulation
target are the same. The embedded target is usually different from, and less
powerful than, the MATLAB host or the emulation target; often it can do little
more than run a downloaded executable file.
When you use Simulink software to execute a model for which you will
later generate code, or use Simulink Coder software to generate code for
deployment on an embedded target, you must provide information about the
embedded target hardware and the compiler that you will use with it. The
Simulink software uses this information to get bit-true agreement for the
results of integer and fixed-point operations performed in simulation and in
code generated for the embedded target. The Simulink Coder code generator
uses the information to create code that executes with maximum efficiency.
When you generate code for testing on an emulation target, you must
additionally provide information about the emulation target hardware and the
compiler that you will use with it. The code generator uses this information
to create code that provides bit-true agreement for the results of integer and
fixed-point operations performed in simulation, in code generated for the
embedded target, and in code generated for the emulation target. Agreement
can result even though the embedded target and emulation target may use
very different hardware, and the compilers for the two targets may use
different defaults where the C standard does not completely define behavior.

5-2

Configure Emulation and Embedded Target Hardware

Configure Emulation and Embedded Target Hardware
The Configuration Parameters dialog Hardware Implementation pane
provides options that you can use to describe hardware properties, such as
data size and byte ordering, and compiler behavior details that may vary with
the compiler, such as integer rounding. The Hardware Implementation
pane contains two subpanes:
• Embedded Hardware — Describes the embedded target hardware
and the compiler that you will use with it. This information affects both
simulation and code generation.
• Emulation Hardware — Describes the emulation target hardware and
the compiler that you will use with it. This information affects only code
generation.
The two subpanes provide identical options and value choices. By default, the
Embedded Hardware subpane initially looks like this:

The default assumption is that the embedded target and emulation target are
the same, so the Emulation Hardware subpane by default does not need
to specify anything and contains only a checked option labeled None. Code
generated under this configuration will be suitable for production use, or for
testing in an environment identical to the production environment.
If you clear the check box, the Emulation Hardware subpane appears,
initially showing the same values as the Embedded Hardware subpane. If
you change any of these values, then generate code, the code will be able to
execute in the environment specified by the Emulation Hardware subpane,

5-3

5

Configure Model Parameters

but will behave as if it were executing in the environment specified by the
Embedded Hardware subpane. See “Describing Emulation Hardware
Characteristics” on page 9-55 for details.
If you have used the Code Generation pane to specify a System target
file, and the target file specifies a default microprocessor and its hardware
properties, the default and properties appear as initial values in the
Hardware Implementation pane.
Options with only one possible value cannot be changed. Any option that has
more than one possible value provides a list of legal values. If you specify
any hardware properties manually, check carefully that their values are
consistent with the system target file. Otherwise, the generated code may fail
to compile or execute, or may execute but give incorrect results.
Note Hardware Implementation pane options do not control hardware
or compiler behavior. They describe hardware and compiler properties to
MATLAB software, which uses the information to generate code for the
platform thatruns as efficiently as possible, and gives bit-true agreement for
the results of integer and fixed-point operations in simulation, production
code, and test code.
The rest of this section describes the options in the Embedded Hardware
and Emulation Hardware subpanes. Subsequent sections describe
considerations that apply only to one or the other subpane. For more about
Hardware Implementation options, see “Hardware Implementation Pane”.
To see an example of Hardware Implementation pane capabilities, run the
rtwdemo_targetsettings example.

Identify the Device Vendor
The Device vendor option gives the name of the device vendor. To set the
option, select a vendor name from the Device vendor menu. Your selection
of vendor will determine the available device values in the Device type list.
If the desired vendor name does not appear in the menu, select Generic and
then use the Device type option to further specify the device.

5-4

Configure Emulation and Embedded Target Hardware

Note
• For complete lists of Device vendor and Device type values, see “Device
vendor” and “Device type” in the Simulink reference documentation.
• To add Device vendor and Device type values to the default set that
is displayed on the Hardware Implementation pane, see “Registering
Additional Device Vendor and Device Type Values” on page 9-47.

Identify the Device Type
The Device type option selects a hardware device among the supported
devices listed for your Device vendor selection. To set the option, select
a microprocessor name from the Device type menu. If the desired
microprocessor does not appear in the menu, change the Device vendor
to Generic.
If you specified the Device vendor as Generic, examine the listed device
descriptions and select the device type that matches your hardware. If no
available device type matches, select Custom.
If you select a device type for which the target file specifies default hardware
properties, the properties appear as initial values in the subpane. Options
with only one possible value cannot be changed. An option that has more
than one possible value provides a list of legal values. Select values for your
hardware. If the device type is Custom, more options can be set, and each
option has a list of possible values.

Register Additional Device Vendor and Device Type
Values
To add Device vendor and Device type values to the default set that is
displayed on the Hardware Implementation pane, you can use a hardware
device registration API provided by the Simulink Coder software.
To use this API, you create an sl_customization.m file, located in your
MATLAB path, that invokes the registerTargetInfo function and fills
in a hardware device registry entry with device information. The device

5-5

5

Configure Model Parameters

information will be registered with Simulink software for each subsequent
Simulink session. (To register your device information without restarting
MATLAB, issue the MATLAB command sl_refresh_customizations.)
For example, the following sl_customization.m file adds device vendor
MyDevVendor and device type MyDevType to the Simulink device lists.
function sl_customization(cm)
cm.registerTargetInfo(@loc_register_device);
end
function thisDev = loc_register_device
thisDev = RTW.HWDeviceRegistry;
thisDev.Vendor = 'MyDevVendor';
thisDev.Type = 'MyDevType';
thisDev.Alias = {};
thisDev.Platform = {'Prod', 'Target'};
thisDev.setWordSizes([8 16 32 32 32]);
thisDev.LargestAtomicInteger = 'Char';
thisDev.LargestAtomicFloat = 'None';
thisDev.Endianess = 'Unspecified';
thisDev.IntDivRoundTo = 'Undefined';
thisDev.ShiftRightIntArith = true;
thisDev.setEnabled({'IntDivRoundTo'});
end

If you subsequently select the device in the Hardware Implementation
pane, it is displayed as follows:

5-6

Configure Emulation and Embedded Target Hardware

To register multiple devices, you can specify an array of
RTW.HWDeviceRegistry objects in your sl_customization.m file. For
example,
function sl_customization(cm)
cm.registerTargetInfo(@loc_register_device);
end
function thisDev = loc_register_device
thisDev(1) = RTW.HWDeviceRegistry;
thisDev(1).Vendor = 'MyDevVendor';
thisDev(1).Type = 'MyDevType1';
...
thisDev(4) = RTW.HWDeviceRegistry;
thisDev(4).Vendor = 'MyDevVendor';
thisDev(4).Type = 'MyDevType4';
...
end

The following table lists the RTW.HWDeviceRegistry properties that you can
specify in the registerTargetInfo function call in your sl_customization.m
file.
Property

Description

Vendor

String specifying the Device vendor value for your
hardware device.

Type

String specifying the Device type value for your
hardware device.

5-7

5

Configure Model Parameters

Property

Description

Alias

Cell array of strings specifying any aliases or
legacy names that users might specify that
should resolve to this device. Specify each alias
or legacy name in the format 'Vendor->Type'.
(Embedded Coder software provides the
utility functions RTW.isHWDeviceTypeEq and
RTW.resolveHWDeviceType for detecting and
resolving alias values or legacy values when testing
user-specified values for the target device type.)

Platform

Cell array of enumerated string values specifying
whether this device should be listed in the
Embedded hardware subpane ({'Prod'}), the
Emulation hardware subpane ({'Target'}), or
both ({'Prod', 'Target'}).

setWordSizes

Array of integer sizes to associate with the Number
of bits parameters char, short, int, long, and
native word size, respectively.

LargestAtomicIntegerString specifying an enumerated value for the
Largest atomic size: integer parameter: 'Char',
'Short','Int', or 'Long'.
LargestAtomicFloat String specifying an enumerated value for the

Largest atomic size: floating-point parameter:
'Float', 'Double', or 'None'.

5-8

Endianess

String specifying an enumerated value for the Byte
ordering parameter: 'Unspecified', 'Little' for
little Endian, or 'Big' for big Endian.

IntDivRoundTo

String specifying an enumerated value for the
Signed integer division rounds to parameter:
'Zero', 'Floor', or 'Undefined'.

Configure Emulation and Embedded Target Hardware

Property

Description

ShiftRightIntArith Boolean value specifying whether your compiler

implements a signed integer right shift as an
arithmetic right shift (true) or not (false).
setEnabled

Cell array of strings specifying which device
properties should be enabled (modifiable) in
the Hardware Implementation pane when
this device type is selected. In addition to
the 'Endianess', 'IntDivRoundTo', and
'ShiftRightIntArith' properties listed above, you
can enable individual Number of bits parameters
using the property names 'BitPerChar',
'BitPerShort', 'BitPerInt', 'BitPerLong', and
'NativeWordSize'.

Set Native Word Size for the Device
The Number of bits options describe the native word size of the
microprocessor, and the bit lengths of char, short, int, and long data. For
code generation to succeed:
• The bit lengths must be such that char <= short <= int <= long.
• Bit lengths must be multiples of 8, with a maximum of 32.
• The bit length for long data must not be less than 32.
Simulink Coder integer type names are defined in the file rtwtypes.h. The
values that you provide must be consistent with the word sizes as defined in
the compiler’s limits.h header file. The following table lists the standard
Simulink Coder integer type names and maps them to the corresponding
Simulink names.
Simulink Coder Integer
Type

Simulink Integer Type

boolean_T

boolean

int8_T

int8

uint8_T

uint8

5-9

5

Configure Model Parameters

Simulink Coder Integer
Type

Simulink Integer Type

int16_T

int16

uint16_T

uint16

int32_T

int32

uint32_T

uint32

If no ANSI® C type with a matching word size is available, but a larger ANSI
C type is available, the Simulink Coder code generator uses the larger type
for int8_T, uint8_T, int16_T, uint16_T, int32_T, and uint32_T.
An application can use integer data of any length from 1 (unsigned) or 2
(signed) bits up 32 bits. If the integer length matches the length of an
available type, the Simulink Coder code generator uses that type. If no
matching type is available, the code generator uses the smallest available
type that can hold the data, generating code that never uses unnecessary
higher-order bits. For example, on a target that provided 8-bit, 16-bit, and
32-bit integers, a signal specified as 24 bits would be implemented as an
int32_T or uint32_T.
Code that uses emulated integer data is not maximally efficient, but can be
useful during application development for emulating integer lengths that are
available only on production hardware. The use of emulation does not affect
the results of execution.

Set Byte Ordering Used By Device
The Byte ordering option specifies whether the target hardware uses Big
Endian (most significant byte first) or Little Endian (least significant byte
first) byte ordering. If left as Unspecified, the Simulink Coder software
generates code that determines the endianness of the target; this is the least
efficient option.

5-10

Configure Emulation and Embedded Target Hardware

Set Quotient Rounding Technique for Signed Integer
Division
ANSI C does not completely define the quotient rounding technique to
be used when dividing one signed integer by another, so the behavior is
implementation-dependent. If both integers are positive, or both are negative,
the quotient must round down. If either integer is positive and the other is
negative, the quotient can round up or down.
The Signed integer division rounds to parameter tells the Simulink
Coder code generator how the compiler rounds the result of signed integer
division. Providing this information does not affect the operation of the
compiler, it only describes that behavior to the code generator, which uses
the information to optimize code generated for signed integer division. The
parameter options are:
• Zero — If the quotient is between two integers, the compiler chooses the
integer that is closer to zero as the result.
• Floor — If the quotient is between two integers, the compiler chooses the
integer that is closer to negative infinity.
• Undefined — Choose this option if neither Zero nor Floor describes the
compiler’s behavior, or if that behavior is unknown.
The following table illustrates the compiler behavior that corresponds to each
of these three options:

N

D

Ideal
N/D

Zero

Floor

Undefined

33

4

8.25

8

8

8

-33

4

-8.25

-8

-9

-8 or -9

33

-4

-8.25

-8

-9

-8 or -9

-33

-4

8.25

8

8

8 or 9

5-11

5

Configure Model Parameters

Note Select Undefined only as a last resort. When the code generator does
not know the signed integer division rounding behavior of the compiler, it
generates extra code.
The compiler’s implementation for signed integer division rounding can
be obtained from the compiler documentation, or by experiment if no
documentation is available.

Set Arithmetic Right Shift Behavior for Signed
Integers
ANSI C does not define the behavior of right shifts on negative integers, so the
behavior is implementation-dependent. The Shift right on a signed integer
as arithmetic shift parameter tells the code generator how the compiler
implements right shifts on negative integers. Providing this information does
not affect the operation of the compiler, it only describes that behavior to the
code generator, which uses the information to optimize the code generated for
arithmetic right shifts.
Select the option if the C compiler implements a signed integer right shift as
an arithmetic right shift, and clear the option otherwise. An arithmetic right
shift fills bits vacated by the right shift with the value of the most significant
bit, which indicates the sign of the number in twos complement notation.
The option is selected by default. If your compiler handles right shifts as
arithmetic shifts, this is the preferred setting.
• When the option is selected, the Simulink Coder software generates simple
efficient code whenever the Simulink model performs arithmetic shifts on
signed integers.
• When the option is cleared, the Simulink Coder software generates fully
portable but less efficient code to implement right arithmetic shifts.
The compiler’s implementation for arithmetic right shifts can be obtained
from the compiler documentation, or by experiment if no documentation is
available.

5-12

Configure Embedded Hardware Characteristics

Configure Embedded Hardware Characteristics
“Describing the Emulation and Embedded Targets” on page 9-45 documents
the options available on the Hardware Implementation subpanes. This
section describes considerations that apply only to the Embedded Hardware
subpane. When you use this subpane, keep the following in mind:
• Code generation targets can have word sizes and other hardware
characteristics that differ from the MATLAB host. Furthermore, code can
be prototyped on hardware that is different from either the deployment
target or the MATLAB host. The Simulink Coder code generator takes
these differences into account when generating code.
• The Simulink product uses some of the information in the Embedded
Hardware subpane so that simulation without code generation gives
the same results as executing generated code, including detecting error
conditions that could arise on the target hardware, such as hardware
overflow.
• The Simulink Coder software generates code that has bit-true agreement
with Simulink results for integer and fixed-point operations. Generated
code that emulates unavailable data lengths runs less efficiently than
it would without emulation, but the emulation does not affect bit-true
agreement with Simulink for integer and fixed-point results.
• If you change targets during application development, you must reconfigure
the hardware implementation parameters for the new target before
generating or regenerating code. Bit-true agreement might not be achieved
for results of integer and fixed-point operations in simulation, production
code, and test code when code executes on hardware for which it was not
generated.
• Use the Integer rounding mode parameter on your model’s blocks to
simulate the rounding behavior of the C compiler that you intend to use
to compile code generated from the model. This setting appears on the
Signal Attributes pane of the parameter dialog boxes of blocks that can
perform signed integer arithmetic, such as the Product and n-D Lookup
Table blocks.
• For most blocks, the value of Integer rounding mode completely defines
rounding behavior. For blocks that support fixed-point data and the

5-13

5

Configure Model Parameters

Simplest rounding mode, the value of Signed integer division rounds to
also affects rounding. For details, see “Rounding”.
• When models contain Model blocks, models that they reference must be
configured to use identical hardware settings.

5-14

Configure Emulation Hardware Characteristics

Configure Emulation Hardware Characteristics
“Describing the Emulation and Embedded Targets” on page 9-45 documents
the options available on the Hardware Implementation subpanes. This
section describes considerations that apply only to the Emulation Hardware
subpane.
Note (If the Emulation Hardware subpane contains a button labeled
Configure current execution hardware device, see “Updating from
Earlier Versions” on page 9-57, then continue from this point.)
The default assumption is that the embedded target and emulation target are
the same, so the Emulation Hardware subpane by default does not need to
specify anything and contains only a selected check box labeled None. Code
generated under this configuration will be suitable for production use, or for
testing in an environment identical to the production environment.
To generate code that runs on an emulation target for test purposes, but
behaves as if it were running on an embedded target in a production
application, you must specify the properties of both targets in the Hardware
Implementation pane. The Embedded Hardware subpane specifies
embedded target hardware properties, as described previously. To specify
emulation target properties:
1 Clear the None option in the Emulation Hardware subpane.

By default, the Hardware Implementation pane now looks like this:

5-15

5

Configure Model Parameters

2 In the Emulation Hardware subpane, specify the properties of the

emulation target, using the instructions in “Describing the Emulation and
Embedded Targets” on page 9-45
If you have used the Code Generation pane to specify a System target
file, and the target file specifies a default microprocessor and its hardware
properties, the default and properties appear as initial values in both
subpanes of the Hardware Implementation pane.
Options with only one possible value cannot be changed. Any option that has
more than one possible value provides a list of legal values. If you specify
any hardware properties manually, check carefully that their values are
consistent with the system target file. Otherwise, the generated code may fail
to compile or execute, or may execute but give incorrect results.
If you do not display the Emulation Hardware subpane, the Simulink and
Simulink Coder software defaults every Emulation Hardware option to

5-16

Configure Emulation Hardware Characteristics

have the same value as the corresponding Embedded Hardware option.
If you hide the Emulation Hardware subpane after setting its values,
the values that you specified will be lost. The underlying configuration
parameters immediately revert to the values that they had when you exposed
the subpane, and these values, rather than the values that you specified, will
appear if you re-expose the subpane.

Update Release 14 Hardware Configuration
If your model was created before Release 14 and has not been updated, by
default the Hardware Implementation pane initially looks like this:

Click Configure current execution hardware device. The Configure
current execution hardware device button disappears. The subpane then
appears as shown in the first figure in this section. Save your model at this
point to avoid redoing Configure current execution hardware device
next time you access the Hardware Implementation pane.

5-17

5

Configure Model Parameters

Control the Location for Generated Files
By default, the files generated by Simulink diagram updates and model
builds are placed in a build folder, the root of which is the current working
folder (pwd). If you are doing model builds, which potentially generate files
for simulation targets as well as code generation targets, artifacts used for
simulation and Simulink Coder code generation files coexist in subfolders
within that build folder. However, in some situations, you might want the
generated files to go to a root folder outside the current working folder. For
example,
• You need to keep generated files separate from the models and other source
materials used to generate them.
• You want to reuse or share previously-built simulation targets without
having to set the current working folder back to a previous working folder.
You might also want to separate generated simulation artifacts from
generated production code.
To allow you to control the output locations for the files generated by diagram
updates and model builds, the software allows you to separately specify the
following build folders:
• Simulation cache folder — root folder in which to place build artifacts
used for simulation
• Code generation folder — root folder in which to place Simulink Coder
code generation files
For specifying the folder locations, the software provides
• MATLAB session parameters CacheFolder and CodeGenFolder
• Simulink preferences Simulation cache folder and Code generation
folder, which, if specified, provide the initial defaults for the MATLAB
session parameters
• Function Simulink.fileGenControl for directly manipulating the
MATLAB session parameters, for example, overriding or restoring the
initial default values for the current session

5-18

Control the Location for Generated Files

For more information about setting up a simulation cache folder, see “Control
Generated Files Location Used for Simulation” on page 5-20.
For more information about setting up a code generation folder, see “Control
the Location for Code Generation Files” on page 5-22.
For more information about directly manipulating the MATLAB session
parameters CacheFolder and CodeGenFolder, see “Override Build Folder
Settings for Current Session” on page 5-24.

5-19

5

Configure Model Parameters

Control Generated Files Location Used for Simulation
By default, the files generated by Simulink diagram updates are placed in a
build folder, the root of which is the current working folder (pwd). However,
in some situations, you might want the generated files to go to a root folder
outside the current working folder. For example,
• You need to keep generated files separate from the models and other source
materials used to generate them.
• You want to reuse or share previously-built simulation targets without
having to set the current working folder back to a previous working folder.
The Simulink preference Simulation cache folder provides control over
the output location for files generated by Simulink diagram updates. The
preference appears in the Simulink Preferences Window, Main Pane, in the
File generation control group. To specify the root folder location for files
generated by Simulink diagram updates, set the preference value by entering
or browsing to a folder path, for example:

The folder path that you specify provides the initial default for the MATLAB
session parameter CacheFolder. When you initiate a Simulink diagram
update, any files generated are placed in a build folder at the root location
specified by CacheFolder (if any), rather than in the current working folder
(pwd).
For example, using a 32-bit Windows host platform, if you set the Simulation
cache folder to 'C:\Work\mymodelsimcache' and then simulate the example
model rtwdemo_capi, files are generated into the specified folder as follows:

5-20

Control Generated Files Location Used for Simulation

As an alternative to using the Simulink preferences GUI to set Simulation
cache folder, you also can get and set the preference value from the
command line using get_param and set_param. For example,
>> get_param(0, 'CacheFolder')
ans =
''
>> set_param(0, 'CacheFolder', fullfile('C:','Work','mymodelsimcache'))
>> get_param(0, 'CacheFolder')
ans =
C:\Work\mymodelsimcache

Also, you can choose to override the Simulation cache folder preference
value for the current MATLAB session.

5-21

5

Configure Model Parameters

Control the Location for Code Generation Files
By default, the files generated by Simulink model builds are placed in a
build folder, the root of which is the current working folder (pwd). Model
builds potentially generate files for simulation targets as well as code
generation targets, and the resulting build folder contains both artifacts used
for simulation and Simulink Coder code generation files. However, in some
situations, you might want the generated files to go to one or more root folders
outside the current working folder. For example,
• You need to keep generated files separate from the models and other source
materials used to generate them.
• You want to separate generated production code from generated simulation
artifacts.
The Simulink preference Code generation folder provides control over the
output location for files generated by model builds for code generation targets.
The preference appears in the Simulink Preferences Window, Main Pane, in
the File generation control group. To specify the root folder location for
code generation files generated by model builds, set the preference value by
entering or browsing to a folder path, for example:

The folder path that you specify provides the initial default for the MATLAB
session parameter CodeGenFolder. When you initiate a Simulink model
build, any code generation files generated are placed in a build folder at the
root location specified by CodeGenFolder (if any), rather than in the current
working folder (pwd).
For example, using a 32-bit Windows host platform, if you set the Code
generation folder to 'C:\test\mymodelgencode' and then build the
example model rtwdemo_capi, files are generated into the specified folder as
follows:

5-22

Control the Location for Code Generation Files

As an alternative to using the Simulink preferences GUI to set Code
generation folder, you also can get and set the preference value from the
command line using get_param and set_param. For example,
>> get_param(0, 'CodeGenFolder')
ans =
''
>> set_param(0, 'CodeGenFolder', fullfile('C:','test','mymodelgencode'))
>> get_param(0, 'CodeGenFolder')
ans =
C:\test\mymodelgencode

Also, you can choose to override the Code generation folder preference
value for the current MATLAB session. For more information, see “Override
Build Folder Settings for Current Session” on page 5-24.

5-23

5

Configure Model Parameters

Override Build Folder Settings for Current Session
The Simulink preferences Simulation cache folder and Code generation
folder provide the initial defaults for the MATLAB session parameters
CacheFolder and CodeGenFolder, which determine where files generated
by Simulink diagram updates and model builds are placed. However,
you can override these build folder settings during the current MATLAB
session, using the Simulink.fileGenControl function. This function
allows you to directly manipulate the MATLAB session parameters, for
example, overriding or restoring the initial default values. The values
you set using Simulink.fileGenControl expire at the end of the current
MATLAB session. For more information and detailed examples, see the
Simulink.fileGenControl function reference page.

5-24

6
Model Protection
• “Protect a Referenced Model” on page 6-2
• “Harness Model” on page 6-4
• “Protected Model Report” on page 6-5
• “Code Generation Support in a Protected Model” on page 6-6
• “Protected Model File” on page 6-8
• “Create a Protected Model” on page 6-9
• “Test the Protected Model” on page 6-13
• “Save Base Workspace Definitions” on page 6-15
• “Package a Protected Model” on page 6-16

6

Model Protection

Protect a Referenced Model
Protect a model when you want to share a model with a third party without
revealing the intellectual property. Protecting a model does not use encryption
technology.
When you create a protected model:
• By default, Simulink creates and stores a protected version of the
referenced model in the current working folder. The protected model has
the same name as the source model, with a .slxp extension.
• The original Model block does not change. However, if the Model block
parameter Model name does not specify an extension, a protected model,
.slxp, takes precedence over a model file, .slx.
• The Simulation mode parameter of the protected model is automatically
set to Accelerator. You cannot change this value.
• You can optionally create a harness model which includes the protected
model. A shield icon appears in the lower-left corner of the protected model
block in the harness model. For more information, see “Harness Model”
on page 6-4.
• You can optionally include generated code with the protected model so that
a third party can generate code for a model that contains the protected
model. Including code generation support with a protected model also
allows the third party to simulate a model that references the protected
model in Accelerator mode. For more information, see “Code Generation
Support in a Protected Model” on page 6-6.
• If the Model block uses variants, only the active variant is protected. For
more information, see “Set Up Model Variants”.
• If you rename a protected model, or change its suffix, the model is unusable
until you restore its original name and suffix. You cannot change a
protected model internally because any internal change destroys the
usability of the file.
You can create a protected model using either:
• A Model block context menu. For more information, see “Create a Protected
Model” on page 6-9 and

6-2

Protect a Referenced Model

• A Simulink.ModelReference.protect function.

Requirements for Protecting a Model
When you create a protected model from a referenced model, the referenced
model must meet all requirements listed in “Model Referencing Limitations”,
as well as these requirements:
• You must have a Simulink Coder license to create a protected model.
• A model that you protect must be available on the MATLAB path and not
have any unsaved changes.
• A model that you protect cannot reference a protected model directly or
indirectly.
• A model that you protect cannot use a non-inlined S-function directly or
indirectly.
Model protection has certain limitations, as listed in “Limitations on All Model
Referencing” and “Limitations on Accelerator Mode Referenced Models”.

6-3

6

Model Protection

Harness Model
You can create a harness model for the generated protected model. The
harness model opens as a new, untitled model that contains only a Model
block which references the protected model. This Model block:
• Specifies the Model block parameter, Model name, as the name of the
protected model.
• Has a shield icon in the lower-left corner.
• Has the same number of input and output ports as the protected model.
• Defines any model reference arguments that the protected model uses, but
does not provide any values.
To create a harness model, see “Create a Protected Model” on page 6-9. You
can use a harness model to test your protected model. For more information,
see “Test the Protected Model” on page 6-13. You can also copy the Model
block in your harness model to another model, where it is an interface to
the protected model.

6-4

Protected Model Report

Protected Model Report
You can generate a report for a protected model to include with the protected
model. The report provides information to the receiver to determine if the
protected model can be used. The report has:
• A Summary, including the Simulink version and platform used to create
the protected model.
• An Interface Report, including model interface information, such as,
input and output specifications, exported function information, and
whether code generation support is included.
A protected model report is generated while the protected model is created. In
the Create Protected Model dialog box, select the Create protected model
report parameter. For an example, see “Create a Protected Model” on page
6-9.
After you create the protected model, to view the protected model report,
double-click the protected model block.

6-5

6

Model Protection

Code Generation Support in a Protected Model
You can create a protected model that supports code generation. When a
protected model includes generated code, a third party can generate code for a
model that includes the protected model. If you choose to obfuscate the code,
all code is obfuscated before compilation. The protected model file contains
only obfuscated headers and binaries. No source, such as, .c and .cpp, is
present in the protected model file, although the headers are documented in
the protected model report. For more information, see “Protected Model File”
on page 6-8 and “Protected Model Report” on page 6-5.
In the Create Protected Model dialog box, select the Include generated code
parameter, which enables the Obfuscate code parameter. For an example on
including code generation support, see “Create a Protected Model” on page 6-9.

Protected Model Requirements to Support Code
Generation
Contents and configuration of a model might prevent code generation support
of the protected model. Interaction between the parent model and the
protected model might also prevent code generation.
• Code generation for the protected model is only supported for Accelerator
mode and a single target. Both GRT and ERT targets cannot be supported
by the same protected model.
• A protected model cannot include a model reference hierarchy.
• Source code comments in the Code Generation > Comments pane are
ignored. Obfuscation of the generated code removes comments because
comments might reveal intellectual property.
• Custom code in the Code Generation > Custom Code pane should not be
included. Custom code is obfuscated, but identifiers are not.
• Code generation of a model that includes a protected model produces an
error, if:

-

6-6

Their interfaces do not match.
There are incompatible parameters.

Code Generation Support in a Protected Model

-

A protected model and another model share the same name in the same
model reference hierarchy.

6-7

6

Model Protection

Protected Model File
A protected model file (.slxp) consists of the model itself and supporting files,
depending on the options that you selected when you created the protected
model.
If you created a protected model for simulation only, after simulation, the
model.mexext file is placed in the build folder.

For simulation with a report, these additional files are unpacked:
• slprj/sim/model/html/*
• slprj/sim/model/buildinfo.mat
If you opted to include code generation support when you created the
protected model, after building your model the following files are unpacked
(in addition to the preceding files):
• slprj/sim/model/*.h
• slprj/sim/model/modellib.a (or modellib.lib)
• slprj/sim/model/tmwinternal/*
• slprj/sim/_sharedutils/*
• slprj/target/model/*.h
• slprj/target/model/model_rtwlib.a (or model_rtwlib.lib)
• slprj/target/model/buildinfo.mat
• slprj/target/_sharedutils/*
• slprj/target/model/tmwinternal/*
For code generation with a report, after building your model these files are
unpacked (in addition to the preceding files):
• slprj/target/model/html/*
• slprj/target/model/buildinfo.mat
• slprj/target/_sharedutils/html/*

6-8

Create a Protected Model

Create a Protected Model
This example shows how to create a protected model to be used for simulation
and code generation.
1 Open the model rtwdemo_roll.
2 In the Simulink Editor, right-click the Model block that references the model

for which you want to generate protected model code. In this example,
right-click HeadingMode.
3 From the context menu, select Block Parameters (ModelReference).
4 In the Block Parameters dialog box, in the Model name field, specify the

extension for the model, .slx. When both the model and the protected model
exist in the same folder, .slxp takes precedence over .slx. In the Model
name field, if you do not specify an extension, when you create the protected
model, the original Model block in the model becomes protected.
5 Click Apply and OK.
6 Right-click the Model block. From the context menu, select Subsystem &

Model Reference > Create Protected Model for Selected Model Block.
7 In the Create Protected Model dialog box, select Include generated code

to include generated code with the protected model. This parameter enables
and selects the Obfuscate code parameter. For more information about
the generated code, see “Code Generation Support in a Protected Model” on
page 6-6.
8 In the Package path field, specify the folder path for the protected model.

The default value is the current working folder.
9 To create a harness model for the protected model, select Create harness

model for protected model.

6-9

6

Model Protection

10 Click Create. An untitled harness model opens and contains a Model block,

which refers to the protected model rtwdemo_heading.slxp. The Simulation
mode for the Model block is set to Accelerator. You cannot change the mode.

6-10

Create a Protected Model

11 To view the protected model report, double-click the HeadingMode block.

6-11

6

Model Protection

To test the protected model before packaging, see “Test the Protected Model”
on page 6-13. To package the protected model for a third party, see “Package
a Protected Model” on page 6-16.

6-12

Test the Protected Model

Test the Protected Model
To test a protected model that you created, you use the generated harness
model and the procedure described in “Use Protected Model in Simulation”.
You can also compare the output of the protected model to the output of
the original model. Because you are the supplier, both the original and the
protected model might exist on the MATLAB path. In the original model, if
the Model block Model name parameter names the model without providing
a suffix, the protected model takes precedence over the unprotected model.
If you need to override this default when testing the output, in the Model
block Model name parameter, specify the file name with the extension of
the unprotected model, .slx.
To compare the unprotected and protected versions of a Model block, use
the Simulation Data Inspector. This example uses rtwdemo_roll and the
protected model, rtwdemo_heading.slxp, which is created in “Create a
Protected Model” on page 6-9.
1 If it is not already open, open rtwdemo_roll.
2 Enable logging for the output signal of the Model block, HeadingMode. In

the Configuration Parameters dialog box, on the Data Import/Export
pane, select the Signal logging parameter and set Signal logging
format to Dataset. Click Apply and OK.
3 Right-click the output signal. From the context menu, select Properties.

In the Signal Properties dialog box, select Log signal data. Click Apply
and OK. For more information, see “Export Signal Data Using Signal
Logging”.
4 Right-click the HeadingMode block. From the context menu, select Block

Parameters (ModelReference). In the Block Parameters dialog box,

specify the Model name parameter with the name of the unprotected
model and the extension, rtwdemo_heading.slx. Click Apply and OK.
5 In the Simulink Editor, click the Record button on. Simulate the model.

When the simulation is complete, the Simulation Data Inspector opens.

6-13

6

Model Protection

6 In the Simulation Data Inspector, rename the run to indicate that it is

for the unprotected model.
7 In the Simulink Editor, right-click the HeadingMode block. From the

context menu, select Block Parameters (ModelReference). In the Block
Parameters dialog box, specify the Model name parameter with the name
of the protected model, rtwdemo_heading.slxp. A shield icon appears
on the Model block.
8 In the Simulink Editor, the Record button is still on. Simulate the model,

which now refers to the protected model. When the simulation is complete,
the Simulation Data Inspector opens.
9 In the Simulation Data Inspector, rename the new run to indicate that it

is for the protected model.
10 In the Simulation Data Inspector, select the Compare Runs tab to

compare the runs for the unprotected and the protected model. For more
information about comparing runs, see “Compare All Logged Signal Data
From Multiple Simulations”.

6-14

Save Base Workspace Definitions

Save Base Workspace Definitions
Referenced models might use object definitions or tunable parameters that
are defined in the MATLAB base workspace. These variables are not saved
with the model. When you protect a model, you must obtain the definitions of
required base workspace entities and ship them with the model.
The following base workspace variables must be saved to a MAT-file:
• Global tunable parameter
• Global data store
• Any of the following objects used by a signal that connects to a root-level
model Inport or Outport:

-

Simulink.Signal
Simulink.Bus
Simulink.Alias
Simulink.NumericType that is an alias

For more information, see “Workspace Variables in Model Explorer”.
Before executing the protected model as a part of a third-party model, the
receiver of the protected model must load the MAT-file.

6-15

6

Model Protection

Package a Protected Model
In addition to the protected model file (.slxp), you might need to include
additional files in the protected model package:
• Harness model file.
• Any required definitions saved in a MAT-file. For more information, see
“Save Base Workspace Definitions” on page 6-15.
• Instructions on how to retrieve the files.
Some ways to deliver the protected model package are:
• Provide the .slxp file and other supporting files as separate files.
• Combine the files into a ZIP or other container file.
• Combine the files using a manifest. For more information, see “Export
Files in a Manifest”.
• Provide the files in some other standard or proprietary format specified
by the receiver.
Whichever approach you use to deliver a protected model, include information
on how to retrieve the original files. One approach to consider is to use the
Simulink Manifest Tools, as described in “Analyze Model Dependencies”.

6-16

Data, Function, and File
Definition
• Chapter 7, “Data Representation”
• Chapter 8, “Entry Point Functions and Scheduling”

7
Data Representation
• “Enumerations” on page 7-2
• “Structure Parameters and Generated Code” on page 7-49
• “Parameters” on page 7-10
• “Signals” on page 7-52
• “States” on page 7-83
• “Data Stores” on page 7-93

7

Data Representation

Enumerations
In this section...
“About Enumerated Data Types” on page 7-2
“Default Code for an Enumerated Data Type” on page 7-2
“Type Casting for Enumerations” on page 7-3
“Override Default Methods (Optional)” on page 7-4
“Enumerated Type Limitations” on page 7-7

About Enumerated Data Types
Enumerated data is data that is restricted to a finite set of values. An
enumerated data type is a MATLAB class that defines a set of enumerated
values. Each enumerated value consists of an enumerated name and an
underlying integer which the software uses internally and in generated code.
The following is a MATLAB class definition for an enumerated data type
named BasicColors, which is used in the examples in this section.
classdef(Enumeration) BasicColors < Simulink.IntEnumType
enumeration
Red(0)
Yellow(1)
Blue(2)
end
end

For information about enumerated data types and their use in Simulink
models, see “Use Enumerated Data in Simulink Models”. For information
about enumerated data types in Stateflow charts, see “How to Define
Enumerated Data in a Chart”.

Default Code for an Enumerated Data Type
By default, enumerated data types in generated code are defined in the
generated header file model_types.h for the model. For example, the default
code for BasicColors, which is defined in the previous section, appears as
follows:

7-2

Enumerations

#ifndef _DEFINED_TYPEDEF_FOR_BasicColors_
#define _DEFINED_TYPEDEF_FOR_BasicColors_
typedef enum {
Red = 0,
Yellow = 1,
Blue = 2,
} BasicColors;

/* Default value */

#endif

Type Casting for Enumerations
How Safe Casting Works
A Simulink Data Type Conversion block can accept a signal of integer type
and convert the input to one of the underlying values of an enumerated type.
If the input value does not match any of the underlying values of the
enumerated type’s values, Simulink can insert a safe cast to replace the input
value with the enumerated type’s default value.

Enable and Disable Safe Casting
You can enable or disable safe casting for enumerations during code
generation for a Simulink Data Type Conversion block or a Stateflow block.
To control safe casting, enable or disable the block’s Saturate on integer
overflow parameter. The parameter works as follows:
• Enabled: Simulink replaces a non-matching input value with the default
value of the enumerated values during simulation and generates a safe
cast function during code generation.
• Disabled: For a non-matching input value, Simulink generates an error
during simulation and omits the safe cast function during code generation.
While the code is more efficient in this case, it may be more vulnerable to
runtime errors.

7-3

7

Data Representation

Safe Cast Function in Generated Code
This example shows how the safe cast function int32_T
ET08_safe_cast_to_BasicColors for the enumeration BasicColors appears
in generated code.
static int32_T ET08_safe_cast_to_BasicColors(int32_T input)
{
int32_T output;
/* Initialize output value to default value for BasicColors (Red) */
output = 0;
if ((input >= 0) && (input <= 2)) {
/* Set output value to input value if it is a member of BasicColors */
output = input;
}
return output;
}

Through this function, the enumerated type’s default value is used if the
input value does not match one of underlying values of the enumerated type’s
values.
If the block’s Saturate on integer overflow parameter is disabled, this
function does not appear in generated code.

Override Default Methods (Optional)
Every enumerated class has four associated static methods, which it inherits
from Simulink.IntEnumType. You can optionally override any or all of
these static methods to customize the behavior of an enumerated type. The
methods are:
• getDefaultValue — Returns the default value of the enumerated data
type.
• getDescription — Returns a description of the enumerated data type.
• getHeaderFile — Specifies a file where the type is defined for generated
code.
• addClassNameToEnumNames — Specifies whether the class name becomes
a prefix in code.

7-4

Enumerations

The first of these methods, getDefaultValue, is relevant to both simulation
and code generation, and is described in “Specifying a Default Enumerated
Value” in the Simulink documentation. The other three methods are relevant
only to code generation, and are described in this section. To override any of
the methods, include a customized version of the method in the enumerated
class definition’s methods section. If you do not want to override any default
methods, omit the methods section entirely. The following table summarizes
the four methods and the data to supply for each one:
Method

Purpose

Default Return

Custom Return

getDefaultValue

Returns the default
value for the class,
which must be an
instance of the class.

The lexically
first value in the
enumeration.

Any enumerated
value in the class.
See “Instantiate
Enumerations”.

getDescription

Returns a string
containing a
description of the
enumerated class.

''

Any string that
MATLAB accepts.

getHeaderFile

Returns a string
containing the name
of the header file

''

The name of the file
that contains the
enumerated type
definition.

false

true or false

addClassNameToEnumNames Returns a boolean

value indicating
whether to prefix
the class name in
generated code

Specifying a Description
To specify a description for an enumerated data type, include the following
method in the enumerated class’s methods section:
function retVal = getDescription()
% GETDESCRIPTION Optional string to describe the data type.
retVal = 'description';
end

7-5

7

Data Representation

Substitute any legal MATLAB string for description. The generated code
that defines the enumerated type will include the specified description.

Specify a Header File
To prevent the declaration of an enumerated type from being embedded in the
generated code, allowing you to provide the declaration in an external file,
include the following method in the enumerated class’s methods section:
function retVal = getHeaderFile()
% GETHEADERFILE File where type is defined for generated code.
%
If specified, this file is #included in the code.
%
Otherwise, the type is written out in the generated code.
retVal = 'filename';
end

Substitute any legal filename for filename. Be sure to provide a filename
suffix, typically .h. Providing the method replaces the declaration that would
otherwise have appeared in model_types.h with a #include statement like:
#include "imported_enum_type.h"

The getHeaderFile method does not create the declaration file itself. You
must provide a file of the specified name that declares the enumerated data
type.

Add Prefixes To Class Names
By default, enumerated values in generated code have the same names that
they have in the enumerated class definition. Alternatively, the code can
prefix every enumerated value in an enumerated class with the name of
the class. This technique can be useful for preventing identifier conflicts or
improving the clarity of the code. To specify class name prefixing, include the
following method in an enumerated class’s methods section:
function retVal = addClassNameToEnumNames()
% ADDCLASSNAMETOENUMNAMES Control whether class name is added as
%
a prefix to enumerated names in the generated code.
%
By default the code does not use the class name as a prefix.
retVal = boolean;
end

7-6

Enumerations

Replace boolean with true to enable class name prefixing, or false to
suppress prefixing without having to delete the method itself. If boolean
is true, each enumerated value in the class appears in generated code as
EnumTypeName_EnumName. For BasicColors, which was defined in “About
Enumerated Data Types” on page 7-2, the data type definition with class
name prefixing looks like this:
#ifndef _DEFINED_TYPEDEF_FOR_BasicColors_
#define _DEFINED_TYPEDEF_FOR_BasicColors_
typedef enum {
BasicColors_Red = 0,
BasicColors_Yellow = 1,
BasicColors_Blue = 2,
} BasicColors;

/* Default value */

#endif

In this example, the enumerated class name BasicColors appears as a prefix
for each of the enumerated names. The definition is otherwise the same as
it would be without name prefixing.

Enumerated Type Limitations
• Generated code does not support logging enumerated data.

7-7

7

Data Representation

Structure Parameters and Generated Code
In this section...
“About Structure Parameters and Generated Code” on page 7-49
“Include Structure Parameters in Generated Code” on page 7-50
“Control Naming of Structure Parameter Types” on page 7-50

About Structure Parameters and Generated Code
Structure parameters provide a way to improve generated code to use
structures rather multiple separate variables. You also have the option of
configuring the appearance of a structure parameter in generated code.
For more information about structure parameters, see“Structure Parameters”
in the Simulink documentation. For an example of how to convert a model
that uses unstructured workspace variables to a model that uses structure
parameters, see sldemo_applyVarStruct.

Configure Structure Parameters for Generated Code
By default, structure parameters do not appear in generated code. Structure
parameters include numeric variables and the code generator inlines numeric
values.
To make structure type definition appear in generated code for a structure
parameter,
1 Create a Simulink.Parameter object.
2 Define the object value to be the parameter structure.
3 Define the object storage class to be a value other than Auto.

The code generator places a structure type definition or the tunable parameter
structure in model_types.h. By default, the code generator identifies
the type with a nondescriptive, automatically generated name, such as
struct_z98c0D2qc4btL.

7-8

Structure Parameters and Generated Code

For information on how to control the naming of the type, see “Control
Naming of Structure Parameter Types” on page 7-50. For an example, see
sldemo_applyVarStruct

Control Name of Structure Parameter Type
To control the naming of a structure parameter type, use a Simulink.Bus
object to specify the data type of the Simulink.Parameter object.
1 Use Simulink.Bus.createObject to create a bus object with the same shape

as the parameter structure. For example:
busInfo=Simulink.Bus.createObject(ControlParam.Value);
2 Assign the bus object name to the data type property of the parameter

object.
ParamType=eval(busInfo.busName);
ControlParam.DataType='Bus: ParamType';

Only Simulink.Parameter can accept the bus object name as a data type.
For an example, see sldemo_applyVarStruct

7-9

7

Data Representation

Parameters
In this section...
“About Parameters” on page 7-10
“Nontunable Parameter Storage” on page 7-11
“Tunable Parameter Storage” on page 15-119
“Tunable Parameter Storage Classes” on page 15-121
“Declare Tunable Parameters” on page 15-124
“Tunable Expressions” on page 15-128
“Linear Block Parameter Tunability” on page 15-132
“Configuration Parameter Quick Reference Diagram” on page 7-27
“Generated Code for Parameter Data Types” on page 7-28
“Tunable Workspace Parameter Data Type Considerations” on page 15-133
“Tune Parameters” on page 7-36
“Parameter Objects” on page 7-38
“Structure Parameters and Generated Code” on page 7-49

About Parameters
This section discusses how the Simulink Coder product generates parameter
storage declarations, and how you can generate the storage declarations
you need to interface block parameters to your code. For information about
defining block parameters in Simulink models, see “Set Block Parameters”.
If you are using S-functions in your model and intend to tune their run-time
parameters in the generated code, see “Tuning Run-Time Parameters” in the
Simulink documentation. Note that
• Parameters must be numeric, logical, or character arrays.
• Parameters may not be sparse.
• Parameter arrays must not be greater than 2 dimensions.

7-10

Parameters

For guidance on implementing a parameter tuning interface using a C API,
see “Data Interchange Using the C API” on page 15-137.
Simulink external mode offers a way to monitor signals and modify parameter
values while generated model code executes. However, external mode might
not be the optimal solution for your application. For example, the S-function
target does not support external mode. For other targets, you might want
your existing code to access parameters and signals of a model directly, rather
than using the external mode communications mechanism. For information
on external mode, see “Host/Target Communication” on page 15-50.

Nontunable Parameter Storage
By default, block parameters are not tunable in the generated code. When
Inline Parameters is off (the default), the Simulink Coder product has
control of parameter storage declarations and the symbolic naming of
parameters in the generated code.
Nontunable parameters are stored as fields within model_P (formerly rtP), a
model-specific global parameter data structure. The Simulink Coder product
initializes each field of model_P to the value of the corresponding block
parameter at code generation time.
When the Inline parameters option is on, block parameters are evaluated at
code generation time, and their values appear as constants in the generated
code, if possible (in certain circumstances, parameters cannot be inlined, and
are then included in a constant parameter or model parameter structure.)
As an example of nontunable parameter storage, consider the following model.

The workspace variable Kp sets the gain of the Gain block.

7-11

7

Data Representation

Assume that Kp is nontunable and has a value of 5.0. The next table shows
the variable declarations and the code generated for Kp in the noninlined
and inlined cases.
The generated code does not preserve the symbolic name Kp. The noninlined
code represents the gain of the Gain block as model_P.Gain_Gain. When Kp is
noninlined, the parameter is tunable.
Inline
Parameters

Generated Variable Declaration and Code

Off
struct Parameters_non_tunable_sin { real_T SineWave_Amp;
real_T SineWave_Bias;
real_T SineWave_Freq;
real_T SineWave_Phase;
real_T Gain_Gain;
};
.
.
.
Parameters_non_tunable_sin non_tunable_sin_P = {

7-12

Parameters

Inline
Parameters

Generated Variable Declaration and Code

1.0
0.0
1.0
0.0
5.0

,
,
,
,

/*
/*
/*
/*
/*

SineWave_Amp : '/Sine Wave' */
SineWave_Bias : '/Sine Wave' */
SineWave_Freq : '/Sine Wave' */
SineWave_Phase : '/Sine Wave' */
Gain_Gain : '/Gain' */

};
.
.
.
non_tunable_sin_Y.Out1 = rtb_u *
non_tunable_sin_P.Gain_Gain;

On
non_tunable_sin_Y.Out1 = rtb_u * 5.0;

Tunable Parameter Storage
A tunable parameter is a block parameter whose value can be changed at
run-time. A tunable parameter is inherently noninlined. Consequently, when
Inlined parameters is off, all parameters are members of model_P, and thus
are tunable. A tunable expression is an expression that contains one or more
tunable parameters.
When you declare a parameter tunable, you control whether or not the
parameter is stored within model_P. You also control the symbolic name of
the parameter in the generated code.
When you declare a parameter tunable, you specify
• The storage class of the parameter.
The storage class property of a parameter specifies how the Simulink Coder
product declares the parameter in generated code.
The term “storage class,” as used in the Simulink Coder product, is not
synonymous with the term storage class specifier, as used in the C language.

7-13

7

Data Representation

• A storage type qualifier, such as const or volatile. This is simply a string
that is included in the variable declaration.
• (Implicitly) the symbolic name of the variable or field in which the
parameter is stored. The Simulink Coder product derives variable and field
names from the names of tunable parameters.
The Simulink Coder product generates a variable or struct storage
declaration for each tunable parameter. Your choice of storage class controls
whether the parameter is declared as a member of model_P or as a separate
global variable.
You can use the generated storage declaration to make the variable visible
to external legacy code. You can also make variables declared in your code
visible to the generated code. You are responsible for linking your code to
generated code modules.
You can use tunable parameters or expressions in your root model and
in masked or unmasked subsystems, subject to certain restrictions. (See
“Tunable Expressions” on page 15-128.)

Override Inlined Parameters for Tuning
When the Inline parameters option is selected, you can use the Model
Parameter Configuration dialog box to remove individual parameters from
inlining and declare them to be tunable. This allows you to improve overall
efficiency by inlining most parameters, while at the same time retaining the
flexibility of run-time tuning for selected parameters. Another way you can
achieve the same result is by using Simulink data objects; see “Parameters”
on page 7-10 for specific details.
The mechanics of declaring tunable parameters are discussed in “Declare
Tunable Parameters” on page 15-124.

Tunable Parameter Storage Classes
The Simulink Coder product defines four storage classes for tunable
parameters. You must declare a tunable parameter to have one of the
following storage classes:

7-14

Parameters

• SimulinkGlobal (Auto): This is the default storage class. The Simulink
Coder product stores the parameter as a member of model_P. Each member
of model_P is initialized to the value of the corresponding workspace
variable at code generation time.
• ExportedGlobal: The generated code instantiates and initializes the
parameter and model.h exports it as a global variable. An exported global
variable is independent of the model_P data structure. Each exported
global variable is initialized to the value of the corresponding workspace
variable at code generation time.
• ImportedExtern: model_private.h declares the parameter as an extern
variable. Your code must supply the variable definition and initializer.
• ImportedExternPointer: model_private.h declares the variable as an
extern pointer. Your code must supply the pointer variable definition
and initializer, if any.
The generated code for model.h includes model_private.h to make the
extern declarations available to subsystem files.
As an example of how the storage class declaration affects the code generated
for a parameter, consider the next figure.

7-15

7

Data Representation

The workspace variable Kp sets the gain of the Gain block. Assume that
the value of Kp is 3.14. The following table shows the variable declarations
and the code generated for the gain block when Kp is declared as a tunable
parameter. An example is shown for each storage class.
Note The Simulink Coder product uses column-major ordering for
two-dimensional signal and parameter data. When interfacing your
hand-written code to such signals or parameters by using ExportedGlobal,
ImportedExtern, or ImportedExternPointer declarations, make sure that
your code observes this ordering convention.
The symbolic name Kp is preserved in the variable and field names in the
generated code.
Storage Class
SimulinkGlobal
(Auto)

Generated Variable Declaration and Code
typedef struct _Parameters_tunable_sin
Parameters_tunable_sin;
struct _Parameters_tunable_sin {
real_T Kp;
};
Parameters_tunable_sin tunable_sin_P = {
3.14
};
.
.
tunable_sin_Y.Out1 = rtb_u *
tunable_sin_P.Kp;

ExportedGlobal
real_T Kp = 3.14;
.
.
tunable_sin_Y.Out1 = rtb_u * Kp;

7-16

Parameters

Storage Class

Generated Variable Declaration and Code

ImportedExtern
extern real_T Kp;
.
.
tunable_sin_Y.Out1 = rtb_u * Kp;
ImportedExtern
Pointer

extern real_T *Kp;
.
.
tunable_sin_Y.Out1 = rtb_u * (*Kp);

Declare Tunable Parameters
• “Declare Workspace Variables as Tunable Parameters” on page 15-124
• “Declare New Tunable Parameters” on page 15-124
• “Declare Tunable Parameters Using Configuration Parameter Dialog” on
page 15-125
• “Select Workspace Variables” on page 15-126
• “Create New Tunable Parameters” on page 15-127
• “Set Tunable Parameter Properties” on page 15-128
• “Remove Unused Tunable Parameters” on page 15-128

Declare Workspace Variables as Tunable Parameters
To declare tunable parameters,
1 Open the Model Parameter Configuration dialog box.
2 In the Source list pane, select one or more variables.
3 Click Add to table . The variables then appear as tunable parameters in

the Global (tunable) parameters pane.

7-17

7

Data Representation

4 Select a parameter in the Global (tunable) parameters pane.
5 Select a storage class from the Storage class menu.
6 Optionally, select (or enter) a storage type qualifier, such as const or

volatile for the parameter.
7 Click Apply, or click OK to apply changes and close the dialog box.

Declare New Tunable Parameters
To declare tunable parameters,
1 Open the Model Parameter Configuration dialog box.
2 In the Global (tunable) parameters pane, click New.
3 Specify a name for the parameter.
4 Select a storage class from the Storage class menu.
5 Optionally, select (or enter) a storage type qualifier, such as const or

volatile for the parameter.
6 Click Apply, or click OK to apply changes and close the dialog box.

Declare Tunable Parameters Using Configuration Parameters
The Model Configuration Parameters dialog box lets you select base
workspace variables and declare them to be tunable parameters in the current
model. Using controls in the dialog box, you move variables from a source list
to a global (tunable) parameter list for a model.
To open the dialog box,
1 Select the Inline parameters check box on the Optimization > Signals

and Parameters pane of the Configuration Parameters dialog box. This
activates a Configure button, as shown below.

7-18

Parameters

2 Click Configure to open the Model Configuration Parameters dialog box.

Note The Model Configuration Parameters dialog box cannot tune
parameters within referenced models. See “Parameterize Model References”
for tuning techniques that work with referenced models.

Select Workspace Variables
The Source list pane displays a menu and a scrolling table of numerical
workspace variables. To select workspace variables,
1 From the menu, select the source of variables you want listed.

7-19

7

Data Representation

To List...

Choose...

All variables in the MATLAB
workspace that have numeric
values

MATLAB workspace

Only variables in the MATLAB
workspace that have numeric
values and are referenced by the
model

Referenced workspace
variables

A list of workspace variables appear in the Source List pane.
2 Select one or more variables from the source list. This enables the Add

to table button.
3 Click Add to table to add the selected variables to the tunable parameters

list in the Global (tunable) parameters pane. In the Source list, the
names of variables added to the tunable parameters list are displayed in
bold type (see the preceding figure).
Note If you selected a variable with a name that matches a block
parameter that is not tunable and you click Add to table , a warning
appears during simulation and code generation.
To update the list of variables to reflect the current state of the workspace,
at any time, click Refresh list . For example, you might use Refresh list if
you define or remove variables in the workspace while the Model Parameter
Configuration dialog box is open.

Create New Tunable Parameters
To create a new tunable parameter,
1 In the Global (tunable) parameters pane, click New.
2 In the Name field, enter a name for the parameter.

7-20

Parameters

If you enter a name that matches the name of a workspace variable in
the Source list pane, that variable is declared tunable and appears in
italics in the Source list.
3 Click Apply.

The model does not need to be using a parameter before you create it. You can
add references to the parameter later.
Note If you edit the name of an existing variable in the list, you actually
create a new tunable variable with the new name. The previous variable is
removed from the list and loses its tunability (that is, it is inlined).

Set Tunable Parameter Properties
To set the properties of tunable parameters listed in the Global (tunable)
parameters pane, select a parameter and then specify a storage class and,
optionally, a storage type qualifier.
Property

Description

Storage class

Select one of the following to be used for code
generation:
• SimulinkGlobal (Auto)
• ExportedGlobal
• ImportedExtern
• ImportedExternPointer
See “Tunable Parameter Storage Classes” on
page 15-121 for definitions.

Storage type qualifier

For variables with any storage class except
SimulinkGlobal (Auto), you can add a
qualifier (such as const or volatile) to the

generated storage declaration. To do so, you
can select a predefined qualifier from the list
or add qualifiers not in the list. The code

7-21

7

Data Representation

Property

Description
generator does not check the storage type
qualifier for validity, and includes the qualifier
string in the generated code without checking
syntax .

Remove Unused Tunable Parameters
To remove unused tunable parameters from the table in the Global (tunable)
parameters pane, click Remove. Removed variables are inlined if the
Inlined parameters option is enabled.

Tunable Expressions
• “Tunable Expressions in Masked Subsystems” on page 15-129
• “Tunable Expression Limitations” on page 15-131
The Simulink Coder product supports the use of tunable variables in
expressions. An expression that contains one or more tunable parameters is
called a tunable expression.

Tunable Expressions in Masked Subsystems
Tunable expressions are allowed in masked subsystems. You can use tunable
parameter names or tunable expressions in a masked subsystem dialog box.
When referenced in lower-level subsystems, such parameters remain tunable.
As an example, consider the masked subsystem in the next figure. The
masked variable k sets the gain parameter of theGain.

7-22

Parameters

Suppose that the base workspace variable b is declared tunable with
SimulinkGlobal (Auto) storage class. The next figure shows the tunable
expression b*3 in the subsystem’s mask dialog box.

Tunable Expression in Subsystem Mask Dialog Box

The Simulink Coder product produces the following output computation for
theGain. The variable b is represented as a member of the global parameters
structure, model_P. (For clarity in showing the individual Gain block
computation, expression folding is off in this example.)
/* Gain: '/theGain' */
rtb_theGain_C = rtb_SineWave_n * ((subsys_mask_P.b * 3.0));
/* Outport: '/Out1' */
subsys_mask_Y.Out1 = rtb_theGain_C;

As this example shows, for GRT targets, the parameter structure is mangled
to create the structure identifier model_P (subject to the identifier length
constraint). This is done to avoid namespace clashes in combining code from
multiple models using model reference. ERT-based targets provide ways to
customize identifier names.
When expression folding is on, the above code condenses to
/* Outport: '/Out1' incorporates:
*

Gain: '/theGain'

*/
subsys_mask_Y.Out1 = rtb_SineWave_n * ((subsys_mask_P.b * 3.0));

7-23

7

Data Representation

Expressions that include variables that were declared or modified in mask
initialization code are not tunable.
As an example, consider the subsystem above, modified as follows:
• The mask initialization code is
t = 3 * k;

• The parameter k of the myGain block is 4 + t.
• Workspace variable b = 2. The expression b * 3 is plugged into the mask
dialog box as in the preceding figure.
Since the mask initialization code can run only once, k is evaluated at code
generation time as
4 + (3 * (2 * 3) )

The Simulink Coder product inlines the result. Therefore, despite the fact
that b was declared tunable, the code generator produces the following output
computation for theGain. (For clarity in showing the individual Gain block
computation, expression folding is off in this example.)
/* Gain Block: /theGain */
rtb_temp0 *= (22.0);

Tunable Expression Limitations
Currently, there are certain limitations on the use of tunable variables in
expressions. When an unsupported expression is encountered during code
generation a warning is issued and the equivalent numeric value is generated
in the code. The limitations on tunable expressions are
• Complex expressions are not supported, except where the expression is
simply the name of a complex variable.
• The use of certain operators or functions in expressions containing tunable
operands is restricted. Restrictions are applied to four categories of
operators or functions, classified in the following table:

7-24

Parameters

Category

Operators or Functions

1

+ - .* ./ < > <= >= == ~= & |

2

* /

3

abs, acos, asin, atan, atan2, boolean, ceil, cos, cosh,
exp, floor, log, log10, sign, sin, sinh, sqrt, tan, tanh,

4

single, int8, int16, int32, uint8, uint16, uint32

5

: .^ ^ [] {} .

\ .\ ' .'

; ,

The rules applying to each category are as follows:

-

Category 1 is unrestricted. These operators can be used in tunable
expressions with any combination of scalar or vector operands.

-

Category 2 operators can be used in tunable expressions where at least
one operand is a scalar. That is, scalar/scalar and scalar/matrix operand
combinations are supported, but not matrix/matrix.

-

Category 3 lists functions that support tunable arguments. Tunable
arguments passed to these functions retain their tunability. Tunable
arguments passed to any other functions lose their tunability.

-

Category 4 lists the casting functions that do not support tunable
arguments. Tunable arguments passed to these functions lose their
tunability.
Note The Simulink Coder product casts values using MATLAB
typecasting rules. The MATLAB typecasting rules are different from C
code typecasting rules. For example, using the MATLAB typecasting
rules, int8(3.7) returns the result 4, while in C code int8(3.7) returns
the result 3.

-

Category 5 operators are not supported.

• Expressions that include variables that were declared or modified in mask
initialization code are not tunable.
• The Fcn block does not support tunable expressions in code generation.

7-25

7

Data Representation

• Model workspace parameters can take on only the Auto storage class, and
thus are not tunable. See “Parameterize Model References” for tuning
techniques that work with referenced models.
• Non-double expressions are not supported.
• Blocks that access parameters only by address support the use of tunable
parameters, if the parameter expression is a simple variable reference.
When an operation such as a data type conversion or a math operation
is applied, the Simulink Coder product creates a nontrivial expression
that cannot be accessed by address, resulting in an error during the build
process.

Linear Block Parameter Tunability
The following blocks have a Realization parameter that affects the
tunability of their parameters:
• Transfer Fcn
• State-Space
• Discrete State-Space
The Realization parameter must be set by using the MATLAB set_param
function, as in the following example.
set_param(gcb,'Realization','auto')

The following values are defined for the Realization parameter:
• general: The block’s parameters are preserved in the generated code,
permitting parameters to be tuned.
• sparse: The block’s parameters are represented in the code by transformed
values that increase the computational efficiency. Because of the
transformation, the block’s parameters are no longer tunable.
• auto: This setting is the default. A general realization is used if one or
more of the block’s parameters are tunable. Otherwise sparse is used.

7-26

Parameters

Note To tune the parameter values of a block of one of the above types
without restriction during an external mode simulation, you must set
Realization to general.

Code Reuse for Subsystems with Mask Parameters
The Simulink Coder product can generate reusable (reentrant) code for
a model containing identical atomic subsystems. Selecting the Reusable
function option for Function packaging enables such code reuse, and
causes a single function with arguments to be generated that is called when
any of the identical atomic subsystem executes. See “Subsystems” for details
and restrictions on the use of this option.
Mask parameters become arguments to reusable functions. However, for
reuse to occur, each instance of a reusable subsystem must declare the same
set of mask parameters. If, for example subsystem A has mask parameters b
and K, and subsystem B has mask parameters c and K, then code reuse is not
possible, and the Simulink Coder product will generate separate functions
for A and B.

Configuration Parameter Quick Reference Diagram
The next figure shows the code generation and storage class options that
control the representation of parameters in generated code.

7-27

7

Data Representation

Kp = 5.0;
u

Kp

y
SIMULINK CODER CONTROLS SYMBOL USED IN CODE

[OFF]

1 y = u* (rtP.);

Include parameters as fields
in a global structure
(field names based on block names)

SIMULINK CODER CONTROLS SYMBOL USED IN CODE

[Auto]
(implicit)
Inline
Parameters

Use numeric value of
parameter (if possible)

2

y = u* (5.0);

3

const *p_ = &rtP.[0];
for (i=0; i[i]);
}

INCLUDED IN LIST OF GLOBAL (TUNABLE) PARAMETERS

ON

[SimulinkGlobal(Auto)] 4 y = u* (rtP.Kp);
ExportedGlobal

5 y = u* (Kp);

ImportedExtern

6 y = u* (Kp);

Include in a
global structure

Unstructured
storage

Symbol preserved
(must be unique)

ImportedExternPointer 7 y = u* (*Kp);
KEY:
[option] : default for code generation option
 : Generated symbol for parameter storage field

Generated Code for Parameter Data Types
For an example of the code generated from Simulink parameters with
different data types, run the model rtwdemo_paramdt. This model shows
options that are available for controlling the data type of tunable parameters
in the generated code. The model’s subsystem includes several instances of

7-28

Parameters

Gain blocks feeding Saturation blocks. Each pair of blocks uses a workspace
variable of a particular data type, as shown in the next figure.

7-29

7

Data Representation

Inlined parameters (InLineParameters ON + Auto storage class)
==> numeric value inlined
1

single

Kinline

single

single

1

Upper: Kinline
Lower: 0
Double-precision (context-sensitive) parameters
==> tunable parameter inherits data type from run-time parameter
2

single

Kcs

single

single

2

Upper: Kcs
Lower: 0
Tunable parameters with explicit data type specification
==> parameter is cast to run-time parameter data type in generated code
3

4

5

6

7

single

single

single

single

single

Ksingle

Kint8

Kfixpt

Kalias

Kuser

single

single

single

Upper: Ksingle
Lower: 0
single

single

Upper: Kint8
Lower: 0
single

single

Upper: Kfixpt
Lower: 0
single

single

Upper: Kalias
Lower: 0
single
Upper: Kuser
Lower: 0

7-30

3

4

5

6

7

Parameters

The Simulink engine initializes the parameters in the model by executing
the script rtwdemo_paramdt_data.m. You can view the initialization script
and inspect the workspace variables in Model Explorer by double-clicking
the yellow boxes in the model.
In the model, note that the Inline parameters option on the
Optimization > Signals and Parameters pane of the Configuration
Parameters dialog box is selected. The Model Parameter Configuration
dialog box reveals that all base workspace variables (with the exception
of Kinline) have their Storage class property set to ExportedGlobal.
Consequently, Kinline is a nontunable parameter while the remaining
variables are tunable parameters.
To generate code for the model, double-click the blue boxes. The following
table shows both the MATLAB code used to initialize parameters and the code
generated for each parameter in the rtwdemo_paramdt model.
Parameter & MATLAB Code

Generated Variable Declaration and Code

Kinline
rtb_Gain1 = rtwdemo_paramdt_U.In1 * 2.0F;
Kinline = 2;

.
.
rtwdemo_paramdt_Y.Out1 = rt_SATURATE(rtb_Gain1, 0.0F, 2.0F);

Kcs
real32_T Kcs = 3.0F;
Kcs = 3;

.
.
rtb_Gain1 = rtwdemo_paramdt_U.In2 * Kcs;
.
.
rtwdemo_paramdt_Y.Out2 = rt_SATURATE(rtb_Gain1, 0.0F, Kcs);

7-31

7

Data Representation

Parameter & MATLAB Code

Generated Variable Declaration and Code

Ksingle
real32_T Ksingle = 4.0F;
Ksingle = single(4);

.
.
rtb_Gain1 = rtwdemo_paramdt_U.In3 * Ksingle;
.
.
rtwdemo_paramdt_Y.Out3 = rt_SATURATE(rtb_Gain1, 0.0F, Ksingle);

Kint8
int8_T Kint8 = 5;
Kint8 = int8(5);

.
.
rtb_Gain1 = rtwdemo_paramdt_U.In4 * ((real32_T)( Kint8 ));
.
.
rtwdemo_paramdt_Y.Out4 = rt_SATURATE(rtb_Gain1, 0.0F,
((real32_T)( Kint8 )));

Kfixpt
int16_T Kfixpt = 192;
Kfixpt = Simulink.Parameter;
Kfixpt.Value = 6;
Kfixpt.DataType = ...

.
.
rtb_Gain1 = rtwdemo_paramdt_U.In5 *

'fixdt(true, 16, 2^-5, 0)';
Kfixpt.CoderInfo.StorageClass = ...
'ExportedGlobal';

(((real32_T)ldexp((real_T)Kfixpt, -5)));
.
.
rtwdemo_paramdt_Y.Out5 = rt_SATURATE(rtb_Gain1, 0.0F,
(((real32_T)ldexp((real_T)Kfixpt, -5))));

7-32

Parameters

Parameter & MATLAB Code

Generated Variable Declaration and Code

Kalias
typedef real32_T aliasType;
aliasType = ...

.

Simulink.AliasType('single');
Kalias = Simulink.Parameter;
Kalias.Value = 7;

.
aliasType Kalias = 7.0F;
.

Kalias.DataType = 'aliasType';
Kalias.CoderInfo.StorageClass = ...
'ExportedGlobal';

.
rtb_Gain1 = rtwdemo_paramdt_U.In6 * Kalias;
.
.
rtwdemo_paramdt_Y.Out6 = rt_SATURATE(rtb_Gain1, 0.0F, Kalias);

Kuser
typedef int16_T userType;
userType = Simulink.NumericType;
userType.DataTypeMode = ...
'Fixed-point: slope and bias scaling';
userType.Slope = 2^-3;

.
.
userType Kuser = 64;
.

userType.isAlias = true;
Kuser = Simulink.Parameter;

.
rtb_Gain1 = rtwdemo_paramdt_U.In7 *

Kuser.Value = 8;

(((real32_T)ldexp((real_T)Kuser, -3)));

Kuser.DataType = 'userType';
Kuser.CoderInfo.StorageClass = ...
'ExportedGlobal';

.
.
rtwdemo_paramdt_Y.Out7 = rt_SATURATE(rtb_Gain1, 0.0F,
(((real32_T)ldexp((real_T)Kuser, -3))));

The salient features of the code generated for this model are as follows:
• The Simulink Coder product inlines nontunable parameters, for example,
Kinline. However, the product does not inline tunable parameters, such
as Kcs, Ksingle, and Kint8.
• The Simulink engine treats tunable parameters of data type double in a
context-sensitive manner, such that the parameter inherits its data type
from the context in which the block uses it. For example, Kcs inherits a
single data type from the Gain block’s input signal.

7-33

7

Data Representation

• If a parameter’s data type matches that of the block’s run-time parameter,
the block can use the tunable parameter without any transformation.
Consequently, the Simulink Coder product need not cast the parameter
from one data type to another, as illustrated by Ksingle and Kalias.
However, if a parameter’s data type does not match that of the block’s
run-time parameter, the block cannot readily compute its output. In
this case, the product casts parameters to the relevant data type. For
example, Kint8, Kfixpt, and Kuser require casts to a single data type for
compatibility with the input signals to the Gain and Saturation blocks.
• If you are using an ERT target and a parameter specifies a data type alias,
for example, created by an instance of the Simulink.AliasType class, its
variable definition in the generated code uses the alias data type. For
example, the Simulink Coder product declares Kalias and Kuser to be of
data types aliasType and userType, respectively.
• If a parameter specifies a fixed-point data type, the Simulink Coder product
initializes its value in the generated code to the value of Q computed from
the expression V = SQ + B (see the Simulink Fixed Point documentation for
more information about fixed-point semantics and notation), where

-

V is a real-world value
Q is an integer that encodes V
S is the slope
B is the bias

For example, Kfixpt has a real-world value of 6, slope of 2-5, and bias of 0.
Consequently, the product declares the value of Kfixpt to be 192.

Tunable Workspace Parameter Data Type
Considerations
If you are using tunable workspace parameters, you need to be aware of
potential issues regarding data types. A workspace parameter is tunable
when the following conditions exist:
• You select the Inline parameters option on the Optimization > Signals
and Parameters pane of the Configuration Parameters dialog box
• The parameter has a storage class other than Auto

7-34

Parameters

When generating code for tunable workspace parameters, the Simulink Coder
product checks and compares the data types used for a particular parameter
in the workspace and in Block Parameter dialog boxes.
If...

The Simulink Coder Product...

The data types match

Uses that data type for the parameter in the
generated code.

You do not explicitly
specify a data type
other than double in
the workspace

Uses the data type specified by the block in
the generated code. If multiple blocks share a
parameter, they must all specify the same data
type. If the data type varies between blocks,
the product generates an error similar to the
following:
Variable 'K' is used in incompatible ways
in the dialog fields of the following:
cs_params/Gain, cs_params/Gain1. The
variable'value is being used both directly
and after a transformation. Only one of
these usages is permitted for any given
variable.

You explicitly specify
a data type other
than double in the
workspace

Uses the data type from the workspace for the
parameter. The block typecasts the parameter to
the block specific data type before using it.

Guidelines for Specifying Data Types
The following table provides guidelines on specifying data types for tunable
workspace parameters.
If You Want to...

Then Specify Data Types in...

Minimize memory usage (int8
instead of single)

The workspace explicitly

Avoid typecasting

Blocks only

7-35

7

Data Representation

If You Want to...

Then Specify Data Types in...

Interface to legacy or custom code

The workspace explicitly

Use the same parameter for
multiple blocks that specify
different data types

The workspace explicitly

The Simulink Coder product enforces limitations on the use of data types
other than double in the workspace, as explained in “Limitations on
Specifying Workspace Data Types Explicitly” on page 15-135.

Limitations on Data Type Specifications in Workspace
When you explicitly specify a data type other than double in the workspace,
blocks typecast the parameter to a corresponding data type. This is an
issue for blocks that use pointer access for their parameters. Blocks cannot
use pointer access if they need to typecast the parameter before using it
(because of a data type mismatch). Another case in which this occurs is for
workspace variables with bias or fractional slope. Two possible solutions
to these problems are
• Remove the explicit data type specification in the workspace for parameters
used in such blocks.
• Modify the block so that it uses the parameter with the same data type
as specified in the workspace. For example, the Lookup Table block uses
the data types of its input signal to determine the data type that it uses
to access the X-breakpoint parameter. You can prevent the block from
typecasting the run-time parameter by converting the input signal to the
data type used for X-breakpoints in the workspace. (Similarly, the output
signal is used to determine the data types used to access the lookup table
Y data.)

Tune Parameters
Tune Parameters from the Command Line
When parameters are MATLAB workspace variables, the Model Parameter
Configuration dialog box is the recommended way to see or set the properties

7-36

Parameters

of tunable parameters. In addition to that dialog box, you can also use
MATLAB get_param and set_param commands.
Note You can also use Simulink.Parameter objects for tunable parameters.
See “Configure Parameter Objects for Code Generation” on page 7-39 for
details.
The following commands return the tunable parameters and corresponding
properties:
• get_param(gcs, 'TunableVars')
• get_param(gcs, 'TunableVarsStorageClass')
• get_param(gcs, 'TunableVarsTypeQualifier')
The following commands declare tunable parameters or set corresponding
properties:
• set_param(gcs, 'TunableVars', str)
The argument str (string) is a comma-separated list of variable names.
• set_param(gcs, 'TunableVarsStorageClass', str)
The argument str (string) is a comma-separated list of storage class
settings.
The valid storage class settings are

-

Auto
ExportedGlobal
ImportedExtern
ImportedExternPointer

• set_param(gcs, 'TunableVarsTypeQualifier', str)
The argument str (string) is a comma-separated list of storage type
qualifiers.

7-37

7

Data Representation

The following example declares the variable k1 to be tunable, with storage
class ExportedGlobal and type qualifier const. The number of variables and
number of specified storage class settings must match. If you specify multiple
variables and storage class settings, separate them with a comma.
set_param(gcs, 'TunableVars', 'k1')
set_param(gcs, 'TunableVarsStorageClass','ExportedGlobal')
set_param(gcs, 'TunableVarsTypeQualifier','const')

Interfaces for Tuning Parameters
The Simulink Coder product includes
• Support for developing a Target Language Compiler API for tuning
parameters independent of external mode. See “Parameter Functions” in
the Target Language Compiler documentation for information.
• A C application program interface (API) for tuning parameters independent
of external mode. See “Data Interchange Using the C API” on page 15-137
for information.
• An interface for exporting ASAP2 files, which you customize to use
parameter objects. For details, see “ASAP2 Data Measurement and
Calibration” on page 15-174.

Parameter Objects
• “About Parameter Objects for Code Generation” on page 7-39
• “Use Parameter Objects for Code Generation” on page 7-39
• “Configure Parameter Objects for Code Generation” on page 7-39
• “Storage Classes and Code Generation for Parameter Objects” on page 7-40
• “Generate Code for Parameter Objects from Command Line” on page 7-41
• “Generate Code for Parameter Objects Using Model Explorer” on page 7-42
• “Parameter Object Configuration Quick Reference Diagram” on page 7-46
• “Resolve Conflicts in Parameter Object Configurations” on page 7-47

7-38

Parameters

About Parameter Objects for Code Generation
Within the class hierarchy of Simulink data objects, the Simulink product
provides a class that is designed as base class for parameter storage. This
topic explains how to use parameter objects in code generation.
The CoderInfo properties of parameter objects are used by the Simulink
Coder product during code generation. These properties let you assign storage
classes to the objects, thereby controlling how the generated code stores and
represents parameters.
The Simulink Coder build process also writes information about the properties
of parameter objects to the model.rtw file. This information, formatted as
Object records, is accessible to Target Language Compiler programs. For
general information on Object records, see “Data Object Information in
model.rtw”.
Before using Simulink parameter objects with the Simulink Coder product,
read the discussion of Simulink data objects in the Simulink documentation.

Use Parameter Objects for Code Generation
The general procedure for using parameter objects in code generation is as
follows:
1 Define a subclass of Simulink.Parameter.
2 Instantiate parameter objects from your subclass and set their properties

from the command line or by using Model Explorer.
3 Use the objects as parameters within your model.
4 Generate code and build your target executable.

Configure Parameter Objects for Code Generation
In configuring parameter objects for code generation, you use the following
code generation and parameter object properties:
• The Inline parameters option (see “Parameters” on page 7-10).
• Parameter object properties:

7-39

7

Data Representation

-

Value. The numeric value of the object, used as an initial (or inlined)

-

DataType. The data type of the object. This can be any Simulink numeric
data type, including a fixed-point, user-defined, or alias data type.

-

CoderInfo.StorageClass. Controls the generated storage declaration

parameter value in generated code.

and code for the parameter object.

Other parameter object properties (such as user-defined properties of
classes derived from Simulink.Parameter) do not affect code generation.
Note If Inline parameters is off (the default), the
CoderInfo.StorageClass parameter object property is ignored
in code generation.

Storage Classes and Code Generation for Parameter Objects
The Simulink Coder product generates code and storage declarations based
on the CoderInfo.StorageClass property of the parameter object. The logic
is as follows:
• If the storage class is 'Auto' (the default), the parameter object is inlined
(if possible), using the Value property.
• For storage classes other than 'Auto', the parameter object is handled as a
tunable parameter.

-

A global storage declaration is generated. You can use the generated
storage declaration to make the variable visible to your hand-written
code. You can also make variables declared in your hand-written code
visible to the generated code.

-

The symbolic name of the parameter object is generally preserved in
the generated code.

See the table in “Generate Code for Parameter Objects Using Model
Explorer” on page 7-42 for examples of code generated for possible settings of
CoderInfo.StorageClass.

7-40

Parameters

Generate Code for Parameter Objects from Command Line
In this section, the Gain block computations of the model shown in the next
figure are used as an example of how the Simulink Coder build process
generates code for a parameter object.

Model Using Parameter Object Kp As Block Parameter

In this model, Kp sets the gain of the Gain block.
To configure a parameter object such as Kp for code generation:
1 Instantiate a Simulink.Parameter object called Kp. In this

example, the parameter object is an instance of the example class
SimulinkDemos.Parameter, which is provided with the Simulink product.
Kp = Simulink.Parameter
Kp =
Simulink.Parameter
Value: 5
CoderInfo: [1x1 Simulink.ParamCoderInfo]
Description: ''
DataType: 'auto'

7-41

7

Data Representation

Min:
Max:
DocUnits:
Complexity:
Dimensions:

[]
[]
''
'real'
'[1x1]'

Make sure that the name of the parameter object matches the desired block
parameter in your model. This enables the Simulink engine to associate
the parameter name with the corresponding object. In the preceding model,
the Gain block parameter Kp resolves to the parameter object Kp.
2 Set the object properties you need. You can do this by using the Model

Explorer, or you can assign properties by using MATLAB commands, as
follows:
• To specify the Value property, type
Kp.Value = 5.0;

• To specify the storage class of for the parameter, set the
CoderInfo.StorageClass property, for example:
Kp.CoderInfo.StorageClass = 'ExportedGlobal';

The CoderInfo parameters are now
Kp.CoderInfo
Simulink.ParamCoderInfo
StorageClass: 'ExportedGlobal'
Alias: ''
CustomStorageClass: 'Default'
CustomAttributes: [1x1
SimulinkCSC.AttribClass_Simulink_Default]

Generate Code for Parameter Objects Using Model Explorer
If you prefer, you can create and modify attributes of parameter objects using
the Model Explorer. This lets you see the attributes of a parameter in a
dialog box, and alleviates the need to remember and type field names. Do the
following to instantiate Kp and set its attributes from Model Explorer:

7-42

Parameters

1 Choose Model Explorer from the View menu.

Model Explorer opens or activates if it already was open.
2 Select Base Workspace in the Model Hierarchy pane.
3 Select Simulink Parameter from the Add menu.

A new parameter named Param appears in the Contents pane.

4 To set Kp.Name in the Model Explorer:
a Click the word Param in the Name column to select it.
b Rename it by typing Kp in place of Param.
c Press Enter or Return.
5 To set Kp.Value in Model Explorer:

7-43

7

Data Representation

a Select the Value field at the top of the Dialog pane.
b Type 5.0.
c Click the Apply button.
6 To set the Kp.CoderInfo.StorageClass in Model Explorer:
a Click the Storage class menu and select ExportedGlobal, as shown in

the next figure.

b Click Apply.

The following table shows the variable declarations for Kp and the code
generated for the Gain block in the model shown in the preceding model,
with the Inline parameters and Eliminate superfluous local variables
(Expression folding) check boxes selected (which includes the gain
computation in the output computation). An example is shown for each

7-44

Parameters

possible setting of CoderInfo.StorageClass. Global structures include the
model name (symbolized as model_ or _model).
StorageClass
Property

Generated Variable Declaration
and Code

Auto
model_Y.Out1 = rtb_u * 5.0;

SimulinkGlobal
struct _Parameters_model {
real_T Kp;
}
.
.
Parameters_model model_P = {
5.0
};
.
.
model_Y.Out1 = rtb_u * model_P.Kp;
ExportedGlobal
extern real_T Kp;
.
.
real_T Kp = 5.0;
.
.
model_Y.Out1 = rtb_u * Kp;

7-45

7

Data Representation

StorageClass
Property

Generated Variable Declaration
and Code

ImportedExtern
extern real_T Kp;
.
.
model_Y.Out1 = rtb_u * Kp;
ImportedExternPointer
extern real_T *Kp;
.
.
model_Y.Out1 = rtb_u * (*Kp);

Parameter Object Configuration Quick Reference Diagram
The next figure shows the code generation and storage class options that
control the representation of parameter objects in generated code.

7-46

Parameters

Kp = Simulink.Parameter; Kp.Value = 5.0;
u

Kp

y
SIMULINK CODER CONTROLS SYMBOL USED IN CODE

[OFF]

1 y = u* (rtP.);

Include parameters as fields
in a global structure
(field names based on block names)

SIMULINK CODER CONTROLS SYMBOL USED IN CODE

[Auto]
Inline
Parameters

Use numeric value of
parameter (if possible)

2

y = u* (5.0);

3

const *p_ = &rtP.[0];
for (i=0; i[i]);
}

INCLUDED IN LIST OF GLOBAL (TUNABLE) PARAMETERS

ON

SimulinkGlobal

4 y = u* (rtP.Kp);

ExportedGlobal

5 y = u* (Kp);

ImportedExtern

6 y = u* (Kp);

Include in a
global structure

Unstructured
storage

Symbol preserved
(must be unique)

ImportedExternPointer 7 y = u* (*Kp);
KEY:
[option] : default for code generation option
 : Generated symbol for parameter storage field

Resolve Conflicts in Parameter Object Configurations
Two methods are available for controlling the tunability of parameters. You
can
• Define them as Simulink.Parameter objects in the MATLAB workspace

7-47

7

Data Representation

• Use the Model Parameter Configuration dialog box
The next figures show how you can use each of these methods to control
the tunability of parameter Kp. The first figure shows Kp defined as
Simulink.Parameter in the Model Explorer. You control the tunability of Kp
by specifying the parameter’s storage class.

Parameter Object Kp with Auto Storage Class in Model Explorer

The next figure shows how you can use the Model Parameter Configuration
dialog box to specify a storage class for numeric variables in the MATLAB
workspace.

7-48

Parameters

Parameter Kp Defined with SimulinkGlobal Storage Class

Note Do not use both methods for controlling the tunability of a given
parameter. If you use both methods and the storage class settings for the
parameter do not match, an error results.

Structure Parameters and Generated Code
• “About Structure Parameters and Generated Code” on page 7-49
• “Include Structure Parameters in Generated Code” on page 7-50
• “Control Naming of Structure Parameter Types” on page 7-50

About Structure Parameters and Generated Code
Structure parameters provide a way to improve generated code to use
structures rather multiple separate variables. You also have the option of
configuring the appearance of a structure parameter in generated code.
For more information about structure parameters, see“Structure Parameters”
in the Simulink documentation. For an example of how to convert a model

7-49

7

Data Representation

that uses unstructured workspace variables to a model that uses structure
parameters, see sldemo_applyVarStruct.

Include Structure Parameters in Generated Code
By default, structure parameters do not appear in generated code. Structure
parameters include numeric variables and the code generator inlines numeric
values.
To make structure type definition appear in generated code for a structure
parameter,
1 Create a Simulink.Parameter object.
2 Define the object value to be the parameter structure.
3 Define the object storage class to be a value other than Auto.

The code generator places a structure type definition or the tunable parameter
structure in model_types.h. By default, the code generator identifies
the type with a nondescriptive, automatically generated name, such as
struct_z98c0D2qc4btL.
For information on how to control the naming of the type, see “Control
Naming of Structure Parameter Types” on page 7-50. For an example, see
sldemo_applyVarStruct

Control Naming of Structure Parameter Types
To control the naming of a structure parameter type, by using a Simulink.Bus
object to specify the data type of the Simulink.Parameter object.
1 Use Simulink.Bus.createObject to create a bus object with the same shape

as the parameter structure. For example:
busInfo=Simulink.Bus.createObject(ControlParam.Value);
2 Assign the bus object name to the data type property of the parameter

object.
ParamType=eval(busInfo.busName);

7-50

Parameters

ControlParam.DataType='Bus: ParamType';

Only Simulink.Parameter can accept the bus object name as a data type.
For an example, see sldemo_applyVarStruct

7-51

7

Data Representation

Signals
In this section...
“About Signals” on page 7-52
“Signal Storage Concepts” on page 7-53
“Signals with Auto Storage Class” on page 7-55
“Signals with Test Points” on page 7-59
“Interface Signals to External Code” on page 7-60
“Symbolic Naming Conventions for Signals” on page 7-62
“Summary of Signal Storage Class Options” on page 7-63
“Interfaces for Monitoring Signals” on page 7-64
“Signal Objects” on page 7-65
“Initialize Signals and States Using Signal Objects” on page 7-74

About Signals
The Simulink Coder product offers a number of options that let you control
how signals in your model are stored and represented in the generated code.
This section discusses how you can use these options to
• Control whether signal storage is declared in global memory space or
locally in functions (that is, in stack variables).
• Control the allocation of stack space when using local storage.
• Delcare signals as test points to store them in unique memory locations
• Reduce memory usage by instructing the Simulink Coder product to store
signals in reusable buffers.
• Control whether or not signals declared in generated code are interfaceable
(visible) to externally written code. You can also specify that signals are to
be stored in locations declared by externally written code.
• Preserve the symbolic names of signals in generated code by using signal
labels.

7-52

Signals

The discussion in the following sections refers to code generated from
signal_examp, the model shown in the next figure.

Signal_examp Model

Signal Storage Concepts
This section discusses structures and concepts you must understand to choose
the best signal storage options for your application:
• The global block I/O data structure model_B
• The concept of signal storage classes as used in the Simulink Coder product

Global Block I/O Structure
By default, the Simulink Coder product attempts to optimize memory usage
by sharing signal memory and using local variables.
However, under a number of circumstances you should place signals in global
memory. For example,
• You might want a signal to be stored in a structure that is visible to
externally written code.
• The number and/or size of signals in your model might exceed the stack
space available for local variables.
In such cases, it is possible to override the default behavior and store selected
(or all) signals in a model-specific global block I/O data structure. The global
block I/O structure is called model_B (in earlier versions this was called rtB).

7-53

7

Data Representation

The following code shows how model_B is defined and declared in code
generated (with signal storage optimizations off) from the signal_examp
model shown in the Signal_examp Model on page 7-53 figure.
(in signal_examp.h)
/* Block signals (auto storage) */
extern BlockIO_signal_examp signal_examp_B;
(in signal_examp.c)
/* Block signals (auto storage) */
BlockIO_signal_examp signal_examp_B;

Field names for signals stored in model_B are generated according to the rules
described in “Symbolic Naming Conventions for Signals” on page 7-62.

Signals Storage Classes
In the Simulink Coder product, the storage class property of a signal
specifies how the product declares and stores the signal. In some cases this
specification is qualified by more options.
In the context of the Simulink Coder product, the term “storage class” is not
synonymous with the term storage class specifier, as used in the C language.
Default Storage Class. Auto is the default storage class and is the storage
class you should use for signals that you do not need to interface to external
code. Signals with Auto storage class can be stored in local and/or shared
variables or in a global data structure. The form of storage depends on
the Signal storage reuse, Reuse block outputs, Enable local block
outputs, and Minimize data copies between local and global variables
options, and on available stack space. See “Signals with Auto Storage Class”
on page 7-55 for a full description of code generation options for signals with
Auto storage class.
Explicitly Assigned Storage Classes. Signals with storage classes other
than Auto are stored either as members of model_B, or in unstructured global
variables, independent of model_B. These storage classes are for signals that
you want to monitor and/or interface to external code.

7-54

Signals

The Signal storage reuse, Enable local block outputs, Reuse block
outputs, Eliminate superfluous local variables (expression folding),
and Minimize data copies between local and global variables
optimizations do not apply to signals with storage classes other than Auto.
Use the Signal Properties dialog box to assign these storage classes to signals:
• SimulinkGlobal(Test Point): Test points are stored as fields of the
model_B structure that are not shared or reused by any other signal. See
“Signals with Test Points” on page 7-59 for more information.
• ExportedGlobal: The signal is stored in a global variable, independent
of the model_B data structure. model.h exports the variable. Signals
with ExportedGlobal storage class must have unique signal names. See
“Interface Signals to External Code” on page 7-60 for more information.
• ImportedExtern: model_private.h declares the signal as an extern
variable. Your code must supply the variable definition. Signals with
ImportedExtern storage class must have unique signal names. See
“Interface Signals to External Code” on page 7-60 for more information.
• ImportedExternPointer: model_private.h declares the signal as an
extern pointer. Your code must define a valid pointer variable. Signals
with ImportedExtern storage class must have unique signal names. See
“Interface Signals to External Code” on page 7-60 for more information.

Signals with Auto Storage Class
Options are available for signals with Auto storage class:
• Signal storage reuse
• Enable local block outputs
• Reuse block outputs
• Eliminate superfluous local variables (expression folding)
• Minimize data copies between local and global variables
Use these options to control signal memory reuse and choose local or global
(model_B) storage for signals. The Signal storage reuse option is on
the Optimization > Signals and Parameters pane of the Configuration
Parameters dialog box, as shown in the next figure.

7-55

7

Data Representation

These options interact. When the Signal storage reuse option is selected,
• The Reuse block outputs option is enabled and selected, and signal
memory is reused.
• The Enable local block outputs option is enabled and selected. This
lets you choose whether reusable signal variables are declared as local
variables in functions or as members of model_B.
• The Eliminate superfluous local variables (expression folding)
is enabled and selected, and block computations collapse into single
expressions.
• The Minimize data copies between local and global variables is
enabled and cleared, and global memory is not reused.
The following code examples illustrate the effects of the Signal storage
reuse, Enable local block outputs, Reuse block outputs, Eliminate
superfluous local variables (expression folding) and Minimize data
copies between local and global variables options. The examples were
generated from the signal_examp model (see figure Signal_examp Model
on page 7-53).
The first example illustrates signal storage optimization, with Signal
storage reuse, Enable local block outputs, Reuse block outputs, and
Minimize data copies between local and global variables selected. (For
clarity in showing the individual Gain and Sum block computation, expression
folding is off in this example.) The output signal from the Sum block reuses
signal_examp_Y.Out1, a variable local to the model output function.

7-56

Signals

/* Model output function */
static void signal_examp_output(int_T tid)
{
/* Sum: 'Sum' incorporates:
*

Constant: '/Constant'

*

Inport: '>/In1'

*/
signal_examp_Y.Out1 = signal_examp_U.In1 + signal_examp_P.Constant_Value;
/* Gain: '/Gain' */
signal_examp_Y.Out1 = signal_examp_P.Gain_Gain * signal_examp_Y.Out1;
/* tid is required for a uniform function interface.
* Argument tid is not used in the function. */
UNUSED_PARAMETER(tid);
}

If you are constrained by limited stack space, you can turn Enable local
block outputs off and still benefit from memory reuse. The following
example was generated with Enable local block outputs cleared and
Signal storage reuse, Reuse block outputs, and Minimize data copies
between local and global variables selected. The output signals from
the Sum and Gain blocks use global structure signal_examp_B rather than
declaring local variables and in both cases the signal name is gainSig.
/* Model output function */
static void signal_examp_output(int_T tid)
{
/* Sum: '/Add' incorporates:
*

Constant: '/Constant'

*

Inport: '/In1'

*/
signal_examp_B.gainSig = signal_examp_U.In1 +
signal_examp_P.Constant_Value;
/* Gain: '/Gain' */
signal_examp_B.gainSig = signal_examp_P.Gain_Gain *
signal_examp_B.gainSig;
/* Outport: '/Out1' */

7-57

7

Data Representation

signal_examp_Y.Out1 = signal_examp_B.gainSig;
/* tid is required for a uniform function interface.
* Argument tid is not used in the function. */
UNUSED_PARAMETER(tid);
}

When the Signal storage reuse option is cleared, Reuse block outputs,
Enable local block outputs, and Minimize data copies between local
and global variables are disabled. This makes the block output signals
global and unique, signal_examp_B.sumSig and signal_examp_B.gainSig,
as shown in the following code.
/* Model output function */
static void signal_examp_output(int_T tid)
{
/* Sum: '/Add' incorporates:
*

Constant: '/Constant'

*

Inport: '/In1'

*/
signal_examp_B.sumSig = signal_examp_U.In1 +
signal_examp_P.Constant_Value;
/* Gain: '/Gain' */
signal_examp_B.gainSig = signal_examp_P.Gain_Gain *
signal_examp_B.sumSig;
/* Outport: '/Out1' */
signal_examp_Y.Out1 = signal_examp_B.gainSig;
/* tid is required for a uniform function interface.
* Argument tid is not used in the function. */
UNUSED_PARAMETER(tid);
}

In large models, disabling Signal storage reuse can significantly increase
RAM and ROM usage. Therefore, this approach is not recommended for code
deployment; however it can be useful in rapid prototyping environments.

7-58

Signals

The following table summarizes the possible combinations of the Signal
storage reuse / Reuse block outputs and Enable local block outputs
options.

Signal storage reuse
and Reuse block
outputs ON

Signal storage reuse
OFF
(Reuse block outputs
disabled)

Enable local block
outputs ON

Reuse signals in
local memory (fully
optimized)

N/A

Enable local block
outputs OFF

Reuse signals in
model_B structure

Individual signal
storage in model_B
structure

Control Stack Space Allocation
The value of the “Maximum stack size (bytes)” parameter, on the
Optimization > Signals and Parameters pane of the Configuration
Parameters dialog box constrains the use of stack space used by local
block output variables. The command-line equivalent for this parameter
is MaxStackSize. If the accumulated size of variables in local memory
exceeds MaxStackSize, the product places subsequent local variables in
global memory space.
If it is important that you maximize potential for signal storage optimization,
then set MaxStackSize to accommodate the size and number of signals in your
model. This minimizes overflow into global memory space and maximizes use
of local memory. Local variables offer more optimization potential through
mechanisms such as expression folding and buffer reuse. See “Use Stack
Space Allocation” on page 20-6 for more information.

Signals with Test Points
A test point is a signal that is stored in a unique location no other signals share
or reuse. See “Test Points” in the Simulink documentation for information
about including test points in your model.

7-59

7

Data Representation

When you generate code for models that include test points, the Simulink
Coder build process allocates a separate memory buffer for each test point.
Test points are stored as members of the model_B structure.
Declaring a signal as a test point disables the following options for that signal.
This can lead to increased code and data size. You do not lose the benefits of
optimized storage for any other signals in your model.
• Signal storage reuse
• Enable local block outputs
• Reuse block outputs
• Eliminate superfluous local variables (expression folding)
• Minimize data copies between local and global variables
For an example of storage declarations and code generated for a test point,
see “Summary of Signal Storage Class Options” on page 7-63.
If you have an Embedded Coder license, you can specify that the Simulink
Coder build process ignore test points in the model, allowing optimal buffer
allocation, using the “Ignore test point signals” parameter. Ignoring test
points facilitates transitioning from prototyping to deployment and avoids
accidental degradation of generated code due to workflow artifacts. For more
information, see “Ignore test point signals”.

Interface Signals to External Code
The Simulink Signal Properties dialog box lets you interface selected signals
to externally written code. In this way, your hand-written code has access
to such signals for monitoring or other purposes. To interface a signal to
external code, use the Code Generation tab of the Signal Properties dialog
box to assign one of the following storage classes to the signal:
• ExportedGlobal
• ImportedExtern
• ImportedExternPointer
Set the storage class as follows:

7-60

Signals

1 In your Simulink block diagram, select the line that carries the signal.

Then select Signal Properties from the Edit menu of your model. This
opens the Signal Properties dialog box. Alternatively, right-click the line
that carries the signal, and select Signal properties from the menu.
2 Select the Code Generation tab of the Signal Properties dialog box.
3 Select the desired storage class (Auto, ExportedGlobal, ImportedExtern,

or ImportedExternPointer) from the Storage class menu. The next
figure shows ExportedGlobal selected.

4 Optional: For storage classes other than Auto, you can enter a storage type

qualifier such as const or volatile in the Storage type qualifier field.
The Simulink Coder product does not check this string for errors; whatever
you enter is included in the variable declaration.
5 Click Apply.

7-61

7

Data Representation

Note You can also interface test points and other signals that are stored
as members of model_B to your code. To do this, your code must know
the address of the model_B structure where the data is stored, and other
information. This information is not automatically exported. The Simulink
Coder product provides C/C++ and Target Language Compiler APIs that
give your code access to model_B and other data structures. See “Interfaces
for Monitoring Signals” on page 7-64 for more information.

Symbolic Naming Conventions for Signals
When signals have a storage class other than Auto, the Simulink Coder
product preserves symbolic information about the signals or their originating
blocks in the generated code.
For labeled signals, field names in model_B derive from the signal names. In
the following example, the field names model_B.sumSig and model_B.gainSig
are derived from the corresponding labeled signals in the signal_examp
model (shown in figure Signal_examp Model on page 7-53).
/* Block signals (auto storage) */
typedef struct _BlockIO_signal_examp {
real_T sumSig;
real_T gainSig;
} BlockIO_signal_examp;

/* '/Add' */
/* '/Gain' */

When you clear the Signal storage reuse optimization, sumSig is not
part of model_B, and a local variable is used for it instead. For unlabeled
signals, model_B field names are derived from the name of the source block
or subsystem.
The components of a generated signal label are
• The root model name, followed by
• The name of the generating signal object, followed by
• A unique name mangling string (if required)
The number of characters that a signal label can have is limited by the
Maximum identifier length parameter specified on the Symbols pane

7-62

Signals

of the Configuration Parameters dialog box. See “Configure Generated
Identifiers” on page 9-73 for more detail.
When a signal has Auto storage class, the Simulink Coder build process
controls generation of variable or field names without regard to signal labels.

Summary of Signal Storage Class Options
The next table shows, for each signal storage class option, the variable
declaration and the code generated for Sum (sumSig) and Gain (gainSig)
block outputs of the model shown in figure Signal_examp Model on page 7-53.
Storage Class

Declaration

Auto

In model.c or model.cpp

(with Signal
storage reuse
optimizations on)

Code
rtb_sumSig = signal_examp_U.In1 +

real_T rtb_sumSig;

signal_examp_P.Constant_Value;
rtb_sumSig *=
signal_examp_P.Gain_Gain;
signal_examp_Y.Out1 = rtb_sumSig;

Test point (for
sumSig only)

In model.h
signal_examp_B.sumSig =
typedef struct
_BlockIO_signal_examp

signal_examp_U.In1 +
signal_examp_P.Constant_Value;
rtb_gainSig =

{
real_T sumSig;
}
BlockIO_signal_examp;

signal_examp_B.sumSig *
signal_examp_P.Gain_Gain;
signal_examp_Y.Out1 = rtb_gainSig;

In model.c or model.cpp
BlockIO_signal_examp
signal_examp_B;
real_T rtb_gainSig;

7-63

7

Data Representation

Storage Class

Declaration

ExportedGlobal
(for sumSig only)

In model.h

Code
sumSig = signal_examp_U.In1 +

extern real_T sumSig;

signal_examp_P.Constant_Value;
rtb_gainSig = sumSig *

In model.c or model.cpp

signal_examp_P.Gain_Gain;
signal_examp_Y.Out1 = rtb_gainSig;

real_T sumSig;
real_T rtb_gainSig;

ImportedExtern

In model_private.h
sumSig = signal_examp_U.In1 +
extern real_T sumSig;

signal_examp_P.Constant_Value;
rtb_gainSig = sumSig *

In model.c or model.cpp

signal_examp_P.Gain_Gain;
signal_examp_Y.Out1 = rtb_gainSig;

real_T rtb_gainSig;

ImportedExternPointer
In model_private.h
(*sumSig) = signal_examp_U.In1 +
extern real_T *sumSig;

signal_examp_P.Constant_Value;
rtb_gainSig = (*sumSig) *

In model.c or model.cpp

signal_examp_P.Gain_Gain;
signal_examp_Y.Out1 = rtb_gainSig;

real_T rtb_gainSig;

Interfaces for Monitoring Signals
The Simulink Coder product includes
• Support for developing a Target Language Compiler API for monitoring
signals and states independent of external mode. See “Input Signal
Functions” and “Output Signal Functions” in the Target Language
Compiler documentation for information.
• A C application program interface (API) for monitoring signals and states
independent of external mode. See “Data Interchange Using the C API” on
page 15-137 for information.

7-64

Signals

• An interface for exporting ASAP2 files, which you customize to use signal
objects. For details, see “ASAP2 Data Measurement and Calibration” on
page 15-174.

Signal Objects
• “About Signal Objects for Code Generation” on page 7-65
• “Use Signal Objects for Code Generation” on page 7-66
• “Configure Signal Objects for Code Generation” on page 7-66
• “Storage Classes and Code Generation for Signal Objects” on page 7-66
• “Generate Code for Signal Objects from Command Line” on page 7-67
• “Generate Code for Signal Objects Using Model Explorer” on page 7-69
• “Resolve Conflicts in Configuration of Signals Objects” on page 7-72
This section discusses how to use signal objects in code generation. Signal
objects can be used to represent both signal and state data, and behave
similarly to parameter objects, described in “Parameter Objects” on page 7-38.

About Signal Objects for Code Generation
Within the class hierarchy of Simulink data objects, the Simulink product
provides a class that is designed as base class for signal storage. This topic
explains how to use signal objects in code generation.
The CoderInfo properties of signal objects are used by the Simulink Coder
product during code generation. These properties let you assign storage
classes to the objects, thereby controlling how the generated code stores and
represents signals.
The Simulink Coder build process also writes information about the properties
of signal objects to the model.rtw file. This information, formatted as Object
records, is accessible to Target Language Compiler programs. For general
information on Object records, see “Data Object Information in model.rtw”.
Before using Simulink signal objects with the Simulink Coder product, read
the discussion of Simulink data objects in the Simulink documentation.

7-65

7

Data Representation

Use Signal Objects for Code Generation
The general procedure for using signal objects in code generation is as follows:
1 Define a subclass of Simulink.Signal.
2 Instantiate signal objects from your subclass and set their properties from

the command line or by using Model Explorer.
3 Use the objects as signals within your model.
4 Generate code and build your target executable.

Configure Signal Objects for Code Generation
In configuring signal objects for code generation, you use the following code
generation options and signal object properties:
• The Signal storage reuse code generation option (see “Signals” on page
7-52).
• The Enable local block outputs code generation option (see “Signals” on
page 7-52).
• The Minimize data copies between local and global variables code
generation option (see “Signals” on page 7-52).
• The CoderInfo.StorageClass signal object property: The storage classes
defined for signal objects, and their effect on code generation, are the same
for model signals and signal objects (see “Signals Storage Classes” on
page 7-54).
Other signal object properties (such as user-defined properties of classes
derived from Simulink.Signal) do not affect code generation.

Storage Classes and Code Generation for Signal Objects
The way in which the Simulink Coder product uses storage classes to
determine how signals are stored is the same with and without signal
objects. However, if a signal’s label resolves to a signal object, the object’s
CoderInfo.StorageClass property is used in place of the port configuration
of the signal.

7-66

Signals

The default storage class is Auto. If the storage type is Auto, the Simulink
Coder product follows the Signal storage reuse, Reuse block outputs,
Enable local block outputs, Eliminate superfluous local variables
(expression folding), and Minimize data copies between local and
global variables code generation options to determine whether signal objects
are stored in reusable and/or local variables. Make sure that these options
are set for your application.
To generate a test point or signal storage declaration that can interface
externally, use an explicit CoderInfo.StorageClass assignment. For
example, setting the storage class to SimulinkGlobal, as in the following
command, is equivalent to declaring a signal as a test point.
SinSig.CoderInfo.StorageClass = 'SimulinkGlobal';

Generate Code for Signal Objects from Command Line
The discussion and code examples in this section refer to the model shown in
the next figure.

To configure a signal object, you must first create it and associate it with a
labeled signal in your model. To do this,
1 Define a subclass of Simulink.Signal. In this example, the signal object

is an instance of the class Simulink.Signal, which is provided with the
Simulink product.
2 Instantiate a signal object from your subclass. The following example

instantiates inSig, a signal object of class Simulink.Signal.
inSig = Simulink.Signal
inSig =

7-67

7

Data Representation

Simulink.Signal
CoderInfo: [1x1 Simulink.SignalCoderInfo]
Description: ''
DataType: 'auto'
Min: []
Max: []
DocUnits: ''
Dimensions: -1
Complexity: 'auto'
SampleTime: -1
SamplingMode: 'auto'
InitialValue: ''

Make sure that the name of the signal object matches the label of the
desired signal in your model. This enables the Simulink engine to resolve
the signal label to the corresponding object. For example, in the model
shown in the above figure, the signal label inSig would resolve to the
signal object inSig.
3 You can require signals in a model to resolve to Simulink.Signal objects.

To do this for the signal inSig, in the model window right-click the signal
line labeled inSig and choose Signal Properties from the context menu.
A Signal Properties dialog appears.

7-68

Signals

4 In the Signal Properties dialog box that appears, select the check box

labelled Signal name must resolve to Simulink signal object, and
click OK or Apply.
5 Set the object properties as required. You can do this by using the

Simulink Model Explorer. Alternatively, you can assign properties by using
MATLAB commands. For example, assign the signal object’s storage class
by setting the CoderInfo.StorageClass property as follows.
inSig.CoderInfo.StorageClass = 'ExportedGlobal';

Generate Code for Signal Objects Using Model Explorer
If you prefer, you can create signal objects and modify their attributes using
Model Explorer. This lets you see and set attributes of a signal in a dialog

7-69

7

Data Representation

box pane, and alleviates the need to remember and type field names. Do the
following to instantiate inSig and set its attributes from Model Explorer:
1 Choose Model Explorer from the View menu.

Model Explorer opens or activates if it already was open.
2 Select Base Workspace in the Model Hierarchy pane.
3 Select Simulink Signal from the Add menu.

A new signal named Sig appears in the Contents pane.

4 To set the signal name in Model Explorer, click the word Sig in the Name

column to select it, and rename it by typing inSig followed by Return
in place of Sig.

7-70

Signals

5 To set the inSig.CoderInfo.StorageClass in Model Explorer, click the

Storage class menu and select ExportedGlobal, as shown in the next
figure.

6 Click Apply.

The following table shows, for each setting of CoderInfo.StorageClass, the
variable declaration and the code generated for the inport signal (inSig)
of the current model:

7-71

7

Data Representation

Storage Class

Declaration

Code

Auto (with

In model.h

storage
optimizations
on)

typedef struct

signal_objs_examp_U.inSig *

_ExternalInputs_signal_ objs_examp_tag

signal_objs_examp_P.Gain_Gain;

rtb_Gain1Sig =

{
real_T inSig;
}
ExternalInputs_signal_ objs_examp;

SimulinkGlobal

In model.h
rtb_Gain1Sig =
typedef struct

signal_objs_examp_U.inSig *

_ExternalInputs_signal_objs_examp_tag

signal_objs_examp_P.Gain_Gain;

{
real_T inSig;
}
ExternalInputs_signal_objs_examp;

ExportedGlobal

In model.c or model.cpp
rtb_Gain1Sig = inSig *
real_T inSig;

signal_objs_examp_P.Gain_Gain;

In model.h
extern real_T inSig;

ImportedExtern

In model_private.h
rtb_Gain1Sig = inSig *
extern real_T inSig;

signal_objs_examp_P.Gain_Gain;

ImportedExternPointer
In model_private.h
rtb_Gain1Sig = (*inSig) *
extern real_T *inSig;

signal_objs_examp_P.Gain_Gain;

Resolve Conflicts in Configuration of Signals Objects
If a signal is defined in the Signal Properties dialog box and a signal object of
the same name is defined by using the command line or in the Model Explorer,
the potential exists for ambiguity when the Simulink engine attempts to
resolve the symbol representing the signal name. One way to resolve the

7-72

Signals

ambiguity is to specify that a signal must resolve to a Simulink data object. To
do this, select the Signal name must resolve to Simulink signal object
option in the Signal Properties dialog box. When you do this, you no longer
can specify the Storage class property in the Code Generation tab of the
Signal Properties dialog box, as the next figure shows.

As the preceding figure shows, the Storage class menu is disabled because it
is up to the SinSig Simulink.Signal object to specify its own storage class.
The signal and signal objects SinSig both have SimulinkGlobal storage class.
Therefore, no conflict arises, and SinSig resolves to the signal object SinSig.
Note The rules for compatibility between block states/signal objects are
identical to those given for signals/signal objects.

7-73

7

Data Representation

Initialize Signals and States Using Signal Objects
You can use Simulink signal objects to initialize signals and discrete
states with user-defined values for simulation and code generation. Data
initialization increases application reliability and is a requirement of safety
critical applications. Initializing signals for both simulation and code
generation can expedite transitions between phases of Model-Based Design.
For details on simulation behavior, see “Initialization Behavior Summary for
Signal Objects” in the Simulink documentation.

Specify Initial Value for Signal Object
You can use signal objects that have a storage class other than 'auto’ or
'SimulinkGlobal' to initialize
• Discrete states with an initial condition parameter
• Any signals in a model except bus signals and signals with constant sample
time
The initial value is the signal or state value before a simulation takes its
first time step.

7-74

Signals

Note Some initial value settings may depend on the initialization mode. For
more information, see “Underspecified initialization detection”.
Classic initialization mode: In this mode, initial value settings for
signal objects that represent the following signals and states override the
corresponding block parameter initial values if undefined (specified as []):
• Output signals of conditionally executed subsystems and Merge blocks
• Block states
Simplified initialization mode: In this mode, initial values of signal
objects associated with the output of the following blocks are ignored. The
initial values of the corresponding blocks (which cannot be specified as [])
are used instead.
• Output signals of conditionally executed subsystems
• Merge blocks

To specify an initial value, use the Model Explorer or MATLAB commands to
do the following:
1 Create the signal object.

Model Explorer

7-75

7

Data Representation

MATLAB Command
S1=Simulink.Signal;

The name of the signal object must be the same as the name of the signal
that the object is initializing. Although not required, consider setting the
Signal name must resolve to Simulink signal object option in the
Signal Properties dialog box. This setting makes signal objects in the
MATLAB workspace consistent with signals that appear in your model.
Consider using the Data Object Wizard to create signal objects. The Data
Object Wizard searches a model for signals for which signal objects do not
exist. You can then selectively create signal objects for multiple signals
listed in the search results with a single operation. For more information
about the Data Object Wizard, see “Data Object Wizard” in the Simulink
documentation.

7-76

Signals

2 Set the signal object’s storage class to a value other than 'auto’ or

'SimulinkGlobal'.

Model Explorer

MATLAB Command
S1.CoderInfo.StorageClass='ExportedGlobal';
3 Set the initial value. You can specify any MATLAB string expression that

evaluates to a double numeric scalar value or array.

7-77

7

Data Representation

Model Explorer

MATLAB Command

1.5
[1 2 3]
1+0.5

foo = 1.5;
s1.InitialValue = 'foo';

Invalid uint(1)

foo = '1.5';
s1.InitialValue = 'foo';

Valid

The Simulink engine converts the initial value so the type, complexity, and
dimension are consistent with the corresponding block parameter value.
If you specify an invalid value or expression, an error message appears
when you update the model.
Model Explorer

MATLAB Command

7-78

Signals

S1.InitialValue='0.5'

The following example shows a signal object specifying the initial output of
an enabled subsystem.

Enable

1

2

In1

Gain

e

1
Out1
Initial Output = []

Enable
Ts = 0.1
Phase Delay = 10 samples

Scope
In1

Sine Wave
Amplitude = 1
Period = 10 samples
Ts = 0.1

Out1

s

Enabled
Subsystem

Signal s is initialized to 4.5. Note that to avoid a consistency error, the initial
value of the enabled subsystem’s Outport block must be [ ] or 4.5.

Signal Object Initialization in Generated Code
The initialization behavior for code generation is the same as that for model
simulation with the following exceptions:

7-79

7

Data Representation

• RSim executables can use the Data Import/Export pane of the
Configuration Parameters dialog box to load input values from MAT-files.
GRT and ERT executables cannot load input values from MAT-files.
• The initial value for a block output signal or root level input or output
signal can be overwritten by an external (calling) program.
• Setting the initial value for persistent signals is relevant if the value is
used or viewed by an external application.
For details on initialization behavior for different types of signals and discrete
states, see “Initialization Behavior Summary for Signal Objects” in the
Simulink documentation.
When you initialize Simulink signal objects in a model during code generation,
the corresponding initialization statements are placed in model.c or
model.cpp in the model’s initialize code.
For example, consider the model rtwdemo_sigobj_iv.

If you create and initialize signal objects in the base workspace, the
Simulink Coder product places initialization code for the signals in the file
rtwdemo_sigobj_iv.c under the rtwdemo_sigobj_iv_initialize function,
as shown below.
/* Model initialize function */

void rtwdemo_sigobj_iv_initialize(boolean_T firstTime)

{

7-80

Signals

.
.
.
/* exported global signals */
S3 = -3.0;

S2 = -2.0;
.
.
.
/* exported global states */
X1 = 0.0;
X2 = 0.0;

/* external inputs */
S1 = -4.5;
.
.
.

The following code shows the initialization code for the enabled subsystem’s
Unit Delay block state X1 and output signal S2.
void MdlStart(void) {
.
.
.
/* InitializeConditions for UnitDelay: '/Unit Delay' */
X1 = aa1;

/* Start for enable system: '/Enabled Subsystem (state X1 inside)' */

/* virtual outports code */

/* (Virtual) Outport Block: '/Out1' */

S2 = aa2;

}

7-81

7

Data Representation

Also note that for an enabled subsystem, such as the one shown in the
preceding model, the initial value is also used as a reset value if the
subsystem’s Outport block parameter Output when disabled is set
to reset. The following code from rtwdemo_sigobj_iv.c shows the
assignment statement for S3 as it appears in the model output function
rtwdeni_sigobj_iv_output.
/* Model output function */

static void rtwdemo_sigobj_iv_output(void)
{
.
.
.
/* Disable for enable system: '/Enabled Subsystem (state X1 inside)' */

/* (Virtual) Outport Block: '/Out1' */

S2 = aa2;

Tunable Initial Values
If you specify a tunable parameter in the initial value for a signal object, the
parameter expression is preserved in the initialization code in model.c.
For example, if you configure parameter df to be tunable for model signal_iv
and you initialize the signal object for discrete state X1 with the expression
df*2, the following initialization code appears for signal object X1 in
signal_iv.c.
void MdlInitialize(void) {

/* InitializeConditions for UnitDelay: '/Unit Delay X1=2' */
X1 = (tunable_param_P.df * 2.0);
}

For more information about the treatment of tunable parameters in generated
code, see “Parameters” on page 7-10.

7-82

States

States
In this section...
“About States” on page 7-83
“State Storage” on page 7-83
“State Storage Classes” on page 7-84
“Interface States to External Code” on page 7-85
“Symbolic Names for States” on page 7-87
“Control Code Generation for Block States” on page 7-90
“Summary of State Storage Class Options” on page 7-91

About States
For certain block types, the Simulink Coder product lets you control how block
states in your model are stored and represented in the generated code. Using
the State Attributes tab of a block dialog box, you can:
• Control whether or not states declared in generated code are interfaceable
(visible) to externally written code. You can also specify that states be
stored in locations declared by externally written code.
• Assign symbolic names to block states in generated code.

State Storage
The discussion of block state storage in this section applies to the following
blocks:
• Discrete Filter
• Discrete PID Controller
• Discrete PID Controller (2DOF)
• Discrete State-Space
• Discrete-Time Integrator
• Discrete Transfer Function

7-83

7

Data Representation

• Discrete Zero-Pole
• Memory
• Unit Delay
These blocks require persistent memory to store values representing the
state of the block between consecutive time intervals. By default, such values
are stored in a data type work vector. This vector is usually referred to as
the DWork vector. It is represented in generated code as model_DWork, a
global data structure.
If you want to interface a block state to your hand-written code, you can
specify that the state is to be stored in a location other than the DWork vector.
You do this by assigning a storage class to the block state.
You can also define a symbolic name, to be used in code generation, for a
block state.

State Storage Classes
The storage class property of a block state specifies how the Simulink Coder
product declares and stores the state in a variable. Storage class options for
block states are similar to those for signals. The available storage classes are
• Auto
• ExportedGlobal
• ImportedExtern
• ImportedExternPointer

Default Storage Class
Auto is the default storage class and is the storage class you should use for
states that you do not need to interface to external code. States with Auto
storage class are stored as members of the Dwork vector.

You can assign a symbolic name to states with Auto storage class. If you do
not supply a name, the Simulink Coder product generates one, as described in
“Symbolic Names for States” on page 7-87.

7-84

States

Explicitly Assigned Storage Classes
Block states with storage classes other than Auto are stored in unstructured
global variables, independent of the Dwork vector. These storage classes are
for states that you want to interface to external code. The following storage
classes are available for states:
• ExportedGlobal: The state is stored in a global variable. model.h exports
the variable. States with ExportedGlobal storage class must have unique
names.
• ImportedExtern: model_private.h declares the state as an extern
variable. Your code must supply the variable definition. States with
ImportedExtern storage class must have unique names.
• ImportedExternPointer: model_private.h declares the state as an
extern pointer. Your code must supply the pointer variable definition.
States with ImportedExternPointer storage class must have unique
names.
The table in “Summary of Signal Storage Class Options” on page 7-63 gives
examples of variable declarations and the code generated for block states
with each type of storage class.
Note Assign a symbolic name to states to specify a storage class other than
auto. If you do not supply a name for auto states, the Simulink Coder product
generates one, as described in “Symbolic Names for States” on page 7-87.
The next section explains how to use the State Attributes tab of the block
dialog box to assign storage classes to block states.

Interface States to External Code
In the State Attributes tab of a block parameter dialog box, you can
interface a block’s state to external code by assigning the state a storage
class other than Auto (that is, ExportedGlobal, ImportedExtern, or
ImportedExternPointer).
Set the storage class as follows:

7-85

7

Data Representation

1 In your block diagram, double-click the desired block. This action opens the

block dialog box with two or more tabs, which includes State Attributes.
2 Click the State Attributes tab.

3 Enter a name for the variable to be used to store block state in the State

name field.
The State name field turns yellow to indicate that you changed it.
4 Click Apply to register the variable name.

The first two fields beneath the State name, State name must resolve
to Simulink signal object and Code generation storage class, become
enabled.
5 If the state is to be stored in a Simulink signal object in the base or model

workspace, select State name must resolve to Simulink signal object.
If you choose this option, you cannot declare a storage class for the state in
the block, and the fields below become disabled.

7-86

States

6 Select the desired storage class (ExportedGlobal, ImportedExtern, or

ImportedExternPointer) from the Code generation storage class

menu.
7 Optional: For storage classes other than Auto, you can enter a storage type

qualifier such as const or volatile in the Code generation storage
type qualifier field. The Simulink Coder product does not check this
string for errors; what you enter is included in the variable declaration.
8 Click OK or Apply and close the dialog box.

Symbolic Names for States
To determine the variable or field name generated for a block’s state, you can:
• Use a default name generated by the Simulink Coder product
• Define a symbolic name by using the State name field of the State
Attributes tab in a block dialog box

Default Block State Naming Convention
If you do not define a symbolic name for a block state, the Simulink Coder
product uses the following default naming convention:
BlockType#_DSTATE

where
• BlockType is the name of the block type (for example, Discrete_Filter).
• # is a unique ID number (#) assigned by the Simulink Coder product if
multiple instances of the same block type appear in the model. The ID
number is appended to BlockType.
• _DSTATE is a string that is always appended to the block type and ID
number.
For example, consider the model shown in the next figure.

7-87

7

Data Representation

Model with Two Discrete Filter Block States

Examine the code generated for the states of the two Discrete Filter blocks.
Assume that:
• Neither block’s state has a user-defined name.
• The upper Discrete Filter block has Auto storage class (and is therefore
stored in the DWork vector).
• The lower Discrete Filter block has ExportedGlobal storage class.
The states of the two Discrete Filter blocks are stored in DWork vectors,
initialized as shown in the code below:
/* data type work */
disc_filt_states_M->Work.dwork = ((void *)
&disc_filt_states_DWork);
(void)memset((char_T *) &disc_filt_states_DWork, 0,
sizeof(D_Work_disc_filt_states));
{
int_T i;
real_T *dwork_ptr = (real_T *)
&disc_filt_states_DWork.DiscFilt_DSTATE;
for (i = 0; i < 2; i++) {
dwork_ptr[i] = 0.0;
}
}

7-88

States

Define User Block State Names
Using the State Attributes tab of a block dialog box, you can define your
own symbolic name for a block state:
1 In your block diagram, double-click the desired block. This action opens

the block dialog box, containing two or more tabs, which includes State
Attributes.
2 Click the State Attributes tab.
3 Enter the symbolic name in the State name field. For example, enter

the state name Top_filter.
4 Click Apply. The dialog box now looks like this:

5 Click OK.

The following state initialization code was generated from the example model
shown in “Generate Code for Signal Objects from Command Line” on page
7-67, under the following conditions:

7-89

7

Data Representation

• The upper Discrete Filter block has the state name Top_filter, and Auto
storage class (and is therefore stored in the DWork vector).
• The lower Discrete Filter block has the state name Lower_filter, and
storage class ExportedGlobal.
Top_filter is placed in the Dwork vector.
/* data type work */
disc_filt_states_M->Work.dwork = ((void *)
&disc_filt_states_DWork);
(void)memset((char_T *) &disc_filt_states_DWork, 0,
sizeof(D_Work_disc_filt_states));
disc_filt_states_DWork.Top_filter = 0.0;
/* exported global states */
Lower_filter = 0.0;

Control Code Generation for Block States
If you are not familiar with Simulink data objects and signal objects, you
should read “Signals” on page 7-52 before reading this section.
You can associate a block state with a signal object and control code
generation for the block state through the signal object:
1 Instantiate the desired signal object, and set its CoderInfo.StorageClass

property.
2 Open the dialog box for the block whose state you want to associate with

the signal object.
3 Click the State Attributes tab.
4 Enter the name of the signal object in the State name field.
5 Select State name must resolve to Simulink signal object.

This step disables the Code generation storage class and Code
generation storage type qualifier options in the State Attributes tab,
because the signal object specifies these settings.

7-90

States

6 Click Apply and close the dialog box.

Note When a block state is associated with a signal object, the mapping
between the block state and the signal object must be one-to-one. If two or
more identically named entities, such as a block state and a signal, map
to the same signal object, the name conflict is flagged as an error at code
generation time.

Summary of State Storage Class Options
Here is a simple model, unit_delay, which contains a Unit Delay block:

The following table shows, for each state storage class option, the variable
declaration and initialization code generated for a Unit Delay block state. The
block state has the user-defined state name udx.
Storage Class

Declaration

Auto

In model.h

Initialization Code
unit_delay_DWork.udx = 0.0;

typedef struct
D_Work_unit_delay_tag
{
real_T udx;
}
D_Work_unit_delay;

Exported Global

In model.c or model.cpp

In model.c or model.cpp

real_T udx;

udx = 0.0;

In model.h
extern real_T udx;

7-91

7

Data Representation

Storage Class

Declaration

Initialization Code

ImportedExtern

In model_private.h

In model.c or model.cpp

extern real_T udx;

udx =
unit_delay_P.UnitDelay_X0;

ImportedExternPointer

In model_private.h

In model.c or model.cpp

extern real_T *udx;

(*udx) =
unit_delay_P.UnitDelay_X0;

7-92

Data Stores

Data Stores
In this section...
“About Data Stores” on page 7-93
“Storage Classes for Data Store Memory Blocks” on page 7-93
“Generate Code for Data Store Memory Blocks” on page 7-96
“Nonscalar Data Stores in Generated Code” on page 7-97
“Data Store Buffering in Generated Code” on page 7-99

About Data Stores
A data store contains data that is accessible at any point in a model hierarchy
at or below the level in which the data store is defined. Data stores can allow
subsystems and referenced models to share data without having to use I/O
ports to pass the data from level to level. See “Data Stores with Data Store
Memory Blocks” for information about data stores in Simulink. This section
provides additional information about data store code generation.

Storage Classes for Data Store Memory Blocks
You can control how Data Store Memory blocks in your model are stored
and represented in the generated code by assigning storage classes and type
qualifiers. You do this in almost exactly the same way you assign storage
classes and type qualifiers for block states.
Data Store Memory blocks, like block states, have Auto storage class by
default, and their memory is stored within the DWork vector. The symbolic
name of the storage location is based on the data store name.
You can generate code from multiple Data Store Memory blocks that have the
same data store name, subject to the following restriction: at most one of the
identically named blocks can have a storage class other than Auto. An error is
reported if this condition is not met.
For blocks with Auto storage class, the Simulink Coder product generates a
unique symbolic name for each block to avoid name clashes. For Data Store

7-93

7

Data Representation

Memory blocks with storage classes other than Auto, the generated code uses
the data store name as the symbol.
In the following model, a Data Store Write block writes to memory declared
by the Data Store Memory block myData:

To control the storage declaration for a Data Store Memory block, use the
Code Generation > Storage class and Code Generation > Storage type
qualifier fields of the Data Store Memory block dialog box. The next figure
shows the Data Store Memory block dialog box for the preceding model.

7-94

Data Stores

Data Store Memory blocks are nonvirtual because code is generated for
their initialization in .c and .cpp files and their declarations in header
files. The following table shows how the code generated for the Data Store
Memory block in the preceding model differs for different settings of Code
Generation > Storage class. The table gives the variable declarations and
MdlOutputs code generated for the myData block.

7-95

7

Data Representation

Storage Class

Declaration

Auto

In model.h

Code
model_DWork.myData =

typedef struct

rtb_SineWave;

D_Work_tag
{
real_T myData;
}
D_Work;

In model.c or model.cpp
/* Block states (auto storage) */
D_Work model_DWork;

In model.c or model.cpp

ExportedGlobal

myData = rtb_SineWave;
/* Exported block states */
real_T myData;

In model.h
extern real_T myData;

In model_private.h

ImportedExtern

myData = rtb_SineWave;
extern real_T myData;

ImportedExternPointer

In model_private.h
(*myData) = rtb_SineWave;
extern real_T *myData;

Generate Code for Data Store Memory Blocks
If you are not familiar with Simulink data objects and signal objects, you
should read “Signals” on page 7-52 before reading this section.

7-96

Data Stores

You can associate a Data Store Memory block with a signal object, and control
code generation for the block through the signal object. To do this:
1 Instantiate the desired signal object.
2 Set the object’s CoderInfo.StorageClass property to indicate the desired

storage class.
3 Open the block dialog box for the Data Store Memory block that you want

to associate with the signal object.
4 Enter the name of the signal object in the Data store name field.
5 Select Data store name must resolve to Simulink signal object.
6 Do not set the storage class field to a value other than Auto (the default).
7 Click OK or Apply.

Note When a Data Store Memory block is associated with a signal object,
the mapping between the Data store name and the signal object name
must be one-to-one. If two or more identically named entities map to
the same signal object, the name conflict is flagged as an error at code
generation time. See “Resolve Conflicts in Configuration of Signals Objects”
on page 7-72 for more information.

Nonscalar Data Stores in Generated Code
Stateflow generates efficient code for accessing individual elements of
nonscalar data stores. For example, the next figure shows a data store
named A that has seven elements. The Stateflow chart assigns the fourth
element of the data store from a value computed from the third element.
The generated code is efficient and involves no unnecessary access of any of
the other elements of A.

7-97

7

Data Representation

In contrast, modeling and code generation for data store element selection
and assignment in Simulink is more explicit. The next figure shows the same
algorithm modeled without using a Stateflow chart. The assignment block

7-98

Data Stores

copies each element of the data store back to itself, in addition to updating
the element.

Data Store Buffering in Generated Code
A Data Store Read block is a nonvirtual block that copies the value of the
data store to its output buffer when it executes. Since the value is buffered,
all downstream blocks connected to the output of the data store read utilize
the same value, even if a Data Store Write block updates the data store in
between execution of two of the downstream blocks.
The next figure shows a model that uses blocks whose priorities have been
modified to achieve a particular order of execution:

7-99

7

Data Representation

The following execution order applies:
1 The block Data Store Read buffers the current value of the data store

A at its output.
2 The block Abs1 uses the buffered output of Data Store Read.
3 The block Data Store Write updates the data store.
4 The block Abs uses the buffered output of Data Store Read.

Because the output of Data Store Read is a buffer, both Abs and Abs1 use the
same value: the value of the data store at the time that Data Store Read
executes.
The next figure shows another example:

7-100

Data Stores

In this example, the following execution order applies:
1 The block Data Store Read buffers the current value of the data store

A at its output.
2 Atomic Subsystem executes.
3 The Sum block adds the output of Atomic Subsystem to the output of Data

Store Read.
Simulink assumes that Atomic Subsystem might update the data store, so
Simulink buffers the data store. Atomic Subsystem executes after Data Store

7-101

7

Data Representation

Read buffers its output, and the buffer provides a way for the Sum block to
use the value of the data store as it was when Data Store Read executed.
In some cases, theSimulink Coder code generator determines that it can
optimize away the output buffer for a Data Store Read block, and the
generated code will refer to the data store directly, rather than a buffered
value of it. The next figure shows an example:

In the generated code, the argument of the fabs() function is the data store A
rather than a buffered value.

7-102

8
Entry Point Functions and
Scheduling
• “Entry Point Functions and Scheduling” on page 8-2
• “About Model Execution” on page 8-4
• “Non-Real-Time Single-Tasking Systems” on page 8-6
• “Non-Real-Time Multitasking Systems” on page 8-7
• “Real-Time Single-Tasking Systems” on page 8-9
• “Real-Time Multitasking Systems” on page 8-11
• “Multitasking Systems Using Real-Time Tasking Primitives” on page 8-14
• “Program Timing” on page 8-16
• “Program Execution” on page 8-18
• “External Mode Communication” on page 8-19
• “Data Logging in Single-Tasking and Multitasking Model Execution” on
page 8-20
• “Rapid Prototyping and Embedded Model Execution Differences” on page
8-22
• “Rapid Prototyping Model Functions” on page 8-23
• “Embedded Model Functions” on page 8-30

8

Entry Point Functions and Scheduling

Entry Point Functions and Scheduling
The following functions represent entry points in the generated code for a
Simulink model.
Function

Description

model_initialize

Initialization entry point in
generated code for Simulink model

model_SetEventsForThisBaseStep

Set event flags for multirate,
multitasking operation before calling
model_step for Simulink model
— not generated as of Version 5.1
(R2008a)

model_step

Step routine entry point in generated
code for Simulink model

model_terminate

Termination entry point in generated
code for Simulink model

For ERT-based models, the calling interface generated for each of these
functions differs significantly depending on how you set the Generate
reusable code parameter. By default, Generate reusable code is off, and
the model entry point functions access model data with statically allocated
global data structures. When Generate reusable code is on, model data
structures are passed in (by reference) as arguments to the model entry point
functions. For efficiency, only those data structures that are actually used in
the model are passed in. Therefore when Generate reusable code is on, the
argument lists generated for the entry point functions vary according to the
requirements of the model.
The entry points are exported with model.h. To call the entry-point functions
from your hand-written code, add an #include model.h directive to your
code. For ERT-based models, if Generate reusable code is on, you must
examine the generated code to determine the calling interface required for
these functions.

8-2

Entry Point Functions and Scheduling

For more information, see the reference pages for the listed functions.
Note The function reference pages document the default (GRT or ERT with
Generate reusable code off) calling interface generated for these functions.

8-3

8

Entry Point Functions and Scheduling

About Model Execution
Before looking at the two styles of generated code, you need to have a
high-level understanding of how the generated model code is executed. The
Simulink Coder software generates algorithmic code as defined by your
model. You can include your own code in your model by using S-functions.
S-functions can range from high-level signal manipulation algorithms to
low-level device drivers.
The Simulink Coder product also provides a run-time interface that executes
the generated model code. The run-time interface and model code are
compiled together to create the model executable. The next figure shows a
high-level object-oriented view of the executable.

Execution driver for model code,
operating system interface routines,
I/O dependent routines,
solver and data logging routines.

Model code
and S-functions

Run-Time Interface
The Object-Oriented View of a Real-Time Program

In general, the conceptual design of the model execution driver does not
change between the rapid prototyping and embedded style of generated
code. The following sections describe model execution for single-tasking and
multitasking environments both for simulation (non-real-time) and for real
time. For most models, the multitasking environment will provide the most
efficient model execution (that is, fastest sample rate).
The following concepts are useful in describing how models execute.
• Initialization: model_initialize initializes the run-time interface code
and the model code.
• ModelOutputs: Calling all blocks in your model that have a sample hit at
the current time and having them produce their output. model_output can

8-4

About Model Execution

be done in major or minor time steps. In major time steps, the output is
a given simulation time step. In minor time steps, the run-time interface
integrates the derivatives to update the continuous states.
• ModelUpdate: model_update calls all blocks in your model that have a
sample hit at the current point in time and has them update their discrete
states or similar type objects.
• ModelDerivatives: Calling all blocks in your model that have continuous
states and having them update their derivatives. model_derivatives
is only called in minor time steps.
• ModelTerminate: model_terminate terminates the program if it is
designed to run for a finite time. It destroys the real-time model data
structure, deallocates memory, and can write data to a file.
The identifying names in the preceding list (ModelOutputs, and so on) identify
functions in pseudocode examples shown in the following sections.
• “Non-Real-Time Single-Tasking Systems” on page 8-6
• “Non-Real-Time Multitasking Systems” on page 8-7
• “Real-Time Single-Tasking Systems” on page 8-9
• “Real-Time Multitasking Systems” on page 8-11
• “Multitasking Systems Using Real-Time Tasking Primitives” on page 8-14

8-5

8

Entry Point Functions and Scheduling

Non-Real-Time Single-Tasking Systems
The pseudocode below shows the execution of a model for a non-real-time
single-tasking system.
main()
{
Initialization
While (time < final time)
ModelOutputs
-- Major time step.
LogTXY
-- Log time, states and root outports.
ModelUpdate
-- Major time step.
Integrate
-- Integration in minor time step for
-- models with continuous states.
ModelDerivatives
Do 0 or more
ModelOutputs
ModelDerivatives
EndDo -- Number of iterations depends upon the solver
Integrate derivatives to update continuous states.
EndIntegrate
EndWhile
Termination
}

The initialization phase begins first. This consists of initializing model states
and setting up the execution engine. The model then executes, one step at a
time. First ModelOutputs executes at time t, then the workspace I/O data is
logged, and then ModelUpdate updates the discrete states. Next, if your model
has any continuous states, ModelDerivatives integrates the continuous
states’ derivatives to generate the states for time tnew = t + h , where h is the
step size. Time then moves forward to tnew and the process repeats.
During the ModelOutputs and ModelUpdate phases of model execution, only
blocks that reach the current point in time execute.

8-6

Non-Real-Time Multitasking Systems

Non-Real-Time Multitasking Systems
The pseudocode below shows the execution of a model for a non-real-time
multitasking system.
main()
{
Initialization
While (time < final time)
ModelOutputs(tid=0)
-- Major time step.
LogTXY
-- Log time, states, and root
-- outports.
ModelUpdate(tid=0)
-- Major time step.
Integrate
-- Integration in minor time step for
-- models with continuous states.
ModelDerivatives
Do 0 or more
ModelOutputs(tid=0)
ModelDerivatives
EndDo (Number of iterations depends upon the solver.)
Integrate derivatives to update continuous states.
EndIntegrate
For i=1:NumTids
ModelOutputs(tid=i) -- Major time step.
ModelUpdate(tid=i) -- Major time step.
EndFor
EndWhile
Termination
}

Multitasking operation is more complex than single-tasking execution because
the output and update functions are subdivided by the task identifier (tid)
that is passed into these functions. This allows for multiple invocations of
these functions with different task identifiers using overlapped interrupts, or
for multiple tasks when using a real-time operating system. In simulation,
multiple tasks are emulated by executing the code in the order that would
occur if no preemption existed in a real-time system.
Multitasking execution assumes that all task rates are multiples of the
base rate. The Simulink product enforces this when you create a fixed-step

8-7

8

Entry Point Functions and Scheduling

multitasking model. The multitasking execution loop is very similar to that
of single-tasking, except for the use of the task identifier (tid) argument
to ModelOutputs and ModelUpdate.

8-8

Real-Time Single-Tasking Systems

Real-Time Single-Tasking Systems
The pseudocode below shows the execution of a model in a real-time
single-tasking system where the model is run at interrupt level.
rtOneStep()
{
Check for interrupt overflow
Enable "rtOneStep" interrupt
ModelOutputs
-- Major time step.
LogTXY
-- Log time, states and root outports.
ModelUpdate
-- Major time step.
Integrate
-- Integration in minor time step for models
-- with continuous states.
ModelDerivatives
Do 0 or more
ModelOutputs
ModelDerivatives
EndDo (Number of iterations depends upon the solver.)
Integrate derivatives to update continuous states.
EndIntegrate
}
main()
{
Initialization (including installation of rtOneStep as an
interrupt service routine, ISR, for a real-time clock).
While(time < final time)
Background task.
EndWhile
Mask interrupts (Disable rtOneStep from executing.)
Complete any background tasks.
Shutdown
}

Real-time single-tasking execution is very similar to non-real-time
single-tasking execution, except that instead of free-running the code, the
rt_OneStep function is driven by a periodic timer interrupt.

8-9

8

Entry Point Functions and Scheduling

At the interval specified by the program’s base sample rate, the interrupt
service routine (ISR) preempts the background task to execute the model code.
The base sample rate is the fastest in the model. If the model has continuous
blocks, then the integration step size determines the base sample rate.
For example, if the model code is a controller operating at 100 Hz, then
every 0.01 seconds the background task is interrupted. During this
interrupt, the controller reads its inputs from the analog-to-digital converter
(ADC), calculates its outputs, writes these outputs to the digital-to-analog
converter (DAC), and updates its states. Program control then returns to the
background task. All these steps must occur before the next interrupt.

8-10

Real-Time Multitasking Systems

Real-Time Multitasking Systems
The following pseudocode shows how a model executes in a real-time
multitasking system where the model is run at interrupt level.
rtOneStep()
{
Check for interrupt overflow
Enable "rtOneStep" interrupt
ModelOutputs(tid=0)
-- Major time step.
LogTXY
-- Log time, states and root outports.
ModelUpdate(tid=0)
-- Major time step.
Integrate
-- Integration in minor time step for
-- models with continuous states.
ModelDerivatives
Do 0 or more
ModelOutputs(tid=0)
ModelDerivatives
EndDo (Number of iterations depends upon the solver.)
Integrate derivatives and update continuous states.
EndIntegrate
For i=1:NumTasks
If (hit in task i)
ModelOutputs(tid=i)
ModelUpdate(tid=i)
EndIf
EndFor
}
main()
{
Initialization (including installation of rtOneStep as an
interrupt service routine, ISR, for a real-time clock).
While(time < final time)
Background task.
EndWhile
Mask interrupts (Disable rtOneStep from executing.)
Complete any background tasks.
Shutdown
}

8-11

8

Entry Point Functions and Scheduling

Running models at interrupt level in a real-time multitasking environment
is very similar to the previous single-tasking environment, except that
overlapped interrupts are employed for concurrent execution of the tasks.
The execution of a model in a single-tasking or multitasking environment
when using real-time operating system tasking primitives is very similar to
the interrupt-level examples discussed above. The pseudocode below is for a
single-tasking model using real-time tasking primitives.
tSingleRate()
{
MainLoop:
If clockSem already "given", then error out due to overflow.
Wait on clockSem
ModelOutputs
-- Major time step.
LogTXY
-- Log time, states and root
-- outports
ModelUpdate
-- Major time step
Integrate
-- Integration in minor time step
-- for models with continuous
-- states.
ModelDeriviatives
Do 0 or more
ModelOutputs
ModelDerivatives
EndDo (Number of iterations depends upon the solver.)
Integrate derivatives to update continuous states.
EndIntegrate
EndMainLoop
}
main()
{
Initialization
Start/spawn task "tSingleRate".
Start clock that does a "semGive" on a clockSem semaphore.
Wait on "model-running" semaphore.
Shutdown
}

8-12

Real-Time Multitasking Systems

In this single-tasking environment, the model executes as real-time operating
system tasking primitives. In this environment, create a single task
(tSingleRate) to run the model code. This task is invoked when a clock tick
occurs. The clock tick gives a clockSem (clock semaphore) to the model task
(tSingleRate). The model task waits for the semaphore before executing.
The clock ticks occur at the fundamental step size (base rate) for your model.

8-13

8

Entry Point Functions and Scheduling

Multitasking Systems Using Real-Time Tasking Primitives
The pseudocode below is for a multitasking model using real-time tasking
primitives.
tSubRate(subTaskSem,i)
{
Loop:
Wait on semaphore subTaskSem.
ModelOutputs(tid=i)
ModelUpdate(tid=i)
EndLoop
}
tBaseRate()
{
MainLoop:
If clockSem already "given", then error out due to overflow.
Wait on clockSem
For i=1:NumTasks
If (hit in task i)
If task i is currently executing, then error out due to
overflow.
Do a "semGive" on subTaskSem for task i.
EndIf
EndFor
ModelOutputs(tid=0)
-- major time step.
LogTXY
-- Log time, states and root outports.
ModelUpdate(tid=0)
-- major time step.
Loop:
-- Integration in minor time step for
-- models with continuous states.
ModelDeriviatives
Do 0 or more
ModelOutputs(tid=0)
ModelDerivatives
EndDo (number of iterations depends upon the solver).
Integrate derivatives to update continuous states.
EndLoop
EndMainLoop
}
main()

8-14

Multitasking Systems Using Real-Time Tasking Primitives

{
Initialization
Start/spawn task "tSubRate".
Start/spawn task "tBaseRate".
Start clock that does a "semGive" on a clockSem semaphore.
Wait on "model-running" semaphore.
Shutdown
}

In this multitasking environment, the model is executed using real-time
operating system tasking primitives. Such environments require several
model tasks (tBaseRate and several tSubRate tasks) to run the model code.
The base rate task (tBaseRate) has a higher priority than the subrate tasks.
The subrate task for tid=1 has a higher priority than the subrate task for
tid=2, and so on. The base rate task is invoked when a clock tick occurs. The
clock tick gives a clockSem to tBaseRate. The first thing tBaseRate does is
give semaphores to the subtasks that have a hit at the current point in time.
Because the base rate task has a higher priority, it continues to execute. Next
it executes the fastest task (tid=0), consisting of blocks in your model that
have the fastest sample time. After this execution, it resumes waiting for the
clock semaphore. The clock ticks are configured to occur at the fundamental
step size for your model.

8-15

8

Entry Point Functions and Scheduling

Program Timing
Real-time programs require careful timing of the task invocations (either by
using an interrupt or a real-time operating system tasking primitive) so that
the model code executes to completion before another task invocation occurs.
This includes time to read and write data to and from external hardware.
The next figure illustrates interrupt timing.
Sample interval is appropriate for this model code execution.

Time to execute
the model code

time
Time available to process background tasks

Sample interval is too short for this model code execution.

Time to execute the model code

time

Task Timing

The sample interval must be long enough to allow model code execution
between task invocations.
In the figure above, the time between two adjacent vertical arrows is the
sample interval. The empty boxes in the upper diagram show an example of a
program that can complete one step within the interval and still allow time
for the background task. The gray box in the lower diagram indicates what
happens if the sample interval is too short. Another task invocation occurs
before the task is complete. Such timing results in an execution error.
Note also that, if the real-time program is designed to run forever (that is, the
final time is 0 or infinite so the while loop never exits), then the shutdown
code never executes.

8-16

Program Timing

For more information on how the timing engine works, see “Timers” on page
1-79.

8-17

8

Entry Point Functions and Scheduling

Program Execution
As the previous section indicates, a real-time program cannot require 100%
of the CPU’s time. This provides an opportunity to run background tasks
during the free time.
Background tasks include operations such as writing data to a buffer or file,
allowing access to program data by third-party data monitoring tools, or using
Simulink external mode to update program parameters.
It is important, however, that the program be able to preempt the background
task so the model code can execute in real time.
The way the program manages tasks depends on capabilities of the
environment in which it operates.

8-18

External Mode Communication

External Mode Communication
External mode allows communication between the Simulink block diagram
and the standalone program that is built from the generated code. In this
mode, the real-time program functions as an interprocess communication
server, responding to requests from the Simulink engine.

8-19

8

Entry Point Functions and Scheduling

Data Logging in Single-Tasking and Multitasking Model
Execution
The Simulink Coder data-logging features, described in “Debug” on page
9-80, enable you to save system states, outputs, and time to a MAT-file at the
completion of the model execution. The LogTXY function, which performs data
logging, operates differently in single-tasking and multitasking environments.
If you examine how LogTXY is called in the single-tasking and multitasking
environments, you will notice that for single-tasking LogTXY is called
after ModelOutputs. During this ModelOutputs call, all blocks that have
a hit at time t execute, whereas in multitasking, LogTXY is called after
ModelOutputs(tid=0), which executes only the blocks that have a hit at
time t and that have a task identifier of 0. This results in differences in the
logged values between single-tasking and multitasking logging. Specifically,
consider a model with two sample times, the faster sample time having a
period of 1.0 second and the slower sample time having a period of 10.0
seconds. At time t = k*10, k=0,1,2... both the fast (tid=0) and slow (tid=1)
blocks execute. When executing in multitasking mode, when LogTXY is
called, the slow blocks execute, but the previous value is logged, whereas in
single-tasking the current value is logged.
Another difference occurs when logging data in an enabled subsystem.
Consider an enabled subsystem that has a slow signal driving the enable port
and fast blocks within the enabled subsystem. In this case, the evaluation of
the enable signal occurs in a slow task, and the fast blocks see a delay of one
sample period; thus the logged values will show these differences.
To summarize differences in logged data between single-tasking and
multitasking, differences will be seen when
• Any root outport block has a sample time that is slower than the fastest
sample time
• Any block with states has a sample time that is slower than the fastest
sample time
• Any block in an enabled subsystem where the signal driving the enable
port is slower than the rate of the blocks in the enabled subsystem

8-20

Data Logging in Single-Tasking and Multitasking Model Execution

For the first two cases, even though the logged values are different between
single-tasking and multitasking, the model results are not different. The only
real difference is where (at what point in time) the logging is done. The third
(enabled subsystem) case results in a delay that can be seen in a real-time
environment.

8-21

8

Entry Point Functions and Scheduling

Rapid Prototyping and Embedded Model Execution
Differences
The rapid prototyping program framework provides a common application
programming interface (API) that does not change between model definitions.
The Embedded Coder product provides a different framework called the
embedded program framework. The embedded program framework provides
an optimized API that is tailored to your model. When you use the embedded
style of generated code, you are modeling how you would like your code to
execute in your embedded system. Therefore, the definitions defined in your
model should be specific to your embedded targets. Items such as the model
name, parameter, and signal storage class are included as part of the API for
the embedded style of code.
One major difference between the rapid prototyping and embedded style of
generated code is that the latter contains fewer entry-point functions. The
embedded style of code can be configured to have only one run-time function,
model_step.
Thus, when you look again at the model execution pseudocode presented
earlier in this chapter, you can eliminate the Loop...EndLoop statements,
and group ModelOutputs, LogTXY, and ModelUpdate into a single statement,
model_step.
For more information about how generated embedded code executes, see
“Embedded Model Functions” on page 8-30.

8-22

Rapid Prototyping Model Functions

Rapid Prototyping Model Functions
The rapid prototyping code defines the following functions that interface with
the run-time interface:
• Model(): The model registration function. This function initializes the
work areas (for example, allocating and setting pointers to various data
structures) used by the model. The model registration function calls the
MdlInitializeSizes and MdlInitializeSampleTimes functions. These
two functions are very similar to the S-function mdlInitializeSizes and
mdlInitializeSampleTimes methods.
• MdlStart(void): After the model registration functions
MdlInitializeSizes and MdlInitializeSampleTimes execute, the
run-time interface starts execution by calling MdlStart. This routine is
called once at startup.
The function MdlStart has four basic sections:

-

Code to initialize the states for each block in the root model that has
states. A subroutine call is made to the “initialize states” routines of
conditionally executed subsystems.

-

Code generated by the one-time initialization (start) function for each
block in the model.

-

Code to enable the blocks in the root model that have enable methods,
and the blocks inside triggered or function-call subsystems residing in
the root model. Simulink blocks can have enable and disable methods.
An enable method is called just before a block starts executing, and the
disable method is called just after the block stops executing.

-

Code for each block in the model that has a constant sample time.

• MdlOutputs(int_T tid): MdlOutputs updates the output of blocks. The
tid (task identifier) parameter identifies the task that in turn maps when
to execute blocks based upon their sample time. This routine is invoked by
the run-time interface during major and minor time steps. The major time
steps are when the run-time interface is taking an actual time step (that
is, it is time to execute a specific task). If your model contains continuous
states, the minor time steps will be taken. The minor time steps are when
the solver is generating integration stages, which are points between major

8-23

8

Entry Point Functions and Scheduling

outputs. These integration stages are used to compute the derivatives used
in advancing the continuous states. The solver is called to updates
• MdlUpdate(int_T tid): MdlUpdate updates the states and work vector
state information (that is, states that are neither continuous nor discrete)
saved in work vectors. The tid (task identifier) parameter identifies the
task that in turn indicates which sample times are active, allowing you to
conditionally update only states of active blocks. This routine is invoked
by the run-time interface after the major MdlOutputs has been executed.
The solver is also called, and model_Derivatives is called in minor steps
by the solver during its integration stages. All blocks that have continuous
states have an identical number of derivatives. These blocks are required
to compute the derivatives so that the solvers can integrate the states.
• MdlTerminate(void): MdlTerminate contains any block shutdown code.
MdlTerminate is called by the run-time interface, as part of the termination
of the real-time program.
The contents of the above functions are directly related to the blocks in your
model. A Simulink block can be generalized to the following set of equations.

y = f0 (t, xc , xd , u)
Output y is a function of continuous state xc, discrete state xd, and input u.
Each block writes its specific equation in a section of MdlOutputs.

xd +1 = fu (t, xd , u)
The discrete states xd are a function of the current state and input. Each block
that has a discrete state updates its state in MdlUpdate.

x = fd (t, xc , u)
The derivatives x are a function of the current input. Each block that has
continuous states provides its derivatives to the solver (for example, ode5) in
model_Derivatives. The derivatives are used by the solver to integrate the
continuous state to produce the next value.
The output, y, is generally written to the block I/O structure. Root-level
Outport blocks write to the external outputs structure. The continuous and

8-24

Rapid Prototyping Model Functions

discrete states are stored in the states structure. The input, u, can originate
from another block’s output, which is located in the block I/O structure, an
external input (located in the external inputs structure), or a state. These
structures are defined in the model.h file that the Simulink Coder software
generates.
The next example shows the general contents of the rapid prototyping style of
C code written to the model.c file.

8-25

8

Entry Point Functions and Scheduling

The next figure shows a flow chart describing the execution of the rapid
prototyping generated code.

8-26

Rapid Prototyping Model Functions

Start Execution
MdlStart

Execution Loop

MdlOutputs
MdlUpdate
model_Derivatives
MdlOutputs
model_Derivatives
Integration in Minor Time Steps

MdlTerminate
End

Rapid Prototyping Execution Flow Chart

Each block places code in specific Mdl routines according to the algorithm that
it is implementing. Blocks have input, output, parameters, and states, as well
as other general items. For example, in general, block inputs and outputs are
written to a block I/O structure (model_B). Block inputs can also come from
the external input structure (model_U) or the state structure when connected
to a state port of an integrator (model_X), or ground (rtGround) if unconnected
or grounded. Block outputs can also go to the external output structure
(model_Y). The next figure shows the general mapping between these items.

8-27

8

Entry Point Functions and Scheduling

External
inputs
struct
model_U

Block I/O
struct
model_B

rtGround

Block

States
struct
model_X

External
outputs
struct
model_Y

Parameter
struct
model_P

Work
structs
rtRWork,
rtIWork,
rtPWork,
....

Data View of the Generated Code

The following list defines the structures shown in the preceding figure:
• Block I/O structure (model_B): This structure consists of persistent block
output signals. The number of block output signals is the sum of the
widths of the data output ports of all nonvirtual blocks in your model. If
you activate block I/O optimizations, the Simulink and Simulink Coder
products reduce the size of the model_B structure by

-

Reusing the entries in the model_B structure
Making other entries local variables

See “Signals” on page 7-52 for more information on these optimizations.
Structure field names are determined either by the block’s output signal
name (when present) or by the block name and port number when the
output signal is left unlabeled.
• Block states structures: The continuous states structure (model_X) contains
the continuous state information for any blocks in your model that have
continuous states. Discrete states are stored in a data structure called
the DWork vector (model_DWork).
• Block parameters structure (model_P): The parameters structure contains
block parameters that can be changed during execution (for example, the
parameter of a Gain block).
• External inputs structure (model_U): The external inputs structure consists
of all root-level Inport block signals. Field names are determined by either

8-28

Rapid Prototyping Model Functions

the block’s output signal name, when present, or by the Inport block’s name
when the output signal is left unlabeled.
• External outputs structure (model_Y): The external outputs structure
consists of all root-level Outport blocks. Field names are determined by the
root-level Outport block names in your model.
• Real work, integer work, and pointer work structures (model_RWork,
model_IWork, model_PWork): Blocks might have a need for real, integer,
or pointer work areas. For example, the Memory block uses a real work
element for each signal. These areas are used to save internal states or
similar information.

8-29

8

Entry Point Functions and Scheduling

Embedded Model Functions
The Embedded Coder target generates the following functions:
• model_initialize: Performs model initialization and should be called once
before you start executing your model.
• If the Single output/update function code generation option is selected,
then you see

-

model_step: Contains the output and update code for all blocks in your

model.

Otherwise, you see

-

model_output: Contains the output code for all blocks in your model.
model_update: Contains the update code for all blocks in your model.

• If the Terminate function required code generation option is selected,
then you see

-

model_terminate: This contains model shutdown code and should be

called as part of system shutdown.

See “Entry Point Functions and Scheduling” in the Embedded Coder
documentation for complete descriptions of these functions.

8-30

Code Generation
• Chapter 9, “Configuration”
• Chapter 10, “Source Code Generation”
• Chapter 11, “Report Generation”

9
Configuration
• “Configuring a Model for Code Generation” on page 9-2
• “Application Objectives” on page 9-6
• “Target” on page 9-9
• “Select the Target Language” on page 9-71
• “Code Appearance” on page 9-72
• “Debug” on page 9-80

9

Configuration

Configuring a Model for Code Generation
In this section...
“Code Generation Configuration” on page 9-2
“Open the Model Configuration for Code Generation” on page 9-3
“Configure a Model Programmatically” on page 9-3

Code Generation Configuration
When you are ready to generate code for a model, you can modify the model
configuration parameters specific to code generation. The code generation
parameters affect how the Simulink Coder software generates code and builds
an executable from your model.
Your application objectives might include a combination of the following code
generation objectives: debugging, traceability, execution efficiency, and safety
precaution. There are tradeoffs associated with these configuration choices,
such as execution speed and memory usage. You can use the Model Advisor
and the Code Generation Advisor to help configure any model to achieve your
application objectives. For more information, see “Advice About Optimizing
Models for Code Generation” on page 16-5 and “Configure Code Generation
Objectives Using Code Generation Advisor” on page 9-7.
You modify the model configuration parameters for code generation in the
Code Generation and Optimization panes of the Configuration Parameters
dialog box. The content of the Code Generation pane and its subpanes
can change depending on the target that you specify. To open the Code
Generation pane, see “Open the Model Configuration for Code Generation”
on page 9-3. Some configuration options are available only with the Embedded
Coder product. The Optimization pane includes code generation parameters
that help to improve the performance of the generated code.
To automate the configuration of models, you can use the set_param
function from the MATLAB command line to adjust the model configuration
parameters. For more information, see “Parameter Command-Line
Information Summary” in the Simulink Coder documentation. For an
example of automating the configuration of a model, see “Configure a Model
Programmatically” on page 9-3.

9-2

Configuring a Model for Code Generation

Open the Model Configuration for Code Generation
To modify the model configuration parameters for code generation, open the
Code Generation pane. There are four ways to open the Code Generation
pane from the Simulink editor:
• To open the Configuration Parameters dialog box, click the model
configuration parameters icon:

and select Code Generation.
• From the Simulation menu, select Model Configuration Parameters.
When the Configuration Parameters dialog box opens, click Code
Generation in the Select (left) pane.
• From the Code menu, select C/C++ Code > Code Generation Options.
• From the View menu in the model window, select Model Explorer, or
from the MATLAB command line, type daexplr and press Enter. In the
Model Explorer, expand the node for the current model in the left pane and
click Configuration (active). The configuration elements are listed in
the middle pane. Clicking any of these elements displays the corresponding
parameters in the right pane. Alternatively, right-clicking the Code
Generation element in the middle pane and choosing Properties from
the context menu opens the Code Generation pane in a separate window.
Note In a Configuration Parameters dialog box, when you change a check
box, menu selection, or edit field, the white background of the element turns
to light yellow to indicate that you made an unsaved change. When you click
OK, Cancel, or Apply, the background resets to white.
For more information on model configurations, see “Configuration Sets”.

Configure a Model Programmatically
This example shows you how to modify code generation parameters for the
active configuration set from the MATLAB command line. Use this approach
for creating a script that automates setting parameters for an established

9-3

9

Configuration

model configuration. The configuration parameters that you can get and
set are listed in “Parameter Command-Line Information Summary” in the
Simulink Coder reference.
In this example, you modify the configuration parameters to support the Code
Generation Advisor application objective, Execution efficiency.
Step 1. Open a model.

sldemo_f14
Step 2. Get the active configuration set.

cs = getActiveConfigSet(model);
Step 3. Select the Generic Real-Time (GRT) target.

switchTarget(cs,'grt.tlc',[]);
Step 4. Modify parameters to optimize execution speed.

If your application objective is Execution efficiency, use set_param to
modify the following parameters:
set_param(cs,'MatFileLogging','off');
set_param(cs,'SupportNonFinite','off');
set_param(cs,'RTWCompilerOptimization','on');
set_param(cs,'OptimizeBlockIOStorage','on');
set_param(cs,'EnhancedBackFolding','on');
set_param(cs,'ConditionallyExecuteInputs','on')
set_param(cs,'InlineParams','on');
set_param(cs,'BooleanDataType','on');
set_param(cs,'BlockReduction','on');
set_param(cs,'ExpressionFolding','on');
set_param(cs,'LocalBlockOutputs','on');
set_param(cs,'EfficientFloat2IntCast','on');
set_param(cs,'BufferReuse','on');
Step 5. Save the model configuration to a file.

9-4

Configuring a Model for Code Generation

Save the model configuration to a file, `Exec_efficiency_cs.m', and view
the parameter settings.
saveAs(cs,'Exec_Efficiency_cs');
dbtype Exec_Efficiency_cs 1:50

Using this technique, you can create a script to configure multiple models.
An alternative method for configuring multiple models is to save the
configuration set to the base workspace. Then, create a configuration
reference to point to that configuration set. For more information, see “About
Configuration References”.

9-5

9

Configuration

Application Objectives
In this section...
“About Code Generation Objectives” on page 9-6
“Configure Code Generation Objectives Using Code Generation Advisor”
on page 9-7

About Code Generation Objectives
Depending on the type of application that your model represents, you are
likely to have specific code generation objectives in mind. For example, safety
and traceability might be more critical than efficient use of memory. If you
have specific objectives in mind, you can quickly configure your model to
meet those objectives by selecting and prioritizing from the following list of
code generation objectives:
• Execution efficiency (all targets)
• ROM efficiency (ERT-based targets)
• RAM efficiency (ERT-based targets)
• Safety precaution (ERT-based targets)
• Traceability (ERT-based targets)
• Debugging (all targets)
• MISRA-C:2004 guidelines (ERT-based targets)
Based on your objective selections and prioritization, the Code Generation
Advisor checks your model and suggests changes that you can make to
achieve your code generation objectives.

9-6

Application Objectives

Note If you select the MISRA-C:2004 guidelines code generation objective,
the Code Generation Advisor checks:
• The model configuration settings for compliance with the MISRA-C:2004
configuration setting recommendations.
• For blocks that are not supported or recommended for MISRA-C:2004
compliant code generation.

Setting code generation objectives and running the Code Generation Advisor
provides information on how to meet code generation objectives for your
model. The Code Generation Advisor does not alter the generated code.
You can use the Code Generation Advisor to make the suggested changes
to your model. The generated code is changed only after you modify your
model and regenerate code. If you use the Code Generation Advisor to set
code generation objectives and check your model, the generated code includes
comments identifying which objectives you specified, the checks the Code
Generation Advisor ran on the model, and the results of running the checks.
For detailed information, see “Application Objectives” in the Embedded Coder
documentation.

Configure Code Generation Objectives Using Code
Generation Advisor
To configure the code generation objectives and use the Code Generation
Advisor:
1 Open the Configuration Parameters dialog box and select Code

Generation.
2 Select or confirm selection of a System target file.
3 Specify the objectives using the Select objectives drop down list

(GRT-based targets) or clicking Set objectives button (ERT-based targets).
Clicking Set objectives opens the Set Objectives - Code Generation
Advisor dialog box.

9-7

9

Configuration

4 Click Check model to run the model checks. The Code Generation Advisor

dialog box opens. The Code Generation Advisor uses the code generation
objectives to determine which model checks to run.
5 On the left pane, the Code Generation Advisor lists the checks run on

the model and the results. Click each warning to see the suggestions for
changes that you can make to your model to pass the check.
6 Determine which changes to make to your model. On the right pane of

the Code Generation Advisor, follow the instructions listed for each check
to modify the model.
To run the Code Generation Advisor during code generation, on the
Code Generation pane, set the Check model before generating code
parameter to either:
• On (stop for warnings) - Code generation stops with a check warning.
The Code Generation Advisor dialog box opens as described in step 5.
• On (proceed with warnings) - Code generation proceeds with check
warnings. The Code Generation Advisor interface opens with a list of the
checks it ran on the model, along with the results.
For more information, see “Set Objectives — Code Generation Advisor Dialog
Box”

9-8

Target

Target
In this section...
“Hardware Targets” on page 9-9
“Available Targets” on page 9-10
“About Targets and Code Formats” on page 9-15
“Types of Target Code Formats” on page 9-16
“Targets and Code Formats” on page 9-29
“Targets and Code Styles” on page 9-29
“Backwards Compatibility of Code Formats” on page 9-31
“Selecting a Target” on page 9-34
“Template Makefiles and Make Options” on page 9-38
“Custom Targets” on page 9-44
“Describing the Emulation and Embedded Targets” on page 9-45
“Describing Embedded Hardware Characteristics” on page 9-54
“Describing Emulation Hardware Characteristics” on page 9-55
“Specifying Target Interfaces” on page 9-58
“Selecting and Viewing Code Replacement Libraries” on page 9-61

Hardware Targets
When you use Simulink software to create and execute a model, and Simulink
Coder software to generate code, you may need to consider up to three
platforms, often called hardware targets:
• MATLAB Host — The platform that runs MathWorks software during
application development
• Embedded Target — The platform on which an application will be deployed
when it is put into production
• Emulation Target — The platform on which an application under
development is tested before deployment

9-9

9

Configuration

The same platform might serve in two or possibly all three capacities, but they
remain conceptually distinct. Often the MATLAB host and the emulation
target are the same. The embedded target is usually different from, and less
powerful than, the MATLAB host or the emulation target; often it can do little
more than run a downloaded executable file.
When you use Simulink software to execute a model for which you will
later generate code, or use Simulink Coder software to generate code for
deployment on an embedded target, you must provide information about the
embedded target hardware and the compiler that you will use with it. The
Simulink software uses this information to produce bit-true agreement for the
results of integer and fixed-point operations performed in simulation and in
code generated for the embedded target. The Simulink Coder code generator
uses the information to create code that executes with maximum efficiency.
When you generate code for testing on an emulation target, you must
additionally provide information about the emulation target hardware
and the compiler that you will use with it. The code generator uses this
information to create code that provides bit-true agreement for the results of
integer and fixed-point operations performed in simulation, in code generated
for the embedded target, and in code generated for the emulation target.
The agreement is possible even though the embedded target and emulation
target may use very different hardware, and the compilers for the two targets
may use different defaults where the C standard does not completely define
behavior.

Available Targets
The following table lists supported system target files and their associated
code formats. The table also gives references to relevant manuals or chapters
in this book. All of these targets are built using the make_rtw make command.
Note You can select any target of interest using the System Target File
Browser. This allows you to experiment with configuration options and save
your model with different configurations. However, you cannot build or
generate code for non-GRT targets unless you have the required license on
your system (Embedded Coder license for ERT, Real-Time Windows Target
license for RTWIN, and so on).

9-10

Target

Each system target file invokes one or more template makefiles. The template
makefile that is invoked activates a particular compiler (for example, Lcc,
gcc, or Watcom compilers). This is specified for you by MEXOPTS, which is
determined when you run mex -setup to select a compiler for mex. One
exception is the Microsoft Visual C++® project target, which has separate
System Target File Browser entries.

9-11

9

Configuration

Targets Available from the System Target File Browser
Target/Code
Format

System Target
File

Template Makefile
and Comments

Embedded Coder
(for PC or UNIX3
platforms)

ert.tlc
ert_shrlib.tlc

ert_default_tmf

Embedded Coder
for Visual C++4
Solution File

ert.tlc

Embedded Coder for
AUTOSAR

autosar.tlc

ert_default_tmf

“Target” (Embedded
Coder topic)

Generic Real-Time
for PC or UNIX
platforms

grt.tlc

grt_default_tmf

“Targets and Code
Formats” on page 9-29

Generic Real-Time
for Visual C++
Solution File

grt.tlc

Use mex -setup to
configure for Lcc,
Watcom, vc, gcc, and
other compilers
RTW.MSVCBuild

Creates and builds
Visual C++ Solution
(.sln) file

Use mex -setup to
configure for Lcc,
Watcom, vc, gcc, and
other compilers
RTW.MSVCBuild

Creates and builds
Visual C++ Solution
(.sln) file

Reference
“Target” (Embedded
Coder topic)

“Target” (Embedded
Coder topic)

“Targets and Code
Formats” on page 9-29

3. UNIX® is a registered trademark of The Open Group in the United States and other
countries.
4. Visual C++® is a registered trademark of Microsoft® Corporation.

9-12

Target

Targets Available from the System Target File Browser (Continued)
Target/Code
Format

System Target
File

Template Makefile
and Comments

Reference

Generic Real-Time
(dynamic) for PC or
UNIX platforms

grt_malloc.tlc

grt_malloc_default_
tmf

“Targets and Code
Formats” on page 9-29

Use mex -setup to
configure for Lcc,
Watcom, vc, gcc, and
other compilers
Does not support
SimStruct.

Generic Real-Time
(dynamic) for Visual
C++ Solution File

grt_malloc.tlc

Rapid Simulation
Target (default
for PC or UNIX
platforms)

rsim.tlc

Rapid Simulation
Target for LCC
compiler

rsim.tlc

rsim_lcc.tmf

“Rapid Simulations” on
page 12-2

Rapid Simulation
Target for UNIX
platforms

rsim.tlc

rsim_unix.tmf

“Rapid Simulations” on
page 12-2

Rapid Simulation
Target for Visual
C++ compiler

rsim.tlc

rsim_vc.tmf

“Rapid Simulations” on
page 12-2

Rapid Simulation
Target for Watcom
compiler

rsim.tlc

rsim_watc.tmf

“Rapid Simulations” on
page 12-2

RTW.MSVCBuild

Creates and builds
Visual C++ Solution
(.sln) file
rsim_default_tmf

Use mex -setup to
configure

“Targets and Code
Formats” on page 9-29

“Rapid Simulations” on
page 12-2

9-13

9

Configuration

Targets Available from the System Target File Browser (Continued)

9-14

Target/Code
Format

System Target
File

Template Makefile
and Comments

S-Function Target
for PC or UNIX
platforms

rtwsfcn.tlc

rtwsfcn_default_tmf

S-Function Target
for LCC

rtwsfcn.tlc

rtwsfcn_lcc.tmf

“Generated S-Function
Block” on page 12-34

S-Function Target
for UNIX platforms

rtwsfcn.tlc

rtwsfcn_unix.tmf

“Generated S-Function
Block” on page 12-34

S-Function Target
for Visual C++
compiler

rtwsfcn.tlc

rtwsfcn_vc.tmf

“Generated S-Function
Block” on page 12-34

S-Function Target
for Watcom

rtwsfcn.tlc

rtwsfcn_watc.tmf

“Generated S-Function
Block” on page 12-34

Tornado (VxWorks)
Real-Time Target

tornado.tlc

tornado.tmf

“Asynchronous Support”
on page 1-35

ASAM-ASAP2 Data
Definition Target

asap2.tlc

asap2_default_tmf

“ASAP2 Data
Measurement and
Calibration” on page
15-174

Real-Time Windows
Target for Open
Watcom

rtwin.tlc
rtwinert.tlc

rtwin.tmf
rtwinert.tmf

“Use Simulink Models”
(Real-Time Windows
Target topic)

xPC Target for
Visual C++ or
Watcom C/C++
compilers

xpctarget.tlc
xpc_default_tmf
xpctargetert.tlc xpc_ert_tmf
xpc_vc.tmf
xpc_watc.tmf

IDE Link capability

idelink_grt.tlc
idelink_ert.tlc

Use mex -setup to
configure

N/A

Reference
“Generated S-Function
Block” on page 12-34

“xPC Target Options
Configuration
Parameter” (xPC Target
topic)
Desktop IDE/target topics
such as “Model Setup”
on page 25-2; Embedded
IDE/target topics such as
“Model Setup” (Embedded
Coder topic)

Target

Targets Supporting Nonzero Start Time
When you try to build models with a nonzero start time, if the selected target
does not support a nonzero start time, the Simulink Coder software does not
generate code and displays an error message. The Rapid Simulation (RSim)
target supports a nonzero start time when the RSim Target > Solver
selection parameter in the Configuration Parameters dialog box is set to
Use Simulink solver module. The other listed targets do not support a
nonzero start time.

About Targets and Code Formats
A target (such as the GRT target) is an environment for generating and
building code intended for execution on a certain hardware or operating
system platform. A target is defined at the top level by a system target file,
which in turn invokes other target-specific files.
A code format (such as embedded or real-time) is one property of a target.
The code format controls decisions made at several points in the code
generation process. These include whether and how certain data structures
are generated (for example, SimStruct or rtModel), whether or not static
or dynamic memory allocation code is generated, and the calling interface
used for generated model functions. In general, the Embedded-C code format
is more efficient than the RealTime code format. Embedded-C code format
provides more compact data structures, a simpler calling interface, and static
memory allocation. These characteristics make the Embedded-C code format
the preferred choice for production code generation.
In prior releases, only the ERT target and targets derived from the ERT
target used the Embedded-C code format. Non-ERT targets used other code
formats (for example, RealTime or RealTimeMalloc).
In Release 14, the GRT target uses the Embedded-C code format for back end
code generation. This includes generation of both algorithmic model code
and supervisory timing and task scheduling code. The GRT target (and
derived targets) generates a RealTime code format wrapper around the
Embedded-C code. This wrapper provides a calling interface that is backward
compatible with existing GRT-based custom targets. The wrapper calls are
compatible with the main program module of the GRT target (grt_main.c
or grt_main.cpp). This use of wrapper calls incurs some calling overhead;

9-15

9

Configuration

the pure Embedded-C calling interface generated by the ERT target is more
highly optimized.
For a description of the calling interface generated by the ERT target, see
“Entry Point Functions and Scheduling”.
Code format unification simplifies the conversion of GRT-based custom targets
to ERT-based targets. See “Making Pre-R2012a Custom GRT-Based Targets
ERT-Compatible” on page 9-26 for a discussion of target conversion issues.

Types of Target Code Formats
• “Real-Time Code Format” on page 9-20
• “Real-Time malloc Code Format” on page 9-21
• “S-Function Code Format” on page 9-23
• “Embedded Code Format” on page 9-23
Your choice of code format is the most important code generation option.
The code format specifies the overall framework of the generated code and
determines its style.
When you choose a target, you implicitly choose a code format. Typically, the
system target file will specify the code format by assigning the TLC variable
CodeFormat. The following example is from ert.tlc.
%assign CodeFormat = "Embedded-C"

If the system target file does not assign CodeFormat, the default is RealTime
(as in grt.tlc).
If you are developing a custom target, you must consider which code format is
best for your application and assign CodeFormat accordingly.
Choose the RealTime or RealTime malloc code format for rapid prototyping.
If your application does not have significant restrictions in code size, memory
usage, or stack usage, you might want to continue using the generic real-time
(GRT) target throughout development.

9-16

Target

For production deployment, and when your application demands that you
limit source code size, memory usage, or maintain a simple call structure, you
should use the Embedded-C code format. Consider using the Embedded Coder
product, if you need added flexibility to configure and optimize code.
Finally, you should choose the Model Reference or the S-function formats if
you are not concerned about RAM and ROM usage and want to
• Use a model as a component, for scalability
• Create a proprietary S-function MEX-file object
• Interface the generated code using the S-function C API
• Speed up your simulation
The following table summarizes how different targets support applications:
Application

Targets

Fixed- or variable-step
acceleration

RSIM, S-Function, Model Reference

Fixed-step real-time
deployment

GRT, GRT-Malloc, ERT, xPC Target,
Wind River Systems Tornado, Real-Time
Windows Target, Texas Instruments™
DSP, ...

The following table summarizes the various options available for each
Simulink Coder code format/target, with the exceptions noted.

9-17

9

Configuration

Features Supported by Simulink Coder Targets and Code Formats

Feature
Static
memory
allocation

Wind
River
Systems
RealERT
time
Shared VxWorks
GRT malloc ERT Library /Tornado
X

X

X

Dynamic
memory
allocation

RT
RSIM Win xPC

X

X

X

X

X

X

Other
Supported
Targets1
X

X

Continuous
time

X

X

X

X

X

X

X

X

C/C++ MEX
S-functions
(noninlined)

X

X

X

X

X

X

X

X

S-function
(inlined)

X

X

X

X

X

X

X

X

X

X

X2

X2

X

X

X

Minimize
RAM/ROM
usage
Supports
external
mode

X

X

Rapid
prototyping

X

X

Production
code

9-18

SFunc

X
X

X2

X

X

X

X

X

X

X2

X3

Target

Features Supported by Simulink Coder Targets and Code Formats (Continued)

Feature

Wind
River
Systems
RealERT
time
Shared VxWorks
GRT malloc ERT Library /Tornado

Batch
parameter
tuning
and Monte
Carlo
methods

X

System-level
Simulator

X
X4

X4

X4

Non-real-time X
executable
included

X

X

Multiple
instances
of model

X6

Executes in
hard real
time

X6,

SFunc

RT
RSIM Win xPC
X

X

X

X6

X

X5

X2, 6,

X2, 6, 7

7

X

Supports
SIL/PIL

X

X

7

Supports
variable-step
solvers

Other
Supported
Targets1

X

X

1

The Embedded Targets capabilities in Simulink Coder support other targets.

2

Does not apply to GRT based targets. Applies only to an ERT based target.

9-19

9

Configuration

The default GRT, GRT malloc, and ERT rt_main files emulate execution of
hard real time, and when explicitly connected to a real-time clock execute
in hard real time.

4

You can generate code for multiple instances of a Stateflow chart or
subsystem containing a chart, except when the chart contains exported
graphical functions or the Stateflow model contains machine parented events.
6

You must enable Generate reusable code in the Code
Generation > Interface pane of the Configuration Parameters dialog box.

7

Real-Time Code Format
• “About Real-Time Code Format” on page 9-20
• “Unsupported Blocks” on page 9-20
• “System Target Files” on page 9-21
• “Template Makefiles” on page 9-21
About Real-Time Code Format. The real-time code format (corresponding
to the generic real-time target) is useful for rapid prototyping applications. If
you want to generate real-time code while iterating model parameters rapidly,
you should begin the design process with the generic real-time target. The
real-time code format supports:
• Continuous time
• Continuous states
• C/C++ MEX S-functions (inlined and noninlined)
For more information on inlining S-functions, see “Insert S-Function Code” on
page 14-46 and “Inlining S-Functions”.
The real-time code format declares memory statically, that is, at compile time.
Unsupported Blocks. The real-time format does not support the following
built-in user-defined blocks:
• Interpreted MATLAB Function block (note that Fcn blocks are supported)

9-20

Target

• S-Function block — MATLAB language S-functions, Fortran S-functions,
or C/C++ MEX S-functions that call into the MATLAB environment (Fcn
block calls are supported)
System Target Files.
• grt.tlc - Generic Real-Time Target
• rsim.tlc - Rapid Simulation Target
• tornado.tlc - Tornado (VxWorks) Real-Time Target
Template Makefiles.
• grt

-

grt_lcc.tmf — Lcc compiler
grt_unix.tmf — The Open Group UNIX host
grt_vc.tmf — Microsoft Visual C++
grt_watc.tmf — Watcom C

• rsim

-

rsim_lcc.tmf — Lcc compiler
rsim_unix.tmf — UNIX host
rsim_vc.tmf — Visual C++
rsim_watc.tmf — Watcom C

• tornado.tmf
• win_watc.tmf

Real-Time malloc Code Format
• “About Real-Time malloc Code Format” on page 9-22
• “Unsupported Blocks” on page 9-22
• “System Target Files” on page 9-22
• “Template Makefiles” on page 9-23

9-21

9

Configuration

About Real-Time malloc Code Format. The real-time malloc code format
(corresponding to the generic real-time malloc target) is very similar to the
real-time code format. The differences are
• Real-time malloc declares memory dynamically.
For MathWorks blocks, malloc calls are limited to the model initialization
code. Generated code is designed to be free from memory leaks, provided
that the model termination function is called.
• Real-time malloc allows you to deploy multiple instances of the same
model with each instance maintaining its own unique data.
• Real-time malloc allows you to combine multiple models together in
one executable. For example, to integrate two models into one larger
executable, real-time malloc maintains a unique instance of each of the
two models. If you do not use the real-time malloc format, the Simulink
Coder code generator will not necessarily create uniquely named data
structures for each model, potentially resulting in name clashes.
grt_malloc_main.c (or .cpp), the main routine for the generic real-time
malloc (grt_malloc) target, supports one model by default. See

“Use GRT Malloc to Combine Models” on page 4-4 for information on
modifying grt_malloc_main.c (or .cpp) to support multiple models.
grt_malloc_main.c and grt_malloc_main.cpp are located in the folder
matlabroot/rtw/c/grt_malloc.
Unsupported Blocks. The real-time malloc format does not support the
following built-in blocks, as shown:
• Functions & Tables

-

Interpreted MATLAB Function block (note that Fcn blocks are
supported)

-

S-Function block — MATLAB language S-functions, Fortran S-functions,
or C/C++ MEX S-functions that call into the MATLAB environment (Fcn
block calls are supported)

System Target Files.
• grt_malloc.tlc - Generic Real-Time Target with dynamic memory
allocation

9-22

Target

• tornado.tlc - Tornado (VxWorks) Real-Time Target
Template Makefiles.
• grt_malloc

-

grt_malloc_lcc.tmf — Lcc compiler
grt_malloc_unix.tmf — The Open Group UNIX host
grt_malloc_vc.tmf — Microsoft Visual C++
grt_malloc_watc.tmf — Watcom C

• tornado.tmf

S-Function Code Format
The S-function code format (corresponding to the S-function target) generates
code that conforms to the Simulink MEX S-function API. Using the S-function
target, you can build an S-function component and use it as an S-Function
block in another model.
The S-function code format is also used by the accelerated simulation target
to create the Accelerator MEX-file.
In general, you should not use the S-function code format in a system target
file. However, you might need to do special handling in your inlined TLC
files to account for this format. You can check the TLC variable CodeFormat
to see if the current target is a MEX-file. If CodeFormat = "S-Function"
and the TLC variable Accelerator is set to 1, the target is an accelerated
simulation MEX-file.
See “Generated S-Function Block” on page 12-34, for more information.

Embedded Code Format
• “About Embedded Code Format” on page 9-24
• “Using the Real-Time Model Data Structure” on page 9-24
• “Making Pre-R2012a Custom GRT-Based Targets ERT-Compatible” on
page 9-26

9-23

9

Configuration

• “Converting Your Target to Use rtModel” on page 9-27
• “Generating Pre-R2012a GRT Wrapper Code” on page 9-29
About Embedded Code Format. The Embedded-C code format corresponds
to the Embedded Coder target (ERT), and targets derived from ERT. This code
format includes a number of memory-saving and performance optimizations.
See the Embedded Coder “Product Description” and configuration topics such
as “Application Objectives”, “Target”, and “Code Appearance” for details.
Using the Real-Time Model Data Structure. The Embedded-C format
uses the real-time model (RT_MODEL) data structure. This structure is also
referred to as the rtModel data structure. You can access rtModel data by
using a set of macros analogous to the ssSetxxx and ssGetxxx macros that
S-functions use to access SimStruct data, including noninlined S-functions
compiled by the Simulink Coder code generator.
You need to use the set of macros rtmGetxxx and rtmSetxxx to access the
real-time model data structure, which is specific to the Simulink Coder
product. The rtModel is an optimized data structure that replaces SimStruct
as the top level data structure for a model. The rtmGetxxx and rtmSetxxx
macros are used in the generated code as well as from the main.c or main.cpp
module. If you are customizing main.c or main.cpp (either a static file or a
generated file), you need to use rtmGetxxx and rtmSetxxx instead of the
ssSetxxx and ssGetxxx macros.
Usage of rtmGetxxx and rtmSetxxx macros is the same as for the ssSetxxx
and ssGetxxx versions, except that you replace SimStruct S by real-time
model data structure rtM. The following table lists rtmGetxxx and rtmSetxxx
macros that are used in grt_main.c, grt_main.cpp, grt_malloc_main.c,
and grt_malloc_main.cpp.
Macros for Accessing the Real-Time Model Data Structure

9-24

rtm Macro Syntax

Description

rtmGetdX(rtm)

Get the derivatives of a block’s continuous
states

rtmGetOffsetTimePtr(RT_MDL rtM)

Return the pointer of vector that stores sample
time offsets of the model associated with rtM

Target

Macros for Accessing the Real-Time Model Data Structure (Continued)
rtm Macro Syntax

Description

rtmGetNumSampleTimes(RT_MDL rtM)

Get the number of sample times that a block
has

rtmGetPerTaskSampleHitsPtr(RT_MDL)

Return a pointer of NumSampleTime ×
NumSampleTime matrix

rtmGetRTWExtModeInfo(RT_MDL rtM)

Return an external mode information data
structure of the model. This data structure is
used internally for external mode.

rtmGetRTWLogInfo(RT_MDL)

Return a data structure used by Simulink
Coder logging. Internal use.

rtmGetRTWRTModelMethodsInfo(RT_MDL)

Return a data structure of Simulink Coder
real-time model methods information. Internal
use.

rtmGetRTWSolverInfo(RT_MDL)

Return data structure containing solver
information of the model. Internal use.

rtmGetSampleHitPtr(RT_MDL)

Return a pointer of Sample Hit flag vector

rtmGetSampleTime(RT_MDL rtM, int TID)

Get a task’s sample time

rtmGetSampleTimePtr(RT_MDL rtM)

Get pointer to a task’s sample time

rtmGetSampleTimeTaskIDPtr(RT_MDL rtM)

Get pointer to a task’s ID

rtmGetSimTimeStep(RT_MDL)

Return simulation step type ID
(MINOR_TIME_STEP, MAJOR_TIME_STEP)

rtmGetStepSize(RT_MDL)

Return the fundamental step size of the model

rtmGetT(RT_MDL,t)

Get the current simulation time

rtmSetT(RT_MDL,t)

Set the time of the next sample hit

rtmGetTaskTime(RT_MDL,tid)

Get the current time for the current task

rtmGetTFinal(RT_MDL)

Get the simulation stop time

rtmSetTFinal(RT_MDL,finalT)

Set the simulation stop time

rtmGetTimingData(RT_MDL)

Return a data structure used by timing engine
of the model. Internal use.

9-25

9

Configuration

Macros for Accessing the Real-Time Model Data Structure (Continued)
rtm Macro Syntax

Description

rtmGetTPtr(RT_MDL)

Return a pointer of the current time

rtmGetTStart(RT_MDL)

Get the simulation start time

rtmIsContinuousTask(rtm)

Determine whether a task is continuous

rtmIsMajorTimeStep(rtm)

Determine whether the simulation is in a
major step

rtmIsSampleHit(RT_MDL,tid)

Determine whether the sample time is hit

For additional details on usage, see “SimStruct Macros and Functions Listed
by Usage”.
Making Pre-R2012a Custom GRT-Based Targets ERT-Compatible. If
you developed a GRT-based custom target in a release before R2012a, it
is simple to make your target ERT compatible. By doing so, you can take
advantage of many efficiencies.
There are several approaches to ERT compatibility:
• If your installation does not include an Embedded Coder license, you can
convert a GRT-based target as described in “Converting Your Target to Use
rtModel” on page 9-27. This enables your custom target to support current
GRT features, including back end Embedded-C code generation.
• If your installation includes an Embedded Coder license, you can do either
of the following:

9-26

-

Create an ERT-based target, but continue to use your customized version
of grt_main.c or grt_main.cpp module. To do this, you can configure
the ERT target to generate a pre-R2012a GRT calling interface, as
described in “Generating Pre-R2012a GRT Wrapper Code” on page 9-29.
This lets your target support the full ERT feature set, without changing
your GRT-based run-time interface.

-

Reimplement your custom target as a completely ERT-based target,
including use of an ERT generated main program. This approach lets

Target

your target support the full ERT feature set, without the overhead
caused by wrapper calls.
Note If you intend to use custom storage classes (CSCs) with a custom
target, you must use an ERT-based target. See “Custom Storage Classes”
in the Embedded Coder documentation for detailed information on CSCs.
For details on how GRT targets are made call-compatible with previous
Simulink Coder product versions, see “Using the Real-Time Model Data
Structure” on page 9-24.
Converting Your Target to Use rtModel. The real-time model data
structure (rtModel) encapsulates model-specific information in a much more
compact form than the SimStruct. Many ERT-related efficiencies depend on
generation of rtModel rather than SimStruct, including
• Integer absolute and elapsed timing services
• Independent timers for asynchronous tasks
• Generation of improved C API code for signal, state, and parameter
monitoring
• Pruning the data structure to minimize its size (ERT-derived targets only)
To take advantage of such efficiencies, you must update your GRT-based
target to use the rtModel (unless you already did so for Release 13). The
conversion requires changes to your system target file, template makefile,
and main program module.
The following changes to the system target file and template makefile are
required to use rtModel instead of SimStruct:
• In the system target file, add the following global variable assignment:
%assign GenRTModel = TLC_TRUE

• In the template makefile, define the symbol USE_RTMODEL. See one of the
GRT template makefiles for an example.

9-27

9

Configuration

The following changes to your main program module (that is, your customized
version of grt_main.c or grt_main.cpp) are required to use rtModel instead
of SimStruct:
• Include rtmodel.h instead of simstruc.h.
• Since the rtModel data structure has a type that includes the model name,
define the following macros at the top of the main program file:
#define EXPAND_CONCAT(name1,name2) name1 ## name2
#define CONCAT(name1,name2) EXPAND_CONCAT(name1,name2)
#define RT_MODEL CONCAT(MODEL,_rtModel)

• Change the extern declaration for the function that creates and initializes
the SimStruct to
extern RT_MODEL *MODEL(void);

• Change the definitions of rt_CreateIntegrationData and
rt_UpdateContinuousStates to be as shown in the Release 14 version
of grt_main.c.
• Change function prototypes to have the argument 'RT_MODEL' instead of
the argument 'SimStruct'.
• The prototypes for the functions rt_GetNextSampleHit,
rt_UpdateDiscreteTaskSampleHits, rt_UpdateContinuousStates,
rt_UpdateDiscreteEvents, rt_UpdateDiscreteTaskTime, and
rt_InitTimingEngine have changed. Change their names to use the prefix
rt_Sim instead of rt_ and then change the arguments you pass in to them.
See the Release 14 version of grt_main.c for the list of arguments passed
in to each function.
• Modify all macros that refer to the SimStruct to now refer to the rtModel.
SimStruct macros begin with the prefix ss, whereas rtModel macros
begin with the prefix rtm. For example, change ssGetErrorStatus to
rtmGetErrorStatus.

9-28

Target

Generating Pre-R2012a GRT Wrapper Code. The Simulink Coder
product supports the “Classic call interface” model option. When this
option is selected, the Simulink Coder product generates model function calls
that are compatible with the main program module of the pre-R2012a GRT
target (grt_main.c or grt_main.cpp). These calls act as wrappers that
interface to code generated with R2012a or higher.
This option provides a quick way to use code generated with R2012a or
higher with a main program module based on pre-R2012a grt_main.c or
grt_main.cpp.

Targets and Code Formats
The Simulink Coder product provides five different code formats. Each
code format specifies a framework for code generation suited for specific
applications. The five code formats and corresponding application areas are
• Real-time — Rapid prototyping
• Real-time malloc — Rapid prototyping
• S-function — Creating proprietary S-function MEX-file objects, code
reuse, and speeding up your simulation
• Model reference — Creating MEX-file objects from entire models that
other models can use, sometimes in place of S-functions
• Embedded C — Deeply embedded systems
This chapter discusses the relationship of code formats to the available target
configurations, and factors you should consider when choosing a code format
and target. This chapter also summarizes the real-time, real-time malloc,
S-function, model referencing, and embedded C/C++ code formats.

Targets and Code Styles
The Simulink Coder software generates two styles of code. One code style is
suitable for rapid prototyping (and simulation by using code generation). The
other style is suitable for embedded applications. This chapter discusses the
program architecture, that is, the structure of code generated by the Simulink
Coder code generator, associated with these two styles of code. The next table
classifies the targets shipped with the product. For related details about

9-29

9

Configuration

code style and target characteristics, see “Types of Target Code Formats”
on page 9-16.
Code Styles Listed by Target
Target

Code Style (Using C or C++ Unless Noted)

Embedded Coder
embedded real-time
(ERT) target

Embedded — Useful as a starting point when
using generated C/C++ code in an embedded
application (often referred to as a production code
target).

Simulink Coder
Generic real-time
(GRT) target

Rapid prototyping — Use as a starting point for
creating a rapid prototyping target that does not
use real-time operating system tasking primitives,
and for verifying the generated code on your
workstation. Uses components of ERT, with a
different calling interface.

Real-time malloc
target

Rapid prototyping — Similar to the generic
real-time (GRT) target except that this target
allocates model working memory dynamically
rather than statically declaring it in advance.

Rapid simulation
target (RSim)

Rapid prototyping — Non-real-time simulation
of your model on your workstation. Useful as a
high-speed or batch simulation tool.

S-function target

Rapid prototyping — Creates a C MEX S-function
for simulation of your model within another
Simulink model.

Tornado (VxWorks)
real-time target5

Rapid prototyping — Runs model in real time
using the VxWorks real-time operating system
tasking primitives. Also useful as a starting point
for targeting a real-time operating system.

5. Tornado® and VxWorks® are registered trademarks of Wind River® Systems, Inc.

9-30

Target

Code Styles Listed by Target (Continued)
Target

Code Style (Using C or C++ Unless Noted)

Real-Time Windows
Target

Rapid prototyping — Runs model in real time
at interrupt level while your PC is running
a Microsoft Windows environment in the
background.

xPC Target

Rapid prototyping — Runs model in real time on
target PC running the xPC Target kernel.

Third-party vendors supply additional targets for the Simulink Coder product.
Generally, these can be classified as rapid prototyping targets. For more
information about third-party products, see the MathWorks Connections
Program Web page: http://www.mathworks.com/products/connections.
This chapter is divided into three sections. The first section discusses model
execution, the second section discusses the rapid prototyping style of code,
and the third section discusses the embedded style of code.

Backwards Compatibility of Code Formats
Because GRT targets now use Embedded-C code format, existing applications
that depend on the RealTime code format’s calling interface could have
compatibility issues. To address this, a set of macros is generated (in model.h)
that maps Embedded-C data structures to the identifiers that RealTime code
format used. The following, which can be found in any model.h file created
for a GRT target, describes these identifier mappings:
/* Backward compatible GRT Identifiers */
model_B
#define rtB
#define BlockIO
BlockIO_model
#define rtXdot
model_Xdot
#define StateDerivatives
StateDerivatives_model
#define tXdis
model_Xdis
#define StateDisabled
StateDisabled_model
#define rtY
model_Y
#define ExternalOutputs
ExternalOutputs_model
#define rtP
model_P
#define Parameters
Parameters_model

9-31

9

Configuration

Since the GRT target now uses the Embedded-C code format for back end code
generation, many Embedded-C optimizations are available to all Simulink
Coder users. In general, the GRT and ERT targets now have many more
common features, but the ERT target offers additional controls for common
features. The availability of features is now determined by licensing, rather
than being tied to code format. The following table compares features
available with a Simulink Coder license with those available under an
Embedded Coder license:
Comparison of Features Licensed with the Simulink Coder Product Versus the Embedded
Coder Product
Feature

Simulink Coder License

Embedded Coder License

rtModel data

• Full rtModel structure
generated

• rtModel is optimized for the
model

• GRT variable declaration:

• Optional suppression of error
status field and data logging
fields

structure

rtModel_model model_M_;

• ERT variable declaration:
RT_MODEL_model model_M_;

9-32

Custom storage
classes (CSCs)

Code generation ignores CSCs;
objects are assigned a CSC default
to Auto storage class

Code generation with CSCs is
supported

HTML code
generation report

Basic HTML code generation
report

Enhanced report with additional
detail and hyperlinks to the model

Symbol formatting

Symbols (for signals, parameters
and so on) are generated in
accordance with hard-coded
default

Detailed control over generated
symbols.

User-defined
maximum identifier
length for generated
symbols

Supported

Supported

Generation of
terminate function

Always generated

Option to suppress terminate
function

Target

Comparison of Features Licensed with the Simulink Coder Product Versus the Embedded
Coder Product (Continued)
Feature

Simulink Coder License

Embedded Coder License

Combined
output/update
function

Separate output/update functions
are generated

Option to generate combined
output/update function

Optimized data
initialization

Not available

Options to suppress generation of
unnecessary initialization code for
zero-valued memory, I/O ports, and
so on

Comments generation

Basic options to include or suppress
comment generation

Options to include Simulink block
descriptions, Stateflow object
descriptions, and Simulink data
object descriptions in comments

Module Packaging
Features (MPF)

Not supported

Extensive code customization
features (see Embedded Coder
topics such as “Data Types”,
“User-Defined Data Types”, and
“Custom Storage Classes”.)

Target-optimized
data types header file

Requires full tmwtypes.h header
file

Generates optimized rtwtypes.h
header file, including definitions
required by the target

User-defined types

User-defined types default to base
types in code generation

User defined data type aliases are
supported in code generation

Rate grouping

Not supported

Supported

Auto-generation of
main program module

Not supported; static main
program module is provided.

Automated and customizable
generation of main program
module is supported (static main
program also available)

Reusable
(multi-instance) code
generation with static
memory allocation

Not supported

Option to generate reusable code

9-33

9

Configuration

Comparison of Features Licensed with the Simulink Coder Product Versus the Embedded
Coder Product (Continued)
Feature

Simulink Coder License

Embedded Coder License

Software constraint
options

Support for floating point, complex,
and nonfinite numbers is always
enabled

Options to enable or disable
support for floating-point, complex,
and nonfinite numbers

Application life span

Defaults to inf

User-specified; determines most
efficient word size for integer
timers

Software-in-the-loop
(SIL) testing

Model reference simulation target
can be used for SIL testing

Additional SIL testing support by
using auto-generation of SIL block

ANSI6-C/C++ code
generation

Supported

Supported

ISO®7-C/C++ code
generation

Supported

Supported

GNU®8-C/C++ code
generation

Supported

Supported

Generate scalar
inlined parameters as
#DEFINE statements

Not supported

Supported

MAT-file variable
name modifier

Supported

Supported

Data exchange: C
API, external mode,
ASAP2

Supported

Supported

Selecting a Target
The first step to configuring a model for Simulink Coder code generation is
to choose and configure a code generation target. When you select a target,
6. ANSI® is a registered trademark of the American National Standards Institute, Inc.
7. ISO® is a registered trademark of the International Organization for Standardization.
8. GNU® is a registered trademark of the Free Software Foundation.

9-34

Target

other model configuration parameters change automatically to best serve
requirements of the target. For example:
• Code interface parameters
• Build process parameters, such as the template make file
• Target hardware parameters, such as word size and byte ordering
Use the Browse button on the Code Generation pane to open the System
Target File Browser. The browser lets you select a preset target configuration
consisting of a system target file, template makefile, and make command. For
a complete list of available target configurations, see “Available Targets”
on page 9-10.
If you select a target configuration by using the System Target File Browser,
your selection appears in the System target file field (target.tlc).
If you are using a target configuration that does not appear in the System
Target File Browser, enter the name of your system target file in the System
target file field. Click Apply or OK to configure for that target.
You also can select a target programmatically from MATLAB code, as
described in “Selecting a System Target File Programmatically” on page 9-37.
After selecting a target, you can modify model configuration parameter
settings.
If you want to switch between different targets in a single workflow for
different code generation purposes (for example, rapid prototyping versus
product code deployment), set up different configuration sets for the same
model and switch the active configuration set for the current operation.
For more information on how to set up configuration sets and change the
active configuration set, see “Manage a Configuration Set” in the Simulink
documentation.
To select a target configuration using the System Target File Browser,
1 Open the Code Generation pane of the Configuration Parameters dialog

box.

9-35

9

Configuration

2 Click the Browse button next to the System target file field. This opens

the System Target File Browser. The browser displays a list of currently
available target configurations, including customizations. When you
select a target configuration, the Simulink Coder software automatically
chooses the system target file, template makefile, and make command for
that configuration.
The next step shows the System Target File Browser with the generic
real-time target selected.
3 Click the desired entry in the list of available configurations. The

background of the list box turns yellow to indicate an unapplied choice has
been made. To apply it, click Apply or OK.

System Target File Browser

When you choose a target configuration, the Simulink Coder software
automatically chooses the system target file, template makefile, and make
command for that configuration, and displays them in the System target
file field. The description of the target file from the browser is placed below
its name in the Code Generation pane.

9-36

Target

Selecting a System Target File Programmatically
Simulink models store model-wide parameters and target-specific data in
configuration sets. Every configuration set contains a component that defines
the structure of a particular target and the current values of target options.
Some of this information is loaded from a system target file when you select a
target using the System Target File Browser. You can configure models to
generate alternative target code by copying and modifying old or adding new
configuration sets and browsing to select a new target. Subsequently, you can
interactively select an active configuration from among these sets (only one
configuration set can be active at a given time).
Scripts that automate target selection need to emulate this process.
To program target selection
1 Obtain a handle to the active configuration set with a call to the

getActiveConfigSet function.
2 Define string variables that correspond to the required Simulink Coder

system target file, template makefile, and make command settings. For
example, for the ERT target, you would define variables for the strings
'ert.tlc', 'ert_default_tmf', and 'make_rtw'.
3 Select the system target file with a call to the switchTarget function. In

the function call, specify the handle for the active configuration set and
the system target file.
4 Set the TemplateMakefile and MakeCommand configuration parameters to

the corresponding variables created in step 2.
For example:
cs = getActiveConfigSet(model);
stf = 'ert.tlc';
tmf = 'ert_default_tmf';
mc = 'make_rtw';
switchTarget(cs,stf,[]);
set_param(cs,'TemplateMakefile',tmf);
set_param(cs,'MakeCommand',mc);

9-37

9

Configuration

Template Makefiles and Make Options
The Simulink Coder product includes a set of built-in template makefiles that
are designed to build programs for specific targets.
There are two types of template makefiles:
• Compiler-specific template makefiles are designed for use with a particular
compiler or development system.
By convention, compiler-specific template makefiles are named according to
the target and compiler (or development system). For example, grt_vc.tmf
is the template makefile for building a generic real-time program under the
Visual C++ compiler; ert_lcc.tmf is the template makefile for building an
Embedded Coder program under the Lcc compiler.
• Default template makefiles make your model designs more portable, by
choosing the compiler-specific makefile and compiler for your installation.
“Choose and Configure a Compiler” on page 15-2 describes the operation of
default template makefiles in detail.
Default template makefiles are named target_default_tmf. They
are MATLAB language files that, when run, select the TMF for the
specified target configuration. For example, grt_default_tmf is the
default template makefile for building a generic real-time program;
ert_default_tmf is the default template makefile for building an
Embedded Coder program.
You can supply options to makefiles by using arguments to the Make
command field in the Code Generation pane of the Configuration
Parameters dialog box. Append the arguments after make_rtw (or make_xpc
or other make command), as in the following example:
make_rtw OPTS="-DMYDEFINE=1"

The syntax for make command options differs slightly for different compilers.
Complete details on the structure of template makefiles are provided in the
Embedded Coder documentation. This information is provided for those who
want to customize template makefiles. This section describes compiler-specific
template makefiles and common options you can use with each.

9-38

Target

Note To control compiler optimizations for your Simulink Coder makefile
build at the Simulink GUI level, use the Compiler optimization level
option on the Code Generation pane of the Configuration Parameters dialog
box. The Compiler optimization level option provides
• Target-independent values Optimizations on (faster runs) and
Optimizations off (faster builds), which allow you to easily toggle
compiler optimizations on and off during code development
• The value Custom for entering custom compiler optimization flags at
Simulink GUI level (rather than at other levels of the build process)
If you specify compiler options for your Simulink Coder makefile build using
OPT_OPTS, MEX_OPTS (except MEX_OPTS="-v"), or MEX_OPT_FILE, the value of

Compiler optimization level is ignored and a warning is issued about
the ignored parameter.

Template Makefiles for UNIX Platforms
The template makefiles for UNIX platforms are designed to be used with the
Free Software Foundation’s GNU Make. These makefile are set up to conform
to the guidelines specified in the IEEE®9 Std 1003.2-1992 (POSIX) standard.
• ert_unix.tmf
• grt_malloc_unix.tmf
• grt_unix.tmf
• rsim_unix.tmf
• rtwsfcn_unix.tmf
You can supply options by using arguments to the make command.
• OPTS — User-specific options, for example,
make_rtw OPTS="-DMYDEFINE=1"
9. IEEE® is a registered trademark of The Institute of Electrical and Electronics Engineers,
Inc.

9-39

9

Configuration

• OPT_OPTS— Optimization options. Default is -O. To enable debugging
specify as OPT_OPTS=-g. Because of optimization problems in IBM_RS, the
default is no optimization.
• CPP_OPTS — C++ compiler options.
• USER_SRCS — Additional user sources, such as files used by S-functions.
• USER_INCLUDES — Additional include paths, for example,
USER_INCLUDES="-Iwhere-ever -Iwhere-ever2"

These options are also documented in the comments at the head of the
respective template makefiles.

Template Makefiles for the Microsoft Visual C++ Compiler
The Simulink Coder product offers two sets of template makefiles designed
for use with the Visual C++ compiler.
To build an executable within the Simulink Coder build process, use one of
the target_vc.tmf template makefiles:
• ert_vc.tmf
• grt_malloc_vc.tmf
• grt_vc.tmf
• rsim_vc.tmf
• rtwsfcn_vc.tmf
You can supply options by using arguments to the make command.
• OPT_OPTS — Optimization option. Default is -O2. To enable debugging
specify as OPT_OPTS=-Zi.
• OPTS — User-specific options.
• CPP_OPTS — C++ compiler options.
• USER_SRCS — Additional user sources, such as files used by S-functions.
• USER_INCLUDES — Additional include paths, for example,

9-40

Target

USER_INCLUDES="-Iwhere-ever -Iwhere-ever2"

These options are also documented in the comments at the head of the
respective template makefiles.
Visual C++ Code Generation Only. To create a Visual C++ project
makefile (model.mak) without building an executable, use one of the
target_msvc.tmf template makefiles:
• ert_msvc.tmf
• grt_malloc_msvc.tmf
• grt_msvc.tmf
These template makefiles are designed to be used with nmake, which is
bundled with the Visual C++ compiler.
You can supply the following options by using arguments to the nmake
command:
• OPTS — User-specific options, for example,
make_rtw OPTS="/D MYDEFINE=1"

• USER_SRCS — Additional user sources, such as files used by S-functions.
• USER_INCLUDES — Additional include paths, for example,
USER_INCLUDES="-Iwhere-ever -Iwhere-ever2"

These options are also documented in the comments at the head of the
respective template makefiles.

Template Makefiles for the Watcom C/C++ Compiler
The Simulink Coder product provides template makefiles to create an
executable for the Microsoft Windows platform using Watcom C/C++. These
template makefiles are designed to be used with wmake, which is bundled
with Watcom C/C++.

9-41

9

Configuration

Note The Watcom C compiler is no longer available from the manufacturer.
However, the Simulink Coder product continues to ship with Watcom-related
template makefiles.

• ert_watc.tmf
• grt_malloc_watc.tmf
• grt_watc.tmf
• rsim_watc.tmf
• rtwsfcn_watc.tmf
You can supply options by using arguments to the make command. Note that
the location of the quotes is different from the other compilers and make
utilities discussed in this chapter.
• OPTS — User-specific options, for example,
make_rtw "OPTS=-DMYDEFINE=1"

• OPT_OPTS — Optimization options. The default optimization option is
-oxat. To turn off optimization and add debugging symbols, specify the
-d2 compiler switch in the make command, for example,
make_rtw "OPT_OPTS=-d2"

• CPP_OPTS — C++ compiler options.
• USER_OBJS — Additional user objects, such as files used by S-functions.
• USER_PATH — The folder path to the source (.c or .cpp) files that are used
to create any .obj files specified in USER_OBJS. Multiple paths must be
separated with a semicolon. For example,
USER_PATH="path1;path2"

• USER_INCLUDES — Additional include paths, for example,
USER_INCLUDES="-Iinclude-path1 -Iinclude-path2"

9-42

Target

These options are also documented in the comments at the head of the
respective template makefiles.

Template Makefiles for the LCC Compiler
The Simulink Coder product provides template makefiles to create an
executable for the Windows platform using Lcc compiler Version 2.4 and
GNU Make (gmake).
• ert_lcc.tmf
• grt_lcc.tmf
• grt_malloc_lcc.tmf
• rsim_lcc.tmf
• rtwsfcn_lcc.tmf
You can supply options by using arguments to the make command:
• OPTS — User-specific options, for example,
make_rtw OPTS="-DMYDEFINE=1"

• OPT_OPTS — Optimization options. Default is none. To enable debugging,
specify -g4 in the make command:
make_rtw OPT_OPTS="-g4"

• CPP_OPTS — C++ compiler options.
• USER_SRCS — Additional user sources, such as files used by S-functions.
• USER_INCLUDES — Additional include paths, for example,
USER_INCLUDES="-Iwhere-ever -Iwhere-ever2"

For Lcc, have a / as file separator before the filename instead of a \, for
example, d:\work\proj1/myfile.c.
These options are also documented in the comments at the head of the
respective template makefiles.

9-43

9

Configuration

Enabling the Simulink Coder Software to Build When Path
Names Contain Spaces
The Simulink Coder software is able to handle path names that include
spaces. Spaces might appear in the path from several sources:
• Your MATLAB installation folder
• The current MATLAB folder in which you initiate a build
• A compiler you are using for a Simulink Coder build
If your work environment includes one or more of the preceding scenarios, use
the following support mechanisms as they apply::
• Add the following code to your template makefile (.tmf):
ALT_MATLAB_ROOT
= |>ALT_MATLAB_ROOT<|
ALT_MATLAB_BIN
= |>ALT_MATLAB_BIN<|
!if "$(MATLAB_ROOT)" != "$(ALT_MATLAB_ROOT)"
MATLAB_ROOT = $(ALT_MATLAB_ROOT)
!endif
!if "$(MATLAB_BIN)" != "$(ALT_MATLAB_BIN)"
MATLAB_BIN = $(ALT_MATLAB_BIN)
!endif

This code replaces MATLAB_ROOT with ALT_MATLAB_ROOT when the values
of the two tokens are not equal, indicating the path for your MATLAB
installation folder includes spaces. Likewise, ALT_MATLAB_BIN replaces
MATLAB_BIN.
Note the preceding code is specific to nmake. See the supplied Simulink
Coder template make files for platform-specific examples.
• When using operating system commands, such as system or dos, enclose
path that specify executables or command parameters in double quotes
(" "). For example,
system('dir "D:\Applications\Common Files"')

Custom Targets
You can create your own system target files to build custom targets that
interface with external code or operating environments.

9-44

Target

See “About Embedded Target Development” on page 24-2 and the topics it
references for details and examples showing how to make your custom targets
appear in the System Target File Browser and display relevant controls in
panes of the Configuration Parameters dialog box.

Describing the Emulation and Embedded Targets
The Configuration Parameters dialog Hardware Implementation pane
provides options that you can use to describe hardware properties, such as
data size and byte ordering, and compiler behavior details that may vary with
the compiler, such as integer rounding. The Hardware Implementation
pane contains two subpanes:
• Embedded Hardware — Describes the embedded target hardware
and the compiler that you will use with it. This information affects both
simulation and code generation.
• Emulation Hardware — Describes the emulation target hardware and
the compiler that you will use with it. This information affects only code
generation.
The two subpanes provide identical options and value choices. By default, the
Embedded Hardware subpane initially looks like this:

The default assumption is that the embedded target and emulation target are
the same, so the Emulation Hardware subpane by default does not need
to specify anything and contains only a checked option labeled None. Code
generated under this configuration will be suitable for production use, or for
testing in an environment identical to the production environment.

9-45

9

Configuration

If you clear the check box, the Emulation Hardware subpane appears,
initially showing the same values as the Embedded Hardware subpane. If
you change any of these values, then generate code, the code will be able to
execute in the environment specified by the Emulation Hardware subpane,
but will behave as if it were executing in the environment specified by the
Embedded Hardware subpane. See “Describing Emulation Hardware
Characteristics” on page 9-55 for details.
If you have used the Code Generation pane to specify a System target
file, and the target file specifies a default microprocessor and its hardware
properties, the default and properties appear as initial values in the
Hardware Implementation pane.
Options with only one possible value cannot be changed. Any option that has
more than one possible value provides a list of legal values. If you specify
any hardware properties manually, check carefully that their values are
consistent with the system target file. Otherwise, the generated code may fail
to compile or execute, or may execute but give incorrect results.
Note Hardware Implementation pane options do not control hardware or
compiler behavior in any way. Their purpose is solely to describe hardware
and compiler properties to MATLAB software, which uses the information to
generate code for the platform thatruns as efficiently as possible, and gives
bit-true agreement for the results of integer and fixed-point operations in
simulation, production code, and test code.
The rest of this section describes the options in the Embedded Hardware
and Emulation Hardware subpanes. Subsequent sections describe
considerations that apply only to one or the other subpane. For more about
Hardware Implementation options, see “Hardware Implementation Pane”.
To see an example of Hardware Implementation pane capabilities, run the
rtwdemo_targetsettings example.

Describing the Device Vendor
The Device vendor option gives the name of the device vendor. To set the
option, select a vendor name from the Device vendor menu. Your selection
of vendor will determine the available device values in the Device type list.

9-46

Target

If the desired vendor name does not appear in the menu, select Generic and
then use the Device type option to further specify the device.

Note
• For complete lists of Device vendor and Device type values, see “Device
vendor” and “Device type” in the Simulink reference documentation.
• To add Device vendor and Device type values to the default set that
is displayed on the Hardware Implementation pane, see “Registering
Additional Device Vendor and Device Type Values” on page 9-47.

Describing the Device Type
The Device type option selects a hardware device among the supported
devices listed for your Device vendor selection. To set the option, select
a microprocessor name from the Device type menu. If the desired
microprocessor does not appear in the menu, change the Device vendor
to Generic.
If you specified Device vendor as Generic, examine the listed device
descriptions and select the device type that matches your hardware. If no
available device type matches, select Custom.
If you select a device type for which the target file specifies default hardware
properties, the properties appear as initial values in the subpane. Options
with only one possible value cannot be changed. Any option that has more
than one possible value provides a list of legal values. Select values for your
hardware. If the device type is Custom, more options can be set, and each
option has a list of possible values.

Registering Additional Device Vendor and Device Type Values
To add Device vendor and Device type values to the default set that is
displayed on the Hardware Implementation pane, you can use a hardware
device registration API provided by the Simulink Coder software.

9-47

9

Configuration

To use this API, you create an sl_customization.m file, located in your
MATLAB path, that invokes the registerTargetInfo function and fills
in a hardware device registry entry with device information. The device
information will be registered with Simulink software for each subsequent
Simulink session. (To register your device information without restarting
MATLAB, issue the MATLAB command sl_refresh_customizations.)
For example, the following sl_customization.m file adds device vendor
MyDevVendor and device type MyDevType to the Simulink device lists.
function sl_customization(cm)
cm.registerTargetInfo(@loc_register_device);
end
function thisDev = loc_register_device
thisDev = RTW.HWDeviceRegistry;
thisDev.Vendor = 'MyDevVendor';
thisDev.Type = 'MyDevType';
thisDev.Alias = {};
thisDev.Platform = {'Prod', 'Target'};
thisDev.setWordSizes([8 16 32 32 32]);
thisDev.LargestAtomicInteger = 'Char';
thisDev.LargestAtomicFloat = 'None';
thisDev.Endianess = 'Unspecified';
thisDev.IntDivRoundTo = 'Undefined';
thisDev.ShiftRightIntArith = true;
thisDev.setEnabled({'IntDivRoundTo'});
end

If you subsequently select the device in the Hardware Implementation
pane, it is displayed as follows:

9-48

Target

To register multiple devices, you can specify an array of
RTW.HWDeviceRegistry objects in your sl_customization.m file. For
example,
function sl_customization(cm)
cm.registerTargetInfo(@loc_register_device);
end
function thisDev = loc_register_device
thisDev(1) = RTW.HWDeviceRegistry;
thisDev(1).Vendor = 'MyDevVendor';
thisDev(1).Type = 'MyDevType1';
...
thisDev(4) = RTW.HWDeviceRegistry;
thisDev(4).Vendor = 'MyDevVendor';
thisDev(4).Type = 'MyDevType4';
...
end

The following table lists the RTW.HWDeviceRegistry properties that you can
specify in the registerTargetInfo function call in your sl_customization.m
file.

9-49

9

Configuration

Property

Description

Vendor

String specifying the Device vendor value for your
hardware device.

Type

String specifying the Device type value for your
hardware device.

Alias

Cell array of strings specifying any aliases or
legacy names that users might specify that
should resolve to this device. Specify each alias
or legacy name in the format 'Vendor->Type'.
(Embedded Coder software provides the
utility functions RTW.isHWDeviceTypeEq and
RTW.resolveHWDeviceType for detecting and
resolving alias values or legacy values when testing
user-specified values for the target device type.)

Platform

Cell array of enumerated string values specifying
whether this device should be listed in the
Embedded hardware subpane ({'Prod'}), the
Emulation hardware subpane ({'Target'}), or
both ({'Prod', 'Target'}).

setWordSizes

Array of integer sizes to associate with the Number
of bits parameters char, short, int, long, and
native word size, respectively.

LargestAtomicIntegerString specifying an enumerated value for the
Largest atomic size: integer parameter: 'Char',
'Short','Int', or 'Long'.
LargestAtomicFloat String specifying an enumerated value for the

Largest atomic size: floating-point parameter:
'Float', 'Double', or 'None'.

9-50

Endianess

String specifying an enumerated value for the Byte
ordering parameter: 'Unspecified', 'Little' for
little Endian, or 'Big' for big Endian.

IntDivRoundTo

String specifying an enumerated value for the
Signed integer division rounds to parameter:
'Zero', 'Floor', or 'Undefined'.

Target

Property

Description

ShiftRightIntArith Boolean value specifying whether your compiler

implements a signed integer right shift as an
arithmetic right shift (true) or not (false).
setEnabled

Cell array of strings specifying which device
properties should be enabled (modifiable) in
the Hardware Implementation pane when
this device type is selected. In addition to
the 'Endianess', 'IntDivRoundTo', and
'ShiftRightIntArith' properties listed above, you
can enable individual Number of bits parameters
using the property names 'BitPerChar',
'BitPerShort', 'BitPerInt', 'BitPerLong', and
'NativeWordSize'.

Describing the Number of Bits
The Number of bits options describe the native word size of the
microprocessor, and the bit lengths of char, short, int, and long data. For
code generation to succeed:
• The bit lengths must be such that char <= short <= int <= long.
• Bit lengths must be multiples of 8, with a maximum of 32.
• The bit length for long data must not be less than 32.
Simulink Coder integer type names are defined in the file rtwtypes.h. The
values that you provide must be consistent with the word sizes as defined in
the compiler’s limits.h header file. The following table lists the standard
Simulink Coder integer type names and maps them to the corresponding
Simulink names.
Simulink Coder Integer
Type

Simulink Integer Type

boolean_T

boolean

int8_T

int8

uint8_T

uint8

9-51

9

Configuration

Simulink Coder Integer
Type

Simulink Integer Type

int16_T

int16

uint16_T

uint16

int32_T

int32

uint32_T

uint32

If no ANSI C type with a matching word size is available, but a larger ANSI C
type is available, the Simulink Coder code generator uses the larger type for
int8_T, uint8_T, int16_T, uint16_T, int32_T, and uint32_T.
An application can use integer data of any length from 1 (unsigned) or 2
(signed) bits up 32 bits. If the integer length matches the length of an
available type, the Simulink Coder code generator uses that type. If no
matching type is available, the code generator uses the smallest available
type that can hold the data, generating code that never uses unnecessary
higher-order bits. For example, on a target that provided 8-bit, 16-bit, and
32-bit integers, a signal specified as 24 bits would be implemented as an
int32_T or uint32_T.
Code that uses emulated integer data is not maximally efficient, but can be
useful during application development for emulating integer lengths that are
available only on production hardware. The use of emulation does not affect
the results of execution.

Describing the Byte Ordering
The Byte ordering option specifies whether the target hardware uses Big
Endian (most significant byte first) or Little Endian (least significant byte
first) byte ordering. If left as Unspecified, the Simulink Coder software
generates code that determines the endianness of the target; this is the least
efficient option.

Describing Quotient Rounding for Signed Integer Division
ANSI C does not completely define the rounding technique to be
used when dividing one signed integer by another, so the behavior is
implementation-dependent. If both integers are positive, or both are negative,

9-52

Target

the quotient must round down. If either integer is positive and the other is
negative, the quotient can round up or down.
The Signed integer division rounds to parameter tells the Simulink
Coder code generator how the compiler rounds the result of signed integer
division. Providing this information does not affect the operation of the
compiler, it only describes that behavior to the code generator, which uses
the information to optimize code generated for signed integer division. The
parameter options are:
• Zero — If the quotient is between two integers, the compiler chooses the
integer that is closer to zero as the result.
• Floor — If the quotient is between two integers, the compiler chooses the
integer that is closer to negative infinity.
• Undefined — Choose this option if neither Zero nor Floor describes the
compiler’s behavior, or if that behavior is unknown.
The following table illustrates the compiler behavior that corresponds to each
of these three options:

N

D

Ideal
N/D

Zero

Floor

Undefined

33

4

8.25

8

8

8

-33

4

-8.25

-8

-9

-8 or -9

33

-4

-8.25

-8

-9

-8 or -9

-33

-4

8.25

8

8

8 or 9

Note Select Undefined only as a last resort. When the code generator does
not know the signed integer division rounding behavior of the compiler, it
generates extra code.
The compiler’s implementation for signed integer division rounding can
be obtained from the compiler documentation, or by experiment if no
documentation is available.

9-53

9

Configuration

Describing Arithmetic Right Shifts on Signed Integers
ANSI C does not define the behavior of right shifts on negative integers, so
the behavior is implementation-dependent. The Shift right on a signed
integer as arithmetic shift parameter tells the Simulink Coder code
generator how the compiler implements right shifts on negative integers.
Providing this information does not affect the operation of the compiler, it
only describes that behavior to the code generator, which uses the information
to optimize the code generated for arithmetic right shifts.
Select the option if the C compiler implements a signed integer right shift as
an arithmetic right shift, and clear the option otherwise. An arithmetic right
shift fills bits vacated by the right shift with the value of the most significant
bit, which indicates the sign of the number in twos complement notation.
The option is selected by default. If your compiler handles right shifts as
arithmetic shifts, this is the preferred setting.
• When the option is selected, the Simulink Coder software generates simple
efficient code whenever the Simulink model performs arithmetic shifts on
signed integers.
• When the option is cleared, the Simulink Coder software generates fully
portable but less efficient code to implement right arithmetic shifts.
The compiler’s implementation for arithmetic right shifts can be obtained
from the compiler documentation, or by experiment if no documentation is
available.

Describing Embedded Hardware Characteristics
“Describing the Emulation and Embedded Targets” on page 9-45 documents
the options available on the Hardware Implementation subpanes. This
section describes considerations that apply only to the Embedded Hardware
subpane. When you use this subpane, keep the following in mind:
• Code generation targets can have word sizes and other hardware
characteristics that differ from the MATLAB host. Furthermore, code can
be prototyped on hardware that is different from either the deployment
target or the MATLAB host. The Simulink Coder code generator takes
these differences into account when generating code.

9-54

Target

• The Simulink product uses some of the information in the Embedded
Hardware subpane to get the same results from simulation without
code generation as executing generated code, including detecting error
conditions that could arise on the target hardware, such as hardware
overflow.
• The Simulink Coder software generates code that produces bit-true
agreement with Simulink results for integer and fixed-point operations.
Generated code that emulates unavailable data lengths runs less efficiently
than it would without emulation, but the emulation does not affect bit-true
agreement with Simulink for integer and fixed-point results.
• If you change targets at any point during application development,
reconfigure the hardware implementation parameters for the new target
before generating or regenerating code. Bit-true agreement for the results
of integer and fixed-point operations in simulation, production code, and
test code might not occur when code executes on hardware for which it
was not generated.
• Use the Integer rounding mode parameter on your model’s blocks to
simulate the rounding behavior of the C compiler that you intend to use
to compile code generated from the model. This setting appears on the
Signal Attributes pane of the parameter dialog boxes of blocks that can
perform signed integer arithmetic, such as the Product and n-D Lookup
Table blocks.
• For most blocks, the value of Integer rounding mode completely defines
rounding behavior. For blocks that support fixed-point data and the
Simplest rounding mode, the value of Signed integer division rounds to
also affects rounding. For details, see “Rounding”.
• When models contain Model blocks, all models that they reference must
be configured to use identical hardware settings.

Describing Emulation Hardware Characteristics
“Describing the Emulation and Embedded Targets” on page 9-45 documents
the options available on the Hardware Implementation subpanes. This
section describes considerations that apply only to the Emulation Hardware
subpane.

9-55

9

Configuration

Note (If the Emulation Hardware subpane contains a button labeled
Configure current execution hardware device, see “Updating from
Earlier Versions” on page 9-57, then continue from this point.)
The default assumption is that the embedded target and emulation target are
the same, so the Emulation Hardware subpane by default does not need to
specify anything and contains only a selected check box labeled None. Code
generated under this configuration will be suitable for production use, or for
testing in an environment identical to the production environment.
To generate code that runs on an emulation target for test purposes, but
behaves as if it were running on an embedded target in a production
application, you must specify the properties of both targets in the Hardware
Implementation pane. The Embedded Hardware subpane specifies
embedded target hardware properties, as described previously. To specify
emulation target properties:
1 Clear the None option in the Emulation Hardware subpane.

2 In the Emulation Hardware subpane, specify the properties of the

emulation target, using the instructions in “Describing the Emulation and
Embedded Targets” on page 9-45
If you have used the Code Generation pane to specify a System target
file, and the target file specifies a default microprocessor and its hardware
properties, the default and properties appear as initial values in both
subpanes of the Hardware Implementation pane.

9-56

Target

Options with only one possible value cannot be changed. Any option that has
more than one possible value provides a list of legal values. If you specify
any hardware properties manually, check carefully that their values are
consistent with the system target file. Otherwise, the generated code may fail
to compile or execute, or may execute but give incorrect results.
If you do not display the Emulation Hardware subpane, the Simulink and
Simulink Coder software defaults every Emulation Hardware option to
have the same value as the corresponding Embedded Hardware option.
If you hide the Emulation Hardware subpane after setting its values,
the values that you specified will be lost. The underlying configuration
parameters immediately revert to the values that they had when you exposed
the subpane, and these values, rather than the values that you specified, will
appear if you re-expose the subpane.

Updating from Earlier Versions
If your model was created before Release 14 and has not been updated, by
default the Hardware Implementation pane initially looks like this:

Click Configure current execution hardware device. The Configure
current execution hardware device button disappears. The subpane then
appears as shown in the first figure in this section. Save your model at this
point to avoid redoing Configure current execution hardware device
next time you access the Hardware Implementation pane.

9-57

9

Configuration

Specifying Target Interfaces
Use the Interface pane to control which math library is used at run time,
whether to include one of three APIs in generated code, and certain other
interface options.
To...

Select or Enter...

Specify the target-specific
math library to use when
generating code

Select C89/C90 (ANSI), C99 (ISO), GNU99 (GNU), or C++ (ISO)
for Code replacement library. (Additional values may be listed
for licensed target products, for Embedded Targets and Desktop
Targets, or if you have created and registered code replacement
libraries with the Embedded Coder product.)
Selecting C89/C90 (ANSI) provides the ANSI10 C set of library
functions. For example, selecting C89/C90 (ANSI) would result in
generated code that calls sin() whether the input argument is
double precision or single precision. However, if you select C99
(ISO), the call instead is to the function sinf(), which is single
precision. If your compiler supports the ISO11 C math extensions,
selecting the ISO C library can result in more efficient code.
For more information about code replacement libraries, see
“Selecting and Viewing Code Replacement Libraries” on page 9-61.

Direct where the Simulink
Coder code generator
should place fixed-point
and other utility code

Select Auto or Shared location for Shared code placement.
The shared location directs code for utilities to be placed within
the slprj folder in your working folder, which is used for building
model reference targets. If you select Auto,
• When the model contains Model blocks, places utility code within
the slprj/target/_sharedutils folder.
• When the model does not contain Model blocks, places utility
code in the build folder (generally, in model.c or model.cpp).

10. ANSI® is a registered trademark of the American National Standards Institute, Inc.
11. ISO® is a registered trademark of the International Organization for Standardization.

9-58

Target

To...

Select or Enter...

Specify a string to be
added to the variable
names used when logging
data to MAT-files, to
distinguish logging data
from Simulink Coder and
Simulink applications

Enter a prefix or suffix, such as rt_ or _rt, for MAT-file variable
name modifier. The Simulink Coder code generator prefixes
or appends the string to the variable names for system outputs,
states, and simulation time specified in the Data Import/Export
pane. See “Logging” on page 15-105 for information on MAT-file
data logging.

Specify an API to be
included in generated code

Select C API, External mode, or ASAP2 for Interface. When you
select C API or External mode, other options appear. C API and
External mode are mutually exclusive. However, this is not the
case for C API and ASAP2. For more information on working with
these interfaces, see “Data Interchange Using the C API” on page
15-137, “Host/Target Communication” on page 15-50, and “ASAP2
Data Measurement and Calibration” on page 15-174.

Note Before setting Code replacement library, verify that your compiler
supports the library you want to use. If you select a parameter value that
your compiler does not support, compiler errors can occur. For example, if
you select C99 (ISO) and your compiler does not support the ISO C math
extensions, compile-time errors likely will occur.
When the Embedded Coder product is installed on your system, the Code
Generation > Interface pane expands to include several additional options.
For descriptions of Code Generation > Interface pane parameters, see
“Code Generation Pane: Interface”. For a summary of option dependencies,
see “Interface Dependencies” on page 9-59.

Interface Dependencies
Several parameters available on the Interface pane have dependencies
on settings of other parameters. The following table summarizes the
dependencies.

9-59

9

9-60

Configuration

Parameter

Dependencies?

Code replacement library

No

Shared code placement

No

Support: floating-point
numbers (ERT targets only)

No

Support: non-finite numbers

Yes (ERT targets)
No (GRT targets)

Support: complex numbers
(ERT targets only)

No

Support: absolute time (ERT
targets only)

No

Support: continuous time
(ERT targets only)

No

Support: non-inlined
S-functions (ERT targets
only)

Yes

Requires that you enable Support
floating-point numbers and
Support non-finite numbers

Classic call interface

Yes (ERT targets)
No (GRT targets)

For ERT targets, requires that you
enable Support floating-point
numbers and disable Single
output/update function

Single output/update function
(ERT targets only)

Yes

Disable for Classic call interface

Terminate function required
(ERT targets only)

Yes

Generate reusable code (ERT
targets only)

Yes

Reusable code error
diagnostic (ERT targets only)

Yes

Dependency Details

For ERT targets, enabled by Support
floating-point numbers

Enabled by Generate reusable code

Target

Parameter

Dependencies?

Dependency Details

Pass root-level I/O as (ERT
targets only)

Yes

Enabled by Generate reusable code

MAT-file logging

Yes

For GRT targets, requires that you
enable Support non-finite numbers;
for ERT targets, requires that you
enable Support floating-point
numbers, Support non-finite
numbers, and Terminate function
required

MAT-file file variable name
modifier

Yes

Enabled by MAT-file logging

Suppress error status in
real-time model data structure
(ERT targets only)

No

Interface

No

Generate C API for: signals

Yes

Set Interface to C API

Generate C API for:
parameters

Yes

Set Interface to C API

Generate C API for: states

Yes

Set Interface to C API

Transport layer

Yes

Set Interface to External mode

MEX-file arguments

Yes

Set Interface to External mode

Static memory allocation

Yes

Set Interface to External mode

Static memory buffer size

Yes

Enable Static memory allocation

Selecting and Viewing Code Replacement Libraries
• “Selecting a Target-Specific Math Library for Your Model” on page 9-62
• “Code Replacement Table Overview” on page 9-63
• “Using the Code Replacement Viewer” on page 9-65

9-61

9

Configuration

Selecting a Target-Specific Math Library for Your Model
A code replacement library (CRL) is a set of one or more code replacement
tables that define the target-specific implementations of math functions
and operators to be used in generating code for your Simulink model.
The Simulink Coder product provides default CRLs, which you can
select from the Code replacement library drop-down list on the Code
Generation > Interface pane of the Configuration Parameters dialog box.
CRL

Description

Contains tables...

C89/C90
(ANSI)

Generates calls to the ISO/IEC 9899:1990
C standard math library for floating-point
functions.

ansi_tfl_table_tmw.mat

C99 (ISO)

Generates calls to the ISO/IEC 9899:1999 C
standard math library.

iso_tfl_table_tmw.mat
ansi_tfl_table_tmw.mat

GNU99 (GNU)

Generates calls to the Free Software
Foundation’s GNU gcc math library, which
provides C99 extensions as defined by compiler
option -std=gnu99.

gnu_tfl_table_tmw.mat
iso_tfl_table_tmw.mat
ansi_tfl_table_tmw.mat

C++ (ISO)

Generates calls to the ISO/IEC 14882:2003
C++ standard math library.

iso_cpp_tfl_table_tmw.mat
private_iso_cpp_tfl_table_tmw.mat
iso_tfl_table_tmw.mat
ansi_tfl_table_tmw.mat

CRL tables provide the basis for replacing default math functions and
operators in your model code with target-specific code. If you select a library
and then hover over the selected library with the cursor, a tool tip is displayed
that describes the CRL and lists the code replacement tables it contains.
Tables are listed in the order in which they are searched for a function or
operator match.

9-62

Target

The Simulink Coder product allows you to view the content of CRL code
replacement tables using the Code Replacement Viewer, as described in
“Using the Code Replacement Viewer” on page 9-65. If you are licensed to
use the Embedded Coder product, you additionally can create and register
the code replacement tables that make up a CRL.

Code Replacement Table Overview
Each CRL code replacement table contains one or more table entries, with
each table entry representing a potential replacement for a single math
function or an operator. Each table entry provides a mapping between a
conceptual view of the function or operator (similar to the Simulink block
view of the function or operator) and a target-specific implementation of that
function or operator.
The conceptual view of a function or operator is represented in a CRL table
entry by the following elements, which identify the function or operator entry
to the code generation process:

9-63

9

Configuration

• A function or operator key (a function name such as 'cos' or an operator
ID string such as 'RTW_OP_ADD')
• A set of conceptual arguments that observe Simulink naming ('y1', 'u1',
'u2', ...), along with their I/O types (output or input) and data types
• Other attributes, such as fixed-point saturation and rounding
characteristics for operators, to identify the function or operator to the code
generation process as exactly as required for matching purposes
The target-specific implementation of a function or operator is represented in
a CRL table entry by the following elements:
• The name of an implementation function (such as 'cos_dbl' or
'u8_add_u8_u8')
• A set of implementation arguments, along with their I/O types (output or
input) and data types
• Parameters providing the build information for the implementation
function, including header file and source file names and paths
Additionally, a CRL table entry includes a priority value (0-100, with 0 as the
highest priority), which defines the entry’s priority relative to other entries
in the table.
During code generation for your model, when the code generation process
encounters a call site for a math function or operator, it creates and partially
populates a CRL entry object, for the purpose of querying the CRL for a
replacement function. The information provided for the CRL query includes
the function or operator key and the conceptual argument list. The CRL
entry object is then passed to the CRL. If the CRL contains a matching table
entry, a fully-populated CRL entry, including the implementation function
name, argument list, and build information, is returned to the call site and
used to generate code.
Within the CRL that is selected for your model, the tables that comprise the
CRL are searched in the order in which they are listed (in the left or right
pane of the Code Replacement Viewer or in the CRL’s Code replacement
library tool tip). Within each table, if multiple matches are found for a
CRL entry object, priority level determines the match that is returned. A

9-64

Target

higher-priority (lower-numbered) entry will be used over a similar entry with
a lower priority (higher number).

Using the Code Replacement Viewer
The Code Replacement Viewer allows you to examine the content of CRL code
replacement tables. (For an overview of code replacement tables and the
information they contain, see the preceding section.) To launch the viewer
with all currently registered CRLs displayed, issue the following MATLAB
command:
>> RTW.viewTfl

Select the name of a CRL in the left pane, and the viewer displays information
about the CRL in the right pane. For example, the tables that make up the
CRL are listed in priority order. In the following display, the GNU CRL has
been selected.

Click the plus sign (+) next to a CRL name in the left pane to expand its list
of tables, and select a table from the list. The viewer displays the function

9-65

9

Configuration

and operator entries in the selected table in the middle pane, along with
abbreviated table entry information for each entry. In the following display,
the ANSI table has been selected.

The following fields appear in the abbreviated table entry information
provided in the middle pane:

9-66

Field

Description

Name

Name of the function or ID of the operator to be
replaced (for example, cos or RTW_OP_ADD).

Implementation

Name of the implementation function, which can
match or differ from Name.

NumIn

Number of input arguments.

In1Type

Data type of the first conceptual input argument.

In2Type

Data type of the second conceptual input argument.

OutType

Data type of the conceptual output argument.

Target

Field

Description

Priority

The entry’s search priority, 0-100, relative to other
entries of the same name and conceptual argument
list within this table. Highest priority is 0, and
lowest priority is 100. The default is 100. If the
table provides two implementations for a function
or operator, the implementation with the higher
priority will shadow the one with the lower priority.

UsageCount

Not used.

Select a function or operator entry in the middle pane. The viewer displays
detailed information from the table entry in the right pane. In the following
display, the second entry for the cos function has been selected.

The following fields appear in the detailed table entry information provided
in the right pane.

9-67

9

9-68

Configuration

Field

Description

Description

Text description of the table entry (can be empty).

Key

Name of the function or ID of the operator to be replaced
(for example, cos or RTW_OP_ADD), and the number of
conceptual input arguments.

Implementation

Name of the implementation function, and the number
of implementation input arguments.

Implementation
type

Type of implementation: FCN_IMPL_FUNCT for
function or FCN_IMPL_MACRO for macro.

Saturation
mode

Saturation mode supported by the implementation
function for an operator replacement:
RTW_SATURATE_ON_OVERFLOW,
RTW_WRAP_ON_OVERFLOW, or
RTW_SATURATE_UNSPECIFIED.

Rounding mode

Rounding mode supported by the implementation
function for an operator replacement:
RTW_ROUND_FLOOR, RTW_ROUND_CEILING,
RTW_ROUND_ZERO, RTW_ROUND_NEAREST,
RTW_ROUND_NEAREST_ML,
RTW_ROUND_SIMPLEST, RTW_ROUND_CONV, or
RTW_ROUND_UNSPECIFIED.

GenCallback
file

Not used.

Implementation
header

Name of the header file that declares the implementation
function.

Implementation
source

Name of the implementation source file.

Priority

The entry’s search priority, 0-100, relative to other
entries of the same name and conceptual argument
list within this table. Highest priority is 0, and lowest
priority is 100. The default is 100. If the table provides
two implementations for a function or operator, the
implementation with the higher priority will shadow the
one with the lower priority.

Target

Field

Description

Total Usage
Count

Not used.

Conceptual
argument(s)

Name, I/O type (RTW_IO_OUTPUT or
RTW_IO_INPUT), and data type for each conceptual
argument.

Implementation

Name, I/O type (RTW_IO_OUTPUT or
RTW_IO_INPUT), and data type for each
implementation argument.

If you select an operator entry, an additional tab containing fixed-point
setting information is displayed in the right pane. For example:

The following fields appear in the fixed-point setting information provided
in the right pane:

9-69

9

9-70

Configuration

Field

Description

Slopes must be
the same

Indicates whether CRL replacement request processing
must check that the slopes on all arguments (input and
output) are equal. Used with fixed-point addition and
subtraction replacement to disregard specific slope and
bias values and map relative slope and bias values to a
replacement function.

Must have zero
net bias

Indicates whether CRL replacement request processing
must check that the net bias on all arguments is
zero. Used with fixed-point addition and subtraction
replacement to disregard specific slope and bias values
and map relative slope and bias values to a replacement
function.

Relative
scaling factor
F

Slope adjustment factor (F) part of the relative scaling
factor, F2E, for relative scaling CRL entries. Used with
fixed-point multiplication and division replacement to
map a range of slope and bias values to a replacement
function.

Relative
scaling factor
E

Fixed exponent (E) part of the relative scaling factor,
F2E, for relative scaling CRL entries. Used with
fixed-point multiplication and division replacement to
map a range of slope and bias values to a replacement
function.

Select the Target Language

Select the Target Language
Use the Language menu in the Target selection section of the Code
Generation pane to select the target language for the code generated by
the Simulink Coder code generator. You can select C or C++. The Simulink
Coder software generates .c or .cpp files, depending on your selection, and
places the files in your build folder.
Note If you select C++, you might need to configure the Simulink Coder
software to use a compiler before you build a system. For details, see “Choose
and Configure a Compiler” on page 15-2.

9-71

9

Configuration

Code Appearance
In this section...
“Configure Code Comments” on page 9-72
“Configure Generated Identifiers” on page 9-73

Configure Code Comments
Configure how the code generator inserts comments into generated code, by
modifying parameters on the Comments pane.
Note Comments can include international (non-US-ASCII) characters
encountered during code generation when found in Simulink block names and
block descriptions, user comments on Stateflow diagrams, Stateflow object
descriptions, custom TLC files, and code generation template files.

9-72

To...

Select...

Include comments in
generated code

Include comments. Selecting this parameter allows you to select one
or more comment types to be placed in the code.

Include comments
for blocks that
were eliminated
as the result
of optimizations
(such as parameter
inlining)

Show eliminated blocks.

Code Appearance

To...

Select...

Automatically insert
comments that
describe a block’s
code before the code
in the generated file

Simulink block / Stateflow object comments.

Include comments for
parameter variable
names and names
of source blocks in
the model parameter
structure declaration
in model_prm.h

Verbose comments for SimulinkGlobal storage class. If you do not
select this parameter, parameter comments are generated if less than
1000 parameters are declared. This reduces the size of the generated file
for models with a large number of parameters. When you select the
parameter, parameter comments are generated regardless of the number
of parameters.

For descriptions of Comments pane parameters, see “Code Generation Pane:
Comments” in the Simulink Coder reference documentation.

Configure Generated Identifiers
• “Reserved Keywords” on page 9-74
• “Construction of Symbols” on page 9-78
Configure how the code generator uses symbols to name identifiers and
objects by setting parameters on the Symbols pane.
Two options are available for GRT targets: Maximum identifier length and
Reserved names. These are the only symbols options for GRT targets.
The Maximum identifier length field allows you to limit the number of
characters in function, type definition, and variable names. The default is 31
characters. This is also the minimum length you can specify; the maximum
is 256 characters. Consider increasing identifier length for models having
a deep hierarchical structure, and when exercising some of the mnemonic
identifier options described below.
Within a model containing Model blocks, no collisions of constituent model
names can exist. When generating code from a model that uses model

9-73

9

Configuration

referencing, the Maximum identifier length must be large enough to
accommodate the root model name and the name mangling string (if any). A
code generation error occurs if Maximum identifier length is too small.
When a name conflict occurs between a symbol within the scope of a higher
level model and a symbol within the scope of a referenced model, the symbol
from the referenced model is preserved. Name mangling is performed on the
symbol from the higher level model.
The Reserved names field allows you to specify the set of keywords that
the Simulink Coder code generation process should not use, facilitating code
integration where functions and variables from external environments are
unknown in the Simulink model. For a list of rules for specifying reserved
names, see “Reserved names” in the Simulink Coder reference documentation.
If your model contains MATLAB Function or Stateflow blocks, the code
generation process can use the reserved names specified for those blocks if
you select Use the same reserved names as Simulation Target.
If the Embedded Coder product is installed on your system, the Symbols
pane expands to include options for controlling identifier formats, mangle
length, scalar inlined parameters, and Simulink data object naming rules.
For details, see “Customize Generated Identifiers” in the Embedded Coder
documentation.
For descriptions of Symbols pane parameters, see “Code Generation Pane:
Symbols”.

Reserved Keywords
• “C Reserved Keywords” on page 9-75
• “C++ Reserved Keywords” on page 9-75
• “Reserved Keywords for Code Generation” on page 9-76
• “Simulink® Coder™ Code Replacement Library Keywords” on page 9-76
Simulink Coder software reserves certain words for its own use as keywords
of the generated code language. Simulink Coder keywords are reserved for
use internal to Simulink Coder software and should not be used in Simulink

9-74

Code Appearance

models as identifiers or function names. C reserved keywords should also not
be used in Simulink models as identifiers or function names. If your model
contains any reserved keywords, the code generation build does not complete
and an error message is displayed. To address this error, modify your model
to use identifiers or names that are not reserved.
If you are generating C++ code using the Simulink Coder software, your
model must not contain both the “Reserved Keywords for Code Generation” on
page 9-76 and the “C++ Reserved Keywords” on page 9-75.
Note You can register additional reserved identifiers in the Simulink
environment. For more information, see “Reserved names” in the Simulink
Coder reference documentation.

C Reserved Keywords.
auto

double

int

struct

break

else

long

switch

case

enum

register

typedef

char

extern

return

union

const

float

short

unsigned

continue

for

signed

void

default

goto

sizeof

volatile

do

if

static

while

C++ Reserved Keywords.
catch

friend

protected

try

class

inline

public

typeid

const_cast

mutable

reinterpret_cast

typename

delete

namespace

static_cast

using

dynamic_cast

new

template

virtual

9-75

9

Configuration

explicit

operator

this

export

private

throw

wchar_t

Reserved Keywords for Code Generation.
abs

fortran

localZCE

rtNaN

asm

HAVESTDIO

localZCSV

SeedFileBuffer

bool

id_t

matrix

SeedFileBufferLen

boolean_T

int_T

MODEL

single

byte_T

int8_T

MT

TID01EQ

char_T

int16_T

NCSTATES

time_T

cint8_T

int32_T

NULL

true

cint16_T

int64_T

NUMST

TRUE

cint32_T

INTEGER_CODE

pointer_T

uint_T

creal_T

LINK_DATA_BUFFER_SIZE
PROFILING_ENABLED

creal32_T

LINK_DATA_STREAM

PROFILING_NUM_SAMPLES
uint16_T

creal64_T

localB

real_T

uint32_T

cuint8_T

localC

real32_T

uint64_T

cuint16_T

localDWork

real64_T

UNUSED_PARAMETER

cuint32_T

localP

RT

USE_RTMODEL

ERT

localX

RT_MALLOC

VCAST_FLUSH_DATA

false

localXdis

rtInf

vector

FALSE

localXdot

rtMinusInf

uint8_T

Simulink Coder Code Replacement Library Keywords. The list of
code replacement library (CRL) reserved keywords for your development
environment varies depending on which CRLs currently are registered.
Beyond the default ANSI, ISO, and GNU CRLs provided with Simulink
Coder software, additional CRLs might be registered and available for use if
you have installed other products that provide CRLs (for example, a target
product), or if you have used Embedded Coder APIs to create and register
custom CRLs.

9-76

Code Appearance

To generate a list of reserved keywords for CRLs currently registered in your
environment, use the following MATLAB function:
crl_ids = RTW.TargetRegistry.getInstance.getTflReservedIdentifiers()

This function returns an array of CRL keyword strings. Specifying the return
argument is optional.
Note To list the CRLs currently registered in your environment, use the
MATLAB command RTW.viewTfl.
To generate a list of reserved keywords for the CRL that you are using to
generate code, call the function passing the name of the CRL as displayed in
the Code replacement library menu on the Code Generation > Interface
pane of the Configuration Parameters dialog box. For example,
crl_ids = RTW.TargetRegistry.getInstance.getTflReservedIdentifiers('GNU99 (GNU)')

Here is a partial example of the function output:
>> crl_ids = RTW.TargetRegistry.getInstance.getTflReservedIdentifiers('GNU99 (GNU)')
crl_ids =
'exp10'
'exp10f'
'acosf'
'acoshf'
'asinf'
'asinhf'
'atanf'
'atanhf'
...
'rt_lu_cplx'
'rt_lu_cplx_sgl'
'rt_lu_real'
'rt_lu_real_sgl'
'rt_mod_boolean'
'rt_rem_boolean'

9-77

9

Configuration

'strcpy'
'utAssert'

Note Some of the returned keyword strings appear with the suffix
$N, for example, 'rt_atan2$N'. $N expands into the suffix _snf only if
nonfinite numbers are supported. For example, 'rt_atan2$N' represents
'rt_atan2_snf' if nonfinite numbers are supported and 'rt_atan2' if
nonfinite numbers are not supported. As a precaution, you should treat both
forms of the keyword as reserved.

Construction of Symbols
For GRT, GRT-malloc and RSim targets, the Simulink Coder code generator
automatically constructs identifiers for variables and functions in the
generated code. These symbols identify
• Signals and parameters that have Auto storage class
• Subsystem function names that are not user defined
• Stateflow names
The components of a generated symbol include
• The root model name, followed by
• The name of the generating object (signal, parameter, state, and so on),
followed by
• A unique name mangling string
The name mangling string is conditionally generated to resolve potential
conflicts with other generated symbols.
The length of generated symbols is limited by the Maximum identifier
length parameter specified on the Symbols pane of the Configuration
Parameters dialog box. When there is a potential name collision between two
symbols, a name mangling string is generated. The string has the minimum
number of characters required to avoid the collision. The other symbol
components are then inserted. If Maximum identifier length is not large

9-78

Code Appearance

enough to accommodate full expansions of the other components, they are
truncated. To avoid this outcome, it is good practice to:
• Avoid name collisions. For example, avoid using default block names (for
example, Gain1, Gain2...) when the model includes multiple blocks of the
same type. Also, make subsystems atomic and reusable.
• Where possible, increase the Maximum identifier length parameter to
accommodate the length of the symbols you expect to generate.
Model referencing might involve additional naming constraints. Within a
model that uses referenced models, there can be no collisions between the
names of the models. When you generate code from a model that includes
referenced models, the Maximum identifier length parameter must be
large enough to accommodate the root model name and the name mangling
string (if needed). When a name conflict occurs between a symbol within the
scope of a higher-level model and a symbol within the scope of a referenced
model, the symbol from the referenced model is preserved. Name mangling is
performed on the symbol from the higher-level model. For information, see
“Configure Generated Identifiers” on page 9-73 and “Parameterize Model
References”.
The Embedded Coder product provides additional flexibility over how symbols
are constructed, by using a Symbol format field that controls the symbol
formatting in much greater detail. See “Configure Symbols” in the Embedded
Coder documentation for more information.

9-79

9

Configuration

Debug
Use parameters on the Diagnostics and Code Generation > Debug panes
of the Configuration Parameter dialog box to configure a model such that
generated code and the build process are optimized for debugging. You can set
parameters that apply to the model compilation phase, the target language
code generation phase, or both.
Parameters in the following table will be helpful if you are writing TLC code
for customizing targets, integrating legacy code, or developing new blocks.

9-80

To...

Select...

Display progress
information during
code generation
in the MATLAB
Command Window

Verbose build.Compiler output also displays.

Prevent the
build process
from deleting the
model.rtw file from
the build folder at
the end of the build

Retain .rtw file. This parameter is useful if you are
modifying the target files, in which case you need to
look at the model.rtw file.

Instruct the TLC
profiler to analyze
the performance
of TLC code
executed during
code generation
and generate a
report

Profile TLC. The report is in HTML format and can
be read in your Web browser.

Start the TLC
debugger during
code generation

Start TLC debugger when generating code.
Alternatively, enter the argument -dc for the System
target file parameter on the Code Generation
pane. To start the debugger and run a debugger
script, enter -df filename for System target file.

Debug

To...

Select...

Generate a
report containing
statistics indicating
how many times
the Simulink Coder
code generator
reads each line of
TLC code during
code generation

Start TLC coverage when generating code.
Alternatively, enter the argument -dg for the System
Target File parameter on the Code Generation
pane.

Halt a build if any
user-supplied TLC
file contains an
%assert directive
that evaluates to

Enable TLC assertion. Alternatively, you can
use MATLAB commands to control TLC assertion
handling. To set the flag on or off, use the set_param
command. The default is off.

FALSE

set_param(model, 'TLCAssertion', 'on|off')

To check the current setting, use get_param.
get_param(model, 'TLCAssertion')

Detect loss of
tunability

Diagnostics > Data Validity > Detect loss of
tunability. You can use this parameter to report
loss of tunability when an expression is reduced to
a numeric expression. This can occur if a tunable
workspace variable is modified by Mask Initialization
code, or is used in an arithmetic expression with
unsupported operators or functions. Possible values
are:
• none — Loss of tunability can occur without
notification.
• warning — Loss of tunability generates a warning
(default).
• error — Loss of tunability generates an error.

9-81

9

Configuration

To...

Select...

For a list of supported operators and functions, see
“Tunable Expression Limitations” on page 15-131
Enable model
verification
(assertion) blocks

Diagnostics > Data Validity > Model
Verification block enabling . Use this parameter
to enable or disable model verification blocks such
as Assert, Check Static Gap, and related range
check blocks. The diagnostic has the same affect on
generated code as it does on simulation behavior. For
example, simulation and code generation ignore this
parameter when model verification blocks are inside
an S-function. Possible values are:
• User local settings
• Enable All
• Disable All
For Assertion blocks not disabled, generated code for
a model includes one of the following statements,
depending on the blocks input signal type (Boolean,
real, or integer, respectively).
utAssert(input_signal);
utAssert(input_signal != 0.0);
utAssert(input_signal != 0);

By default, utAssert has no effect in generated code.
For assertions to abort execution, you must enable
them by specifying the following make_rtw command
for Code Generation > Make command:
make_rtw OPTS="-DDOASSERTS"

Use the following variant if you want triggered
assertions to print the assertion statement instead of
aborting execution:

9-82

Debug

To...

Select...

make_rtw OPTS="-DDOASSERTS -DPRINT_ASSERTS"

utAssert is defined as #define utAssert(exp)
assert(exp).
To customize assertion behavior, provide your own
definition of utAssert in a handwritten header
file that overrides the default utAssert.h. For
details on how to include a customized header file in
generated code, see “Configure Model for External
Code Integration” on page 14-33.
When running a model in accelerator mode, the
Simulink engine calls back to itself to execute
assertion blocks instead of using generated code.
Thus, user-defined callbacks are still called when
assertions fail.
For more information about the TLC debugging options, see “Debugging”.
Also, consider using the Model Advisor as a tool for troubleshooting model
builds.
For descriptions of Debug pane parameters, see “Code Generation Pane:
Debug” in the Simulink Coder reference documentation.

9-83

9

9-84

Configuration

10
Source Code Generation
• “Initiate Code Generation” on page 10-2
• “Reload Generated Code” on page 10-3
• “Generated Source Files and File Dependencies” on page 10-4
• “Files and Folders Created by Build Process” on page 10-24
• “How Code Is Generated From a Model” on page 10-31
• “Code Generation of Matrices and Arrays” on page 10-33
• “Shared Utility Code” on page 10-37
• “Generating Code Using Simulink Coder™” on page 10-49

10

Source Code Generation

Initiate Code Generation
You can generate code for your model with or without the compilation,
linking, and other processing that occurs as part of a full model build. To
generate code without initiating a full model build, select the Generate code
only option on the Code Generation pane of the Configuration Parameters
dialog box and click Generate Code. To initiate a full model build, clear the
Generate code only option and click the Build button, or use any of the
methods described in “Initiate the Build Process” on page 15-14.

10-2

Reload Generated Code

Reload Generated Code
You can reload the code generated for a model from the Model Explorer.
1 Click the Code for model node in the Model Hierarchy pane.
2 In the Code pane, click the Refresh link.

The Simulink Coder software reloads the code for the model from the
build folder.

10-3

10

Source Code Generation

Generated Source Files and File Dependencies
In this section...
“About Generated Files and File Dependencies” on page 10-4
“Header Dependencies When Interfacing Legacy/Custom Code with
Generated Code” on page 10-6
“Dependencies of the Generated Code” on page 10-16
“Specify Include Paths in Simulink® Coder™ Generated Source Files” on
page 10-21

About Generated Files and File Dependencies
The Simulink Coder software generates code into a set of source files that vary
little among different targets. Not all possible files are generated for every
model. Some files are created only when the model includes subsystems, calls
external interfaces, or uses particular types of data. The Simulink Coder code
generator handles most of the code formatting decisions (such as identifier
construction and code packaging) in consistent ways.
The source and make files created during the Simulink Coder build process
are generated into your build folder, which is created or reused in your
current folder. Some files are unconditionally generated, while the existence
of others depend on target settings and options (for example, support files for
C API or external mode). See “Files and Folders Created by Build Process” on
page 10-24 for descriptions of the generated files.
Note The file packaging of Embedded Coder targets differs slightly from
the file packaging described below. See “Generate Code Modules” in the
Embedded Coder documentation for more information.
Generated source file dependencies are depicted in the next figure. Arrows
coming from a file point to files it includes. Other dependencies exist, for
example on Simulink header files tmwtypes.h and simstruc_types.h, plus C
or C++ library files. The figure maps inclusion relations between only those
files that are generated in the build folder. Utility and model reference code

10-4

Generated Source Files and File Dependencies

located in a project folder might also be referenced by these files. See “Project
Folder Structure for Model Reference Targets” on page 3-16 for details.
The figure shows that parent system header files (model.h) include all child
subsystem header files (subsystem.h). In more layered models, subsystems
similarly include their children’s header files, on down the model hierarchy.
As a consequence, subsystems are able to recursively “see” into their
descendants’ subsystems, as well as to see into the root system (because every
subsystem.c or subsystem.cpp includes model.h and model_private.h).

model_private.h

model.c

subsystem.c

model_data.c

subsystem.h

rtmodel.h is a
dummy include
file used only
for grt and
grt_malloc targets.

model_types.h

model.h

rtmodel.h
Simulink® Coder™ Generated File Dependencies

Note In the preceding figure, files model.h, model_private.h, and
subsystem.h also depend on the Simulink Coder header file rtwtypes.h.
Targets that are not based on the ERT target can have additional
dependencies on tmwtypes.h and simstruct_types.h.

10-5

10

Source Code Generation

Header Dependencies When Interfacing
Legacy/Custom Code with Generated Code
You can incorporate legacy or custom code into a Simulink Coder build in any
of several ways. One common approach is by creating S-functions. For details
on this approach, see “Insert S-Function Code” on page 14-46.
Another approach is to interface code using global variables created
by declaring storage classes for signals and parameters. This requires
customizing an outer code harness, typically referred to as a main.c or
main.cpp file, to properly execute to the generated code. In addition, the
harness can contain custom code.
These scenarios require you to include header files specific to the Simulink
Coder product to make available function declarations, type definitions, and
defines to the legacy or custom code.

rtwtypes.h
The header file rtwtypes.h defines data types, structures, and macros
required by the generated code. Normally, you should include rtwtypes.h
for both GRT and ERT targets instead of including tmwtypes.h or
simstruc_types.h. However, the contents of the header file varies depending
on your target selection.
For...

rtwtypes.h

GRT target

Provides a complete set of definitions by including
tmwtypes.h and simstruct_types.h, both of which
depend on
• System headers limits.h and float.h
• Simulink Coder headers: rtw_matlogging.h,
rtw_extmode.h, rtw_continuous.h, and
rtw_solver.h

ERT target and
targets based on
the ERT target

10-6

Is optimized, when possible, to include a minimum set
of #define statements, enumerations, and so on; does
not include tmwtypes.h and simstruct_types.h

Generated Source Files and File Dependencies

The Simulink Coder build process generates the optimized version of
rtwtypes.h for the ERT target when both of the following conditions exist:
• The Classic call interface option on the Code Generation > Interface
pane of the Configuration Parameters dialog box is cleared.
• The model contains no noninlined S-functions
You should always include rtwtypes.h. If you include it for GRT targets, for
example, it is easier to use your code with ERT-based targets.
rtwtypes.h for GRT targets:
#ifndef __RTWTYPES_H__
#define __RTWTYPES_H__
#include "tmwtypes.h"
/* This ID is used to detect inclusion of an incompatible
* rtwtypes.h
*/
#define RTWTYPES_ID_C08S16I32L32N32F1
#include "simstruc_types.h"
#ifndef POINTER_T
# define POINTER_T
typedef void * pointer_T;
#endif
#ifndef TRUE
# define TRUE (1)
#endif
#ifndef FALSE
# define FALSE (0)
#endif
#endif
Top of rtwtypes.h for ERT targets:
#ifndef __RTWTYPES_H__
#define __RTWTYPES_H__
#ifndef __TMWTYPES__
#define __TMWTYPES__

10-7

10

Source Code Generation

#include 
/*=======================================================================*
* Target hardware information
*

Device type: 32-bit Generic

*

Number of bits:

*

char:

8

long:

32

short:

int:

32

native word size:

16

32

*

Byte ordering: Unspecified

*

Signed integer division rounds to: Undefined

*

Shift right on a signed integer as arithmetic shift: on

*=======================================================================*/
/* This ID is used to detect inclusion of an incompatible rtwtypes.h */
#define RTWTYPES_ID_C08S16I32L32N32F1
/*=======================================================================*
* Fixed width word size data types:

*

*

int8_T, int16_T, int32_T

- signed 8, 16, or 32 bit integers

*

*

uint8_T, uint16_T, uint32_T

- unsigned 8, 16, or 32 bit integers

*

*

real32_T, real64_T

- 32 and 64 bit floating point numbers *

*=======================================================================*/
typedef signed char int8_T;
typedef unsigned char uint8_T;
typedef short int16_T;
typedef unsigned short uint16_T;
typedef int int32_T;
typedef unsigned int uint32_T;
typedef float real32_T;
typedef double real64_T;
. . .

For GRT and ERT targets, the location of rtwtypes.h depends on
whether the build uses the shared utilities location. If you use a
shared location, the Simulink Coder build process places rtwtypes.h in
slprj/target/_sharedutils; otherwise, it places rtwtypes.h in the
standard build folder (model_target_rtw). See “Logging” on page 15-105 for
more information on when and how to use the shared utilities location.

10-8

Generated Source Files and File Dependencies

The header file rtwtypes.h should be included by source files that use
Simulink Coder type names or other Simulink Coder definitions. A typical
example is for files that declare variables using a Simulink Coder data type,
for example, uint32_T myvar;.
A source file that is intended to be used by the Simulink Coder product and by
a Simulink S-function can leverage the preprocessor macro MATLAB_MEX_FILE,
which is defined by the mex function:
#ifdef MATLAB_MEX_FILE
#include "tmwtypes.h"
#else
#include "rtwtypes.h"
#endif

A source file meant to be used as the Simulink Coder main.c (or .cpp) file
would also include rtwtypes.h without any preprocessor checks.
#include "rtwtypes.h"

Custom source files that are generated using the Target Language Compiler
can also emit these include statements into their generated file.

model.h
The header file model.h declares model data structures and a public interface
to the model entry points and data structures. This header file also provides
an interface to the real-time model data structure (model_M) by using access
macros. If your code interfaces to model functions or model data structures,
as illustrated below, you should include model.h:
• Exported global signals
extern int32_T INPUT;

/* '/In' */

• Global structure definitions
/* Block parameters (auto storage) */
extern Parameters_mymodel mymodel_P;

• RTM macro definitions

10-9

10

Source Code Generation

#ifndef rtmGetSampleTime
# define rtmGetSampleTime(rtm, idx)
((rtm)->Timing.sampleTimes[idx])
#endif

• Model entry point functions (ERT example)
extern void mymodel_initialize(void);
extern void mymodel_step(void);
extern void mymodel_terminate(void);

A Simulink Coder target’s main.c (or .cpp) file should include model.h. If
the main.c (or .cpp) file is generated from a TLC script, the TLC source
can include model.h using:
#include "%.h"

If main.c or main.cpp is a static source file, a fixed header filename can be
used, rtmodel.h for GRT or autobuild.h for ERT. These files include the
model.h header file:
#include "model.h"

/* If main.c is generated */

or
#include "rtmodel.h"

/* If static main.c is used with GRT */

or
#include "autobuild.h" /* If static main.c is used with ERT */

Other custom source files might need to include model.h to interface to model
data, for example exported global parameters or signals. The model.h file
itself can have additional header dependencies, as listed in the tables System
Header Files on page 10-11 and Simulink® Coder™ Header Files on page
10-13, due to requirements of generated code.

10-10

Generated Source Files and File Dependencies

System Header Files
Header File

Purpose

GRT Targets

ERT Targets



Defines math
constants

Not included

Included when generated code
honors the Stop time solver
configuration parameter due to
one of the following Simulink
Coder interface option settings:
• MAT-file logging selected
• Interface set to External
mode



Provides
floating-point math
functions

Included when the
model contains
a floating-point
math function

Included when the model
contains a floating-point math
function that is not overridden by
an entry in the code replacement
library (CRL) selected for the
model
For more information about
CRLs, see “Selecting and
Viewing Code Replacement
Libraries” on page 9-61 in this
chapter, and the CRL chapter
in the Embedded Coder User’s
Guide.



Defines NULL

Included when the
model contains a
utility function
that needs it

Included when the model
contains a utility function that
needs it



Provides file I/O
functions

Included when the
model includes a
To File block

Included when the
model includes a To File
block, or you open the
Configuration Parameters
dialog box and select Code
Generation > Interface > MAT-file
logging. See “MAT-file
logging”.

10-11

10

Source Code Generation

System Header Files (Continued)
Header File

Purpose

GRT Targets

ERT Targets



Provides utility
functions such as
div() and abs()

Included when the
model includes
• A Stateflow
chart

Included when the model
includes
• A Stateflow chart and
you select the Support
floating-point numbers
Simulink Coder interface
configuration parameter

• A Math
Function block
configured for
mod() or rem(),
which generate
calls to div()


Provides memory
functions such
as memset() and
memcpy()

Always included
due to use of
memset() in model
initialization code

• A Math Function block
configured for mod() or rem(),
which generate calls to div()
Included when block or model
initialization code calls memcpy()
or memset()
For a list of relevant blocks,
enter showblockdatatypetable
in the MATLAB Command
Window and look for blocks with
the N2 note.
To omit calls to memset()
from model initialization code,
select the Remove root level
I/O zero initialization and
Remove internal data zero
initialization optimization
configuration parameters.

10-12

Generated Source Files and File Dependencies

Simulink Coder Header Files
Header File

Purpose

GRT Targets

ERT Targets

dt_info.h

Defines data
structures for
external mode

Included when you
configure a model
for external mode

Included when you configure a
model for external mode

ext_work.h

Defines external
mode functions

Included when you
configure a model
for external mode

Included when you configure a
model for external mode

fixedpoint.h

Provides
fixed-point support
for noninlined
S-functions

Always included

Included when either of the
following conditions exists:
• The model uses noninlined
S-functions
• You select the Simulink
Coder interface configuration
parameter Classic call
interface

model_types.h

Defines
model-specific data
types

Always included

Always included

rt_logging.h

Supports MAT-file
logging

Always included

Included when you open the
Configuration Parameters
dialog box and select Code
Generation > Interface > MAT-file
logging. See “MAT-file logging”.

rt_nonfinite.h

Provides support
for nonfinite
numbers in the
generated code

Always included

Included when you select one
of the following Simulink
Coder interface configuration
parameters:
• MAT-file logging
• Support non-finite
numbers (and the generated
code requires nonfinite
numbers)

10-13

10

Source Code Generation

Simulink Coder Header Files (Continued)
Header File

Purpose

rtw_continuous.h Supports

continuous time

rtw_extmode.h

Supports external
mode

rtw_matlogging.h Supports MAT-file

logging

GRT Targets

ERT Targets

Included when you select
the Simulink Coder interface
simstruc_types.h configuration parameter
Support continuous time
and simstruc.h is not already
included
Always
included by

Always
included by

Included when you configure
the model for external mode
simstruc_types.h and simstruc.h is not already
included
Included by

Included by rtw_logging.h

simstruc_types.h

and
rtw_logging.h

rtw_solver.h

Supports
continuous states

Included when you select
the Simulink Coder interface
simstruc_types.h configuration parameter
Support floating-point
numbers and simstruc.h is not
already included

rtwtypes.h

Defines Simulink
Coder data types;
generated file

Always included;
use the complete
version of the file,
which includes
tmwtypes.h and

Always
included by

simstruc_types.h

(see
simstruc_types.h

for dependencies)

10-14

Always included; use the
complete or optimized version
of the file as explained in
“rtwtypes.h” on page 10-6

Generated Source Files and File Dependencies

Simulink Coder Header Files (Continued)
Header File

Purpose

GRT Targets

ERT Targets

simstruc.h

Provides support
for calling
noninlined
S-functions that
use the Simstruct
definition; also
includes limits.h,
string.h,
tmwtypes.h, and

Always included

Included when either of the
following conditions exists:
• The model uses noninlined
S-functions
• You select the Simulink
Coder interface configuration
parameter Classic call
interface

simstruc_types.h
simstruc_types.h Provides

definitions used by
generated code
and includes
the header files

Always included
with rtwtypes.h

Not included; rtwtypes.h
contains definitions and model.h
contains header files

rtw_matlogging.h,
rtw_extmode.h,
rtw_continuous.h,
rtw_solver.h, and
sysran_types.h
sysran_types.h

Supports external
mode

Always
included by

Included when you configure
the model for external mode
simstruc_types.h and simstruc.h is not already
included

Note Header file dependencies noted in the preceding table apply to the
system target files grt.tlc and ert.tlc. Targets derived from these base
targets may have additional header dependencies. Also, code generation
for blocks from blocksets, embedded targets, and custom S-functions may
introduce additional header dependencies.

10-15

10

Source Code Generation

Dependencies of the Generated Code
The Simulink Coder software can directly build standalone executables for
the host system such as when using the GRT target. Several processor- and
operating system-specific targets also provide automated builds using a
cross-compiler. All of these targets are typically makefile-based interfaces for
which the Simulink Coder software provides a “Template MakeFile (TMF) to
makefile” conversion capability. Part of this conversion process is to include,
in the generated makefile, source file, header file, and library file information
(the dependencies) for a compilation.
In other instances, the generated model code needs to be integrated into a
specific application. Or, it may be desired to enter the generated files and
any file dependencies into a configuration management system. This section
discusses the various aspects of the generated code dependencies and how to
determine them.
Typically, the generated code for a model consists of a small set of files:
• model.c or model.cpp
• model.h
• model_data.c or model_data.cpp
• model_private.h
• rtwtypes.h
These are generated in the build folder for a standalone model or a subfolder
under the slprj folder for a model reference target. There is also a top-level
main.c (or .cpp) file that calls the top model functions to execute the model.
main.c (or .cpp) is a static (not generated) file (such as grt_main.c or
grt_main.cpp for GRT-based targets), and is either a static file (ert_main.c
or ert_main.cpp) or is dynamically generated for ERT-based targets.
The preceding files also have dependencies on other files, which occur due to:
• Including other header files
• Using macros declared in other header files
• Calling functions declared in other source files

10-16

Generated Source Files and File Dependencies

• Accessing variables declared in other source files
These dependencies are introduced for a number of reasons such as:
• Blocks in a model generate code that makes function calls. This can occur
in several forms:

-

The called functions are declared in other source files. In some cases
such as a blockset, these source file dependencies are typically managed
by compiling them into a library file.

-

In other cases, the called functions are provided by the compilers own
run-time library, such as for functions in the ANSI12 C header, math.h.

-

Some function dependencies are themselves generated files. Some
examples are for fixed-point utilities and nonfinite support. These
dependencies are referred to as shared utilities. The generated functions
can appear in files in the build folder for standalone models or in the
_sharedutils folder under the slprj folder for builds that involve
model reference.

• Models with continuous time require solver source code files.
• Simulink Coder options such as external mode, C API, and MAT-file
logging are examples that trigger additional dependencies.
• Specifying custom code can introduce dependencies.

Providing the Dependencies
The Simulink Coder product provides several mechanisms for feeding
file dependency information into the Simulink Coder build process. The
mechanisms available to you depend on whether your dependencies are block
based or are model or target based.
For block dependencies, consider using
• S-functions and blocksets

-

folders that contain S-function MEX-files used by a model are added
to the header include path.

12. ANSI® is a registered trademark of the American National Standards Institute, Inc.

10-17

10

Source Code Generation

-

Makefile rules are created for these folders to allow source code to be
found.

-

For S-functions that are not inlined with a TLC file, the S-function
source filename is added to the list of sources to compile.

-

The S-Function block parameter SFunctionModules provides the ability
to specify additional source filenames.

-

The rtwmakecfg.m mechanism provides further capability in specifying
dependencies. See “Use rtwmakecfg.m API to Customize Generated
Makefiles” on page 14-124 for more information.

For more information on applying these approaches to legacy or custom
code integration, see “Integrate External Code Using Legacy Code Tool” on
page 14-28.
• S-Function Builder block, which provides its own GUI for specifying
dependency information
For model- or target-based dependencies, such as custom header files,
consider using
• The Code Generation > Custom Code pane of the Configuration
Parameters dialog box, which provides the ability to specify additional
libraries, source files, and include folders.
• TLC functions LibAddToCommonIncludes() and LibAddToModelSources(),
which allow you to specify dependencies during the TLC
phase. See “LibAddToCommonIncludes(incFileName)” and
“LibAddSourceFileCustomSection
(file, builtInSection, newSection)” in the Target Language Compiler
documentation for details. The Embedded Coder product also provides a
TLC-based customization template capability for generating additional
source files.

Makefile Considerations
As previously mentioned, Simulink Coder targets are typically makefile
based and the Simulink Coder product provides a “Template MakeFile (TMF)
to makefile” conversion capability. The template makefile contains a token
expansion mechanism in which the build process expands different tokens in
the makefile to include the additional dependency information. The resulting

10-18

Generated Source Files and File Dependencies

makefile contains the complete dependency information. See “Customize
Template Makefiles” on page 24-75 for more information on working with
template makefiles.
The generated makefile contains the following information:
• Names of the source file dependencies (by using various SRC variables)
• folders where source files are located (by using unique rules)
• Location of the header files (by using the INCLUDE variables)
• Precompiled library dependencies (by using the LIB variables)
• Libraries which need to be compiled and created (by using rules and the
LIB variables)
A property of make utilities is that the specific location for a given source C or
C++ file does not need to be specified. If a rule exists for that folder and the
source filename is a prerequisite in the makefile, the make utility can find
the source file and compile it. Similarly, the C or C++ compiler (preprocessor)
does not require absolute paths to the headers. Given the name of header
file by using an #include directive and an include path, it is able to find
the header. The generated C or C++ source code depends on this standard
compiler capability.
Also, libraries are typically created and linked against, but occlude the
specific functions that are being used.
Although the build process succeeds and can create a minimum-size
executable, these properties can make it difficult to manually determine the
minimum list of file dependencies along with their fully qualified paths. The
makefile can be used as a starting point to determining the dependencies
that the generated model code has.
An additional approach to determining the dependencies is by using linker
information, such as a linker map file, to determine the symbol dependencies.
The location of Simulink Coder and blockset source and header files is
provided below to assist in locating the dependencies.

10-19

10

Source Code Generation

Simulink Coder Static File Dependencies
Several locations in the MATLAB folder tree contain static file dependencies
specific to the Simulink Coder product:
• matlabroot/rtw/c/src/
This folder has subfolders and contains additional files that may need to be
compiled. Examples include solver functions (for continuous time support),
external mode support files, C API support files, and S-function support
files. Source files in this folder are included into the build process using in
the SRC variables of the makefile.
• matlabroot/rtw/extern/include/*.h
• matlabroot/simulink/include/*.h
These folders contain additional header file dependencies such as
tmwtypes.h, simstruc_types.h, and simstruc.h.
Note For ERT-based targets, several header dependencies from the above
locations can be avoided. ERT-based targets generate the minimum set of
type definitions, macros, and so on, in the file rtwtypes.h.

Blockset Static File Dependencies
Blockset products leverage the rtwmakecfg.m mechanism to provide the
Simulink Coder software with dependency information. As such, the
rtwmakecfg.m file provided by the blockset contains the listing of include path
and source path dependencies for the blockset. Typically, blocksets create a
library from the source files, which the generated model code can then link
against. The libraries are created and identified using the rtwmakecfg.m
mechanism.
To locate the rtwmakecfg.m files for blocksets in your MATLAB installed tree,
use the following command:
>> which -all rtwmakecfg.m

For example, for the DSP System Toolbox product, the which command
displays a path similar to the following:

10-20

Generated Source Files and File Dependencies

C:\Program Files\MATLAB\toolbox\dspblks\dspmex\rtwmakecfg.m

If the model being compiled uses one or more of the blocksets listed by the
which command, you can determine folder and file dependency information
from the respective rtwmakecfg.m file. For example, here is an excerpt of the
rtwmakecfg.m file for the DSP System Toolbox product.
function makeInfo=rtwmakecfg()
%RTWMAKECFG adds include and source directories to RTW make files.
%

makeInfo=RTWMAKECFG returns a structured array containing build info.

%

Please refer to the rtwmakecfg API section in the Simulink Coder

%

documentation for details on the format of this structure.

.
.
.
makeInfo.includePath = { ...
fullfile(matlabroot,'toolbox','dspblks','include') };
makeInfo.sourcePath = {};

Specify Include Paths in Simulink Coder Generated
Source Files
You can add #include statements to generated code. Such references can
come from several sources, including TLC scripts for inlining S-functions,
custom storage classes, bus objects, and data type objects. The included
files typically consist of header files for legacy code or other customizations.
Additionally, you can specify compiler include paths with the -I compiler
option. The Simulink Coder build process uses the specified paths to search
for included header files.
Usage scenarios for the generated code include, but are not limited to, the
following:
• Simulink Coder generated code is compiled with a custom build process
that requires an environment-specific set of #include statements.
In this scenario, the code generator is likely invoked with the Generate
code only check box selected. Consider using fully qualified paths, relative

10-21

10

Source Code Generation

paths, or just the header filenames in the #include statements, and
additionally leverage include paths.
• The generated code is compiled using the Simulink Coder build process.
In this case, compiler include paths (-I) can be provided to the Simulink
Coder build process in several ways:

-

The Code Generation > Custom Code pane of the Configuration
Parameters dialog box allows you to specify additional include paths.
The include paths are propagated into the generated makefile when the
template makefile (TMF) is converted to the actual makefile.

-

The rtwmakecfg.m mechanism allows S-functions to introduce additional
include paths into the Simulink Coder build process. The include paths
are propagated when the template makefile (TMF) is converted to the
actual makefile.

-

When building a custom Simulink Coder target that is makefile-based,
the desired include paths can be directly added into the targets template
makefile.

-

A USER_INCLUDES make variable that specifies a folder in which the
Simulink Coder build process should search for included files can be
specified on the Simulink Coder make command. For example,
make_rtw USER_INCLUDES=-Id:\work\feature1

The user includes are passed to the command-line invocation of the make
utility, which will add them to the overall flags passed to the compiler.

Recommended Approaches
The following are recommended approaches for using #include statements
and include paths in conjunction with the Simulink Coder build process to
generate code that remains portable and minimizes compatibility problems
with future versions.
Assume that additional header files are located at
c:\work\feature1\foo.h
c:\work\feature2\bar.h

10-22

Generated Source Files and File Dependencies

• A simple approach is to include in the #include statements only the
filename, such as
#include "foo.h"
#include "bar.h"

Then, the include path passed to the compiler should contain all folders in
which the headers files exist:
cc -Ic:\work\feature1 -Ic:\work\feature2

...

• A second recommended approach is to use relative paths in #include
statements and provide an anchor folder for these relative paths using an
include path, for example,
#include "feature1\foo.h"
#include "feature2\bar.h"

Then specify the anchor folder (for example \work) to the compiler:
cc -Ic:\work

...

Folder Dependencies to Avoid
When using the Simulink Coder build process, avoid dependencies on its
build and project folder structure, such as the model_ert_rtw build folder
or the slprj project folder. Thus, the #include statements should not just
be relative to where the generated source file exists. For example, if your
MATLAB current working folder is c:\work, a generated model.c source file
would be generated into a subfolder such as
c:\work\model_ert_rtw\model.c

The model.c file would have #include statements of the form
#include "..\feature1\foo.h"
#include "..\feature2\bar.h"

However, as this creates a dependency on the Simulink Coder folder structure,
you should instead use one of the approaches described above.

10-23

10

Source Code Generation

Files and Folders Created by Build Process
The following sections discuss
• “Files Created During the Build Process” on page 10-24
• “Folders Used During the Build Process” on page 10-28

Files Created During the Build Process
This section lists model.* files created during the code generation and build
process for the GRT and GRT malloc targets when used with stand-alone
models. Additional folders and files are created to support shared utilities
and model references.
The build process derives many of the files from the model file you create with
Simulink. You can think of the model file as a very high-level programming
language source file.
Note Files generated by the Embedded Coder build process are packaged
slightly differently. Depending on model architectures and code generation
options, the Simulink Coder build process might generate other files.
Descriptions of the principal generated files follow. Note that these
descriptions use the generic term model for the model name:
• model.rtw
An ASCII file, representing the compiled model, generated by the Simulink
Coder build process. This file is analogous to the object file created from a
high-level language source program. By default, the Simulink Coder build
process deletes this file when the build process is complete. However, you
can choose to retain the file for inspection.
• model.c
C source code that corresponds to the model file and is generated by the
Target Language Compiler. This file contains

-

10-24

Include files model.h and model_private.h

Files and Folders Created by Build Process

-

All data except data placed in model_data.c
Model-specific scheduler code
Model-specific solver code
Model registration code
Algorithm code
Optional GRT wrapper functions

• model.h
Defines model data structures and a public interface to the model entry
points and data structures. Also provides an interface to the real-time
model data structure (model_rtM) via access macros. model.h is included
by subsystem .c files in the model. It includes

-

Exported Simulink data symbols
Exported Stateflow machine parented data
Model data structures, including rtM
Model entry point functions

• model_private.h
Contains local define constants and local data required by the model
and subsystems. This file is included by the generated source files in the
model. You might need to include model_private.h when interfacing
legacy hand-written code to a model. See “Header Dependencies When
Interfacing Legacy/Custom Code with Generated Code” on page 10-6 for
more information. This header file contains

-

Imported Simulink data symbols
Imported Stateflow machine parented data
Stateflow entry points
Simulink Coder details (various macros, enums, and so forth that are
private to the code)

• model_types.h
Provides forward declarations for the real-time model data structure and
the parameters data structure. These structure might be used by function

10-25

10

Source Code Generation

declarations of reusable functions. model_types.h is included by all the
generated header files in the model.
• model_data.c
A conditionally generated C source code file containing declarations for
the parameters data structure and the constant block I/O data structure,
and any zero representations for structure data types that are used in the
model. If these data structures are not used in the model, model_data.c is
not generated. Note that these structures are declared extern in model.h.
When present, this file contains

-

Constant block I/O parameters

-

Constant parameters

Include files model.h and model_private.h
Definitions for the zero representations for any user-defined structure
data types used by the model

• model.exe (Microsoft Windows platforms) or model (UNIX platforms),
generated in the current folder, not in the build folder
Executable program file created under control of the make utility by your
development system (unless you have explicitly specified that Simulink
Coder generate code only and skip the rest of the build process)
• model.mk
Customized makefile generated by the Simulink Coder build process. This
file builds an executable program file.
• rtmodel.h
Contains #include directives required by static main program modules
such as grt_main.c and grt_malloc_main.c. Since these modules are
not created at code generation time, they include rt_model.h to access
model-specific data structures and entry points. If you create your own
main program module, take care to include rtmodel.h.
• rtwtypes.h
For GRT targets, a header file that includes simstruc_types.h, which,
in turn, includes tmwtypes.h. For Embedded Coder ERT targets,
rtwtypes.h provides the defines, enums, and so on, instead of including
tmwtypes.h and simstruc_types.h. The rtwtypes.h file generated for

10-26

Files and Folders Created by Build Process

ERT is an optimized (reduced) file based on the settings provided with the
model that is being built. See “Header Dependencies When Interfacing
Legacy/Custom Code with Generated Code” on page 10-6 in the Simulink
Coder documentation for more information.
• rt_nonfinite.c
C source file that declares and initializes global nonfinite values for inf,
minus inf, and nan. Nonfinite comparison functions are also provided.
This file is always generated for GRT-based targets and optionally
generated for other targets.
• rt_nonfinite.h
C header file that defines extern references to nonfinite variables and
functions. This file is always generated for GRT-based targets and
optionally generated for other targets.
• rtw_proj.tmw
Simulink Coder file generated for the make utility to use to determine
when to rebuild objects when the name of the current Simulink Coder
project changes
• model.bat
Windows batch file used to set up the compiler environment and invoke
the make command
• modelsources.txt
List of additional sources that should be included in the compilation.
Optional files:
• model_targ_data_map.m
MATLAB language file used by external mode to initialize the external
mode connection
• model_dt.h
C header file used for supporting external mode. Declares structures that
contain data type and data type transition information for generated model
data structures.
• subsystem.c

10-27

10

Source Code Generation

C source code for each noninlined nonvirtual subsystem or copy thereof
when the subsystem is configured to place code in a separate file
• subsystem.h
C header file containing exported symbols for noninlined nonvirtual
subsystems. Analogous to model.h.
• model_capi.h, model_capi.c
Header and sources file that contain data structures that describe the
model’s signals, states, and parameters without using external mode. See
“Data Interchange Using the C API” on page 15-137 in Simulink Coder
User’s Guide for more information.
• rt_sfcn_helper.h, rt_sfcn_helper.c
Header and source files providing functions usec by noninlined S-functions
in a model. The functions rt_CallSys, rt_enableSys, and rt_DisableSys
are used when noninlined S-functions call downstream function-call
subsystems.
In addition, when you select the Create code generation report check box,
the Simulink Coder software generates a set of HTML files (one for each
source file plus a model_contents.html index file) in the html subfolder
within your build folder.
The above source files have dependency relationships, and there are
additional file dependencies that you might need to take into account. These
are described in “Generated Source Files and File Dependencies” on page 10-4
in the Simulink Coder documentation.

Folders Used During the Build Process
The Simulink Coder build process places output files in three folders:
• The working folder
If you choose to generate an executable program file, the Simulink Coder
build process writes the file model.exe (Windows) or model (UNIX) to your
working folder.
• The build folder — model_target_rtw

10-28

Files and Folders Created by Build Process

A subfolder within your working folder. The build folder name is
model_target_rtw, where model is the name of the source model and
target is the selected target type (for example, grt for the generic real-time
target). The build folder stores generated source code and all other files
created during the build process (except the executable program file).
• Project folder — slprj
A subfolder within your working folder. When models referenced via Model
blocks are built for simulation or Simulink Coder code generation, files are
placed in slprj. The Embedded Coder configuration has an option that
places generated shared code in slprj without the use of model reference.
Subfolders in slprj provide separate places for simulation code, some
Simulink Coder code, utility code shared between models, and other files.
Of particular importance to Simulink Coder users are:

-

Header files from models referenced by this model
slprj/target/model/referenced_model_includes

-

Model reference Simulink Coder target files
slprj/target/model

-

MAT-files used during code generation of model reference
Simulink Coder target and stand-alone code generation
slprj/target/model/tmwinternal

-

Shared (fixed-point) utilities
slprj/target/_sharedutils

See “Work with Project Folders” on page 3-14 for more information on
organizing your files with respect to project folders.
The build folder always contains the generated code modules model.c,
model.h, and the generated makefile model.mk.

Depending on the target, code generation, and build options you select, the
build folder might also include
• model.rtw
• Object files (.obj or .o)

10-29

10

Source Code Generation

• Code modules generated from subsystems
• HTML summary reports of files generated (in the html subfolder)
• TLC profiler report files
• Block I/O, state, and parameter tuning information file (model_capi.c)
• Simulink Coder project (model.tmw) files
For additional information about using project folders, see “Project Folder
Structure for Model Reference Targets” on page 3-16 and “Customize Build to
Use Shared Utility Code” on page 22-34 in the Simulink Coder documentation.

10-30

How Code Is Generated From a Model

How Code Is Generated From a Model
In this section...
“Model Compilation” on page 10-31
“Code Generation” on page 10-31

Model Compilation
The build process begins with the Simulink software compiling the block
diagram. During this stage, Simulink
• Evaluates simulation and block parameters
• Propagates signal widths and sample times
• Determines the execution order of blocks within the model
• Computes work vector sizes, such as those used by S-functions. (For more
information about work vectors, see “DWork Vector Basics”).
When Simulink completes this processing, it compiles an intermediate
representation of the model. This intermediate description is stored in a
language-independent format in the ASCII file model.rtw. The model.rtw file
is the input to the next stage of the build process. For a general description
of the model.rtw file format, see “model.rtw file”.

Code Generation
The Simulink Coder code generator uses the Target Language Compiler (TLC)
and a supporting TLC function library to transform the intermediate model
description stored in model.rtw into target-specific code.
The target language compiled by the TLC is an interpreted programming
language designed to convert a model description to code. The TLC executes a
TLC program comprising several target files (.tlc scripts). The TLC scripts
specify how to generate code from the model, using the model.rtw file as input.
The TLC
1 Reads the model.rtw file

10-31

10

Source Code Generation

2 Compiles and executes commands in a system target file

The system target file is the entry point or main file. You select it from
those available on the MATLAB path with the system target file browser or
you can type the name of any such file on your system prior to building.
3 Compiles and executes commands in block-level target files

For blocks in the Simulink model, there is a corresponding target file that
is either dynamically generated or statically provided.
Note The Simulink Coder software executes all user-written S-function
target files, but optionally executes block target files for Simulink blocks.
4 Writes a source code version of the Simulink block diagram

10-32

Code Generation of Matrices and Arrays

Code Generation of Matrices and Arrays
In this section...
“Simulink® Coder™ Matrix Parameters” on page 10-34
“Internal Data Storage for Complex Number Arrays” on page 10-36
MATLAB, Simulink, and Simulink Coder software store matrix data and
arrays(1–D, 2–D, ...) in column-major format as a vector. Column-major
format orders elements in a matrix starting from the first column, top to
bottom, and then moving on to the next column. For example, the following
3x3 matrix:
A =
1
4
7

2
5
8

3
6
9

translates to an array of length 9 in the following order:
A(1)
A(2)
A(3)
A(4)
A(5)

=
=
=
=
=

A(1,1)
A(2,1)
A(3,1)
A(1,2)
A(2,2)

=
=
=
=
=

1;
4;
7;
2;
5;

and so on.
In column-major format, the next element of an array in memory is always
accessed by incrementing the first index of the array. For example, these
element pairs are stored sequentially in memory: A(i) and A(i+1), B(i,j)
and B(i+1,j), C(i,j,k) and C(i+1,j,k). For more information on the
internal representation of MATLAB data, see “MATLAB Data” in the
MATLAB External Interfaces document.
Code generation software uses column-major format for several reasons:
• The world of signal and array processing is largely column major:
MATLAB, LAPack, Fortran90, DSP libraries.

10-33

10

Source Code Generation

• A column is equivalent to a channel in frame-based processing. In this
case, column-major storage is more efficient.
• A column major array is self-consistent with its component submatrices:

-

A column major 2–D array is a simple concatenation of 1–D arrays.

-

Row-major n-D arrays have their stride of 1 for the highest dimension.
Any submatrix manipulations are typically accessing a scattered data
set in memory, which does not allow for efficient indexing.

A column major 3–D array is a simple concatenation of 2–D arrays.
The stride of the first dimension is always 1 element, where the stride
is the number of memory locations to index to the next element in the
same dimension. The stride of the n’th dimension element is always the
product of sizes of the lower dimensions.

Simulink Coder Matrix Parameters
The compiled model file, model.rtw, represents matrices as strings in
MATLAB syntax, with no implied storage format. This format allows you to
copy the string out of an .rtw file and paste it into a MATLAB file and have
it recognized by MATLAB.
Simulink Coder software declares Simulink block matrix parameters as
scalar or 1-D array variables
real_T scalar;
real_T mat[ nRows * nCols ];

where real_T can be any of the data types supported by Simulink, and
matches the variable type given in the model file.
For example, the 3-by-3 matrix in the 2–D Look-Up Table block
1
4
7

2
5
8

3
6
9

is stored in model.rtw as
Parameter {

10-34

Code Generation of Matrices and Arrays

Name
"OutputValues"
Value
Matrix(3,3)
[[1.0, 2.0, 3.0]; [4.0, 5.0, 6.0]; [7.0, 8.0, 9.0];]
String
"t"
StringType
"Variable"
ASTNode {
IsNonTerminal
0
Op
SL_NOT_INLINED
ModelParameterIdx
3
}
}

and results in this definition in model.h
typedef struct Parameters_tag {
real_T s1_Look_Up_Table_2_D_Table[9];
/* Variable:s1_Look_Up_Table_2_D_Table
* External Mode Tunable:yes
* Referenced by block:
* /Look-Up Table (2-D
*/
[ ... other parameter definitions ... ]
} Parameters;

The model.h file declares the actual storage for the matrix parameter and you
can see that the format is column-major.

1

2

3

4

5

6

7

8

9

Parameters model_P = {

10-35

10

Source Code Generation

/* 3 x 3 matrix s1_Look_Up_Table_2_D_Table */
{ 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 },
[ ... other parameter declarations ...]
};

Note C typically uses row-major format, while MATLAB and Simulink use
column-major format. The code generation software cannot be configured
to generate code with row-major ordering. If you are integrating other C
code with the generated code, you might need to transpose the data into
column-major format as a 1–D array.

Internal Data Storage for Complex Number Arrays
Simulink and Simulink Coder internal data storage formatting differs from
MATLAB internal data storage formatting only in the storage of complex
number arrays. In MATLAB, the real and imaginary parts are stored in
separate arrays. In the Simulink and Simulink Coder products they are
stored in an "interleaved" format, where the numbers in memory alternate
real, imaginary, real, imaginary, and so forth. This convention allows efficient
implementations of small signals on Simulink lines and for Mux blocks and
other "virtual" signal manipulation blocks (i.e., they don’t actively copy their
inputs, merely the references to them).

10-36

Shared Utility Code

Shared Utility Code
In this section...
“About Shared Utility Code” on page 10-37
“Controlling Shared Utility Code Placement” on page 10-38
“rtwtypes.h and Shared Utility Code” on page 10-38
“Incremental Shared Utility Code Generation and Compilation” on page
10-39
“Shared Utility Checksum” on page 10-39
“Shared Fixed-Point Utility Functions” on page 10-41
“Share User-Defined Data Types Across Models” on page 10-43

About Shared Utility Code
Blocks in a model can require common functionality to implement their
algorithm. In many cases, it is most efficient to modularize this functionality
into standalone support or helper functions, rather than inlining the code for
the functionally for each block instance.
Typically, functions that can have multiple callers are packaged into a library.
Traditionally, such functions are defined statically, that is, the function
source code exists in a file before you use the Simulink Coder software to
generate code for your model.
In other cases, several model- and block-specific properties can affect which
functions are used and their behavior. Additionally, these properties can
affect type definitions (for example, typedef) in shared utility header files.
Since there are many possible combinations of properties that determine
unique behavior, it is not practical to statically define all possible function
files before code generation. Instead, you can use the Simulink Coder shared
utility mechanism, which generates support functions during code generation
process.

10-37

10

Source Code Generation

Controlling Shared Utility Code Placement
You control the shared utility code placement mechanism with the Shared
code placement option on the Code Generation > Interface pane of the
Configuration Parameters dialog box. By default, the option is set to Auto.
For this setting, if the model being built does not include any Model blocks,
the Simulink Coder build process places any code required for fixed-point and
other utilities in one of the following:
• The model.c or model.cpp file
• In a separate file in the Simulink Coder build folder (for example,
vdp_grt_rtw)
Thus, the code is specific to the model.
If a model does contain Model blocks, the Simulink Coder build process
creates and uses a shared utilities folder within slprj. Model reference builds
require the use of shared utilities. The naming convention for shared utility
folders is slprj/target/_sharedutils, where target is sim for simulations
with Model blocks or the name of the system target file for Simulink Coder
target builds. Some examples follow:
slprj/sim/_sharedutils

% folder used with simulation

slprj/grt/_sharedutils

% folder used with grt.tlc STF

slprj/ert/_sharedutils

% folder used with ert.tlc STF

slprj/mytarget/_sharedutils % folder used with mytarget.tlc STF

To force a model build to use the slprj folder for shared utility generation,
even when the current model contains no Model blocks, set the Shared
code placements option to Shared location. This forces the Simulink
Coder build process to place utilities under the slprj folder rather than in
the normal Simulink Coder build folder. This setting is useful when you
are manually combining code from several models, as it prevents symbol
collisions between the models.

rtwtypes.h and Shared Utility Code
The generated header file rtwtypes.h provides defines, enumerations, and
so on. The location of this file is controlled by whether the build process
is using the shared utilities folder. Typically, the Simulink Coder build

10-38

Shared Utility Code

process places rtwtypes.h in the standard build folder, model_target_rtw.
However, if a shared folder is required, the product places rtwtypes.h in
slprj/target/_sharedutils.

Incremental Shared Utility Code Generation and
Compilation
As explained in “Controlling Shared Utility Code Placement” on page 10-38,
you can specify that C source files, which contain function definitions, and
header files, which contain macro definitions, be generated in a shared
utilities folder. For the purpose of this discussion, the term functions means
functions and macros.
A shared function can be used by blocks within the same model and by blocks
in different models when using model reference or when building multiple
standalone models from the same start build folder. However, the Simulink
Coder software generates the code for a given function only once for the block
that first triggers code generation. As the product determines the need to
generate function code for subsequent blocks, it performs a file existence
check. If the file exists, the function is not regenerated. Thus, the shared
utility code mechanism requires that a given function and file name represent
the same functional behavior regardless of which block or model generates
the function. To satisfy this requirement:
• Model properties that affect function behavior are included in a shared
utility checksum or affect the function and file name.
• Block properties that affect the function behavior also affect the function
and file name.
During compilation, makefile rules for the shared utilities folder are
configured to compile only new C files, and incrementally archive the object
file into the shared utility library, rtwshared.lib or rtwshared.a. Thus,
incremental compilation is also done.

Shared Utility Checksum
As explained in “Incremental Shared Utility Code Generation and
Compilation” on page 10-39, the Simulink Coder software uses the
shared utilities folder when you explicitly configure a model to use the

10-39

10

Source Code Generation

shared location or the model contains Model blocks. During the code
generation process, if relative to the current folder, the configuration file
slprj/target/_sharedutils/checksummap.mat exists, the product reads
that file and makes sure that the current model being built has identical
settings for the required model properties. If mismatches occur between the
properties defined in checksummap.mat and the current model properties,
a Warning dialog appears.

The following table lists properties that must match for the shared utility
checksum.

10-40

Category

Properties

Hardware
Implementation
configuration
properties

get_param(bdroot,
'TargetShiftRightIntArith')
get_param(bdroot, 'TargetEndianess')
get_param(bdroot, 'ProdEndianess')
get_param(bdroot, 'TargetBitPerChar')
get_param(bdroot, 'TargetBitPerShort')
get_param(bdroot, 'TargetBitPerInt')
get_param(bdroot, 'TargetBitPerLong')
get_param(bdroot, 'ProdHWWordLengths')
get_param(bdroot, 'TargetWordSize')
get_param(bdroot, 'ProdWordSize')
get_param(bdroot, 'TargetHWDeviceType')
get_param(bdroot, 'ProdHWDeviceType')

Shared Utility Code

Category

Properties
get_param(bdroot, 'TargetIntDivRoundTo')
get_param(bdroot, 'ProdIntDivRoundTo'

Additional
configuration
properties

get_param(bdroot, 'TargetLibSuffix')
get_param(bdroot, 'TargetLang')
get_param(bdroot, 'TemplateMakefile')

ERT target properties

get_param(bdroot, 'PurelyIntegerCode')
get_param(bdroot, 'SupportNonInlinedSFcns'

Platform property

Return value of the computer command

Shared Fixed-Point Utility Functions
An important set of generated functions that are placed in the shared utility
folder are the fixed-point support functions. Based on model and block
properties, there are many possible versions of fixed-point utilities functions
that make it impractical to provide a complete set as static files. Generating
only the required fixed-point utility functions during the code generation
process is an efficient alternative.
The shared utility checksum mechanism makes sure that several critical
properties are identical for all models that use the shared utilities. For the
fixed-point functions, there are additional properties that affect function
behavior. These properties are coded into the functions and file names to
maintain requirements. The additional properties include
Category

Function/Property

Block
properties

• Fixed-point operation being performed by the block
• Fixed-point data type and scaling (Slope, Bias) of
function inputs and outputs
• Overflow handling mode (Saturation, Wrap)
• Rounding Mode (Floor, Ceil, Zero)

Model
properties

get_param(bdroot, 'NoFixptDivByZeroProtection')

10-41

10

Source Code Generation

The naming convention for the fixed-point utilities is based on the properties
as follows:
operation + [zero protection] + output data type + output bits +
[input1 data] + input1 bits + [input2 data type + input2 bits] +
[shift direction] + [saturate mode] + [round mode]

Below are examples of generated fixed-point utility files, the function or
macro names in the file are identical to the file name without the extension.
FIX2FIX_U12_U16.c
FIX2FIX_S9_S9_SR99.c
ACCUM_POS_S30_S30.h
MUL_S30_S30_S16.h
div_nzp_s16s32_floor.c
div_s32_sat_floor.c

For these examples, the respective fields correspond as follows:
Operation

FIX2FIX

FIX2FIX

ACCUM_POS

MUL

div

div

Zero protection

NULL

NULL

NULL

NULL

_nzp

NULL

Output data type

_U

_S

_S

_S

_s

_s

Output bits

12

9

30

30

16

32

Input data type

_U

_S

_S

_S [and _S]

s

NULL

Input bits

16

9

30

30 [and 16]

32

NULL

Shift direction

NULL

SR99

NULL

NULL

NULL

NULL

Saturate mode

NULL

NULL

NULL

NULL

NULL

_sat

Round mode

NULL

NULL

NULL

NULL

_floor

_floor

Note For the ACCUM_POS example, the output variable is also used as one of
the input variables. Therefore, only the output and second input is contained
in the file and macro name. For the second div example, both inputs and
the output have identical data type and bits. Therefore, only the output is
included in the file and function name.

10-42

Shared Utility Code

Share User-Defined Data Types Across Models
• “About Sharing Data Types” on page 10-43
• “Example: Sharing Simulink Data Type Objects” on page 10-44
• “Example: Sharing Enumerated Data Types” on page 10-45

About Sharing Data Types
By default, user-defined data types that are shared among multiple models
generate duplicate type definitions in the model_types.h file for each
model. However, Simulink Coder software provides the ability to generate
user-defined data type definitions into a header file in the _sharedutils
folder that can be shared across multiple models, removing the need for
duplicate copies of the data type definitions. User-defined data types that you
can set up in a shared header file include:
• Simulink data type objects that you instantiate from the classes
Simulink.AliasType, Simulink.Bus, and Simulink.NumericType.
• Enumeration types that you define in MATLAB code
The general procedure for setting up user-defined data types to be shared
among multiple models is as follows:
1 Define the data type.
2 Set data scope and header file properties that allow the data type to be

shared.
3 Use the data type as a signal type in your models.
4 Before generating code for each model, set the Shared code placement

parameter on the Code Generation > Interface pane of the Configuration
Parameters dialog box to the value Shared location.
5 Generate code.

10-43

10

Source Code Generation

Note You can configure the definition of the user-defined data type
to occur in a header file that is located in the _sharedutils folder,
however user-defined data type names are not used by the shared utility
functions that are generated into the _sharedutils folder. Currently,
the user-defined data type names are used only by model code located in
code folders for each model.
For more information, see “Example: Sharing Simulink Data Type Objects” on
page 10-44 and “Example: Sharing Enumerated Data Types” on page 10-45.

Example: Sharing Simulink Data Type Objects
To export a user-defined Simulink data type object for sharing among
multiple models.
1 In the base workspace, create a data type object of one of the following

classes:
• Simulink.AliasType
• Simulink.Bus
• Simulink.NumericType
For example:
a = Simulink.AliasType
2 To specify that the data type should be exported to a specified header file,

use the data type object property DataScope. Specify the value 'Exported'
for the DataScope property. For example:
a.DataScope = 'Exported'
3 To specify the name of the header file to which the data type should be

exported, use the data type object property HeaderFile. For example:
a.HeaderFile = 'a.h'

Alternatively, if you leave the HeaderFile value empty, the name of the
generated header file defaults to the name of the data type, in this case, a.h.

10-44

Shared Utility Code

4 Use the data type object as a signal type in a model.
5 Before generating code, if you want to generate the header file into

the shared utilities folder for sharing definitions between multiple
models, set the Shared code placement parameter on the Code
Generation > Interface pane of the Configuration Parameters dialog
box to the value Shared location.
6 Generate code. Here is an example of the definition code that is generated

to a.h in the shared utilities folder:
#ifndef RTW_HEADER_a_h_
#define RTW_HEADER_a_h_
#include "rtwtypes.h"
typedef double a;
#endif

/* RTW_HEADER_a_h_ */

To share the data type definition from other models, the alternatives include:
• Simply use the same workspace variable in multiple models. If the contents
of the data type object are the same, generating code will not regenerate
the header file. For example, model A and model B can export the same
data type to the same header file in the shared utilities folder.
• Define the same data type object in other models, but set it up to import
the shared data type definition from the header file. Specify the value
'Imported' for the data type object property DataScope. For example:
a = Simulink.AliasType
a.DataScope = 'Imported'
a.HeaderFile = 'a.h'

Example: Sharing Enumerated Data Types
To export a user-defined enumerated data type for sharing among multiple
models:
1 Define an enumerated data type in MATLAB code. For example, the

following MATLAB file defines BasicColors:

10-45

10

Source Code Generation

% BasicColors.m
classdef(Enumeration) BasicColors < Simulink.IntEnumType
enumeration
Red(0)
Yellow(1)
Blue(2)
end
methods (Static = true)
function retVal = getDefaultValue()
retVal = BasicColors.Blue;
end
end
end
2 To specify that the data type should be exported to a specified header file,

you must override the default getDataScope method of the enumerated
class. Specify the value 'Exported' as the getDataScope return value.
For example:
methods (Static = true)
...
function retVal = getDataScope()
retVal = 'Exported';
end
...
end
3 To specify the name of the header file to which the data type should be

exported, you must override the default getHeaderFile method of the
enumerated class. Specify a file name as the getHeaderFile return value.
For example:
methods (Static = true)
...
function retVal = getHeaderFile()
retVal = 'BasicColors.h';
end
...
end

10-46

Shared Utility Code

Alternatively, if you leave the return value of the getHeaderFile method
unspecified, the name of the generated header file defaults to the name of
the data type, in this case, BasicColors.h.
4 Here is BasicColors.m after the data scope and header file changes.

% BasicColors.m
classdef(Enumeration) BasicColors < Simulink.IntEnumType
enumeration
Red(0)
Yellow(1)
Blue(2)
end
methods (Static = true)
function retVal = getDefaultValue()
retVal = BasicColors.Blue;
end
function retVal = getDataScope()
retVal = 'Exported';
end
function retVal = getHeaderFile()
retVal = 'BasicColors.h';
end
end
end

Make sure BasicColors.m is present in the MATLAB path.
5 Use the type enum:BasicColors as a signal type in a model.
6 Before generating code, if you want to generate the header file into

the shared utilities folder for sharing definitions between multiple
models, set the Shared code placement parameter on the Code
Generation > Interface pane of the Configuration Parameters dialog
box to the value Shared location.
7 Generate code. Here is an example of the definition code that is generated

to BasicColors.h in the shared utilities folder:
#ifndef RTW_HEADER_BasicColors_h
#define RTW_HEADER_BasicColors_h

10-47

10

Source Code Generation

/* Type definition for enum:BasicColors type */
typedef enum {
Red = 0,
Yellow,
Blue
} BasicColors;
#endif

To share the data type definition from other models, the alternatives include:
• Simply use the same enumerated type as a signal type in multiple models.
If the contents of the enumerated type are the same, generating code will
not regenerate the header file. For example, model A and model B can
export the same data type to the same header file in the shared utilities
folder.
• Define the same enumerated type in other models, but set it up to import
the shared data type definition from the header file. In the enumerated
type definition file, specify the value 'Imported' as the getDataScope
return value. For example:
methods (Static = true)
...
function retVal = getDataScope()
retVal = 'Imported';
end
...
end

10-48

Generating Code Using Simulink Coder™

Generating Code Using Simulink Coder™
This example shows how to select a target for a Simulink model, generate C
code for real-time simulation, and view generated files.
1. Open the model.
model='rtwdemo_rtwintro';
open_system(model)

2. Open the Configuration Parameters dialog box from the model editor by
clicking Simulation > Configuration Parameters.
Alternately, type the following commands at the MATLAB command prompt
cs = getActiveConfigSet(model);
openDialog(cs);

3. Select the Code Generation node.

10-49

10

Source Code Generation

4. In the Target Selection pane, click Browse to select a target.
You can generate code for a particular target environment or purpose. Some
built-in targeting options are provided using system target files, which control
the code generation process for a target.

10-50

Generating Code Using Simulink Coder™

5. Select the Generic Real-Time (GRT) target and click Apply.

10-51

10

Source Code Generation

Optionally, in the Code Generation Advisor pane set the Select objective
field to Execution efficiency or Debugging. Then click Check model... to
identify and systematically change parameters to meet your objectives.
6. In the Code Generation pane, click Build to generate code.

7. View the code generation report that appears.
The report includes links to model files such as rtwdemo_rtwintro.c and
associated utility and header files.

10-52

Generating Code Using Simulink Coder™

The figure below contains a portion of rtwdemo_rtwintro.c

10-53

10

10-54

Source Code Generation

Generating Code Using Simulink Coder™

8. Close the model.
bdclose(model)
rtwdemoclean;

10-55

10

10-56

Source Code Generation

11
Report Generation
• “Reports for Code Generation” on page 11-2
• “HTML Code Generation Report Location” on page 11-3
• “HTML Code Generation Report for Referenced Models” on page 11-4
• “Generate a Code Generation Report” on page 11-5
• “Generate Code Generation Report After Build Process” on page 11-6
• “Open Code Generation Report” on page 11-8
• “Generate Code Generation Report Programmatically” on page 11-10
• “Search in the Code Generation Report” on page 11-11
• “View Code Generation Report in Model Explorer” on page 11-12
• “Package and Share the Code Generation Report” on page 11-14
• “Document Generated Code with Simulink® Report Generator™” on page
11-16

11

Report Generation

Reports for Code Generation
Simulink Coder software provides an HTML code generation report so that
you can view and analyze the generated code. When your model is built, the
code generation process produces an HTML file that is displayed in an HTML
browser or in the Model Explorer. The code generation report includes:
• The Summary section lists version, date, and code generation objectives
information. The Configuration settings at the time of code
generation link opens a noneditable view of the Configuration Parameters
dialog box. The dialog box shows the Simulink model settings at the time of
code generation, including TLC options.
• The Subsystem Report section contains information on nonvirtual
subsystems in the model.
• In the Generated Files section on the Contents pane, you can click the
names of source code files generated from your model to view their contents
in a MATLAB Web browser window. In the displayed source code, global
variables are hypertext that links to their definitions.
• A Search box in the left navigation pane. For more information, see
“Search in the Code Generation Report” on page 11-11.
For an example, see “Generate a Code Generation Report” on page 11-5 and
“View Code Generation Report in Model Explorer” on page 11-12.
The contents of HTML reports varies depending on different target types. You
can generate individual HTML reports for a subsystem or referenced model.
For more information, see “HTML Code Generation Report for Referenced
Models” on page 11-4 and “Generate Code for Referenced Models” on page 3-4.
If you have a Simulink Report Generator license, you can document your
code generation project in multiple formats, including HTML, PDF, RTF,
Microsoft Word, and XML. For an example of how to create a Microsoft Word
report, see “Document Generated Code with Simulink® Report Generator™”
on page 11-16.

11-2

HTML Code Generation Report Location

HTML Code Generation Report Location
The default location for the code generation report files is in the html
subfolder of the build folder, model_target_rtw/html/. target is the name
of the System target file specified on the Code Generation pane. The
default name for the top-level HTML report file is model_codegen_rpt.html
or subsystem_codegen_rpt.html. For more information on the location of
the build folder, see “Control the Location for Generated Files” on page 5-18.

11-3

11

Report Generation

HTML Code Generation Report for Referenced Models
To generate a code generation report for a top model and code generation
reports for each referenced model, you need to specify the Create code
generation report on the Code Generation > Report pane for the top
model and each referenced model. You can open the code generation report of
a referenced model in one of two ways:
• From the top-model code generation report, you can access the referenced
model code generation report by clicking a link under Referenced Models
in the left navigation pane. Clicking a link opens the code generation
report for the referenced model in the browser. To navigate back to the top
model code generation report, use the Back button at the top of the left
navigation pane.
• From the referenced model diagram window, select Code > C/C++
Code > Code Generation Report > Open Model Report.
To generate a code generation report for a referenced model individually,
follow the instructions in “Generate a Code Generation Report” on page 11-5
and “Open Code Generation Report” on page 11-8 for the referenced model.

11-4

Generate a Code Generation Report

Generate a Code Generation Report
To generate a code generation report when the model is built:
1 In the model diagram window, select Code > C/C++ Code > Code

Generation Report > Options. The Configuration Parameters dialog box
opens with the Code Generation > Report pane visible.
2 Select the Create code generation report parameter.
3 If you want the code generation report to automatically open after

generating code, select the Open report automatically parameter (which
is enabled by selecting Create code generation report).
4 Generate code.

The build process writes the code generation report files to the html subfolder
of the build folder (see “HTML Code Generation Report Location” on page
11-3). Next, the build process automatically opens a MATLAB Web browser
window and displays the code generation report.
To open an HTML code generation report at any time after a build, see “Open
Code Generation Report” on page 11-8 and “Generate Code Generation Report
After Build Process” on page 11-6.

11-5

11

Report Generation

Generate Code Generation Report After Build Process
After generating code, if you did not configure your model to create a code
generation report, you can generate a code generation report without
rebuilding your model.
1 In the model diagram window, select Code > C/C++ Code > Code

Generation Report > Open Model Report.
2 If your current working folder contains the code generation files the

following dialog opens.

Click Generate Report.
3 If the code generation files are not in your current working directory, the

following dialog opens.

Enter the full path of the build folder for your model, ../model_target_rtw
and click Open Report.

11-6

Generate Code Generation Report After Build Process

The software generates a report from the code generation files in the build
folder you specified.
Note An alternative method for generating the report after the build
process is complete is to configure your model to generate a report and build
your model. In this case, Embedded Coder generates the report without
regenerating the code.

11-7

11

Report Generation

Open Code Generation Report
You can refer to existing code generation reports at any time. If you generated
a code generation report, you can open the report by selecting Code > C/C++
Code > Code Generation Report > Open Model Report. If you are
opening a report for a subsystem, select Open Subsystem Report.
If your current working folder does not contain the code generation files and
the code generation report, the following dialog opens:

Enter the full path of the build folder for your model, ../model_target_rtw
and click Open Report.
Alternatively, you can open the code generation report
(model_codegen_rpt.html or subsystem_codegen_rpt.html)
manually into a MATLAB Web browser window, or into another Web browser.
For the location of the generated report files, see “HTML Code Generation
Report Location” on page 11-3.

Limitation
If you modify legacy or custom code after building your model or generating
the code generation report, you must rebuild your model or regenerate the
report for the code generation report to include the updated legacy source files.
For example, if you modify your legacy code and then use the Code > C/C++
Code > Code Generation Report > Open Model Report menu to open
an existing report, the software does not check if the legacy source file is

11-8

Open Code Generation Report

out of date compared to the generated code. Therefore, the code generation
report is not regenerated and the report includes the out-of-date legacy
code. This issue also occurs if you open a code generation report using the
coder.report.open function.
To regenerate the code generation report, do one of the following:
• Rebuild your model.
• Generate the report using the coder.report.generate function.

11-9

11

Report Generation

Generate Code Generation Report Programmatically
At the MATLAB command line, you can generate, open, and close an HTML
Code Generation Report with the following functions:
• coder.report.generate generates the code generation report for the
specified model.
• coder.report.open opens an existing code generation report.
• coder.report.close closes the code generation report.

11-10

Search in the Code Generation Report

Search in the Code Generation Report
When the code generation report is displayed in the MATLAB Web browser
window, you can search the report using the Search box in the left navigation
pane. The search is not case sensitive.
Pressing Ctrl-F sets focus to the Search box. Type text into the Search
box and hit Enter to start the search. The search highlights any found
terms in the displayed page and scrolls to the first instance found. Press
Enter to scroll through the subsequent search hits. If no terms are found, the
background of the search box is highlighted red.

11-11

11

Report Generation

View Code Generation Report in Model Explorer
After generating an HTML code generation report, you can view the report
in the right pane of the Model Explorer. You can also browse the generated
files directly in the Model Explorer.
When you generate code, or open a model that has generated code for its
current target configuration in your working folder, the Hierarchy (left)
pane of Model Explorer contains a node named Code for model. Under that
node are other nodes, typically called This Model and Shared Code. Clicking
This Model displays in the Contents (middle) pane a list of generated source
code files in the build folder of that model. The next figure shows code for
the rtwdemo_counter model.

In this example, the file S:/rtwdemo_counter_grt_rtw/rtwdemo_counter.c
is being displayed. To view any file in the Contents pane, click it once.
The views in the Document (right) pane are read only. The code listings
there contain hyperlinks to functions and macros in the generated code.
Clicking the file hyperlink opens that source file in a text editing window
where you can modify its contents.

11-12

View Code Generation Report in Model Explorer

If an open model contains Model blocks, and if generated code for any of these
models exists in the current slprj folder, nodes for the referenced models
appear in the Hierarchy pane one level below the node for the top model.
Such referenced models do not need to be open for you to browse and read
their generated source files.
If the Simulink Coder software generates shared utility code for a model, a
node named Shared Code appears directly under the This Model node. It
collects any source files that exist in the ./slprj/target/_sharedutils
subfolder.
Note You cannot use the Search tool built into Model Explorer toolbar to
search generated code displayed in the Code Viewer. On PCs, typing Ctrl+F
when focused on the Document pane opens a Find dialog box that you can
use to search for strings in the currently displayed file. You can also search
for text in the HTML report window, and you can open any of the files in
the editor.

11-13

11

Report Generation

Package and Share the Code Generation Report
In this section...
“Package the Code Generation Report” on page 11-14
“View the Code Generation Report” on page 11-15

Package the Code Generation Report
To share the code generation report, you can package the code generation
report files and supporting files into a zip file for transfer. The default location
for the code generation report files is in two folders:
• /slprj
• html subfolder of the build folder, model_target_rtw, for example
rtwdemo_counter_grt_rtw/html

To create a zip file from the MATLAB command window:
1 In the Current Folder browser, select the two folders:

• /slprj
• Build folder: model_target_rtw
2 Right-click to open the context menu.
3 In the context menu, select Create Zip File. A file appears in the Current

Folder browser.
4 Name the zip file.

Alternatively, you can use the MATLAB zip command to zip the code
generation report files:
zip('myzip',{'slprj','rtwdemo_counter_grt_rtw'})

11-14

Package and Share the Code Generation Report

Note If you need to relocate the static and generated code files for a model
to another development environment, such as a system or an integrated
development environment (IDE) that does not include MATLAB and Simulink
products, use the Simulink Coder pack-and-go utility. For more information,
see “Relocate Code to Another Development Environment” on page 15-33.

View the Code Generation Report
To view the code generation report after transfer, unzip the file and save
the two folders at the same folder level in the hierarchy. Navigate to the
model_target_rtw/html/ folder and open the top-level HTML report file
named model_codgen_rpt.html or subsystem_codegen_rpt.html in a Web
browser.

11-15

11

Report Generation

Document Generated Code with Simulink Report
Generator
In this section...
“Generate Code for the Model” on page 11-17
“Open the Report Generator” on page 11-18
“Set Report Name, Location, and Format” on page 11-20
“Include Models and Subsystems in a Report” on page 11-21
“Customize the Report” on page 11-22
“Generate the Report” on page 11-23
The Simulink Report Generator software creates documentation from your
model in multiple formats, including HTML, PDF, RTF, Microsoft Word, and
XML. This example shows one way to document a code generation project in
Microsoft Word. The generated report includes:
• System snapshots (model and subsystem diagrams)
• Block execution order list
• Simulink Coder and model version information for generated code
• List of generated files
• Optimization configuration parameter settings
• Simulink Coder target selection and build process configuration parameter
settings
• Subsystem map
• File name, path, and generated code listings for the source code
To adjust Simulink Report Generator settings to include custom code and
then generate a report for a model, complete the following tasks:
1 “Generate Code for the Model” on page 11-17
2 “Open the Report Generator” on page 11-18

11-16

Document Generated Code with Simulink® Report Generator™

3 “Set Report Name, Location, and Format” on page 11-20
4 “Include Models and Subsystems in a Report” on page 11-21
5 “Customize the Report” on page 11-22
6 “Generate the Report” on page 11-23

For more information on generating other reports, see the Simulink Report
Generator User Guide.

Generate Code for the Model
Before you use the Report Generator to document your project, generate code
for the model.
1 In the MATLAB Current Folder browser, navigate to a folder where you

have write access.
2 Create a working folder from the MATLAB command line by typing:

mkdir report_ex
3 Make report_ex your working folder:

cd report_ex
4 Open the sldemo_f14 model by clicking the following model name below or

by entering the model name on the MATLAB command line.
5 In the model window, choose File > Save As, navigate to the working

folder, report_ex, and save a copy of the sldemo_f14 model as myf14.
6 Open the Model Explorer by selecting Model Explorer from the model

View menu.
7 In the Model Hierarchy pane, click the expander for the model name to

reveal its components.
8 In the left pane, click Configuration (Active).

11-17

11

Report Generation

9 Select the Solver tab. In the Solver options section, specify the Type

parameter as Fixed-step.
10 Select the General tab. Select Generate code only. Scroll down if the

configuration parameter is not visible.
11 Click Apply.
12 Click Generate code. The Simulink Coder build process generates code

for the model.

Open the Report Generator
After you generate the code, open the Report Generator.
1 In the model diagram window, select Tools > Report Generator.

11-18

Document Generated Code with Simulink® Report Generator™

2 In the Report Explorer window, in the options pane (center), click the folder

rtw (\toolbox\rtw). Click the setup file that it contains, codegen.rpt.

11-19

11

Report Generation

3 Double-click codegen.rpt or select it and click the Open report button

. The Report Explorer displays the structure of the setup file in the
outline pane (left).

Set Report Name, Location, and Format
Before generating a report, you can specify report output options, such as the
folder, file name, and format. For example, to generate a Microsoft Word
report named MyCGModelReport.rtf:

11-20

Document Generated Code with Simulink® Report Generator™

1 In the properties pane, under Report Options, review the options listed.

2 Leave the Directory field set to Present working directory.
3 For Filename, select Custom: and replace index with the name

MyModelCGReport.
4 For File format, specify Rich Text Format and replace Standard Print

with Numbered Chapters & Sections.

Include Models and Subsystems in a Report
Specify the models and subsystems that you want to include in the generated
report by setting options in the Model Loop component.

11-21

11

Report Generation

1 In the outline pane (left), select Model Loop. Report Generator displays

Model Loop component options in the properties pane.
2 If not already selected, select Current block diagram for the Model

name option.
3 In the outline pane, click Report - codegen.rpt*.

Customize the Report
After specifying the models and subsystems to include in the report, you can
customize the sections included in the report.
1 In the outline pane (left), expand the node Chapter - Generated Code.

By default, the report includes two sections, each containing one of two
report components.
2 Expand the node Section 1 — Code Generation Summary.
3 Select Code Generation Summary. Options for the component are

displayed in the properties pane.

11-22

Document Generated Code with Simulink® Report Generator™

4 Click Help to review the report customizations that you can make with the

Code Generation Summary component. For this example, do not customize
the component.
5 In the Report Explorer window, expand the node Section 1 — Generated

Code Listing.
6 Select Import Generated Code. Options for the component are displayed

in the properties pane.
7 Click Help to review the report customizations that you can make with the

Import Generated Code component.

Generate the Report
After you adjust the report options, from the Report Explorer window,
generate the report by clicking File > Report. A Message List dialog
box opens, which displays messages that you can monitor as the report is
generated. Model snapshots also appear during report generation. The
Message List dialog box might be hidden behind other dialog boxes.

When the report is complete, open the report, MyModelCGReport.rtf in the
folder report_ex (in this example).

11-23

11

Report Generation

For alternative ways of generating reports with the Simulink Report
Generator, see “Report Generation”.

11-24

Deployment
• Chapter 12, “Desktops”
• Chapter 13, “Real-Time Systems”
• Chapter 14, “External Code Integration”
• Chapter 15, “Program Building, Interaction, and Debugging”

12
Desktops
• “Rapid Simulations” on page 12-2
• “Generated S-Function Block” on page 12-34

12

Desktops

Rapid Simulations
In this section...
“About Rapid Simulation” on page 12-2
“Rapid Simulation Performance” on page 12-3
“General Rapid Simulation Workflow” on page 12-3
“Identify Rapid Simulation Requirements” on page 12-4
“Configure Inports to Provide Simulation Source Data” on page 12-6
“Configure and Build Model for Rapid Simulation” on page 12-6
“Set Up Rapid Simulation Input Data” on page 12-9
“Scripts for Batch and Monte Carlo Simulations” on page 12-19
“Run Rapid Simulations” on page 12-20
“Rapid Simulation Target Limitations” on page 12-33

About Rapid Simulation
After you create a model, you can use the Simulink Coder rapid simulation
(RSim) target to characterize the model behavior. The RSim target executable
that results from the build process is for non-real-time execution on your
host computer. The executable is highly optimized for simulating models of
hybrid dynamic systems, including models that use variable-step solvers and
zero-crossing detection. The speed of the generated code makes the RSim
target ideal for batch or Monte Carlo simulations.
Use the RSim target to generate an executable that runs fast, standalone
simulations. You can repeat simulations with varying data sets, interactively
or programmatically with scripts, without rebuilding the model. This can
accelerate the characterization and tuning of model behavior and code
generation testing.
Using command-line options:
• Define parameter values and input signals in one or more MAT-files that
you can load and reload at the start of simulations without rebuilding
your model.

12-2

Rapid Simulations

• Redirect logging data to one or more MAT-files that you can then analyze
and compare.
• Control simulation time.
• Specify External mode options.
Note To run an RSim executable, configure your computer to run MATLAB
and have the MATLAB and Simulink installation folders accessible. To deploy
a standalone host executable ( i.e., without MATLAB and Simulink installed),
consider using the Host-Based Shared Library target (ert_shrlib)."

Rapid Simulation Performance
The performance advantage that you gain from rapid simulation varies.
Larger simulations achieve speed improvements of up to 10 times faster than
standard Simulink simulations. Some models might not show any noticeable
improvement in simulation speed. To determine the speed difference for your
model, time your standard Simulink simulation and compare the results
with a rapid simulation. In addition, test the model performance in Rapid
Accelerator simulation mode.

General Rapid Simulation Workflow
Like other stages of Model-Based Design, characterization and tuning of
model behavior is an iterative process, as shown in the general workflow
diagram in the figure. Tasks in the workflow are:
1 Identify your rapid simulation requirements.
2 Configure Inport blocks that provide input source data for rapid

simulations.
3 Configure the model for rapid simulation.
4 Set up simulation input data.
5 Run the rapid simulations.

12-3

12

Desktops

Identify rapid simulation
requirements

Model includes Yes Configure
Inport blocks
Inport blocks?
No
Configure and
build model
Set up input data
Batch
or Monte Carlo
simulations?

Yes

Program script

No
Run simulation
Analyze simulation
results

Yes

Change input
data?

Done

Identify Rapid Simulation Requirements
The first step to setting up a rapid simulation is to identify your simulation
requirements.

12-4

Question...

For More Information, See...

How long do you want simulations to
run?

“Configure and Build Model for Rapid Simulation”
on page 12-6

Are there any solver requirements? Do
you expect to use the same solver for
which the model is configured for your
rapid simulations?

“Configure and Build Model for Rapid Simulation”
on page 12-6

Rapid Simulations

Question...

For More Information, See...

Do your rapid simulations need to
accommodate flexible custom code
interfacing? Or, do your simulations
need to retain storage class settings?

“Configure and Build Model for Rapid Simulation”
on page 12-6

Will you be running simulations with
multiple data sets?

“Set Up Rapid Simulation Input Data” on page 12-9

Will the input data consist of global
parameters, signals, or both?

“Set Up Rapid Simulation Input Data” on page 12-9

What type of source blocks provide input
data to the model — From File, Inport,
From Workspace?

“Set Up Rapid Simulation Input Data” on page 12-9

Will the model’s parameter vector
(model_P) be used as input data?

“Create a MAT-File That Includes a Model Parameter
Structure” on page 12-10

What is the data type of the input
parameters and signals?

“Set Up Rapid Simulation Input Data” on page 12-9

Will the source data consist of one
variable or multiple variables?

“Set Up Rapid Simulation Input Data” on page 12-9

Does the input data include tunable
parameters?

“Create a MAT-File That Includes a Model Parameter
Structure” on page 12-10

Do you need to gain access to tunable
parameter information — model
checksum and parameter data types,
identifiers, and complexity?

“Create a MAT-File That Includes a Model Parameter
Structure” on page 12-10

Will you have a need to vary the
simulation stop time for simulation
runs?

“Configure and Build Model for Rapid Simulation”
on page 12-6 and“Override a Model Simulation Stop
Time” on page 12-23

Do you want to set a time limit for the
simulation? Consider setting a time
limit if your model experiences frequent
zero crossings and has a small minor
step size.

“Set a Clock Time Limit for a Rapid Simulation” on
page 12-23

12-5

12

Desktops

Question...

For More Information, See...

Do you need to preserve the output of
each simulation run?

“Specify a New Output File Name for a Simulation”
on page 12-32 and “Specify New Output File Names
for To File Blocks” on page 12-33

Do you expect to run the simulations
interactively or in batch mode?

“Scripts for Batch and Monte Carlo Simulations” on
page 12-19

Configure Inports to Provide Simulation Source Data
You can use Inport blocks as a source of input data for rapid simulations.
To do so, configure the blocks so that they can import data from external
MAT-files. By default, the Inport block inherits parameter settings from
downstream blocks. In most cases, to import data from an external MAT-file,
you must explicitly set the following parameters to match the source data
in the MAT-file.
• Main > Interpolate data
• Signal Attributes > Port dimensions
• Signal Attributes > Data type
• Signal Attributes > Signal type
If you do not have control over the model content, you might need to modify
the data in the MAT-file to conform to what the model expects for input.
Input data characteristics and specifications of the Inport block that receives
the data must match.
For details on adjusting these parameters and on creating a MAT-file for use
with an Inport block, see “Create a MAT-File for an Inport Block” on page
12-15. For descriptions of the preceding block parameters, see the description
of the Inport block in the Simulink documentation.

Configure and Build Model for Rapid Simulation
After you identify your rapid simulation requirements, configure the model
for rapid simulation.
1 Open the Configuration Parameters dialog box.

12-6

Rapid Simulations

2 Go to the Code Generation pane.
3 On the Code Generation pane, click Browse. The System Target File

Browser opens.
4 Select rsim.tlc (Rapid Simulation Target) and click OK.

On the Code Generation pane, the Simulink Coder software populates
the Make command and Template makefile fields with default settings
and adds the RSim Target pane under Code Generation.
5 Click RSim Target to view the RSim Target pane.

6 Set the RSim target configuration parameters to your rapid simulation

requirements.

12-7

12

Desktops

If You Want to...

Then...

Generate code that allows the RSim
executable to load parameters from a
MAT-file

Select Enable RSim executable to load
parameters from a MAT-file (default).

Let the target choose a solver based on the
solver already configured for the model.

Set Solver selection to auto (default). The
Simulink Coder software uses a built-in solver if a
fixed-step solver is specified on the Solver pane
or calls the Simulink solver module (a shared
library) if a variable-step solver is specified.

Explicitly instruct the target to use a
fixed-step solver

Set Solver selection to Use fixed-step
solvers. In the Configuration Parameters dialog
box, on the Solver pane, specify a fixed-step
solver.

Explicitly instruct the target to use a
variable-step solver

Set Solver selection to Use Simulink solver
module. In the Configuration Parameters dialog
box, on the Solver pane, specify a variable-step
solver.

Force all storage classes to Auto for flexible
custom code interfacing

Select Force storage classes to AUTO (default).

Retain storage class settings, such as
ExportedGlobal or ImportedExtern, due to
application requirements

Clear Force storage classes to AUTO.

7 Set up data import and export options. On the Data Import/Export pane,

in the Save to Workspace section, select the Time, States, Outputs,
and Final States options, as they apply. By default, the Simulink Coder
software saves simulation logging results to a file named model.mat. For
more information, see “Export Simulation Data”.
8 If you are using External mode communications, set up the interface,

using the Code Generation > Interface pane. See “Host/Target
Communication” on page 15-50 for details.
9 Return to the Code Generation pane and click Build. The Simulink

Coder code generator builds a highly optimized executable that you can run
on your host computer with varying data, without rebuilding.

12-8

Rapid Simulations

For more information on compilers that are compatible with the Simulink
Coder product, see “Choose and Configure a Compiler” on page 15-2 and
“Template Makefiles and Make Options” on page 9-38 .

Set Up Rapid Simulation Input Data
• “About Rapid Simulation Data Setup” on page 12-9
• “Create a MAT-File That Includes a Model Parameter Structure” on page
12-10
• “Create a MAT-File for a From File Block” on page 12-14
• “Create a MAT-File for an Inport Block” on page 12-15

About Rapid Simulation Data Setup
The format and setup of input data for a rapid simulation depends on your
requirements.
If the Input Data Source Is...

Then...

The model’s global parameter
vector (model_P)

Use the rsimgetrtp function to get
the vector content and then save it to a
MAT-file.

The model’s global parameter
vector and you want a mapping
between the vector and tunable
parameters

In the Configuration Parameters dialog
box, on the Optimization > Signals
and Parameters pane, enable the
Inline Parameters option. Call the
rsimgetrtp function to get the global
parameter structure and then save it to
a MAT-file.

Provided by a From File block

Create a MAT-file that a From File block
can read.

Provided by an Inport block

Create a MAT-file that adheres to one of
the three data file formats that the Inport
block can read.

Provided by a From Workspace
block

Create structure variables in the
MATLAB workspace.

12-9

12

Desktops

The RSim target requires that MAT-files used as input for From File and
Inport blocks contain data. The grt target inserts MAT-file data directly into
the generated code, which is then compiled and linked as an executable. In
contrast, RSim allows you to replace data sets for each successive simulation.
A MAT-file containing From File or Inport block data must be present if a
From File block or Inport block exists in your model.

Create a MAT-File That Includes a Model Parameter Structure
To create a MAT-file that includes a model global parameter structure
(model_P),
1 Get the structure by calling the function rsimgetrtp.
2 Save the parameter structure to a MAT-file.

If you want to run simulations over varying data sets, consider converting
the parameter structure to a cell array and saving the parameter variations
to a single MAT-file.
Get the Parameter Structure for a Model. Get the global parameter
structure (model_P) for a model by calling the function rsimgetrtp.
param_struct = rsimgetrtp('model')

Argument

Description

model

The model for which you are running the rapid
simulations.

The rsimgetrtp function forces an update diagram action for the specified
model and returns a structure that contains the following fields.

12-10

Rapid Simulations

Field

Description

modelChecksum

A four-element vector that encodes the structure of the
model. The Simulink Coder software uses the checksum
to check whether the structure of the model has changed
since the RSim executable was generated. If you delete or
add a block, and then generate a new model_P vector, the
new checksum no longer matches the original checksum.
The RSim executable detects this incompatibility in
parameter vectors and exits to avoid returning incorrect
simulation results. If the model structure changes, you
must regenerate the code for the model.

parameters

A structure that contains the model’s global parameters.

The parameter structure contains the following information.
Field

Description

dataTypeName

The name of the parameter data type, for example,
double

dataTypeID

Internal data type identifier used by the Simulink Coder
software

complex

The value 0 if real; 1 if complex

dtTransIdx

Internal data index used by Simulink Coder software

values

A vector of the parameter values associated with this
structure

map

If you select the Inline parameters option, this field
contains the mapping information that correlates
the ’values’ to the tunable parameters of the model.
This mapping information, in conjunction with
rsimsetrtpparam, is useful for creating subsequent rtP
structures without compiling the block diagram.

If you select the Inline parameters option for the model, then tunable
parameter information is also available in the parameters field.

12-11

12

Desktops

The Simulink Coder software reports a tunable fixed-point parameter
according to its stored value. For example, an sfix(16) parameter value of
1.4 with a scaling of 2^-8 has a value of 358 as an int16.
In the following example, rsimgetrtp returns the parameter structure for the
example model rtwdemo_rsimtf to param_struct.
param_struct = rsimgetrtp('rtwdemo_rsimtf')
param_struct =
modelChecksum: [1.7165e+009 3.0726e+009 2.6061e+009 2.3064e+009]
parameters: [1x1 struct]

Save the Parameter Structure to a MAT-File. After you issue a call to
rsimgetrtp, save the return value of the function call to a MAT-file. Using a
command-line option, you can then specify that MAT-file as input for rapid
simulations.
The following example saves the parameter structure returned for
rtwdemo_rsimtf to the MAT-file myrsimdemo.mat.
save myrsimdemo.mat param_struct;

For information on using command-line options to specify required files, see
“Run Rapid Simulations” on page 12-20.
Convert the Parameter Structure for Running Simulations on Varying
Data Sets. If you need to use rapid simulations to test changes to specific
parameters, you can convert the model parameter structure to a cell array.
You can then access a specific parameter by using the @ operator to specify
the index for a specific parameter in the file.
To convert the structure to a cell array:
1 Save the parameters vector of the structure returned by rsimgetrtp to a

temporary variable. The following example saves the parameter vector to
temporary variable p.
param_struct = rsimgetrtp('rtwdemo_rsimtf');
p = param_struct.parameters;

12-12

Rapid Simulations

2 Convert the structure to a cell array.

param_struct.parameters = [];
3 Assign the saved contents of the temporary variable to the original

structure name as an element of the cell array.
param_struct.parameters{1} = p;
param_struct.parameters{1}
ans =
dataTypeName:
dataTypeId:
complex:
dtTransIdx:
values:
map: []

'double'
0
0
0
[-140 -4900 0 4900]

4 Make a copy of the cell array to preserve the original parameter values.

param_struct.parameters{2} = param_struct.parameters{1};
param_struct.parameters{2}
ans =
dataTypeName:
dataTypeId:
complex:
dtTransIdx:
values:
map: []

'double'
0
0
0
[-140 -4900 0 4900]

For a subsequent data set, increment the array index.
5 Modify any combination of the parameter values.

param_struct.parameters{2}.values=[-150 -5000 0 4950];
6 Repeat steps 4 and 5 for each parameter data set that you want to use as

input to a rapid simulation of the model.

12-13

12

Desktops

7 Save the cell array representing the parameter structure to a MAT-file.

save rtwdemo_rsimtf.mat param_struct;

For more information on how to specify each data set when you run the
simulations, see“Change Block Parameters for an RSim Simulation” on page
12-30.

Create a MAT-File for a From File Block
You can use a MAT-file as the input data source for a From File block. The
format of the data in the MAT-file must match the data format expected
by that block.
To create a MAT-file for a From File block:
1 For array format data, in the workspace create a matrix that consists of two

or more rows. The first row must contain monotonically increasing time
points. Other rows contain data points that correspond to the time point in
that column. The time and data points must be data of type double.
For example:
t=[0:0.1:2*pi]';
Ina1=[2*sin(t) 2*cos(t)];
Ina2=sin(2*t);
Ina3=[0.5*sin(3*t) 0.5*cos(3*t)];
var_matrix=[t Ina1 Ina2 Ina3]';

For other supported data types, such as int16 or fixed-point, the time data
points must be of type double, just as for array format data. However, the
sample data can be of any dimension.
For more information on setting up the input data, see the description of
the From File block in the Simulink documentation.
2 Save the matrix to a MAT-file.

The following example saves the matrix var_matrix to the MAT-file
myrsimdemo.mat in Version 7.3 format.
save '-v7.3' myrsimdemo.mat var_matrix;

12-14

Rapid Simulations

Using a command-line option, you can then specify that MAT-file as input
for rapid simulations.

Create a MAT-File for an Inport Block
You can use a MAT-file as the input data source for an Inport block.
The format of the data in the MAT-file must adhere to one of the three
column-based formats listed in the following table. The table lists the formats
in order from least flexible to most flexible.
Format

Description

Single time/data
matrix

• Least flexible.
• One variable.
• Two or more columns. Number of columns must equal the sum of the
dimensions of all root Inport blocks plus 1. First column must contain
monotonically increasing time points. Other columns contain data
points that correspond to the time point in a given row.
• Data of type double.
For an example, see Single time/data matrix in the following procedure,
step 4. For more information, see “Import Data Arrays” in the Simulink
documentation.

Format

Description

Signal-and-time
structure

• More flexible than the single time/data matrix format.
• One variable.
• Must contain two top-level fields: time and signals. The time field
contains a column vector of the simulation times. The signals field
contains an array of substructures, each of which corresponds to an
Inport block. The substructure index corresponds to the Inport block
number. Each signals substructure must contain a field named
values. The values field must contain an array of inputs for the
corresponding Inport block, where each input corresponds to a time
point specified by the time field.

12-15

12

Desktops

Format

Description
• If the time field is set to an empty value, clear the check box for the
Inport block Interpolate data parameter.
• No data type limitations, but must match Inport block settings.
For an example, see Signal-and-time structure in the following procedure,
step 4. For more information on this format, see “Import Data Structures”
in the Simulink documentation.

Format

Description

Per-port structure

• Most flexible
• Multiple variables. Number of variables must equal the number of
Inport blocks.
• Consists of a separate structure-with-time or structure-without-time
for each Inport block. Each Inport block data structure has only one
signals field. To use this format, in the Input text field, enter the
names of the structures as a comma-separated list, in1, in2,..., inN,
where in1 is the data for your model’s first port, in2 for the second
port, and so on.
• Each variable can have a different time vector.
• If the time field is set to an empty value, clear the check box for the
Inport block Interpolate data parameter.
• No data type limitations, but must match Inport block settings.
• To save multiple variables to the same data file, you must save them in
the order expected by the model, using the -append option.
For an example, see Per-port structure in the following procedure, step
4. For more information, see “Import Data Structures” in the Simulink
documentation.
The supported formats and the following procedure are illustrated in
rtwdemo_rsim_i.
To create a MAT-file for an Inport block:

12-16

Rapid Simulations

1 Choose one of the preceding data file formats.
2 Update Inport block parameter settings and specifications to match

specifications of the data to be supplied by the MAT-file.
By default, the Inport block inherits parameter settings from downstream
blocks. To import data from an external MAT-file, explicitly set the
following parameters to match the source data in the MAT-file.
• Main > Interpolate data
• Signal Attributes > Port dimensions
• Signal Attributes > Data type
• Signal Attributes > Signal type
If you choose to use a structure format for workspace variables and the
time field is empty, you must clear Interpolate data or modify the field so
that it is set to a nonempty value. Interpolation requires time data.
For descriptions of the preceding block parameters, see the description of
the Inport block in the Simulink documentation.
3 Build an RSim executable for the model. The Simulink Coder build process

creates and calculates a structural checksum for the model and embeds
it in the generated executable. The RSim target uses the checksum to
verify that data being passed into the model is consistent with what the
model executable expects.
4 Create the MAT-file that provides the source data for the rapid simulations.

You can create the MAT-file from a workspace variable. Using the
specifications in the preceding format comparison table, create the
workspace variables for your simulations.
An example of each format follows:
Single time/data matrix
t=[0:0.1:2*pi]';
Ina1=[2*sin(t) 2*cos(t)];
Ina2=sin(2*t);
Ina3=[0.5*sin(3*t) 0.5*cos(3*t)];

12-17

12

Desktops

var_matrix=[t Ina1 Ina2 Ina3];

Signal-and-time structure
t=[0:0.1:2*pi]';
var_single_struct.time=t;
var_single_struct.signals(1).values(:,1)=2*sin(t);
var_single_struct.signals(1).values(:,2)=2*cos(t);
var_single_struct.signals(2).values=sin(2*t);
var_single_struct.signals(3).values(:,1)=0.5*sin(3*t);
var_single_struct.signals(3).values(:,2)=0.5*cos(3*t);
v=[var_single_struct.signals(1).values...
var_single_struct.signals(2).values...
var_single_struct.signals(3).values];

Per-port structure
t=[0:0.1:2*pi]';
Inb1.time=t;
Inb1.signals.values(:,1)=2*sin(t);
Inb1.signals.values(:,2)=2*cos(t);
t=[0:0.2:2*pi]';
Inb2.time=t;
Inb2.signals.values(:,1)=sin(2*t);
t=[0:0.1:2*pi]';
Inb3.time=t;
Inb3.signals.values(:,1)=0.5*sin(3*t);
Inb3.signals.values(:,2)=0.5*cos(3*t);
5 Save the workspace variables to a MAT-file.

Single time/data matrix
The following example saves the workspace variable var_matrix to the
MAT-file rsim_i_matrix.mat.
save rsim_i_matrix.mat var_matrix;

Signal-and-time structure
The following example saves the workspace structure variable
var_single_struct to the MAT-file rsim_i_single_struct.mat.

12-18

Rapid Simulations

save rsim_i_single_struct.mat var_single_struct;

Per-port structure
To order data when saving per-port structure variables to a single MAT-file,
use the save command’s -append option. Be sure to append the data in
the order that the model expects it.
The following example saves the workspace variables Inb1, Inb2, and Inb3
to MAT-file rsim_i_multi_struct.mat.
save rsim_i_multi_struct.mat Inb1;
save rsim_i_multi_struct.mat Inb2 -append;
save rsim_i_multi_struct.mat Inb3 -append;

The save command does not preserve the order in which you specify your
workspace variables in the command line when saving data to a MAT-file.
For example, if you specify the variables v1, v2, and v3, in that order, the
order of the variables in the MAT-file could be v2 v1 v3.
Using a command-line option, you can then specify the MAT-files as input
for rapid simulations.

Scripts for Batch and Monte Carlo Simulations
The RSim target is for batch simulations in which parameters and input
signals vary for multiple simulations. New output file names allow you to run
new simulations without overwriting prior simulation results. You can set up
a series of simulations to run by creating a .bat file for use on a Microsoft
Windows platform.
Create a file for the Windows platform with any text editor and execute it by
typing the file name, for example, mybatch, where the name of the text file
is mybatch.bat.
rtwdemo_rsimtf -f rtwdemo_rsimtf.mat=run1.mat -o results1.mat -tf 10.0
rtwdemo_rsimtf -f rtwdemo_rsimtf.mat=run2.mat -o results2.mat -tf 10.0
rtwdemo_rsimtf -f rtwdemo_rsimtf.mat=run3.mat -o results3.mat -tf 10.0
rtwdemo_rsimtf -f rtwdemo_rsimtf.mat=run4.mat -o results4.mat -tf 10.0

12-19

12

Desktops

In this case, batch simulations run using four sets of input data in files
run1.mat, run2.mat, and so on. The RSim executable saves the data to the
files specified with the -o option.
The variable names containing simulation results in each of the files are
identical. Therefore, loading consecutive sets of data without renaming the
data once it is in the MATLAB workspace results in overwriting the prior
workspace variable with new data. To avoid overwriting, you can copy the
result to a new MATLAB variable before loading the next set of data.
You can also write MATLAB scripts to create new signals and new parameter
structures, as well as to save data and perform batch runs using the bang
command (!).
For details on running simulations and available command-line options, see
“Run Rapid Simulations” on page 12-20. For an example of a rapid simulation
batch script, see the example rtwdemo_rsim_batch_script.

Run Rapid Simulations
• “” on page 12-20
• “Requirements for Running Rapid Simulations” on page 12-22
• “Set a Clock Time Limit for a Rapid Simulation” on page 12-23
• “Override a Model Simulation Stop Time” on page 12-23
• “Read the Parameter Vector into a Rapid Simulation” on page 12-24
• “Specify New Signal Data File for a From File Block” on page 12-24
• “Specify Signal Data File for an Inport Block” on page 12-27
• “Change Block Parameters for an RSim Simulation” on page 12-30
• “Specify a New Output File Name for a Simulation” on page 12-32
• “Specify New Output File Names for To File Blocks” on page 12-33
Using the RSim target, you can build a model once and run multiple
simulations to study effects of varying parameter settings and input signals.
You can run a simulation directly from your operating system command line,

12-20

Rapid Simulations

redirect the command from the MATLAB command line by using the bang
(!) character, or execute commands from a script.
Operating System Command Line
rtwdemo_rsimtf

MATLAB Command Line
!rtwdemo_rsimtf

The following table lists ways you can use RSim target command-line options
to control a simulation.
To...

Use...

Read input data for a From File block from a
MAT-file other than the MAT-file used for the
previous simulation

model -f oldfilename.mat=newfilename.mat

Print a summary of the options for RSim
executable targets

executable filename -h

Read input data for an Inport block from a
MAT-file

model -i filename.mat

Time out after n clock time seconds, where n is
a positive integer value

model -L n

Write MAT-file logging data to file

model -o filename.mat

filename.mat

Read a parameter vector from file

model -p filename.mat

filename.mat

Override the default TCP port (17725) for
External mode

model -port TCPport

Write MAT-file logging data to a MAT-file
other than the MAT-file used for the previous
simulation

model -t
oldfilename.mat=newfilename.mat

Run the simulation until the time value
stoptime is reached

model -tf stoptime

12-21

12

Desktops

To...

Use...

Run in verbose mode

model -v

Wait for the Simulink engine to start the model
in External mode

model -w

The following sections use the rtwdemo_rsimtf example model in examples
to illustrate some of these command-line options. In each case, the example
assumes you have already done the following:
• Created or changed to a working folder.
• Opened the example model.
• Copied the data file

matlabroot/toolbox/rtw/rtwdemos/rsimdemos/rsim_tfdata.mat to
your working folder. You can perform this operation using the command:
copyfile(fullfile(matlabroot,'toolbox','rtw','rtwdemos',...
'rsimdemos','rsim_tfdata.mat'),pwd);

Requirements for Running Rapid Simulations
• You can run the RSim executable on any computer configured to run
MATLAB and for which the MATLAB and Simulink installation folder is
accessible to the RSim.exe. To obtain that access, your PATH environment
variable must include /bin and /bin/($ARCH), where ($ARCH) represents
your operating system architecture. For example, for a personal computer
running on a Windows platform, ($ARCH) is “win32”, whereas for a Linux
machine, ($ARCH) is “glnx86”.
• On GNU Linux platforms, to run an RSim executable, define the
LD_LIBRARY_PATH environment variable to provide the path to the
MATLAB installation folder, as follows:
% setenv LD_LIBRARY_PATH /matlab/sys/os/glnx86:$LD_LIBRARY_PATH

• On the Apple Macintosh OS X platform, to run RSim target executables,
you must define the environment variable DYLD_LIBRARY_PATH to include
the folders bin/mac and sys/os/mac under the MATLAB installation

12-22

Rapid Simulations

folder. For example, if your MATLAB installation is under /MATLAB,
add /MATLAB/bin/mac and /MATLAB/sys/os/mac to the definition for
DYLD_LIBRARY_PATH.

Set a Clock Time Limit for a Rapid Simulation
If a model experiences frequent zero crossings and the model’s minor step size
is small, consider setting a time limit for a rapid simulation. To set a time
limit, specify the -L option with a positive integer value. The simulation
aborts after running for the specified amount of clock time (not simulation
time). For example,
!rtwdemo_rsimtf -L 20

Based on your clock, after the executable runs for 20 seconds, the program is
terminate. You see one of the following messages:
On a Microsoft Windows Platform
Exiting program, time limit exceeded
Logging available data ...

On The Open Group UNIX Platform
** Received SIGALRM (Alarm) signal @ Fri Jul 25 15:43:23 2003
** Exiting model 'vdp' @ Fri Jul 25 15:43:23 2003

You do not need to do anything to your model or to its Simulink Coder
configuration to use this option.

Override a Model Simulation Stop Time
By default, a rapid simulation runs until the simulation time reaches the time
specified the Configuration Parameters dialog box, on the Solver pane. You
can override the model simulation stop time by using the -tf option. For
example, the following simulation runs until the time reaches 6.0 seconds.
!rtwdemo_rsimtf -tf 6.0

The RSim target stops and logs output data using MAT-file data logging rules.

12-23

12

Desktops

If the model includes a From File block, the end of the simulation is regulated
by the stop time setting specified in the Configuration Parameters dialog
box, on the Solver pane, or with the RSim target option -tf. The values in
the block’s time vector are ignored. However, if the simulation time exceeds
the endpoints of the time and signal matrix (if the final time is greater than
the final time value of the data matrix), the signal data is extrapolated to
the final time value.

Read the Parameter Vector into a Rapid Simulation
To read the model parameter vector into a rapid simulation, you must first
create a MAT-file that includes the parameter structure as described in
“Create a MAT-File That Includes a Model Parameter Structure” on page
12-10. You can then specify the MAT-file in the command line with the -p
option.
For example:
1 Build an RSim executable for the example model rtwdemo_rsimtf.
2 Modify parameters in your model and save the parameter structure.

param_struct = rsimgetrtp('rtwdemo_rsimtf');
save myrsimdata.mat param_struct
3 Run the executable with the new parameter set.

!rtwdemo_rsimtf -p myrsimdata.mat
** Starting model 'rtwdemo_rsimtf' @ Tue Dec 27 12:30:16 2005
** created rtwdemo_rsimtf.mat **
4 Load workspace variables and plot the simulation results by entering the

following commands:
load myrsimdata.mat
plot(rt_yout)

Specify New Signal Data File for a From File Block
If your model’s input data source is a From File block, you can feed the block
with input data during simulation from a single MAT-file or you can change

12-24

Rapid Simulations

the MAT-file from one simulation to the next. Each MAT-file must adhere
to the format described in “Create a MAT-File for a From File Block” on
page 12-14.
To change the MAT-file after an initial simulation, you specify the executable
with the -f option and an oldfile.mat=newfile.mat parameter, as shown in
the following example.
1 Set some parameters in the MATLAB workspace. For example:

w = 100;
theta = 0.5;
2 Build an RSim executable for the example model rtwdemo_rsimtf.
3 Run the executable.

!rtwdemo_rsimtf

The RSim executable runs a set of simulations and creates output
MAT-files containing the specific simulation result.
4 Load the workspace variables and plot the simulation results by entering

the following commands:
load rtwdemo_rsimtf.mat
plot(rt_yout)

The resulting plot shows simulation results based on default input data.

12-25

12

Desktops

5 Create a new data file, newfrom.mat, that includes the following data:

t=[0:.001:1];
u=sin(100*t.*t);
tu=[t;u];
save newfrom.mat tu;
6 Run a rapid simulation with the new data by using the -f option to replace

the original file, rsim_tfdata.mat, with newfrom.mat.
!rtwdemo_rsimtf -f rsim_tfdata.mat=newfrom.mat
7 Load the data and plot the new results by entering the following commands:

load rtwdemo_rsimtf.mat
plot(rt_yout)

The next figure shows the resulting plot.

12-26

Rapid Simulations

From File blocks require input data of type double. If you need to import
signal data of a data type other than double, use an Inport block (see “Create
a MAT-File for an Inport Block” on page 12-15) or a From Workspace block
with the data specified as a structure.
Workspace data must be in the format:
variable.time
variable.signals.values

If you have more than one signal, use the following format:
variable.time
variable.signals(1).values
variable.signals(2).values

Specify Signal Data File for an Inport Block
If your model’s input data source is an Inport block, you can feed the block
with input data during simulation from a single MAT-file or you can change

12-27

12

Desktops

the MAT-file from one simulation to the next. Each MAT-file must adhere
to one of the three formats described in “Create a MAT-File for an Inport
Block” on page 12-15.
To specify the MAT-file after a simulation, you specify the executable with
the -i option and the name of the MAT-file that contains the input data.
For example:
1 Open the model rtwdemo_rsim_i.
2 Check the Inport block parameter settings. The following Inport block data

parameter settings and specifications that you specify for the workspace
variables must match settings in the MAT-file, as indicated in “Configure
Inports to Provide Simulation Source Data” on page 12-6:
• Main > Interpolate data
• Signal Attributes > Port dimensions
• Signal Attributes > Data type
• Signal Attributes > Signal type
3 Build the model.
4 Set up the input signals. For example:

t=[0:0.01:2*pi]';
s1=[2*sin(t) 2*cos(t)];
s2=sin(2*t);
s3=[0.5*sin(3*t) 0.5*cos(3*t)];
plot(t, [s1 s2 s3])

12-28

Rapid Simulations

5 Prepare the MAT-file by using one of the three available file formats

described in “Create a MAT-File for an Inport Block” on page 12-15. The
following example defines a signal-and-time structure in the workspace
and names it var_single_struct.
t=[0:0.1:2*pi]';
var_single_struct.time=t;
var_single_struct.signals(1).values(:,1)=2*sin(t);
var_single_struct.signals(1).values(:,2)=2*cos(t);
var_single_struct.signals(2).values=sin(2*t);
var_single_struct.signals(3).values(:,1)=0.5*sin(3*t);
var_single_struct.signals(3).values(:,2)=0.5*cos(3*t);
v=[var_single_struct.signals(1).values...
var_single_struct.signals(2).values...
var_single_struct.signals(3).values];
6 Save the workspace variable var_single_struct to MAT-file

rsim_i_single_struct.
save rsim_i_single_struct.mat var_single_struct;

12-29

12

Desktops

7 Run a rapid simulation with the input data by using the -i option. Load

and plot the results.
!rtwdemo_rsim_i -i rsim_i_single_struct.mat
** Starting model 'rtwdemo_rsim_i' @ Tue Dec 27 14:01:20 2005
*** rsim_i_single_struct.mat is loaded! ***
** created rtwdemo_rsim_i.mat **
** Execution time = 0.2683734753333333sload rsim_i_single_struct.mat;

8 Load and plot the results.

load rtwdemo_rsim_i.mat
plot(rt_tout, rt_yout);

Change Block Parameters for an RSim Simulation
As described in “Create a MAT-File That Includes a Model Parameter
Structure” on page 12-10, after you alter one or more parameters in a

12-30

Rapid Simulations

Simulink block diagram, you can extract the parameter vector, model_P, for
the entire model. You can then save the parameter vector, along with a model
checksum, to a MAT-file. This MAT-file can be read directly by the standalone
RSim executable, allowing you to replace the entire parameter vector or
individual parameter values, for running studies of variations of parameter
values representing coefficients, new data for input signals, and so on.
The RSim target allows you to alter any model parameter, including
parameters that include side-effects functions. An example of a side-effects
function is a simple Gain block that includes the following parameter entry
in a dialog box:
gain value:

2 * a

The Simulink Coder code generator evaluates side-effects functions before
generating code. The generated code for this example retains only one
memory location entry, and the dependence on parameter a is no longer
visible in the generated code. The RSim target overcomes the problem of
handling side-effects functions by replacing the entire parameter structure,
model_P. You must create this new structure by using the rsimgetrtp
function and then saving it in a MAT-file, as described in “Create a MAT-File
That Includes a Model Parameter Structure” on page 12-10.
RSim can read the MAT-file and replace the entire model_P structure
whenever you change one or more parameters, without recompiling the entire
model.
For example, assume that you changed one or more parameters in your model,
generated the new model_P vector, and saved model_P to a new MAT-file
called mymatfile.mat. To run the same rtwdemo_rsimtf model and use these
new parameter values, use the -p option, as shown in the following example:
!rtwdemo_rsimtf -p mymatfile.mat
load rtwdemo_rsimtf
plot(rt_yout)

If you have converted the parameter structure to a cell array for running
simulations on varying data sets, as described in “Convert the Parameter
Structure for Running Simulations on Varying Data Sets” on page 12-12, you
must add an @n suffix to the MAT-file specification. n is the element of the cell
array that contains the specific input that you want to use for the simulation.

12-31

12

Desktops

The following example converts param_struct to a cell array, changes
parameter values, saves the changes to MAT-file mymatfile.mat, and then
runs the executable using the parameter values in the second element of
the cell array as input.
param_struct = rsimgetrtp('rtwdemo_rsimtf');
p = param_struct.parameters;
param_struct.parameters = [];
param_struct.parameters{1} = p;
param_struct.parameters{1}
ans =
dataTypeName: 'double'
dataTypeId: 0
complex: 0
dtTransIdx: 0
values: [-140 -4900 0 4900]
param_struct.parameters{2} = param_struct.parameters{1};
param_struct.parameters{2}.values=[-150 -5000 0 4950];
save mymatfile.mat param_struct;
!rtwdemo_rsimtf -p mymatfile.mat@2 -o rsim2.mat

Specify a New Output File Name for a Simulation
If you have specified any of the Save to Workspace options — Time,
States, Outputs, or Final States — in the Configuration Parameters dialog
box, on the Data Import/Export pane, the default is to save simulation
logging results to the file model.mat. For example, the example model
rtwdemo_rsimtf normally saves data to rtwdemo_rsimtf.mat, as follows:
!rtwdemo_rsimtf
created rtwdemo_rsimtf.mat

You can specify a new output file name for data logging by using the -o option
when you run an executable.
!rtwdemo_rsimtf -o rsim1.mat

In this case, the set of parameters provided at the time of code generation,
including any From File block data, is run.

12-32

Rapid Simulations

Specify New Output File Names for To File Blocks
In much the same way as you can specify a new system output file name,
you can also provide new output file names for data saved from one or more
To File blocks. To do this, specify the original file name at the time of code
generation with a new name, as shown in the following example:
!rtwdemo_rsimtf -t rtwdemo_rsimtf_data.mat=mynewrsimdata.mat

In this case, assume that the original model wrote data to the output file
rtwdemo_rsimtf_data.mat. Specifying a new file name forces RSim to
write to the file mynewrsimdata.mat. With this technique, you can avoid
overwriting an existing simulation run.

Rapid Simulation Target Limitations
The RSim target has the following limitations:
• Does not support algebraic loops.
• Does not support Interpreted MATLAB Function blocks.
• Does not support noninlined MATLAB language or Fortran S-functions.
• If an RSim build includes referenced models (by using Model blocks), set
up these models to use fixed-step solvers to generate code for them. The
top model, however, can use a variable-step solver as long as all blocks in
the referenced models are discrete.
• In certain cases, changing block parameters can result in structural
changes to your model that change the model checksum. An example of
such a change is changing the number of delays in a DSP simulation. In
such cases, you must regenerate the code for the model.
• Variable-step solver support for RSim is not available on Microsoft
Windows platforms when you use the Watcom C/C++ compiler.

12-33

12

Desktops

Generated S-Function Block
S-functions are an important class of target for which the Simulink Coder
product can generate code. The ability to encapsulate a subsystem into an
S-function allows you to increase its execution efficiency and facilitate code
reuse.
The following sections describe the properties of S-function targets and
illustrate how to generate them. For more details on the structure of
S-functions, see “Host-Specific Code”.
In this section...
“About Object Libraries” on page 12-34
“Create S-Function Blocks from a Subsystem” on page 12-37
“Tunable Parameters in Generated S-Functions” on page 12-42
“System Target File and Template Makefiles” on page 12-44
“Checksums and the S-Function Target” on page 12-45
“S-Function Target Limitations” on page 12-45

About Object Libraries
• “About the S-Function Target” on page 12-34
• “Required Files for S-Function Deployment” on page 12-36
• “Sample Time Propagation in Generated S-Functions” on page 12-37
• “Choose a Solver Type” on page 12-37

About the S-Function Target
Using the S-function target, you can build an S-function component and use
it as an S-Function block in another model. The S-function code format
used by the S-function target generates code that conforms to the Simulink
C MEX S-function application programming interface (API). Applications
of this format include

12-34

Generated S-Function Block

• Conversion of a model to a component. You can generate an S-Function
block for a model, m1. Then, you can place the generated S-Function
block in another model, m2. Regenerating code for m2 does not require
regenerating code for m1.
• Conversion of a subsystem to a component. By extracting a subsystem to
a separate model and generating an S-Function block from that model,
you can create a reusable component from the subsystem. See “Create
S-Function Blocks from a Subsystem” on page 12-37 for an example of
this procedure.
• Speeding up simulation. In many cases, an S-function generated from a
model performs more efficiently than the original model.
• Code reuse. You can incorporate multiple instances of one model inside
another without replicating the code for each instance. Each instance will
continue to maintain its own unique data.
The S-function target generates noninlined S-functions. Within the same
release, you can generate an executable from a model that contains generated
S-functions by using the generic real-time or real-time malloc targets. This is
not supported when incorporating a generated S-function from one release
into a model that you build with a different release.
You can place a generated S-Function block into another model from which
you can generate another S-function. This allows any level of nested
S-functions. For limitations related to nesting, see “Limitations on Nesting
S-Functions” on page 12-50.

12-35

12

Desktops

Note While the S-function target provides a means to deploy an application
component for reuse while shielding its internal logic from inspection and
modification, the preferred solutions for protecting intellectual property in
distributed components are:
• The protected model, a referenced model from which all block and line
information has been eliminated using the Model Protection facility. For
more information, see “Protected Model” in the Simulink documentation.
• The Embedded Coder shared library system target file, used to generate
a shared library for a model or subsystem for use in a system simulation
external to Simulink. For more information see “Shared Object Libraries”
in the Embedded Coder documentation.

Required Files for S-Function Deployment
To deploy your generated S-Function block for inclusion in other models
for simulation, you need only provide the binary MEX-file object that was
generated in the current working folder when the S-Function block was
created:
subsys_sf.mexext

where subsys is the subsystem name and mexext is a platform-dependent
MEX-file extension (see mexext). For example, SourceSubsys_sf.mexw32.
To deploy your generated S-Function block for inclusion in other models for
code generation, you must provide all of the files that were generated in the
current working folder when the S-Function block was created:
• subsys_sf.c or .cpp, where subsys is the subsystem name (for example,
SourceSubsys_sf.c)
• subsys_sf.h
• subsys_sf.mexext, where mexext is a platform-dependent MEX-file
extension (see mexext)
• Subfolder subsys_sfcn_rtw and its contents

12-36

Generated S-Function Block

Sample Time Propagation in Generated S-Functions
A generated S-Function block can inherit its sample time from the model in
which it is placed if certain criteria are met. Conditions that govern sample
time propagation for both Model blocks and generated S-Function blocks are
described in “Inherit Sample Times” in the Simulink documentation and
“Inherited Sample Time for Referenced Models” on page 3-29 in the Simulink
Coder documentation.
To generate an S-Function block that meets the criteria for inheriting sample
time, you must constrain the solver for the model from which the S-Function
block is generated. On the Solver configuration parameters dialog pane,
set Type to Fixed-step and Periodic sample time constraint to Ensure
sample time independent. If the model is unable to inherit sample times,
this setting causes the Simulink software to display an error message when
building the model. See “Periodic sample time constraint” in the Simulink
documentation for more information about this option.

Choose a Solver Type
If the model containing the subsystem from which you generate an S-function
uses a variable-step solver, the generated S-function contains zero-crossing
functions and will work properly only in models that use variable-step solvers.
If the model containing the subsystem from which you generate an S-function
uses a fixed-step solver, the generated S-function contains no zero-crossing
functions and the generated S-function will work properly in models that use
variable-step or fixed-step solvers.

Create S-Function Blocks from a Subsystem
This section illustrates how to extract a subsystem from a model and generate
a reusable S-function component from it.
The next figure shows SourceModel, a simple model that inputs signals to a
subsystem. The subsequent figure shows the subsystem, SourceSubsys. The
signals, which have different widths and sample times, are
• A Step block with sample time 1
• A Sine Wave block with sample time 0.5

12-37

12

Desktops

• A Constant block whose value is the vector [-2 3]

SourceModel

SourceSubsys

The objective is to extract SourceSubsys from the model and build an
S-Function block from it, using the S-function target. The S-Function block
must perform identically to the subsystem from which it was generated.
In this model, SourceSubsys inherits sample times and signal widths from its
input signals. However, S-Function blocks created from a model using the
S-function target will have all signal attributes (such as signal widths or
sample times) hard-wired. (The sole exception to this rule concerns sample
times, as described in “Sample Time Propagation in Generated S-Functions”
on page 12-37.)

12-38

Generated S-Function Block

In this example, you want the S-Function block to retain the properties of
SourceSubsys as it exists in SourceModel. Therefore, before you build the
subsystem as a separate S-function component, you must set the inport
sample times and widths explicitly. In addition, the solver parameters of
the S-function component must be the same as those of the original model.
The generated S-function component will operate identically to the original
subsystem (see “Choose a Solver Type” on page 12-37 for an exception to
this rule).
To build SourceSubsys as an S-function component,
1 Create a new model and copy/paste the SourceSubsys block into the empty

window.
2 Set the signal widths and sample times of inports inside SourceSubsys

such that they match those of the signals in the original model. Inport 1,
Filter, has a width of 1 and a sample time of 1. Inport 2, Xferfcn, has
a width of 1 and a sample time of 0.5. Inport 3, offsets, has a width of
2 and a sample time of 0.5.
3 The generated S-Function block should have three inports and one outport.

Connect inports and an outport to SourceSubsys, as shown in the next
figure.

The signal widths and sample times are propagated to these ports.

12-39

12

Desktops

4 Set the solver type, mode, and other solver parameters such that they

are identical to those of the source model. This is easiest to do if you use
Model Explorer.
5 In the Configuration Parameters dialog box, go to the Code Generation

pane.
6 Click Browse to open the System Target File Browser.
7 In the System Target File Browser, select the S-function target,

rtwsfcn.tlc, and click OK. The Code Generation pane appears as

follows.

8 Select the S-Function Target pane. Make sure that Create new model

is selected, as shown in the next figure:

12-40

Generated S-Function Block

When this option is selected, the build process creates a new model after it
builds the S-function component. The new model contains an S-Function
block, linked to the S-function component.
Click Apply.
9 Save the new model containing your subsystem, for example as

SourceSubsys.
10 Build the model.
11 The Simulink Coder build process builds the S-function component in the

working folder. After the build, a new model window is displayed.

Optionally you can save the generated model, for example as
SourceSubsys_Sfunction.
12 You can now copy the Simulink Coder S-Function block from the new model

and use it in other models or in a library.
Note For a list of files required to deploy your S-Function block for
simulation or code generation, see “Required Files for S-Function
Deployment” on page 12-36.
The next figure shows the S-Function block plugged into the original model.
Given identical input signals, the S-Function block will perform identically
to the original subsystem.

12-41

12

Desktops

Generated S-Function Configured Like SourceModel

The speed at which the S-Function block executes is typically faster than the
original model. This difference in speed is more pronounced for larger and
more complicated models. By using generated S-functions, you can increase
the efficiency of your modeling process.

Tunable Parameters in Generated S-Functions
You can use tunable parameters in generated S-functions in two ways:
• Use the Generate S-function feature (see “Automate S-Function
Generation” on page 14-23).
or
• Use the Model Parameter Configuration dialog box (see “Parameters” on
page 7-10) to declare desired block parameters tunable.
Block parameters that are declared tunable with the auto storage class in
the source model become tunable parameters of the generated S-function.
These parameters do not become part of a generated model_P (formerly
rtP) parameter data structure, as they would in code generated from other
targets. Instead, the generated code accesses these parameters by using MEX
API calls such as mxGetPr or mxGetData. Your code should access these
parameters in the same way.
For more information on MEX API calls, see “About Writing C S-Functions”
and “Application Programming Interfaces to MATLAB”.

12-42

Generated S-Function Block

S-Function blocks created by using the S-function target are automatically
masked. The mask displays each tunable parameter in an edit field. By
default, the edit field displays the parameter by variable name, as in the
following example.

You can choose to display the value of the parameter rather than its variable
name by selecting Use value for tunable parameters on the Code
Generation > S-Function Target pane of the Configuration Parameters
dialog box.

When this option is chosen, the value of the variable (at code generation time)
is displayed in the edit field, as in the following example.

12-43

12

Desktops

System Target File and Template Makefiles
• “About System Target File and Template Makefiles” on page 12-44
• “System Target File” on page 12-44
• “Template Makefiles” on page 12-44

About System Target File and Template Makefiles
This section lists the target file and template makefiles that are provided
for use with the S-function target.

System Target File
• rtwsfcn.tlc

Template Makefiles
• rtwsfcn_lcc.tmf — Lcc compiler
• rtwsfcn_unix.tmf — The Open Group UNIX host

12-44

Generated S-Function Block

• rtwsfcn_vc.tmf — Microsoft Visual C++ compiler
• rtwsfcn_watc.tmf — Watcom C compiler

Checksums and the S-Function Target
The Simulink Coder software creates a checksum for a Simulink model and
uses the checksum during the build process for code reuse, model reference,
and External mode features.
The Simulink Coder software calculates a model’s checksum by
1 Calculating a checksum for each subsystem in the model. A subsystem’s

checksum is the combination of properties (data type, complexity, sample
time, port dimensions, and so forth) of the subsystem’s blocks.
2 Combining the subsystem checksums and other model-level information.

An S-function can add additional information, not captured during the block
property analysis, to a checksum by calling the function ssSetChecksumVal.
For the S-Function target, the value that gets added to the checksum is the
checksum of the model or subsystem from which the S-function is generated.
The Simulink Coder software applies the subsystem and model checksums as
follows:
• Code reuse — If two subsystems in a model have the same checksum, the
Simulink Coder build process generates code for one function only.
• Model reference — If the current model checksum matches the checksum
when the model was built, the Simulink Coder build process does not
rebuild submodels.
• External mode — If the current model checksum does not match the
checksum of the code that is running on the target, the Simulink Coder
build process generates an error.

S-Function Target Limitations
• “Limitations on Using Tunable Variables in Expressions” on page 12-46

12-45

12

Desktops

• “Run-Time Parameters and S-Function Compatibility Diagnostics” on
page 12-46
• “Limitations on Using Goto and From Block” on page 12-47
• “Limitations on Building and Updating S-Functions” on page 12-48
• “Unsupported Blocks” on page 12-49
• “SimState Not Supported for Code Generation” on page 12-49
• “Profiling Code Performance Not Supported” on page 12-50
• “Limitations on Nesting S-Functions” on page 12-50
• “Limitations on User-Defined Data Types” on page 12-50
• “Limitation on Right-Click Generation of an S-Function Target” on page
12-50
• “Limitation on S-Functions with Bus I/O Signals” on page 12-51
• “Limitation on Subsystems with Function-Call I/O Signals” on page 12-51

Limitations on Using Tunable Variables in Expressions
Certain limitations apply to the use of tunable variables in expressions. When
Simulink Coder software encounters an unsupported expression during code
generation, a warning appears and the equivalent numeric value is generated
in the code. For a list of the limitations, see “Tunable Expression Limitations”
on page 15-131.

Run-Time Parameters and S-Function Compatibility Diagnostics
If you set the S-function upgrades needed option on the
Diagnostics > Compatibility pane of the Configuration Parameters dialog
box to warning or error, the Simulink Coder software instructs you to
upgrade S-functions that you create with the Generate S-function feature.
This is because the S-function target does not register run-time parameters.
Run-time parameters are only supported for inlined S-Functions and the
generated S-Function supports features that prevent it from being inlined (for
example, it can call or contain other noninlined S-functions).
You can work around this limitation by setting the S-function upgrades
needed option to none. Alternatively, if you have an Embedded Coder

12-46

Generated S-Function Block

license, select the Create Embedded Coder SIL block check box on the
Generate S-function for Subsystem dialog box and create a SIL block
(containing the ERT S-function). In this case, you do not receive the upgrade
messages. However, you cannot include SIL blocks inside other generated
S-functions recursively.

Limitations on Using Goto and From Block
When using the S-function target, the Simulink Coder code generator restricts
I/O to correspond to the root model’s Inport and Outport blocks (or the Inport
and Outport blocks of the Subsystem block from which the S-function target
was generated). No code is generated for Goto or From blocks.
To work around this restriction, create your model and subsystem with the
required Inport and Outport blocks, instead of using Goto and From blocks
to pass data between the root model and subsystem. In the model that
incorporates the generated S-function, you would then add Goto and From
blocks.
Example Before Work Around
• Root model with a From block and subsystem, Subsystem1

• Subsystem1 with a Goto block, which has global visibility and passes its
input to the From block in the root model

12-47

12

Desktops

• Subsystem1 replaced with an S-function generated with the S-Function
target — a warning results when you run the model because the generated
S-function does not implement the Goto block

Example After Work Around
An Outport block replaces the GoTo block in Subsystem1. When you plug the
generated S-function into the root model, its output connects directly to the
To Workspace block.

Limitations on Building and Updating S-Functions
The following limitations apply to building and updating S-functions using
the Simulink Coder S-function target:
• You cannot build models that contain Model blocks using the Simulink
Coder S-function target. This also means that you cannot build a subsystem
module by right-clicking (or by using Code > C/C++ Code > Build
Selected Subsystem) if the subsystem contains Model blocks. This
restriction applies only to S-functions generated using the S-function
target, not to ERT S-functions.

12-48

Generated S-Function Block

• If you modify the model that generated an S-Function block, the Simulink
Coder build process does not automatically rebuild models containing
the generated S-Function block. This is in contrast to the practice of
automatically rebuilding models referenced by Model blocks when they
are modified (depending on the Model Reference Rebuild configuration
setting).
• Handwritten S-functions without corresponding TLC files must contain
exception-free code. For more information on exception-free code, see
“Exception Free Code” in the Simulink documentation.

Unsupported Blocks
The S-function format does not support the following built-in blocks:
• Interpreted MATLAB Function block
• S-Function blocks containing any of the following:

-

MATLAB language S-functions (unless you supply a TLC file for C code
generation)

-

Fortran S-functions (unless you supply a TLC file for C code generation)
C/C++ MEX S-functions that call into the MATLAB environment

• Scope block
• To Workspace block
The S-function format does not support blocks from the embeddedtargetslib
block library in the Embedded Coder product.

SimState Not Supported for Code Generation
You can use SimState within C-MEX and Level-2 MATLAB language
S-functions to save and restore the simulation state (see “S-Function
Compliance with the SimState” in the Simulink documentation). However,
SimState is not supported for code generation, including with the Simulink
Coder S-function target.

12-49

12

Desktops

Profiling Code Performance Not Supported
Profiling the performance of generated code using the Target Language
Compiler (TLC) hook function interface described by the example model
rtwdemo_profile is not supported for the S-function target.

Limitations on Nesting S-Functions
The following limitations apply to nesting a generated S-Function block in a
model or subsystem from which you generate another S-function:
• The software does not support nonvirtual bus input and output signals for
a nested S-function.
• You should avoid nesting an S-function in a model or subsystem having
the same name as the S-function (possibly several levels apart). In such
situations, the S-function can be called recursively. The software currently
does not detect such loops in S-function dependency, which can result
in aborting or hanging your MATLAB session. To prevent this from
happening, be sure to name the subsystem or model to be generated as
an S-function target uniquely, to avoid duplicating any existing MEX
filenames on the MATLAB path.

Limitations on User-Defined Data Types
The Simulink Coder S-function target does not support the HeaderFile
property that can be specified on user-defined data types, including those
based on Simulink.AliasType, Simulink.Bus, and Simulink.NumericType
objects. If a user-defined data type in your model uses the HeaderFile
property to specify an associated header file, Simulink Coder S-function target
code generation disregards the value and does not generate a corresponding
include statement.

Limitation on Right-Click Generation of an S-Function Target
If you generate an S-function target by right-clicking a Function-Call
Subsystem block, the original subsystem and the generated S-function might
not be consistent. An inconsistency occurs when the States when enabling
parameter of the Trigger Port block inside the Function-Call Subsystem block
is set to inherit. You must set the States when enabling parameter to
reset or held, otherwise Simulink reports an error.

12-50

Generated S-Function Block

Limitation on S-Functions with Bus I/O Signals
If an S-function generated using the S-function target has bus input or output
signals, the generated bus data structures might include padding to align
fields of the bus elements with the Simulink representation used during
simulation. However, if you insert the S-function in a model and generate code
using a model target such as grt.tlc, the bus structure alignment generated
for the model build might be incompatible with the padding generated for the
S-function and might affect the numerical results of code execution. To make
the structure alignment consistent between model simulation and execution of
the model code, for each Simulink.Bus object, you can modify the HeaderFile
property to remove the unpadded bus structure header file. This will cause
the bus typedefs generated for the S-function to be reused in the model code.

Limitation on Subsystems with Function-Call I/O Signals
The S-function target does not support creating an S-Function block from a
subsystem that has a function-call trigger input or a function-call output.

12-51

12

12-52

Desktops

13
Real-Time Systems
• “Real-Time System Rapid Prototyping” on page 13-2
• “Hardware-In-the-Loop (HIL) Simulation” on page 13-5

13

Real-Time Systems

Real-Time System Rapid Prototyping
In this section...
“About Real-Time Rapid Prototyping” on page 13-2
“Goals of Real-Time Rapid Prototyping” on page 13-3
“Refine Code With Real-Time Rapid Prototyping” on page 13-3

About Real-Time Rapid Prototyping
Real-time rapid prototyping requires the use of a real-time simulator,
potentially connected to system hardware (for example, physical plant or
vehicle) being controlled. You generate, deploy, and tune code as it runs on
the real-time simulator or embedded microprocessor. This design step is
crucial for verifying whether a component can adequately control the system,
and allows you to assess, interact with, and optimize code.
The following figure shows a typical approach for real-time rapid prototyping.

System model
Environment model

Host

Code
generation

Algorithm model

Real-time
simulator

Tuning and
logging

Harness

Actual environment (plants)

13-2

Real-Time System Rapid Prototyping

Goals of Real-Time Rapid Prototyping
Assuming that you have documented functional requirements, refined concept
models, system hardware for the physical plant or vehicle being controlled,
and access to target products you intend to use (for example, for example, the
xPC Target or Real-Time Windows Target product), you can use real-time
prototyping to:
• Refine component and environment model designs by rapidly iterating
between algorithm design and prototyping
• Validate whether a component can adequately control the physical system
in real time
• Evaluate system performance before laying out hardware, coding
production software, or committing to a fixed design
• Test hardware

Refine Code With Real-Time Rapid Prototyping
To perform real-time rapid prototyping:
1 Create or acquire a real-time system that runs in real time on rapid

prototyping hardware. The xPC Target product facilitates real-time rapid
prototyping. This product provides a real-time operating system that
makes PCs run in real time. It also provides device driver blocks for
numerous hardware I/O cards. You can then create a rapid prototyping
system using inexpensive commercial-off-the-shelf (COTS) hardware. In
addition, third-party vendors offer products based on the xPC Target
product or other code generation technology that you can integrate into a
development environment.
2 Use Simulink Coder system target files to generate code that you can

deploy onto a real-time simulator. See the following information.

13-3

13

Real-Time Systems

Engineering Tasks

Related Product
Information

Generate code for real-time
rapid prototyping

“Targets and Code Formats”
on page 9-29 in the Simulink
Coder documentation

Examples

rtwdemo_counter
rtwdemo_async

Embedded Coder
“What Are the Standards and
Guidelines?” in the Embedded
Coder documentation
Generate code for rapid
prototyping in hard real time,
using PCs

xPC Target

Generate code for rapid
prototyping in soft real time,
using PCs

Real-Time Windows Target

help xpcdemos

“Setting Configuration
Parameters” in the xPC
Target documentation
rtvdp (and others)

“Code Generation Pane:
Real-Time Windows Target” in
the Real-Time Windows Target
documentation

3 Monitor signals, tune parameters, and log data.

13-4

Hardware-In-the-Loop (HIL) Simulation

Hardware-In-the-Loop (HIL) Simulation
In this section...
“About Hardware-In-the-Loop Simulation” on page 13-5
“Set Up and Run HIL Simulations” on page 13-6

About Hardware-In-the-Loop Simulation
Hardware-in-the-loop (HIL) simulation tests and verifies an embedded
system or control unit in the context of a software test platform. Examples
of test platforms include real-time target systems and instruction set
simulators (IISs). You use Simulink software to develop and verify a model
that represents the test environment. Using the Simulink Coder product,
you then generate, build, and download an executable for the model to the
HIL simulation platform. After you set up the environment, you can run the
executable to validate the embedded system or control unit in real time.
During HIL simulation, you gradually replace parts of a system environment
with hardware components as you refine and fabricate the components. HIL
simulation offers an efficient design process that eliminates costly iterations
of part fabrication.
The code that you build for the system simulator provides real-time system
capabilities. For example, the code can include VxWorks from Wind River or
another real-time operating system (RTOS).
The following figure shows a typical HIL setup.

13-5

13

Real-Time Systems

Simulink
Environment model

Embedded
system

Code
generation

Code
generation

Algorithm model

Harness

Real-time
simulator

The HIL platform available from MathWorks is the xPC Target product.
Several third-party products are also available for use as HIL platforms.
The xPC Target product offers hard real-time performance for any PC with
Intel® or AMD® 32-bit processors functioning as your real-time target. The
xPC Target product enables you to add I/O interface blocks to your models
and automatically generate code with code generation technology. The xPC
Target product can download the code to a second PC running the xPC Target
real-time kernel. System integrator solutions that are based on xPC Target
are also available.

Set Up and Run HIL Simulations
To set up and run HIL simulations iterate through the following steps:
1 Develop a model that represents the environment or system under

development. For more information, see:
• “Targets and Code Formats” on page 9-29
2 Generate an executable for the environment model.
3 Download the executable for the environment model to the HIL simulation

platform.
4 Replace software representing a system component with corresponding

hardware.
5 Test the hardware in the context of the HIL system.

13-6

Hardware-In-the-Loop (HIL) Simulation

6 Repeat steps 4 and 5 until you can simulate the system after including

all components that require testing.

13-7

13

13-8

Real-Time Systems

14
External Code Integration
• “Integration Options” on page 14-2
• “Reuse Algorithmic Components in Generated Code” on page 14-5
• “Deploy Algorithm Code Within a Target Environment” on page 14-14
• “Export Generated Algorithm Code for Embedded Applications” on page
14-18
• “Export Algorithm Executables for System Simulation” on page 14-21
• “Modify External Code for Language Compatibility” on page 14-22
• “Automate S-Function Generation” on page 14-23
• “Integrate External Code Using Legacy Code Tool” on page 14-28
• “Configure Model for External Code Integration” on page 14-33
• “Insert Custom Code Blocks” on page 14-36
• “Insert S-Function Code” on page 14-46

14

External Code Integration

Integration Options
In this section...
“About Integration Options” on page 14-2
“Types of External Code Integration” on page 14-2

About Integration Options
The Simulink Coder product includes a variety of approaches for integrating
legacy or custom code with generated code. Legacy code is existing
handwritten code or code for environments that must be integrated with code
generated by the Simulink Coder software. Custom code is legacy code or any
other user-specified lines of code that must be included in the Simulink Coder
build process. Collectively, legacy and custom code are called external code.
There are two ways that you can achieve external code integration. You
can import existing external code into code generated by code generation
technology or you can export generated code into an existing external code
base. For example, you might want to use generated code as a plug-in function.

Types of External Code Integration
Based on application goals, external code integration can be characterized as
follows:
• Import external code into generated code

-

Reuse of an algorithmic component in generated code
Deploy an application with algorithm code within the target environment
Generate target optimizations within algorithm code

• Export generated code into external code

-

Export generated algorithm code for an embedded application
Export an algorithm executable for system simulation

Use the following flow diagram to prepare for integration and choose
integration paths that best map to your application components. As the

14-2

Integration Options

diagram shows, before you make integration decisions, assess your application
architecture and partition it as much as possible. Working with smaller units
makes it easier to map algorithms to modeling components and decide how to
integrate the components. For each component, use the highlighted area of
the flow diagram to identify the most applicable type of integration. Then, see
the information provided for the corresponding type.

14-3

14

External Code Integration

Assess application partitioning

Map algorithms to modeling components

For each component, decide...
Integrate
existing external code with
generated code
?

Yes

Hardware
independent, all C or C++
Example: lookup table
?

Yes

Reuse algorithmic
component in
generated code

Yes

Deploy with algorithm
code within target
environment

No

No

Hardware
specific, external to algorithm
Example: device driver
?
No
Hardware
specific, generated model
code set up to run in real time
Example: connection to timer
interrupt or RTOS
?
No
Hardware
specific, inside algorithm
Example: optimized
instructions
?

Integrate
generated code with existing
external code
?
No
Use component as is

14-4

Yes

Plug
subsystem code
into existing code base
Example: specialized algorithm
inserted into larger
application
?
No
Plug object
code into larger model
Example: intellectual
property protection
?

Yes

Yes

Generate target
optimizations
within algorithm code

Yes

Export generated
algorithm code for
embedded application

Yes

Export algorithm
executable for
system simulation

Reuse Algorithmic Components in Generated Code

Reuse Algorithmic Components in Generated Code
In this section...
“Reusable Algorithmic Components” on page 14-5
“Integrate External MATLAB Code” on page 14-5
“Integrate External C or C++ Code” on page 14-8
“Integrate Fortran Code” on page 14-11
“Integration Considerations for Reusable Algorithmic Components” on
page 14-11

Reusable Algorithmic Components
You have several options for integrating reusable algorithmic components
with the generated code. Such components are hardware-independent and can
be verified with Simulink simulation. Examples of such components include:
• Lookup tables
• Math utilities
• Digital filters
• Special integrators
• Proportional–integral–derivative (PID) control modules
Some integration options allow you to integrate external code for a reusable
component directly, while other options convert external code to modeling
elements. To take full advantage of Model-Based Design, convert code to
modeling elements which you can then use in the Simulink or Stateflow
simulation environment. Doing so enables you to simulate and generate code
for an integrated component and, for example, use software-in-the-loop (SIL)
or processor-in-the-loop (PIL) testing to verify whether algorithm behavior
is the same in both environments.

Integrate External MATLAB Code
The following diagram identifies common characteristics or requirements for
reusable algorithmic components written in MATLAB code and recommends

14-5

14

External Code Integration

solutions in each case. The table that follows the diagram provides more
detail. Collectively, the diagram and table help you choose the best solution
for your application and find more related information.
MATLAB
external code

j

Must
model continuous
state dynamics
?
No
Complies
with MATLAB for
code gen subset
?

Yes

k

Yes

Refactor
code

No
Can
refactor code to
comply with MATLAB
for code gen
subset
?
No

Yes

Embed code in
MATLAB
Function block

No

l

Optimize
for runtime
performance or
prepare to deploy
in embedded
system
?

Yes

m

Yes

Generate C source
code, executable, or
library file with
MATLAB Coder

No

C/C++
programming
experience and MATLAB
code includes C or
C++ constructs
?

Yes
Convert code to C or
C++ by hand and
use a C/C++ external
code option

No

n

Sections
of MATLAB code
map to built-in
blocks
?
Yes
Identify
applicable
built-in blocks

14-6

Embed
MATLAB code in
model
?

No

Write MATLAB
S-function and TLC
file by hand

Add S-function or
blocks to model

If necessary, add
support files to and
control model code
generation andl builds

Reuse Algorithmic Components in Generated Code

If...

Then...

For More Information, See...

The algorithm
must model
continuous state
dynamics

Write a MATLAB
S-function and, for
generating code, a
corresponding TLC file
for the algorithm and add
the S-function to your
model

• “MATLAB S-Functions”

2

You want to
embed MATLAB
code directly in
the model

Add a MATLAB Function
block to the model and
embed the MATLAB code
in that block

MATLAB Function

3

You need to
optimize runtime
performance or
prepare to deploy
the code in an
embedded system

Use MATLAB Coder
software to generate a C
source code, executable, or
library file

“Getting Started with MATLAB Coder”

4

You have C or
C++ programming
experience and the
external MATLAB
code is compact
and primarily
uses C or C++
constructs

Convert the MATLAB code
to C or C++ code manually
and choose an option for
integrating the C or C++
code

“Integrate External C or C++ Code” on
page 14-8

5

Sections of the
external MATLAB
code map to
built-in blocks

Develop the algorithm in
the context of a model,
using the applicable built
in blocks

• “Modeling Basics” and
“Component-Based Modeling”

1

• “Inline MATLAB File S-Functions”

• “Supported Products and Block Usage”
on page 1-92

To embed external MATLAB code in a MATLAB Function block or generate
C or C++ code from MATLAB code with the MATLAB Coder software, the
MATLAB code must use functions suitable for code generation.

14-7

14

External Code Integration

Integrate External C or C++ Code
The following diagram identifies common characteristics or requirements for
reusable algorithmic components written in C or C++ code and recommends
solutions in each case. The table that follows the diagram provides more
detail. Collectively, the diagram and table will help you choose the best
solution for your application and find more related information.
C or C++
external code

j

Simulation
environment
?
Simulink

lFull

Use Stateflow
Custom Code
Interface

Stateflow

kMATLAB for code gen
mModerate

Level of
flexibility and
control
?
Basic

Call C code with
coder.ceval function
embedded in
MATLAB
Function block

Generate S-function
and TLC files with
Legacy Code Tool

n

Generate S-function
and TLC files with
S-Function Builder
(C only)
Write or modify
S-function and TLC
files by hand
Add S-function or
blocks to model
If necessary, add
support files to and
control model code
generation andl builds

14-8

Fine tune
generated files
?
Yes

No

Reuse Algorithmic Components in Generated Code

1

2

3

4

5

If...

Then...

For More Information, See...

The external code will
simulate in a Stateflow
environment

Use the Stateflow
custom code interface

• sf_custom

Performance is not an
issue and you want to
quickly embed a call to
external C or C++ code
in a model

Call the C or C++ code
with the coder.ceval
function from a
MATLAB Function
block

• coder.ceval function description

You want maximum
flexibility and the
ability to control what
code is generated; the
application requires
function overloading or
you need to format data
definitions such that
they are compatible
with a function

Write an S-function and
TLC file manually

• “C S-Function Examples” and “C++
S-Function Examples”

You want ease of
use with moderate
flexibility to control
what code gets
generated,typically for
discrete applications;
you have C or
C++ programming
experience, but prefer
to generate the files
that add the code to
a model; optimizing
generated code is
essential

Use the Legacy Code
Tool to generate the
S-function and TLC
files; optionally, you can
fine-tune the generated
files manually to better
meet application needs

• rtwdemo_lct_lut_script

You want ease of use
with basic flexibility to
control what code gets
generated, typically

Use the S-Function
Builder to generate the
S-function and TLC
files; optionally, you can

“Build S-Functions Automatically” in
the Simulink documentation

• “Calling Custom C Code Functions”
in the Stateflow documentation
• MATLAB Function block

• “S-Function Basics”
• “Insert S-Function Code” on page
14-46

• “Integrate C Functions Using
Legacy Code Tool” in the Simulink
documentation
• “Integrate External Code Using
Legacy Code Tool” on page 14-28

14-9

14

External Code Integration

If...

Then...

for mixed discrete
and continuous-time
applications;
programming
experience is limited
or the external code
requires a Fixed-Point
block interface

fine tune the generated
files manually to better
meet application needs

For More Information, See...

If you must control how code generation technology declares, stores, and
represents data in generated code, you can do so by designing (creating) and
applying custom storage classes (CSCs) if you have an Embedded Coder
license. For information on CSCs see the examples rtwdemo_cscpredef,
rtwdemo_importstruct, and rtwdemo_advsc and “Custom Storage Classes”
in the Embedded Coder documentation.

14-10

Reuse Algorithmic Components in Generated Code

Integrate Fortran Code
The following diagram shows that to integrate external Fortran code as
reusable algorithmic components you must integrate the code by writing an
S-function and corresponding TLC file.
Fortran
external code
Write or modify
S-function and TLC
files by hand
Add S-function
to model
If necessary, add
support files to and
control model code
generation andl builds

For information, see “Fortran S-Function Examples” and “Fortran
S-Functions”

Integration Considerations for Reusable Algorithmic
Components
Note Solutions marked with EC only require an Embedded Coder license.

14-11

14

14-12

External Code Integration

If...

Consider...

For More Information,
See...

Generated code must use math
functions and operators that
are consistent with imported
external code

EC only—Using the code
replacement library (CRL)
API, Code Replacement Tool,
and Code Replacement Viewer
to create, examine, validate,
and register function and
operator replacement tables

• rtwdemo_crl_script

Generated code must share
data with imported external
code

Using data creation and
management technologies,
such as Simulink data objects,
alias and numeric data types,
and data type replacement to
match data type, formatting,
and storage that is consistent
with that used by the imported
external code

• “Data Types”

Style and format of identifiers
in generated code must be
consistent with style and
format applied in imported
external code

In the Configuration
Parameters dialog box, on
the Symbols pane, configure
identifier naming for the
generated code

• rtwdemo_symbols

• “Introduction to Code
Replacement Libraries”
in the Embedded Coder
documentation

• “Data Representation”

• rtwdemo_namerules
• “Configure Generated
Identifiers” on page
9-73 and “Configure
Generated Identifiers in
Embedded System Code”
in the Embedded Coder
documentation

Reuse Algorithmic Components in Generated Code

If...

Consider...

For More Information,
See...

Use of comments in generated
code must match the use
of comments in imported
external code

In the Configuration
Parameters dialog box, on the
Comments pane, configure
comments for the generated
code

• rtwdemo_comments

Style of code, such as style and
usage of parentheses, must
be match the style used in
imported external code

EC only—In the Configuration
Parameters dialog box, on the
Code Style pane, configure
the style for the generated
code

• rtwdemo_parentheses

• “Configure Code Comments”
on page 9-72 and “Configure
Code Comments in
Embedded System Code”
in the Embedded Coder
documentation
• “Control Code Style” in
the Embedded Coder
documentation

14-13

14

External Code Integration

Deploy Algorithm Code Within a Target Environment
Code generation technology can generate a single set of application source
files from an algorithm model and integrated external C or C++ code that
supports the target environment hardware. For example, you might have a
working device driver that you want to integrate with algorithmic code that
has to read data from and write data to the I/O device the driver supports.
Typically, a deployed model algorithm calls out to the external code.
The following diagram identifies common characteristics or requirements for
a target environment in which generated algorithm code might be deployed
and recommends solutions. The table that follows the diagram provides more
detail. Collectively, the diagram and table help you choose the best solution
for your application and find more related information.

14-14

Deploy Algorithm Code Within a Target Environment

External code

j

Embed call
to hardware-specific code
within generated
algorithm code
?

Yes

Use Legacy
Code Tool

k

Insert
external code into
entry-point functions
generated for
model
?

l

m

Control
organization
and format of
generated code
files
?

No

Yes

Level of
control over placement
of generated
code
?

Moderate

Use Custom Code
Configuration
Parameter dialog
boxto insert code

n

Use Custom Code
blocks to insert
code

o

Yes

Use custom
storage classes

Yes

Use memory
sections

Yes

Generate and
customize ERT
target main
program module

No

Insert
comments or
pragmas to identify
sections of
memory
?

p

Use custom file
processing

No

Control
data declaration,
storage, and
representation
?

High

Yes

No

Set up
generated algorithmic
code to run in
real time
?

No
Done - no
more choices

14-15

14

External Code Integration

Note Solutions marked with EC only require an Embedded Coder license.

1

If You Need To...

Then...

For More Information, See...

Embed a call to
hardware-specific
code, such as a device
driver, within generated
algorithm code

Use the Legacy Code Tool

• “Integrate Device Drivers” on
page 24-135
• “Integrate C Functions Using
Legacy Code Tool” in the
Simulink documentation
• “Integrate External Code Using
Legacy Code Tool” on page 14-28

2

3

14-16

Insert target-specific
C or C++ code into
entry-point functions
that Simulink Coder
generates for a model with
a high level of control
over code placement;
for example, inserting
startup, initialization, or
termination code

Use Custom Code blocks

Insert application-specific
C or C++ code—near the
top of the generated source
code or header file or inside
the model initialization or
termination function—or
files for the build
process—source, header,
library—for the external
code

Configure files and
data for the external
code environment by
entering code and
file specifications for
parameters on the Code
Generation > Interface
pane of the Configuration
Parameters dialog box

• rtwdemo_slcustcode
• “Insert Custom Code Blocks” on
page 14-36

• Integrating the Generated Code
into the External Environment
• “Configure Model for External
Code Integration” on page 14-33

Deploy Algorithm Code Within a Target Environment

4

5

6

If You Need To...

Then...

For More Information, See...

Control the organization
and format of code files
generated for a model—for
example, placement of code
in sections, inclusion of
banners, calls to generated
entry-point functions,
generation of a main
program module

EC only—Use the
custom file processing
components—code
generation template
(CGT) files, code template
API, and custom
file processing (CFP)
templates (the API and
CFP templates require
TLC programming
knowledge

• rtwdemo_codetemplate

Control how the
Simulink Coder product
declares, stores, and
represents signals,
tunable parameters, block
states, and data objects in
generated code

EC only— Design (create)
and apply custom storage
classes

Insert comments or

EC only— Use the
memory section capability

pragmas in generated code

to identify memory for
custom storage classes or
model- or subsystem-level
functions and internal
data
7

Set up generated
algorithmic code to run
in real time—within the
context of a real-time
operating system (RTOS)
or on hardware that is
not running an operating
system (bare board)

• “Customize Code Organization
and Format” in the Embedded
Coder documentation

• rtwdemo_cscpredef
• rtwdemo_importstruct
• rtwdemo_advsc
• “Custom Storage Classes”
in the Embedded Coder
documentation

EC only—Generate and
customize an ERT target
main (harness) program
module (ert_main.c or
ert_main.cpp) for the
model

• rtwdemo_memsec
• “About Memory Sections”

• “Deployment”
• “Standalone Programs (No
Operating System)”

14-17

14

External Code Integration

Export Generated Algorithm Code for Embedded
Applications
You have multiple options for configuring and preparing a model or subsystem
so that you can plug its generated source code into an existing external code
base.
Scan the first column of the following table to identify tasks that apply
to the algorithm code you want to export. For each task that applies, the
information in the corresponding row describes how to achieve the goal, using
code generation technology.
Note Solutions marked with EC only require an Embedded Coder license.

If You Need To...

Then...

For More Information, See...

Insert C or C++ code
into specific entry-point
functions that Simulink
Coder generates for
interfacing with the
external code

Use Custom Code blocks

• rtwdemo_slcustcode

Pass composite data

Represent the data in the
model as a vector or bus

• “Insert Custom Code Blocks” on page
14-36

• rtwdemo_scalarrep
• rtwdemo_slbus
• “Composite Signals”
• “Optimize Code Generated for Vector
Assignments” on page 19-6 and“Buses”

Read from or write to a
specific region or area of
memory

14-18

EC only— Set up a Data
Store Memory block in
the model to represent
the area of memory and
define the area with
the built-in advanced
custom storage class
(CSC) GetSet

• “Increase Code Efficiency With GetSet
CSC”
• “GetSet Custom Storage Classes” in
the Embedded Coder documentation

Export Generated Algorithm Code for Embedded Applications

If You Need To...

Then...

For More Information, See...

Generate a C++ class
interface—encapsulated
model data (properties)
and model entry-point
functions (methods)—to
the model code

EC only— Configure
and generate the C++
encapsulation interface
in the Configuration
Parameters dialog box
or programmatically in
the MATLAB command
window or with a script

• “Simple Use of C++ Encapsulation
Control”

Control how Embedded
Coder generates
function prototypes
— arguments, argument
order, and data
types—for a model
(for example, so the
prototypes match the
external code)

EC only— Configure
function prototypes
for the model by
clicking the Configure
Model Functions
button on the Code
Generation > Interface
pane of the Configuration
Parameters dialog
box and entering
data in the Model
Interface dialog box;
alternatively, configure
the function prototypes
programmatically in
the MATLAB command
window or with a script

• “Sample Procedure for Configuring
Function Prototypes”

Insert
application-specific C
or C++ code—near the
top of the generated
source code or header
file or inside the
model initialization or
termination function—or
files for the build
process—source, header,

Configure files and
data for the external
code environment by
entering code and
file specifications for
parameters on the Code
Generation > Interface
pane of the Configuration
Parameters dialog box

• Integrating the Generated Code into
the External Environment

• “C++ Encapsulation Interface Control”
in the Embedded Coder documentation

• “Function Prototype Control” in the
Embedded Coder documentation

• “Configure Model for External Code
Integration” on page 14-33

14-19

14

External Code Integration

If You Need To...

Then...

For More Information, See...

EC only— Review and
adjust for exported
subsystem requirements,
configure the parent
model to use an ERT
target, and right-click
build the subsystem
block using the
C/C++ Code > Export
Functions menu item

• “Techniques for Exporting
Function-Call Subsystems”

library—for the external
code
Generate code, which is
to be integrated with an
existing C code base, for
a function-call or virtual
subsystem

14-20

• rtwdemo_export_functions
• “Export Function-Call Subsystems” in
the Embedded Coder documentation

Export Algorithm Executables for System Simulation

Export Algorithm Executables for System Simulation
If you have an Embedded Coder license, you can use an ERT shared library
target (shrlib.tlc) to build a Windows dynamic link library (.dll) or a
UNIX shared object (.so) file from a model. An application, which runs on a
Windows or a UNIX system, can then load the shared library file. You can
upgrade a shared library without having to recompile applications that use it.
Uses of shared library files include:
• Adding a software component to an application for system simulation
• Reusing off-the-shelf software modules among applications on a host system
• Hiding source code (intellectual property) for software shared with a vendor
For an example, see rtwdemo_shrlib. For more information, see “Shared
Object Libraries” in the Embedded Coder documentation.

14-21

14

External Code Integration

Modify External Code for Language Compatibility
If you need to integrate external C code with generated C++ code or vice
versa, you must modify your external code to be language compatible with the
generated code. Options for making the code language compatible include:
• Writing or rewriting the legacy or custom code in the same language as
the generated code.
• If the generated code is in C++ and your legacy or custom code is in C, for
each C function, create a header file that prototypes the function, using
the following format:
#ifdef __cplusplus
extern "C" {
#endif
int my_c_function_wrapper();
#ifdef __cplusplus
}
#endif

The prototype serves as a function wrapper. If your compiler supports C++
code, the value __cplusplus is defined. The linkage specification extern
"C" specifies C linkage with no name mangling.
• If the generated code is in C and your legacy or custom code is in C++,
include an extern "C" linkage specification in each .cpp file. For example,
the following shows a portion of C++ code in the file my_func.cpp:
extern "C" {
int my_cpp_function()
{
...
}
}

14-22

Automate S-Function Generation

Automate S-Function Generation
The Generate S-function feature automates the process of generating an
S-function from a subsystem. In addition, the Generate S-function feature
presents a display of parameters used within the subsystem, and lets you
declare selected parameters tunable.
As an example, consider SourceSubsys, the same subsystem illustrated in
the example “Create S-Function Blocks from a Subsystem” on page 12-37.
The objective is to automatically extract SourceSubsys from the model and
build an S-Function block from it, as in the previous example. In addition,
the workspace variable K , which is the gain factor of the Gain block within
SourceSubsys (as shown in the Gain block parameter dialog box below), is
declared and generated as a tunable variable.

To auto-generate an S-function from SourceSubsys with tunable parameter K,
1 With the SourceSubsys model open, click the subsystem to select it.
2 From the Code menu, select C/C++ Code > Generate S-Function. This

menu item is enabled when a subsystem is selected in the current model.

14-23

14

External Code Integration

Alternatively, you can right-click the subsystem and select C/C++
Code > Generate S-Function from the subsystem block’s context menu.
3 The Generate S-Function window is displayed (see the next figure). This

window shows all variables (or data objects) that are referenced as block
parameters in the subsystem, and lets you declare them as tunable.
The upper pane of the window displays three columns:
• Variable Name: name of the parameter.
• Class: If the parameter is a workspace variable, its data type is shown.
If the parameter is a data object, its name and class is shown
• Tunable: Lets you select tunable parameters. To declare a parameter
tunable, select the check box. In the next figure, the parameter K is
declared tunable.
When you select a parameter in the upper pane, the lower pane shows all
the blocks that reference the parameter, and the parent system of each
such block.

Generate S-Function Window

14-24

Automate S-Function Generation

4 If you have installed the Embedded Coder product, and if the subsystem

does not have a continuous sample time, the Create Software In the
Loop (SIL) block check box is available, as shown above. Otherwise, it
is appears dimmed. When Create Software In the Loop (SIL) block
is selected, the build process generates a wrapper S-function by using the
Embedded Coder product. See “Generate S-Function Wrappers” in the
Embedded Coder documentation for more information.
5 After selecting tunable parameters, click the Build button. This initiates

code generation and compilation of the S-function, using the S-function
target. The Create New Model option is automatically enabled.
6 The build process displays status messages in the MATLAB Command

Window. When the build completes, the tunable parameters window closes,
and a new untitled model window opens.

7 The model window contains an S-Function block with the same name

as the subsystem from which the block was generated (in this example,
SourceSubsys). Optionally, you can save the generated model containing
the generated block.

14-25

14

External Code Integration

8 The generated code for the S-Function block is stored in the current

working folder. The following files are written to the top level folder:
• subsys_sf.c or .cpp, where subsys is the subsystem name (for example,
SourceSubsys_sf.c)
• subsys_sf.h
• subsys_sf.mexext, where mexext is a platform-dependent MEX-file
extension (for example, SourceSubsys_sf.mexw32)
The source code for the S-function is written to the subfolder
subsys_sfcn_rtw. The top-level .c or .cpp file is a stub file that simply
contains an include directive that you can use to interface other C/C++
code to the generated code.
Note For a list of files required to deploy your S-Function block for
simulation or code generation, see “Required Files for S-Function
Deployment” on page 12-36.
9 The generated S-Function block has inports and outports whose widths and

sample times correspond to those of the original model.
The following code, from the mdlOutputs routine of the generated S-function
code (in SourceSubsys_sf.c), shows how the tunable variable K is referenced
by using calls to the MEX API.
static void mdlOutputs(SimStruct *S, int_T tid)

...
/* Gain: '/Gain' incorporates:
* Sum: '/Sum'
*/
rtb_Gain_n[0] = (rtb_Product_p + (*(((const
real_T**)ssGetInputPortSignalPtrs(S, 2))[0]))) * (*(real_T
*)(mxGetData(K(S))));
rtb_Gain_n[1] = (rtb_Product_p + (*(((const
real_T**)ssGetInputPortSignalPtrs(S, 2))[1]))) * (*(real_T
*)(mxGetData(K(S))));

14-26

Automate S-Function Generation

Notes
• In automatic S-function generation, the Use Value for Tunable
Parameters option is always set to its default value (off).
• A MEX S-function wrapper must only be used in the MATLAB version in
which the wrapper is created.

14-27

14

External Code Integration

Integrate External Code Using Legacy Code Tool
In this section...
“Legacy Code Tool and Code Generation” on page 14-28
“Generate Inlined S-Function Files for Code Generation” on page 14-29
“Apply Code Style Settings to Legacy Functions” on page 14-30
“Address Dependencies on Files in Different Locations” on page 14-31
“Deploy S-Functions for Simulation and Code Generation” on page 14-32

Legacy Code Tool and Code Generation
You can use the Simulink Legacy Code Tool to automatically generate fully
inlined C MEX S-functions for legacy or custom code that is optimized for
embedded components, such as device drivers and lookup tables, that call
existing C or C++ functions.
Note The Legacy Code Tool can interface with C++ functions, but not C++
objects. For a work around so that the tool can interface with C++ objects, see
“Legacy Code Tool Limitations” in the Simulink documentation.
You can use the tool to:
• Compile and build the generated S-function for simulation.
• Generate a masked S-Function block that is configured to call the existing
external code.
If you want to include these types of S-functions in models for which you
intend to generate code, you must use the tool to generate a TLC block file.
The TLC block file specifies how the generated code for a model calls the
existing C or C++ function.
If the S-function depends on files in folders other than the folder containing
the S-function dynamically loadable executable file, and you want to maintain
those dependencies for building a model that includes the S-function, use the

14-28

Integrate External Code Using Legacy Code Tool

tool to also generate an rtwmakecfg.m file for the S-function. For example,
for some applications, such as custom targets, you might want to locate
files in a target-specific location. The Simulink Coder build process looks
for the generated rtwmakecfg.m file in the same folder as the S-function’s
dynamically loadable executable and calls the rtwmakecfg function if the
software finds the file.
For more information, see “Integrate C Functions Using Legacy Code Tool” in
the Simulink documentation.

Generate Inlined S-Function Files for Code Generation
Depending on your application’s code generation requirements, to generate
code for a model that uses the S-function, you can choose to do either of the
following:
• Generate one .cpp file for the inlined S-function. In the Legacy Code
Tool data structure, set the value of the Options.singleCPPMexFile field
to true before generating the S-function source file from your existing C
function. For example:
def.Options.singleCPPMexFile = true;
legacy_code('sfcn_cmex_generate', def);

• Generate a source file and a TLC block file for the inlined S-function. For
example:
def.Options.singleCPPMexFile = false;
legacy_code('sfcn_cmex_generate', def);
legacy_code('sfcn_tlc_generate', def);

singleCPPMexFile Limitations
You cannot set the singleCPPMexFile field to true if
• Options.language='C++'
• You use one of the following Simulink objects with the IsAlias property
set to true:

-

Simulink.Bus

14-29

14

External Code Integration

-

Simulink.AliasType
Simulink.NumericType

• The Legacy Code Tool function specification includes a void* or void** to
represent scalar work data for a state argument
• HeaderFiles field of the Legacy Code Tool structure specifies multiple
header files

Apply Code Style Settings to Legacy Functions
To apply the model configuration parameters for code style to a legacy
function:
1 Initialize the Legacy Code Tool data structure. For example:

def = legacy_code('initialize');
2 In the data structure, set the value of the Options.singleCPPMexFile

field to true. For example:
def.Options.singleCPPMexFile = true;

To verify the setting, enter:
def.Options.singleCPPMexFile

singleCPPMexFile Limitations
You cannot set the singleCPPMexFile field to true if
• Options.language='C++'
• You use one of the following Simulink objects with the IsAlias property
set to true:

-

14-30

Simulink.Bus
Simulink.AliasType
Simulink.NumericType

Integrate External Code Using Legacy Code Tool

• The Legacy Code Tool function specification includes a void* or void** to
represent scalar work data for a state argument
• HeaderFiles field of the Legacy Code Tool structure specifies multiple
header files

Address Dependencies on Files in Different Locations
By default, the Legacy Code Tool assumes that all files on which an S-function
depends reside in the same folder as the dynamically loadable executable file
for the S-function. If your S-function depends on files that reside elsewhere
and you are using the Simulink Coder template makefile build process, you
must generate an rtwmakecfg.m file for the S-function. For example, it is
likely that you need to generate this file if your Legacy Code Tool data
structure defines compilation resources as path names.
To generate the rtwmakecfg.m file, call the legacy_code function with
'rtwmakecfg_generate' as the first argument, and the name of the Legacy
Code Tool data structure as the second argument.
legacy_code('rtwmakecfg_generate', lct_spec);

If you use multiple registration files in the same folder and generate
an S-function for each file with a single call to legacy_code, the call to
legacy_code that specifies 'rtwmakecfg_generate' must be common to all
registration files. For more information, see “Handling Multiple Registration
Files” in the Simulink documentation
For example, if you define defs as an array of Legacy Code Tool structures,
you call legacy_code with 'rtwmakecfg_generate' once.
defs = [defs1(:);defs2(:);defs3(:)];
legacy_code('rtwmakecfg_generate', defs);

For more information, see “Build Support for S-Functions” on page 14-120.

14-31

14

External Code Integration

Deploy S-Functions for Simulation and Code
Generation
You can deploy the S-functions that you generate with the Legacy Code Tool
so that other people can use them. To deploy an S-function for simulation and
code generation, share the following files:
• Registration file
• Compiled dynamically loadable executable
• TLC block file
• rtwmakecfg.m file
• All header, source, and include files on which the generated S-function
depends
Users of the deployed files must be aware that:
• Before using the deployed files in a Simulink model, they must add the
folder that contains the S-function files to the MATLAB path.
• If the Legacy Code Tool data structure registers any required files as
absolute paths and the location of the files changes, they must regenerate
the rtwmakecfg.m file.

14-32

Configure Model for External Code Integration

Configure Model for External Code Integration
Configure a model using the Custom Code pane such that the code generator
includes external code such as headers, files, and functions. You can also
include additional files and paths in the build process.
To...

Select...

Insert custom
code near the top
of the generated
model.c or
model.cpp file,
outside of any
function

Source file and enter the custom code to insert.

Insert custom
code near the top
of the generated
model.h file

Header file and enter the custom code to insert.

Insert custom
code inside the
model’s initialize
function in the
model.c or
model.cpp file

Initialize function

Insert custom
code inside the
model’s terminate
function in the
model.c or
model.cpp file.

Terminate function and enter the custom code to
insert. Also select the Terminate function required
parameter on the Interface pane.

Add include
folders, which
contain header
files, to the build
process

Include directories and enter the absolute or relative
paths to the folders. If you specify relative paths, the
paths must be relative to the folder containing your
model files, not relative to the build folder. The order in
which you specify the folders is the order in which they
are searched for header, source, and library files.

14-33

14

External Code Integration

To...

Select...

Add source files to
be compiled and
linked

Source files and enter the full paths or just the file
names for the files. Enter just the file name if the file is
in the current MATLAB folder or in one of the include
folders. For each additional source that you specify, the
build process expands a generic rule in the template
makefile for the folder in which the source file is found.
For example, if a source file is found in folder inc, the
build process adds a rule similar to the following:
%.obj: buildir\inc\%.c
$(CC) -c -Fo$(@F) $(CFLAGS) $<

The build process adds the rules in the order you list
the source files.

14-34

Add libraries to
be linked

Libraries and enter the full paths or just the file
names for the libraries. Enter just the file name if the
library is located in the current MATLAB folder or in
one of the include folders.

Use the same
custom code
settings as
those specified
for simulation
of MATLAB
Function blocks,
Stateflow charts,
and Truth Table
blocks

Use the same custom code settings as Simulation
Target

Enable a library
model to use
custom code
settings unique
from the parent
model to which
the library is
linked

Use local custom code settings (do not inherit
from main model)

Note This option refers to the Simulation Target
pane in the Configuration Parameters dialog box.

Note This option is available only for library models
that contain MATLAB Function blocks, Stateflow
charts, or Truth Table blocks.

Configure Model for External Code Integration

If you are including a header file, in your custom header file add #ifndef
code. This avoids multiple inclusions. For example, in rtwtypes.h the
following #include guards are added:
#ifndef RTW_HEADER_rtwtypes_h_
#define RTW_HEADER_rtwtypes_h_
...
#endif /* RTW_HEADER_rtwtypes_h_ */

Note Custom code that you include in a configuration set is ignored when
building S-function targets, accelerated simulation targets, and model
reference simulation targets.
For more information about Custom Code pane parameters, see “Code
Generation Pane: Custom Code”.

14-35

14

External Code Integration

Insert Custom Code Blocks
The following sections explain how to use blocks in the Custom Code block
library to insert custom code into the code generated for a model. This chapter
includes the following topics:
In this section...
“Custom Code Library” on page 14-36
“Embed Custom Code Directly Into MdlStart Function” on page 14-40
“Custom Code in Subsystems” on page 14-43
“Preserve User Files in Build Folder” on page 14-44

Custom Code Library
The Custom Code library contains blocks that enable you to insert your own
C or C++ code into specific functions within code generated by the Simulink
Coder product for root models and subsystems. These blocks are a superset of
code customization capabilities built into the Custom Code Configuration
Parameters dialog box, and provide greater flexibility in terms of code
placement than the controls on the dialog box.
The Custom Code library is part of the Simulink Coder library. You can access
the Simulink Coder library by using the Simulink Library Browser. You can
access Custom Code blocks by using the Simulink Coder library or by entering
the MATLAB command rtwlib and then double-clicking the Custom Code
Library block within it. Alternatively, you can enter the command custcode.

14-36

Insert Custom Code Blocks

Note If you need to integrate custom C++ code with generated C code or vice
versa, see “Modify External Code for Language Compatibility” on page 14-22.
All Custom Code blocks except for Model Header and Model Source can be
dragged into either root models or atomic subsystems. Model Header and
Model Source blocks can only be placed in root models.
Note You can use models containing Custom Code blocks as submodels
(models referenced by Model blocks). However, when simulation targets for
submodels are generated, all Custom Code blocks within them are ignored.
On the other hand, when submodel code is generated to create Simulink
Coder targets, custom code is included and is compiled in the generated code.
The Custom Code library contains ten blocks that insert custom code into the
generated model files and functions. You can view the blocks either by
• Expanding the Custom Code node (under Simulink Coder library) in the
Simulink Library Browser
• Right-clicking the Custom Code sublibrary icon in the right pane of the
Simulink Library Browser
The latter method opens the window shown in the previous section.

14-37

14

External Code Integration

The two blocks on the top row contain text fields for inserting custom code at
the top and bottom of
• model.h — Model Header File block
• model.c or model.cpp — Model Source File block
Each block contains two fields, in which you type or paste code and comments:
• Top of Model Source/Header
• Bottom of Model Source/Header
The next figure shows the Model Source block dialog box.

The eight function blocks in the second and third rows contain text fields to
insert custom code sections at the top and bottom of these designated model
functions:

14-38

Insert Custom Code Blocks

• SystemStart — System Start function block
• SystemInitialize — System Initialize function block
• SystemTerminate — System Terminate function block
• SystemEnable — System Enable function block
• SystemDisable — System Disable function block
• SystemOutputs — System Outputs function block
• SystemUpdate — System Update function block
• SystemDerivatives — System Derivatives function block
Each of these blocks provides a System Outputs Function Custom Code dialog
box that contains three fields:
• Declaration code
• Execution code
• Exit code

14-39

14

External Code Integration

Embed Custom Code Directly Into MdlStart Function
The following example uses a System Start Function block to introduce code
into the MdlStart function. The next figure shows a simple model with the
System Start Function block inserted.

14-40

Insert Custom Code Blocks

Double-clicking the System Start Function block opens the System Start
Function Custom Code dialog box.

14-41

14

External Code Integration

The code generator inserts the code
entered here into the MdlStart function.

You can insert custom code into any or all of the available text fields.

14-42

Insert Custom Code Blocks

The code below is the MdlStart function for this example (mymodel).
void MdlStart(void)
{
{
{
/* user code (Start function Header) */
/* System '' */
unsigned int *ptr = 0xFFEE;
/* user code (Start function Body) */
/* System '' */
/* Initialize hardware */
*ptr = 0;
}
}
MdlInitialize();
}

The custom code entered in the System Start Function Custom Code dialog
box is embedded directly in the generated code. Each block of custom code is
tagged with a comment such as
/* user code (Start function Header) */

Custom Code in Subsystems
The location of a Custom Code block in your model determines the location of
the code it contains. You can use System Custom Code blocks either at root
level or within atomic subsystems; the code is local to the subsystem in which
you place the blocks. For example, the System Outputs block places code in
mdlOutputs when the code block resides in the root model. If the System
Outputs block resides in a triggered or enabled subsystem, however, the code
is placed in the subsystem’s Outputs function.
The ordering for a triggered or enabled system is
1 Output entry
2 Output exit

14-43

14

External Code Integration

3 Update entry
4 Update exit

Note If a root model or atomic subsystem does not need to generate a
function for which a Custom Code block has been supplied, either the code
in the block is not used or an error is generated. There is no diagnostic
setting to control this. To eliminate the error, remove the Custom Code
block.

Preserve User Files in Build Folder
Prior to Release 13 (Version 5.0), the Simulink Coder product did not delete
any .c or .h files that you might have placed in the build folder when
rebuilding targets. From Release 13 onward, all foreign source files are by
default deleted during builds, but can be preserved by following the guidelines
given below.
If you put a .c/.cpp or .h source file in a build folder, and you want to
prevent the Simulink Coder product from deleting it during the TLC code
generation process, insert the string target specific file in the first line
of the .c/.cpp or .h file. For example,
/* COMPANY-NAME target specific file
*
*
This file is created for use with the
*
COMPANY-NAME target.
*
It is used for ...
*/
...

Make sure you spell the string “target specific file” as shown in the preceding
example, and that the string is in the first line of the source file. Other text
can appear before or after this string.
In addition to preserving them, flagging user files in this manner prevents
postprocessing them to indent them along with generated source files.
Auto-indenting occurred in previous releases to build folder files with names
having the pattern model_*.c/.cpp (where * could be any string). The

14-44

Insert Custom Code Blocks

indenting is harmless, but can cause differences to be detected by source
control software that might trigger unnecessary updates.

14-45

14

External Code Integration

Insert S-Function Code
In this section...
“About S-Functions and Code Generation” on page 14-46
“Write Noninlined S-Functions” on page 14-52
“Write Wrapper S-Functions” on page 14-54
“Write Fully Inlined S-Functions” on page 14-64
“Write Fully Inlined S-Functions with mdlRTW Routine” on page 14-65
“Guidelines for Writing Inlined S-Functions” on page 14-91
“Write S-Functions That Support Expression Folding” on page 14-91
“S-Functions That Specify Port Scope and Reusability” on page 14-105
“S-Functions That Specify Sample Time Inheritance Rules” on page 14-111
“S-Functions That Support Code Reuse” on page 14-113
“S-Functions for Multirate Multitasking Environments” on page 14-113
“Build Support for S-Functions” on page 14-120

About S-Functions and Code Generation
This chapter describes how to create S-functions that work seamlessly with
Simulink Coder code generation. It begins with basic concepts and concludes
with an example of how to create a highly optimized direct-index lookup table
S-Function block.
This chapter assumes that you understand the following concepts:
• Level 2 S-functions
• Target Language Compiler (TLC) scripting
• How the Simulink Coder software generates and builds C/C++ code

14-46

Insert S-Function Code

Note When this chapter refers to actions performed by the Target Language
Compiler, including parsing, caching, creating buffers, and so on, the name
Target Language Compiler is spelled out fully. When referring to code written
in the Target Language Compiler syntax, this chapter uses the abbreviation
TLC.

Note The guidelines presented in this chapter are for Simulink Coder
users. Even if you do not currently use the Simulink Coder code generator,
you should follow the practices presented in this chapter when writing
S-functions, especially if you are creating general-purpose S-functions.

Classes of Problems Solved by S-Functions
S-functions help solve various kinds of problems you might face when working
with the Simulink and Simulink Coder products. These problems include
• Extending the set of algorithms (blocks) provided by the Simulink and
Simulink Coder products
• Interfacing legacy (hand-written) code with the Simulink and Simulink
Coder products
• Interfacing to hardware through device driver S-functions
• Generating highly optimized code for embedded systems
• Verifying code generated for a subsystem as part of a Simulink simulation
S-functions are written using an application program interface (API) that
allows you to implement generic algorithms in the Simulink environment with
a great deal of flexibility. This flexibility cannot always be maintained when
you use S-functions with the Simulink Coder code generator. For example, it
is not possible to access the MATLAB workspace from an S-function that is
used with the code generator. However, using the techniques presented in
this chapter, you can create S-functions for most applications that work with
the Simulink Coder generated code.

14-47

14

External Code Integration

Although S-functions provide a generic and flexible solution for implementing
complex algorithms in a Simulink model, the underlying API incurs overhead
in terms of memory and computation resources. Most often the additional
resources are acceptable for real-time rapid prototyping systems. In many
cases, though, additional resources are unavailable in real-time embedded
applications. You can minimize memory and computational requirements by
using the Target Language Compiler technology provided with the Simulink
Coder product to inline your S-functions. If you are producing an S-function
for existing code, consider using the Simulink Legacy Code Tool.

Types of S-Functions
The implementation of S-functions changes based on your requirements. This
chapter discusses the typical problems that you may face and how to create
S-functions for applications that need to work with the Simulink and Simulink
Coder products. These are some (informally defined) common situations:
1 “I’m not concerned with efficiency. I just want to write one version of my

algorithm and have it work in the Simulink and Simulink Coder products
automatically.”
2 “I have a lot of hand-written code that I need to interface. I want to call my

function from the Simulink and Simulink Coder products in an efficient
manner.”
or said another way:
“I want to create a block for my blockset that will be distributed throughout
my organization. I’d like it to be very maintainable with efficient code. I’d
like my algorithm to exist in one place but work with both the Simulink
and Simulink Coder products.”
3 “I want to implement a highly optimized algorithm in the Simulink and

Simulink Coder products that looks like a built-in block and generates
very efficient code.”
MathWorks products have adopted terminology for these different
requirements. Respectively, the situations described above map to this
terminology:
1 Noninlined S-function

14-48

Insert S-Function Code

2 Wrapper S-function
3 Fully inlined S-function

Noninlined S-Functions. A noninlined S-function is a C or C++ MEX
S-function that is treated identically by the Simulink engine and Simulink
Coder generated code. In general, you implement your algorithm once
according to the S-function API. The Simulink engine and Simulink Coder
generated code call the S-function routines (for example, mdlOutputs) during
model execution.
Additional memory and computation resources are required for each instance
of a noninlined S-Function block. However, this routine of incorporating
algorithms into Simulink models and Simulink Coder applications is typical
during the prototyping phase of a project where efficiency is not important.
The advantage gained by forgoing efficiency is the ability to change model
parameters and structures rapidly.
Writing a noninlined S-function does not involve any TLC coding. Noninlined
S-functions are the default case for the Simulink Coder build process in
the sense that once you build a MEX S-function in your model, there is no
additional preparation prior to clicking Build in the Code Generation pane
of the Configuration Parameters dialog box for your model.
Some restrictions exist concerning the names and locations of noninlined
S-function files when generating makefiles. See “Write Noninlined
S-Functions” on page 14-52.
Wrapper S-Functions. A wrapper S-function is ideal for interfacing
hand-written code or a large algorithm that is encapsulated within a few
procedures. In this situation, usually the procedures reside in modules that
are separate from the MEX S-function. The S-function module typically
contains a few calls to your procedures. Because the S-function module does
not contain any parts of your algorithm, but only calls your code, it is referred
to as a wrapper S-function.
In addition to the MEX S-function wrapper, you need to create a TLC wrapper
that complements your S-function. The TLC wrapper is similar to the
S-function wrapper in that it contains calls to your algorithm.

14-49

14

External Code Integration

Fully Inlined S-Functions. For S-functions to work in the Simulink
environment, some overhead code is generated. When the Simulink Coder
software generates code from models that contain S-functions (without
sfunction.tlc files), it embeds some of this overhead code in the generated
code. If you want to optimize your real-time code and eliminate some of the
overhead code, you must inline (or embed) your S-functions. This involves
writing a TLC (sfunction.tlc) file that eliminates all overhead code from
the generated code. The Target Language Compiler processes sfunction.tlc
files to define how to inline your S-function algorithm in the generated code.
Note The term inline should not be confused with the C++ inline keyword. In
Simulink Coder terminology, inline means to specify a text string in place of
the call to the general S-function API routines (for example, mdlOutputs). For
example, when a TLC file is used to inline an S-function, the generated code
contains the C/ C++ code that would normally appear within the S-function
routines and the S-function itself has been removed from the build process.
A fully inlined S-function builds your algorithm (block) into Simulink Coder
generated code in a manner that is indistinguishable from a built-in block.
Typically, a fully inlined S-function requires you to implement your algorithm
twice: once for the Simulink model (C/C++ MEX S-function) and once for
Simulink Coder code generation (TLC file). The complexity of the TLC file
depends on the complexity of your algorithm and the level of efficiency you’re
trying to achieve in the generated code. TLC files vary from simple to complex
in structure.
The Simulink Legacy Code Tool can automate the generation of a fully
inlined S-function and a corresponding TLC file based on information that
you register in a Legacy Code Tool data structure. For more information, see
“Integrate C Functions Using Legacy Code Tool” in the Simulink Writing
S-Functions documentation and “Integrate External Code Using Legacy Code
Tool” on page 14-28.

Basic Files Required for Implementation
This section briefly describes what files and functions you need to create
noninlined, wrapper, and fully inlined S-functions.

14-50

Insert S-Function Code

• Noninlined S-functions require the C or C++ MEX S-function source code
(sfunction.c or sfunction.cpp).
• Wrapper S-functions that inline a call to your algorithm (your C/C++
function) require an sfunction.tlc file.
• Fully inlined S-functions also require an sfunction.tlc file. Fully inlined
S-functions produce the optimal code for a parameterized S-function. This
is an S-function that operates in a specific mode dependent upon fixed
S-function parameters that do not change during model execution. For a
given operating mode, the sfunction.tlc file specifies the exact code that
is generated to implement the algorithm for that mode. For example, the
direct-index lookup table S-function at the end of this chapter contains two
operating modes — one for evenly spaced x-data and one for unevenly
spaced x-data.
Fully inlined S-functions might require the placement of the mdlRTW routine in
your S-function MEX-file sfunction.c or sfunction.cpp. The mdlRTW routine
lets you place information in model.rtw, the record file that specifies a model,
and which the Simulink Coder code generator invokes the Target Language
Compiler to process prior to executing sfunction.tlc when generating code.
Including a mdlRTW routine is useful when you want to introduce nontunable
parameters into your TLC file. Such parameters are generally used to
determine which operating mode is active in a given instance of the S-function.
Based on this information, the TLC file for the S-function can generate highly
efficient, optimal code for that operating mode.

Guidelines for Writing S-Functions
• Use only C MEX S-functions with the Simulink Coder code generator. You
cannot use Level-1 MATLAB language S-functions with Simulink Coder
software.
• To inline an S-function, use the Legacy Code Tool. The Legacy Code Tool
automatically generates fully inlined C MEX S-functions for legacy or
custom code. In addition, the tool generates other files for compiling and
building the S-function for simulation and generate a masked S-function
block configured to call existing external code. For more information,
see “Integrate C Functions Using Legacy Code Tool” in the Simulink

14-51

14

External Code Integration

documentation and “Integrate External Code Using Legacy Code Tool” on
page 14-28.
• If you are rapid prototyping, you might not have to inline an S-function.. If
you choose not to inline the C MEX S-function, write the S-function, include
it directly in the model, and let the Simulink Coder software generate the
code. For more information, see “Write Noninlined S-Functions” on page
14-52.

Write Noninlined S-Functions
• “About Noninlined S-Functions” on page 14-52
• “Guidelines for Writing Noninlined S-Functions” on page 14-52
• “Noninlined S-Function Parameter Type Limitations” on page 14-54

About Noninlined S-Functions
Noninlined S-functions are identified by the absence of an sfunction.tlc
file for your S-function. The filename varies depending on your platform.
For example, on a 32–bit Microsoft Windows system, the file name would be
sfunction.mexw32. Type mexext in the MATLAB Command Window to see
which extension your system uses.

Guidelines for Writing Noninlined S-Functions
• The MEX-file cannot call MATLAB functions.
• If the MEX-file uses functions in the MATLAB External Interface libraries,
include the header file cg_sfun.h instead of mex.h or simulink.c. To
handle this case, include the following lines at the end of your S-function:
#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c"

/* MEX-file interface mechanism */

#else
#include "cg_sfun.h"

/* Code generation registration function */

#endif

• Use only MATLAB API function that the code generator supports, which
include:

14-52

Insert S-Function Code

mxGetEps
mxGetInf
mxGetM
mxGetN
mxGetNaN
mxGetPr
mxGetScalar
mxGetString
mxIsEmpty
mxIsFinite
mxIsInf

• MEX library calls are not supported in generated code. To use such calls in
MEX-file and not in the generated code, conditionalize the code as follows:
#ifdef MATLAB_MEX_FILE
#endif

• Use only full matrices that contain only real data.
• Do not specify a return value for calls to mxGetString . If you do specify
a return value, the MEX-file will not compile. Instead, use the function’s
second input argument, which returns a pointer to a string.
• Make sure that the #define s-function_name statement is correct. The
S-function name that you specify must match the S-function’s filename.
• Use the data types real_T and int_T instead of double and int, if possible.
The data types real_T and int_T are more generic and can be used in
multiple environments.
• Provide the Simulink Coder build process with the names of all modules
used to build the S-function. You can do this by using the Simulink Coder
template make file or the set_param function. For example, suppose you
build your S-function with the following command:
mex sfun_main.c sfun_module1.c sfun_module2.c

You can then use the following call to set_param to include all the required
modules:
set_param(sfun_block, "SFunctionModules","sfun_module1 sfun_module2')

14-53

14

External Code Integration

Noninlined S-Function Parameter Type Limitations
Parameters to noninlined S-functions can be of the following types only:
• Double precision
• Characters in scalars, vectors, or 2-D matrices
For more flexibility in the type of parameters you can supply to S-functions or
the operations in the S-function, inline your S-function and consider using an
mdlRTW S-function routine.
Use of other functions from the MATLAB matrix.h API or other MATLAB
APIs, such as mex.h and mat.h, is not supported. If you call unsupported
APIs from an S-function source file, compiler errors occur. See the file
matlabroot/rtw/c/src/rt_matrx.h(.c) for details on supported MATLAB
API functions.
If you use mxGetPr on an empty matrix, the function does not return NULL;
rather, it returns a random value. Therefore, you should protect calls to
mxGetPr with mxIsEmpty.

Write Wrapper S-Functions
• “About Wrapper S-Functions” on page 14-54
• “MEX S-Function Wrapper” on page 14-55
• “TLC S-Function Wrapper” on page 14-59
• “The Inlined Code” on page 14-64

About Wrapper S-Functions
This section describes how to create S-functions that work seamlessly with
the Simulink and Simulink Coder products using the wrapper concept.
This section begins by describing how to interface your algorithms in
Simulink models by writing MEX S-function wrappers (sfunction.mex). It
finishes with a description of how to direct the code generator to insert your
algorithm into the generated code by creating a TLC S-function wrapper
(sfunction.tlc).

14-54

Insert S-Function Code

MEX S-Function Wrapper
Creating S-functions using an S-function wrapper allows you to insert C/C++
code algorithms in Simulink models and Simulink Coder generated code
with little or no change to your original C/C++ function. A MEX S-function
wrapper is an S-function that calls code that resides in another module. A
TLC S-function wrapper is a TLC file that specifies how the code generator
should call your code (the same code that was called from the C MEX
S-function wrapper).
Note A MEX S-function wrapper must only be used in the MATLAB version
in which the wrapper is created.
Suppose you have an algorithm (that is, a C function) called my_alg that
resides in the file my_alg.c. You can integrate my_alg into a Simulink model
by creating a MEX S-function wrapper (for example, wrapsfcn.c). Once
this is done, a Simulink model can call my_alg from an S-Function block.
However, the Simulink S-function contains a set of empty functions that the
Simulink engine requires for various API-related purposes. For example,
although only mdlOutputs calls my_alg, the engine calls mdlTerminate as
well, even though this S-function routine performs no action.
You can integrate my_alg into generated code (that is, embed the call to
my_alg in the generated code) by creating a TLC S-function wrapper (for
example, wrapsfcn.tlc). The advantage of creating a TLC S-function
wrapper is that the empty function calls can be eliminated and the overhead
of executing the mdlOutputs function and then the my_alg function can be
eliminated.
Wrapper S-functions are useful when you are creating new algorithms that
are procedural in nature or when you are integrating legacy code into a
Simulink model. However, if you want to create code that is
• Interpretive in nature (that is, highly parameterized by operating modes)
• Heavily optimized (that is, no extra tests to decide what mode the code
is operating in)
then you must create a fully inlined TLC file for your S-function.

14-55

14

External Code Integration

The next figure shows the wrapper S-function concept.

Simulink Coder
wrapper.c, the generated code,
calls mdlOutputs,
which then calls my_alg.

Simulink
Place the name of your S-function
in the S-Function block dialog box.
wrapper.mdl
wrapsfcn

*See note below

S-function
In Simulink, the S-function
calls mdlOutputs, which
in turn calls my_alg.
wrapsfcn.c
...
mdlOutputs(...)
{
...
my_alg();
}
mdlOutputs in
wrapsfcn.mex
calls external
function my_alg.

wrapper.c
...
MdlOutputs(...)
{
...
my_alg();
}

In the TLC wrapper
version of the S-function,
mdlOutputs in
wrapper.exe calls my_alg.

my_alg.c
...
real_T my_alg(real_T u)
{
...
y=f(u);
}

*The dotted line is the path taken if the S-function does not have a TLC wrapper
file. If there is no TLC wrapper file, the generated code calls mdlOutputs.
Using an S-function wrapper to import algorithms in your Simulink model
means that the S-function serves as an interface that calls your C/C++
algorithms from mdlOutputs. S-function wrappers have the advantage that
you can quickly integrate large standalone C /C++ programs into your model
without having to make changes to the code.

14-56

Insert S-Function Code

The following sample model includes an S-function wrapper.

There are two files associated with the wrapsfcn block, the S-function wrapper
and the C/C++ code that contains the algorithm. The S-function wrapper code
for wrapsfcn.c appears below. The first three statements do the following:
1 Defines the name of the S-function (what you enter in the Simulink

S-Function block dialog).
2 Specifies that the S-function is using the level 2 format.
3 Provides access to the SimStruct data structure, which contains pointers to

data used during simulation and code generation and defines macros that
store data in and retrieve data from the SimStruct.
For more information, see “Templates for C S-Functions” in the Simulink
documentation.
#define S_FUNCTION_NAME wrapsfcn
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"

extern real_T my_alg(real_T u);

/* Declare my_alg as extern */

/*
* mdlInitializeSizes - initialize the sizes array
*/
static void mdlInitializeSizes(SimStruct *S)
{

ssSetNumSFcnParams( S, 0); /*number of input arguments*/

if (!ssSetNumInputPorts(S, 1)) return;

14-57

14

External Code Integration

ssSetInputPortWidth(S, 0, 1);
ssSetInputPortDirectFeedThrough(S, 0, 1);

if (!ssSetNumOutputPorts(S,1)) return;
ssSetOutputPortWidth(S, 0, 1);

ssSetNumSampleTimes( S, 1);
}

/*
* mdlInitializeSampleTimes - indicate that this S-function runs
* at the rate of the source (driving block)
*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
}

/*
* mdlOutputs - compute the outputs by calling my_alg, which
* resides in another module, my_alg.c
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
real_T

*y

= ssGetOutputPortRealSignal(S,0);

*y = my_alg(*uPtrs[0]); /* Call my_alg in mdlOutputs */
}
/*
* mdlTerminate - called when the simulation is terminated.
*/
static void mdlTerminate(SimStruct *S)
{
}

#ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
#include "simulink.c" /* MEX-file interface mechanism */
#else

14-58

Insert S-Function Code

#include "cg_sfun.h" /* Code generation registration function */
#endif

The S-function routine mdlOutputs contains a function call to my_alg, which
is the C function containing the algorithm that the S-function performs. This
is the code for my_alg.c:
#ifdef MATLAB_MEX_FILE
#include "tmwtypes.h"
#else
#include "rtwtypes.h"
#endif
real_T my_alg(real_T u)
{
return(u * 2.0);
}

See the section “Header Dependencies When Interfacing Legacy/Custom Code
with Generated Code” on page 10-6 in the Simulink Coder documentation
for more information.
The wrapper S-function wrapsfcn calls my_alg, which computes u * 2.0. To
build wrapsfcn.mex, use the following command:
mex wrapsfcn.c my_alg.c

TLC S-Function Wrapper
This section describes how to inline the call to my_alg in the mdlOutputs
section of the generated code. In the above example, the call to my_alg is
embedded in the mdlOutputs section as
*y = my_alg(*uPtrs[0]);

When you are creating a TLC S-function wrapper, the goal is to embed the
same type of call in the generated code.
It is instructive to look at how the code generator executes S-functions that
are not inlined. A noninlined S-function is identified by the absence of the
file sfunction.tlc and the existence of sfunction.mex. When generating

14-59

14

External Code Integration

code for a noninlined S-function, the Simulink Coder software generates a
call to mdlOutputs through a function pointer that, in this example, then
calls my_alg.
The wrapper example contains one S-function, wrapsfcn.mex. You must
compile and link an additional module, my_alg, with the generated code.
To do this, specify
set_param('wrapper/S-Function','SFunctionModules','my_alg')

Code Overhead for Noninlined S-Functions. The code generated when
using grt.tlc as the system target file without wrapsfcn.tlc is


#include 
#include 
#include "wrapper.h"
#include "wrapper.prm"

/* Start the model */
void mdlStart(void)
{
/* (no start code required) */
}

/* Compute block outputs */
void mdlOutputs(int_T tid)
{
/* Sin Block: /Sin */
rtB.Sin = rtP.Sin.Amplitude *
sin(rtP.Sin.Frequency * ssGetT(rtS) + rtP.Sin.Phase);

/* Level2 S-Function Block: /S-Function (wrapsfcn) */
{
/* Noninlined S-functions create a SimStruct object and
* generate a call to S-function routine mdlOutputs
*/
SimStruct *rts = ssGetSFunction(rtS, 0);
sfcnOutputs(rts, tid);
}

14-60

Insert S-Function Code

/* Outport Block: /Out */
rtY.Out = rtB.S_Function;
}

/* Perform model update */
void mdlUpdate(int_T tid)
{
/* (no update code required) */
}

/* Terminate function */
void mdlTerminate(void)
{
/* Level2 S-Function Block: /S-Function (wrapsfcn) */
{
/* Noninlined S-functions require a SimStruct object and
* the call to S-function routine mdlTerminate
*/
SimStruct *rts = ssGetSFunction(rtS, 0);
sfcnTerminate(rts);
}
}

#include "wrapper.reg"

/* [EOF] wrapper.c */

In addition to the overhead outlined above, the wrapper.reg generated file
contains the initialization of the SimStruct for the wrapper S-Function block.
There is one child SimStruct for each S-Function block in your model. You
can significantly reduce this overhead by creating a TLC wrapper for the
S-function.
How to Inline. The generated code makes the call to your S-function,
wrapsfcn.c, in mdlOutputs by using this code:
SimStruct *rts = ssGetSFunction(rtS, 0);
sfcnOutputs(rts, tid);

14-61

14

External Code Integration

This call has computational overhead associated with it. First, the Simulink
engine creates a SimStruct data structure for the S-Function block. Second,
the code generator constructs a call through a function pointer to execute
mdlOutputs, then mdlOutputs calls my_alg. By inlining the call to your
C/C++ algorithm, my_alg, you can eliminate both the SimStruct and the
extra function call, thereby improving the efficiency and reducing the size
of the generated code.
Inlining a wrapper S-function requires an sfunction.tlc file for the
S-function (see the “Target Language Compiler” for details). The TLC
file must contain the function call to my_alg. The following figure shows
the relationships between the algorithm, the wrapper S-function, and the
sfunction.tlc file.

The wrapsfcn.tlc file tells
Simulink Coder how to
inline the call to my_alg
using this statement.
wrapsfcn.tlc
...
% = my_alg(%);
...

wrapper.c
...
mdlOutputs
{
...
y = my_alg();
...
}
...

my_alg.c
myalg()
{

}

To inline this call, you have to place your function call in an sfunction.tlc
file with the same name as the S-function (in this example, wrapsfcn.tlc).
This causes the Target Language Compiler to override the default method of
placing calls to your S-function in the generated code.
This is the wrapsfcn.tlc file that inlines wrapsfcn.c.
%% File

: wrapsfcn.tlc

%% Abstract:
%%

Example inlined tlc file for S-function wrapsfcn.c

%%

%implements "wrapsfcn" "C"

14-62

Insert S-Function Code

%% Function: BlockTypeSetup ====================================================
%% Abstract:
%%

Create function prototype in model.h as:

%%

"extern real_T my_alg(real_T u);"

%%
%function BlockTypeSetup(block, system) void
%openfile buffer
extern real_T my_alg(real_T u); /* This line is placed in wrapper.h */
%closefile buffer
%
%endfunction %% BlockTypeSetup

%% Function: Outputs ===========================================================
%% Abstract:
%%

y = my_alg( u );

%%
%function Outputs(block, system) Output
/* % Block: % */
%assign u = LibBlockInputSignal(0, "", "", 0)
%assign y = LibBlockOutputSignal(0, "", "", 0)
%% PROVIDE THE CALLING STATEMENT FOR "algorithm"
%% The following line is expanded and placed in mdlOutputs within wrapper.c
% = my_alg(%);

%endfunction %% Outputs

The first section of this code inlines the wrapsfcn S-Function block and
generates the code in C:
%implements "wrapsfcn" "C"

The next task is to tell the code generator that the routine my_alg needs
to be declared external in the generated wrapper.h file for any wrapsfcn
S-Function blocks in the model. You only need to do this once for all wrapsfcn
S-Function blocks, so use the BlockTypeSetup function. In this function, you
tell the Target Language Compiler to create a buffer and cache the my_alg
as extern in the wrapper.h generated header file.

14-63

14

External Code Integration

The final step is the inlining of the call to the function my_alg. This is done
by the Outputs function. In this function, you access the block’s input and
output and place a direct call to my_alg. The call is embedded in wrapper.c.

The Inlined Code
The code generated when you inline your wrapper S-function is similar to the
default generated code. The mdlTerminate function no longer contains a call
to an empty function and the mdlOutputs function now directly calls my_alg.
void mdlOutputs(int_T tid)
{
/* Sin Block: /Sin */
rtB.Sin = rtP.Sin.Amplitude *
sin(rtP.Sin.Frequency * ssGetT(rtS) + rtP.Sin.Phase);
/* S-Function Block: /S-Function */
rtB.S_Function = my_alg(rtB.Sin); /* Inlined call to my_alg */
/* Outport Block: /Out */
rtY.Out = rtB.S_Function;
}

In addition, wrapper.reg no longer creates a child SimStruct for the
S-function because the generated code is calling my_alg directly. This
eliminates over 1 KB of memory usage.

Write Fully Inlined S-Functions
Continuing the example of the previous section, you could eliminate the
call to my_alg entirely by specifying the explicit code (that is, 2.0 * u) in
wrapsfcn.tlc. This is referred to as a fully inlined S-function. While this
can improve performance, if you are working with a large amount of C/C++
code, this can be a lengthy task. In addition, you now have to maintain your
algorithm in two places, the C/C++ S-function itself and the corresponding
TLC file. However, the performance gains might outweigh the disadvantages.
To inline the algorithm used in this example, in the Outputs section of your
wrapsfcn.tlc file, instead of writing
% = my_alg(%);

14-64

Insert S-Function Code

use
% = 2.0 * %;

This is the code produced in mdlOutputs:
void mdlOutputs(int_T tid)
{
/* Sin Block: /Sin */
rtB.Sin = rtP.Sin.Amplitude *
sin(rtP.Sin.Frequency * ssGetT(rtS) + rtP.Sin.Phase);
/* S-Function Block: /S-Function */
rtB.S_Function = 2.0 * rtB.Sin; /* Explicit embedding of algorithm */
/* Outport Block: /Out */
rtY.Out = rtB.S_Function;
}

The Target Language Compiler has replaced the call to my_alg with the
algorithm itself.

Multiport S-Function
A more advanced multiport inlined S-function example is sfun_multiport.c
and sfun_multiport.tlc. This S-function illustrates how to create a fully
inlined TLC file for an S-function that contains multiple ports. You might find
that looking at this example helps you to understand fully inlined TLC files.

Write Fully Inlined S-Functions with mdlRTW Routine
• “About S-Functions and mdlRTW” on page 14-66
• “S-Function RTWdata” on page 14-67
• “Direct-Index Lookup Table Algorithm” on page 14-67
• “Direct-Index Lookup Table Example” on page 14-69

14-65

14

External Code Integration

About S-Functions and mdlRTW
You can inline more complex S-functions that use the S-function mdlRTW
routine. The purpose of the mdlRTW routine is to provide the code generation
process with more information about how the S-function is to be inlined,
by creating a parameter record of a nontunable parameter for use with
a TLC file. The mdlRTW routine does this by placing information in
the model.rtw file. The mdlRTW function is described in the text file
matlabroot/simulink/src/sfuntmpl_doc.c.
As an example of how to use the mdlRTW function, this section discusses
the steps you must take to create a direct-index lookup S-function. Lookup
tables are collections of ordered data points of a function. Typically, these
tables use some interpolation scheme to approximate values of the associated
function between known data points. To incorporate the example lookup table
algorithm into a Simulink model, the first step is to write an S-function that
executes the algorithm in mdlOutputs. To produce the most efficient code,
the next step is to create a corresponding TLC file to eliminate computational
overhead and improve the performance of the lookup computations.
For your convenience, the Simulink product provides support for two
general-purpose lookup 1-D and 2-D algorithms. You can use these
algorithms as they are or create a custom lookup table S-function to fit your
requirements. This section illustrates how to create a 1-D lookup S-function,
sfun_directlook.c, and its corresponding inlined sfun_directlook.tlc file
(see “Target Language Compiler” for more details). This 1-D direct-index
lookup table example illustrates the following concepts that you need to know
to create your own custom lookup tables:
• Error checking of S-function parameters
• Caching of information for the S-function that doesn’t change during model
execution
• How to use the mdlRTW function to customize Simulink Coder generated
code to produce the optimal code for a given set of block parameters
• How to generate an inlined TLC file for an S-function in a combination of
the fully inlined form and/or the wrapper form

14-66

Insert S-Function Code

S-Function RTWdata
There is a property of blocks called RTWdata, which can be used by the Target
Language Compiler when inlining an S-function. RTWdata is a structure of
strings that you can attach to a block. It is saved with the model and placed in
the model.rtw file when generating code. For example, this set of MATLAB
commands,
mydata.field1 = 'information for field1';
mydata.field2 = 'information for field2';
set_param(gcb,'RTWdata',mydata)
get_param(gcb,'RTWdata')

produces this result:
ans =
field1: 'information for field1'
field2: 'information for field2'

Inside the model.rtw file for the associated S-Function block is this
information.
Block {
Type
RTWdata {
field1
field2
}

"S-Function"
"information for field1"
"information for field2"

Note RTWdata is saved in the model file for S-functions that are not linked
to a library. However, RTWdata is not persistent for S-Function blocks that
are linked to a library.

Direct-Index Lookup Table Algorithm
The 1-D lookup table block provided in the Simulink library uses interpolation
or extrapolation when computing outputs. This extra accuracy might not be
required. In this example, you create a lookup table that directly indexes the
output vector (y-data vector) based on the current input (x-data) point.

14-67

14

External Code Integration

This direct 1-D lookup example computes an approximate solution p(x) to a
partially known function f(x) at x=x0, given data point pairs (x,y) in the form
of an x-data vector and a y-data vector. For a given data pair (for example, the
i’th pair), y_i = f(x_i). It is assumed that the x-data values are monotonically
increasing. If x0 is outside the range of the x-data vector, the first or last
point is returned.
The parameters to the S-function are
XData, YData, XEvenlySpaced
XData and YData are double vectors of equal length representing the values
of the unknown function. XDataEvenlySpaced is a scalar, 0.0 for false and
1.0 for true. If the XData vector is evenly spaced, XDataEvenlySpaced is 1.0

and more efficient code is generated.
The following graph shows how the parameters XData=[1:6]and
YData=[1,2,7,4,5,9] are handled. For example, if the input (x-value) to the
S-Function block is 3, the output (y-value) is 7.

14-68

Insert S-Function Code

Direct-Index Lookup Table Example
This section shows how to improve the lookup table by inlining a direct-index
S-function with a TLC file. This direct-index lookup table S-function does not
require a TLC file. Here the example uses a TLC file for the direct-index
lookup table S-function to reduce the code size and increase efficiency of the
generated code.
Implementation of the direct-index algorithm with inlined TLC file requires
the S-function main module, sfun_directlook.c, and a corresponding

14-69

14

External Code Integration

lookup_index.c module. The lookup_index.c module contains the
GetDirectLookupIndex function that is used to locate the index in the
XData for the current x input value when the XData is unevenly spaced.
The GetDirectLookupIndex routine is called from both the S-function and

the generated code. Here the example uses the wrapper concept for sharing
C/C++ code between Simulink MEX-files and the generated code.
If the XData is evenly spaced, then both the S-function main module and the
generated code contain the lookup algorithm (not a call to the algorithm) to
compute the y-value of a given x-value, because the algorithm is short. This
illustrates the use of a fully inlined S-function for generating optimal code.
The inlined TLC file, which either performs a wrapper call or embeds the
optimal C/C++ code, is sfun_directlook.tlc (see the example in “mdlRTW
Usage” on page 14-71).
Error Handling. In this example, the mdlCheckParameters routine verifies
that
• The new parameter settings valid..
• XData and YData are vectors of the same length containing real finite
numbers.
• XDataEvenlySpaced is a scalar.
• The XData vector is a monotonically increasing vector and evenly spaced.
The mdlInitializeSizes function explicitly calls mdlCheckParameters
after it verifies the number of parameters passed to the S-function.
After the Simulink engine calls mdlInitializeSizes, it then calls
mdlCheckParameters whenever you change the parameters or there is a need
to reevaluate them.
User Data Caching. The mdlStart routine shows how to cache information
that does not change during the simulation (or while the generated code
is executing). The example caches the value of the XDataEvenlySpaced
parameter in UserData, a field of the SimStruct. The following line in
mdlInitializeSizes tells the Simulink engine to disallow changes to
XDataEvenlySpaced.
ssSetSFcnParamTunable(S, iParam, SS_PRM_NOT_TUNABLE);

14-70

Insert S-Function Code

During execution, mdlOutputs accesses the value of XDataEvenlySpaced
from UserData rather than calling the mxGetPr MATLAB API function. This
increases performance.
mdlRTW Usage. The Simulink Coder code generator calls the mdlRTW
routine while generating the model.rtw file. To produce optimal code for your
Simulink model, you can add information to the model.rtw file about the
mode in which your S-Function block is operating.
The following example adds parameter settings to the model.rtw file.
The parameter settings do not change during execution. In this case,
the XDataEvenlySpaced S-function parameter cannot change during
execution (ssSetSFcnParamTunable was specified as false (0) for it in
mdlInitializeSizes). The example writes it out as a parameter setting
(XSpacing) using the function ssWriteRTWParamSettings.
Because xData and yData are registered as run-time parameters in
mdlSetWorkWidths, the code generator handles writing to the model.rtw
file automatically.
Before examining the S-function and the inlined TLC file, consider the
generated code for the following model.

14-71

14

External Code Integration

The model uses evenly spaced XData in the top S-Function block and unevenly
spaced XData in the bottom S-Function block. When creating this model, you
need to specify the following for each S-Function block.
set_param(`sfun_directlook_ex/S-Function','SFunctionModules','lookup_index')
set_param(`sfun_directlook_ex/S-Function1','SFunctionModules','lookup_index')

This informs the Simulink Coder build process to use the module
lookup_index.c when creating the executable.
When generating code for this model, the Simulink Coder software uses the
S-function’s mdlRTW method to generate a model.rtw file with the value
EvenlySpaced for the XSpacing parameter for the top S-Function block,
and the value UnEvenlySpaced for the XSpacing parameter for the bottom
S-Function block. The TLC-file uses the value of XSpacing to determine
what algorithm to include in the generated code. The generated code
contains the lookup algorithm when the XData is evenly spaced, but calls the
GetDirectLookupIndex routine when the XData is unevenly spaced. The
generated model.c or model.cpp code for the lookup table example model is
similar to the following:
/*
* sfun_directlook_ex.c
*
* Code generation for Simulink model
* "sfun_directlook_ex.slx".
*
...
*/
#include "sfun_directlook_ex.h"
#include "sfun_directlook_ex_private.h"
/* External output (root outports fed by signals with auto storage) */
ExternalOutputs_sfun_directlook_ex sfun_directlook_ex_Y;
/* Real-time model */
rtModel_sfun_directlook_ex sfun_directlook_ex_M_;
rtModel_sfun_directlook_ex *sfun_directlook_ex_M = &sfun_directlook_ex_M_;

14-72

Insert S-Function Code

/* Model output function */
static void sfun_directlook_ex_output(int_T tid)
{
/* local block i/o variables */
real_T rtb_SFunction_h;
real_T rtb_temp1;
/* Sin: '/Sine Wave' */
rtb_temp1 = sfun_directlook_ex_P.SineWave_Amp *
sin(sfun_directlook_ex_P.SineWave_Freq * sfun_directlook_ex_M->Timing.t[0] +
sfun_directlook_ex_P.SineWave_Phase) + sfun_directlook_ex_P.SineWave_Bias;
/* Code that is inlined for the top S-function block in the
* sfun_directlook_ex model
*/
/* S-Function Block: /S-Function */
{
const real_T *xData = &sfun_directlook_ex_P.SFunction_XData[0];
const real_T *yData = &sfun_directlook_ex_P.SFunction_YData[0];
real_T spacing = xData[1] - xData[0];
if ( rtb_temp1 <= xData[0] ) {
rtb_SFunction_h = yData[0];
} else if ( rtb_temp1 >= yData[20] ) {
rtb_SFunction_h = yData[20];
} else {
int_T idx = (int_T)( ( rtb_temp1 - xData[0] ) / spacing );
rtb_SFunction_h = yData[idx];
}
}
/* Outport: '/Out1' */
sfun_directlook_ex_Y.Out1 = rtb_SFunction_h;
/* Code that is inlined for the bottom S-function block in the
* sfun_directlook_ex model
*/
/* S-Function Block: /S-Function1 */

14-73

14

External Code Integration

{
const real_T *xData = &sfun_directlook_ex_P.SFunction1_XData[0];
const real_T *yData = &sfun_directlook_ex_P.SFunction1_YData[0];
int_T idx;
idx = GetDirectLookupIndex(xData, 5, rtb_temp1);
rtb_temp1 = yData[idx];
}
/* Outport: '/Out2' */
sfun_directlook_ex_Y.Out2 = rtb_temp1;
}
/* Model update function */
static void sfun_directlook_ex_update(int_T tid)
{
/* Update absolute time for base rate */
if(!(++sfun_directlook_ex_M->Timing.clockTick0))
++sfun_directlook_ex_M->Timing.clockTickH0;
sfun_directlook_ex_M->Timing.t[0] = sfun_directlook_ex_M->Timing.clockTick0 *
sfun_directlook_ex_M->Timing.stepSize0 +
sfun_directlook_ex_M->Timing.clockTickH0 *
sfun_directlook_ex_M->Timing.stepSize0 * 0x10000;
{
/* Update absolute timer for sample time: [0.1s, 0.0s] */
if(!(++sfun_directlook_ex_M->Timing.clockTick1))
++sfun_directlook_ex_M->Timing.clockTickH1;
sfun_directlook_ex_M->Timing.t[1] = sfun_directlook_ex_M->Timing.clockTick1
* sfun_directlook_ex_M->Timing.stepSize1 +
sfun_directlook_ex_M->Timing.clockTickH1 *
sfun_directlook_ex_M->Timing.stepSize1 * 0x10000;
}
}
...

14-74

Insert S-Function Code

matlabroot/toolbox/simulink/simdemos/simfeatures/src/sfun_directlook.c.
/*
* File

:

sfun_directlook.c

* Abstract:
*
*

Direct 1-D lookup. Here we are trying to compute an approximate

*

solution, p(x) to an unknown function f(x) at x=x0, given data point

*

pairs (x,y) in the form of a x data vector and a y data vector. For a

*

given data pair (say the i'th pair), we have y_i = f(x_i). It is

*

assumed that the x data values are monotonically increasing.

*

x0 is outside of the range of the x data vector, then the first or

*

last point will be returned.

If the

*
*

This function returns the "nearest" y0 point for a given x0. No

*

interpolation is performed.

*
*

The S-function parameters are:

*

XData

- double vector

*

YData

- double vector

*

XDataEvenlySpacing - double scalar 0 (false) or 1 (true)

*

The third parameter cannot be changed during simulation.

*
*
*

To build:
mex sfun_directlook.c lookup_index.c

*
* Copyright 1990-2004 The MathWorks, Inc.
* $Revision: 1.1.8.11.2.4 $
*/
#define S_FUNCTION_NAME

sfun_directlook

#define S_FUNCTION_LEVEL 2

#include 
#include "simstruc.h"
#include 
/* use utility function IsRealVect() */
#if defined(MATLAB_MEX_FILE)

14-75

14

External Code Integration

#include "sfun_slutils.h"
#endif
/*================*
* Build checking *
*================*/
#if !defined(MATLAB_MEX_FILE)
/*
* This file cannot be used directly with Simulink Coder. However,
* this S-function does work with Simulink Coder via
* the Target Language Compiler technology. See matlabroot/
* toolbox/simulink/simdemos/simfeatures/tlc_c/sfun_directlook.tlc
* for the C version
*/
# error This_file_can_be_used_only_during_simulation_inside_Simulink
#endif

/*=========*
* Defines *
*=========*/
#define XVECT_PIDX

0

#define YVECT_PIDX

1

#define XDATAEVENLYSPACED_PIDX 2
#define NUM_PARAMS

3

#define XVECT(S)

ssGetSFcnParam(S,XVECT_PIDX)

#define YVECT(S)

ssGetSFcnParam(S,YVECT_PIDX)

#define XDATAEVENLYSPACED(S) ssGetSFcnParam(S,XDATAEVENLYSPACED_PIDX)

/*==============*
* misc defines *
*==============*/
#if !defined(TRUE)
#define TRUE

1

#endif
#if !defined(FALSE)
#define FALSE 0

14-76

Insert S-Function Code

#endif
/*===========*
* typedef's *
*===========*/
typedef struct SFcnCache_tag {
boolean_T evenlySpaced;
} SFcnCache;
/*===================================================================*
* Prototype define for the function in separate file lookup_index.c *
*===================================================================*/
extern int_T GetDirectLookupIndex(const real_T *x, int_T xlen, real_T u);

/*====================*
* S-function methods *
*====================*/

#define MDL_CHECK_PARAMETERS

/* Change to #undef to remove function */

#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
/* Function: mdlCheckParameters ================================================
* Abstract:
*

This routine will be called after mdlInitializeSizes, whenever

*

parameters change or get re-evaluated. The purpose of this routine is

*

to verify

the new parameter settings.

*
*

You should add a call to this routine from mdlInitalizeSizes

*

to check the parameters. After setting your sizes elements, you should:

*

if (ssGetSFcnParamsCount(S) == ssGetNumSFcnParams(S)) {

*
*

mdlCheckParameters(S);
}

*/
static void mdlCheckParameters(SimStruct *S)
{
if (!IsRealVect(XVECT(S))) {
ssSetErrorStatus(S,"1st, X-vector parameter must be a real finite "

14-77

14

External Code Integration

" vector");
return;
}
if (!IsRealVect(YVECT(S))) {
ssSetErrorStatus(S,"2nd, Y-vector parameter must be a real finite "
"vector");
return;
}
/*
* Verify that the dimensions of X and Y are the same.
*/
if (mxGetNumberOfElements(XVECT(S)) != mxGetNumberOfElements(YVECT(S)) ||
mxGetNumberOfElements(XVECT(S)) == 1) {
ssSetErrorStatus(S,"X and Y-vectors must be of the same dimension "
"and have at least two elements");
return;
}
/*
* Verify we have a valid XDataEvenlySpaced parameter.
*/
if ((!mxIsNumeric(XDATAEVENLYSPACED(S)) &&
!mxIsLogical(XDATAEVENLYSPACED(S))) ||
mxIsComplex(XDATAEVENLYSPACED(S)) ||
mxGetNumberOfElements(XDATAEVENLYSPACED(S)) != 1) {
ssSetErrorStatus(S,"3rd, X-evenly-spaced parameter must be logical
scalar");
return;
}
/*
* Verify x-data is correctly spaced.
*/
{
int_T

i;

boolean_T spacingEqual;

14-78

real_T

*xData = mxGetPr(XVECT(S));

int_T

numEl

= mxGetNumberOfElements(XVECT(S));

Insert S-Function Code

/*
* spacingEqual is TRUE if user

XDataEvenlySpaced

*/
spacingEqual = (mxGetScalar(XDATAEVENLYSPACED(S)) != 0.0);
if (spacingEqual) {

/* XData is 'evenly-spaced' */

boolean_T badSpacing = FALSE;
real_T

spacing

real_T

space;

= xData[1] - xData[0];

if (spacing <= 0.0) {
badSpacing = TRUE;
} else {
real_T eps = DBL_EPSILON;
for (i = 2; i < numEl; i++) {
space = xData[i] - xData[i-1];
if (space <= 0.0 ||
fabs(space-spacing) >= 128.0*eps*spacing ){
badSpacing = TRUE;
break;
}
}
}
if (badSpacing) {
ssSetErrorStatus(S,"X-vector must be an evenly spaced "
"strictly monotonically increasing vector");
return;
}
} else {

/* XData is 'unevenly-spaced' */

for (i = 1; i < numEl; i++) {
if (xData[i] <= xData[i-1]) {
ssSetErrorStatus(S,"X-vector must be a strictly "
"monotonically increasing vector");
return;
}
}
}

14-79

14

External Code Integration

}
}
#endif /* MDL_CHECK_PARAMETERS */

/* Function: mdlInitializeSizes ================================================
* Abstract:
*

The sizes information is used by Simulink to determine the S-function

*

block's characteristics (number of inputs, outputs, states, and so on).

*/
static void mdlInitializeSizes(SimStruct *S)
{
ssSetNumSFcnParams(S, NUM_PARAMS);

/* Number of expected parameters */

/*
* Check parameters passed in, providing the correct number was specified
* in the S-function dialog box. If an incorrect number of parameters
* was specified, Simulink will detect the error since ssGetNumSFcnParams
* and ssGetSFcnParamsCount will differ.
*

ssGetNumSFcnParams

- This sets the number of parameters your

*

S-function expects.

*

ssGetSFcnParamsCount - This is the number of parameters entered by

*

the user in the Simulink S-function dialog box.

*/
#if defined(MATLAB_MEX_FILE)
if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
mdlCheckParameters(S);
if (ssGetErrorStatus(S) != NULL) {
return;
}
} else {
return; /* Parameter mismatch will be reported by Simulink */
}
#endif
{
int iParam = 0;
int nParam = ssGetNumSFcnParams(S);

14-80

Insert S-Function Code

for ( iParam = 0; iParam < nParam; iParam++ )
{
switch ( iParam )
{
case XDATAEVENLYSPACED_PIDX:
ssSetSFcnParamTunable( S, iParam, SS_PRM_NOT_TUNABLE );
break;
default:
ssSetSFcnParamTunable( S, iParam, SS_PRM_TUNABLE );
break;
}
}
}
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetInputPortDirectFeedThrough(S, 0, 1);
ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
ssSetInputPortOverWritable(S, 0, TRUE);
if (!ssSetNumOutputPorts(S, 1)) return;
ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED);
ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
ssSetNumSampleTimes(S, 1);
ssSetOptions(S,
SS_OPTION_WORKS_WITH_CODE_REUSE |
SS_OPTION_EXCEPTION_FREE_CODE |
SS_OPTION_USE_TLC_WITH_ACCELERATOR);
} /* mdlInitializeSizes */

14-81

14

External Code Integration

/* Function: mdlInitializeSampleTimes ==========================================
* Abstract:
*

The lookup inherits its sample time from the driving block.

*/
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
} /* end mdlInitializeSampleTimes */
/* Function: mdlSetWorkWidths ===============================================
* Abstract:
*

Set up the [X,Y] data as run-time parameters

*

that is, these values can be changed during execution.

*/
#define MDL_SET_WORK_WIDTHS
static void mdlSetWorkWidths(SimStruct *S)
{
const char_T

*rtParamNames[] = {"XData","YData"};

ssRegAllTunableParamsAsRunTimeParams(S, rtParamNames);
}

#define MDL_START

/* Change to #undef to remove function */

#if defined(MDL_START)
/* Function: mdlStart ==========================================================
* Abstract:
*

Here we cache the state (true/false) of the XDATAEVENLYSPACED parameter.

*

We do this primarily to illustrate how to "cache" parameter values (or

*

information which is computed from parameter values) which do not change

*

for the duration of the simulation (or in the generated code). In this

*

case, rather than repeated calls to mxGetPr, we save the state once.

*

This results in a slight increase in performance.

*/
static void mdlStart(SimStruct *S)
{
SFcnCache *cache = malloc(sizeof(SFcnCache));

14-82

Insert S-Function Code

if (cache == NULL) {
ssSetErrorStatus(S,"memory allocation error");
return;
}
ssSetUserData(S, cache);
if (mxGetScalar(XDATAEVENLYSPACED(S)) != 0.0){
cache->evenlySpaced = TRUE;
}else{
cache->evenlySpaced = FALSE;
}
}
#endif /*

MDL_START */

/* Function: mdlOutputs ========================================================
* Abstract:
*

In this function, you compute the outputs of your S-function

*

block. Generally outputs are placed in the output vector, ssGetY(S).

*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
SFcnCache

*cache = ssGetUserData(S);

real_T

*xData = mxGetPr(XVECT(S));

real_T

*yData = mxGetPr(YVECT(S));

InputRealPtrsType uPtrs

= ssGetInputPortRealSignalPtrs(S,0);

real_T

*y

= ssGetOutputPortRealSignal(S,0);

int_T

ny

= ssGetOutputPortWidth(S,0);

int_T

xLen

= mxGetNumberOfElements(XVECT(S));

int_T

i;

/*
* When the XData is evenly spaced, we use the direct lookup algorithm
* to calculate the lookup
*/
if (cache->evenlySpaced) {
real_T spacing = xData[1] - xData[0];

14-83

14

External Code Integration

for (i = 0; i < ny; i++) {
real_T u = *uPtrs[i];
if (u <= xData[0]) {
y[i] = yData[0];
} else if (u >= xData[xLen-1]) {
y[i] = yData[xLen-1];
} else {
int_T idx = (int_T)((u - xData[0])/spacing);
y[i] = yData[idx];
}
}
} else {
/*
* When the XData is unevenly spaced, we use a bisection search to
* locate the lookup index.
*/
for (i = 0; i < ny; i++) {
int_T idx = GetDirectLookupIndex(xData,xLen,*uPtrs[i]);
y[i] = yData[idx];
}
}
} /* end mdlOutputs */

/* Function: mdlTerminate ======================================================
* Abstract:
*

Free the cache which was allocated in mdlStart.

*/
static void mdlTerminate(SimStruct *S)
{
SFcnCache *cache = ssGetUserData(S);
if (cache != NULL) {
free(cache);
}
} /* end mdlTerminate */

14-84

Insert S-Function Code

#define MDL_RTW

/* Change to #undef to remove function */

#if defined(MDL_RTW) && (defined(MATLAB_MEX_FILE) || defined(NRT))
/* Function: mdlRTW ============================================================
* Abstract:
*

This function is called when Simulink Coder is generating the

*

model.rtw file. In this routine, you can call the following functions

*

which add fields to the model.rtw file.

*
*

Important! Since this S-function has this mdlRTW method, it is required

*

to have a corresponding .tlc file so as to work with Simulink Coder. See the

*

sfun_directlook.tlc in matlabroot/toolbox/simulink/simdemos/simfeatures/tlc_c/.

*/
static void mdlRTW(SimStruct *S)
{
/*
* Write out the spacing setting as a param setting, that is, this cannot be
* changed during execution.
*/
{
boolean_T even = (mxGetScalar(XDATAEVENLYSPACED(S)) != 0.0);
if (!ssWriteRTWParamSettings(S, 1,
SSWRITE_VALUE_QSTR,
"XSpacing",
even ? "EvenlySpaced" : "UnEvenlySpaced")){
return;/* An error occurred which will be reported by Simulink */
}
}
}
#endif /* MDL_RTW */

/*=============================*
* Required S-function trailer *
*=============================*/
#ifdef

MATLAB_MEX_FILE

#include "simulink.c"

/* Is this file being compiled as a MEX-file? */
/* MEX-file interface mechanism */

#else

14-85

14

External Code Integration

#include "cg_sfun.h"

/* Code generation registration function */

#endif

/* [EOF] sfun_directlook.c */

matlabroot/toolbox/simulink/simdemos/simfeatures/src/lookup_index.c.
/* File

: lookup_index.c

* Abstract:
*
*

Contains a routine used by the S-function sfun_directlookup.c to

*

compute the index in a vector for a given data value.

*
*

Copyright 1990-2004 The MathWorks, Inc.

*

$Revision: 1.1.8.11.2.4 $

*/
#include "tmwtypes.h"
/*
* Function: GetDirectLookupIndex ==============================================
* Abstract:
*

Using a bisection search to locate the lookup index when the x-vector

*

isn't evenly spaced.

*
*

Inputs:

*

*x

*

xlen : Number of values in xtable

: Pointer to table, x[0] ....x[xlen-1]

*

u

: input value to look up

*
*
*

Output:
idx

*

: the index into the table such that:
if u is negative

*

x[idx] <= u < x[idx+1]

*

else

*

x[idx] < u <= x[idx+1]

*/
int_T GetDirectLookupIndex(const real_T *x, int_T xlen, real_T u)
{
int_T idx

14-86

= 0;

Insert S-Function Code

int_T bottom = 0;
int_T top

= xlen-1;

/*
* Deal with the extreme cases first:
*
*

i] u <= x[bottom] then idx = bottom

* ii] u >= x[top] then idx = top-1
*
*/
if (u <= x[bottom]) {
return(bottom);
} else if (u >= x[top]) {
return(top);
}
/*
* We have: x[bottom] < u < x[top], onward
* with search for the

index ...

*/
for (;;) {
idx = (bottom + top)/2;
if (u < x[idx]) {
top = idx;
} else if (u > x[idx+1]) {
bottom = idx + 1;
} else {
/*
* We have:

x[idx] <= u <= x[idx+1], only need

* to do two more checks and we have the answer
*/
if (u < 0) {
/*
* We want right continuity, that is,
* if u == x[idx+1]
*

then x[idx+1] <= u < x[idx+2]

* else

x[idx

] <= u < x[idx+1]

*/
return( (u == x[idx+1]) ? (idx+1) : idx);
} else {

14-87

14

External Code Integration

/*
* We want left continuity, that is,
* if u == x[idx]
*

then x[idx-1] < u <= x[idx

* else

x[idx

]

] < u <= x[idx+1]

*/
return( (u == x[idx]) ? (idx-1) : idx);
}
}
}
} /* end GetDirectLookupIndex */
/* [EOF] lookup_index.c */

matlabroot/toolbox/simulink/simdemos/simfeatures/tlc_c/sfun_directlook.tlc.
%% File

: sfun_directlook.tlc

%% Abstract:
%%

Level-2 S-function sfun_directlook block target file.

%%

It is using direct lookup algorithm without interpolation

%%
%% Copyright 1990-2004 The MathWorks, Inc.
%% $Revision: 1.1.8.11.2.4 $

%implements "sfun_directlook" "C"
%% Function: BlockTypeSetup ====================================================
%% Abstract:
%%

Place include and function prototype in the model's header file.

%%
%function BlockTypeSetup(block, system) void
%% To add this external function's prototype in the header of the generated
%% file.
%%
%openfile buffer
extern int_T GetDirectLookupIndex(const real_T *x, int_T xlen, real_T u);
%closefile buffer

14-88

Insert S-Function Code

%
%endfunction
%% Function: mdlOutputs ========================================================
%% Abstract:
%%

Direct 1-D lookup table S-function example.

%%

Here we are trying to compute an approximate solution, p(x) to an

%%

unknown function f(x) at x=x0, given data point pairs (x,y) in the

%%

form of a x data vector and a y data vector. For a given data pair

%%

(say the i'th pair), we have y_i = f(x_i). It is assumed that the x

%%

data values are monotonically increasing.

%%

outside of the range of the x data vector, then the first or last

%%

point will be returned.

If the first or last x is

%%
%%

This function returns the "nearest" y0 point for a given x0.

%%

No interpolation is performed.

%%
%%

The S-function parameters are:

%%

XData

%%

YData

%%

XEvenlySpaced: 0 or 1

%%

The third parameter cannot be changed during execution and is

%%

written to the model.rtw file in XSpacing filed of the SFcnParamSettings

%%

record as "EvenlySpaced" or "UnEvenlySpaced". The first two parameters

%%

can change during execution and show up in the parameter vector.

%%
%function Outputs(block, system) Output
/* % Block: % */
{
%assign rollVars = ["U", "Y"]
%%
%% Load XData and YData as local variables
%%
const real_T *xData

= %;

const real_T *yData

= %;

%assign xDataLen = SIZE(XData.Value, 1)
%%
%% When the XData is evenly spaced, we use the direct lookup algorithm
%% to locate the lookup index.

14-89

14

External Code Integration

%%
%if SFcnParamSettings.XSpacing == "EvenlySpaced"
real_T spacing = xData[1] - xData[0];
%roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
%assign u = LibBlockInputSignal(0, "", lcv, idx)
%assign y = LibBlockOutputSignal(0, "", lcv, idx)
if ( % <= xData[0] ) {
% = yData[0];
} else if ( % >= yData[%] ) {
% = yData[%];
} else {
int_T idx = (int_T)( ( % - xData[0] ) / spacing );
% = yData[idx];
}
%%
%% Generate an empty line if we are not rolling,
%% so that it looks nice in the generated code.
%%
%if lcv == ""
%endif
%endroll
%else
%% When the XData is unevenly spaced, we use a bisection search to
%% locate the lookup index.
int_T idx;
%assign xDataAddr = LibBlockParameterAddr(XData, "", "", 0)
%roll idx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
%assign u = LibBlockInputSignal(0, "", lcv, idx)
idx =

GetDirectLookupIndex(xData, %, %);

%assign y = LibBlockOutputSignal(0, "", lcv, idx)
% = yData[idx];
%%
%% Generate an empty line if we are not rolling,
%% so that it looks nice in the generated code.
%%
%if lcv == ""

14-90

Insert S-Function Code

%endif
%endroll
%endif
}
%endfunction
%% EOF: sfun_directlook.tlc

Guidelines for Writing Inlined S-Functions
• Consider using the block property RTWdata (see “S-Function RTWdata” on
page 14-67). This property is a structure of strings that you can associate
with a block. The code generator saves the structure with the model in
the model.rtw file and makes the .rtw file more readable. For example,
suppose you enter the following commands in the MATLAB Command
Window:
mydata.field1 = 'information for field1';
mydata.field2 = 'information for field2';
set_param(sfun_block, 'RTWdata', mydata);

The .rtw file that Simulink Coder generates for the block, will include the
comments specified in the structure mydata.
• Consider using the mdlRTW function to inline your C MEX S-function in the
generated code. This is useful when you want to

-

Rename tunable parameters in the generated code
Introduce nontunable parameters into a TLC file

Write S-Functions That Support Expression Folding
• “About S-Functions that Support Expression Folding” on page 14-92
• “Categories of Output Expressions” on page 14-93
• “Acceptance or Denial of Requests for Input Expressions” on page 14-98
• “Expression Folding in a TLC Block Implementation” on page 14-100

14-91

14

External Code Integration

About S-Functions that Support Expression Folding
This section describes how you can take advantage of expression folding to
increase the efficiency of code generated by your own inlined S-Function
blocks, by calling macros provided in the S-Function API. This section
assumes that you are familiar with:
• Writing inlined S-functions (see “S-Function Basics”).
• “Target Language Compiler”
The S-Function API lets you specify whether a given S-Function block should
nominally accept expressions at a given input port. A block should not always
accept expressions. For example, if the address of the signal at the input
is used, expressions should not be accepted at that input, because it is not
possible to take the address of an expression.
The S-Function API also lets you specify whether an expression can represent
the computations associated with a given output port. When you request an
expression at a block’s input or output port, the Simulink engine determines
whether or not it can honor that request, given the block’s context. For
example, the engine might deny a block’s request to output an expression if the
destination block does not accept expressions at its input, if the destination
block has an update function, or if multiple output destinations exist.
The decision to honor or deny a request to output an expression can also
depend on the category of output expression the block uses (see “Categories of
Output Expressions” on page 14-93).
The sections that follow explain
• When and how you can request that a block accept expressions at an input
port
• When and how you can request that a block generate expressions at an
outport
• The conditions under which the Simulink engine will honor or deny such
requests
To take advantage of expression folding in your S-functions, you should
understand when to request acceptance and generation of expressions for

14-92

Insert S-Function Code

specific blocks. You do not have to understand the algorithm by which the
Simulink engine chooses to accept or deny these requests. However, if you
want to trace between the model and the generated code, it is helpful to
understand some of the more common situations that lead to denial of a
request.

Categories of Output Expressions
When you implement a C MEX S-function, you can specify whether the code
corresponding to a block’s output is to be generated as an expression. If
the block generates an expression, you must specify that the expression is
constant, trivial, or generic.
A constant output expression is a direct access to one of the block’s
parameters. For example, the output of a Constant block is defined as a
constant expression because the output expression is simply a direct access to
the block’s Value parameter.
A trivial output expression is an expression that can be repeated, without any
performance penalty, when the output port has multiple output destinations.
For example, the output of a Unit Delay block is defined as a trivial expression
because the output expression is simply a direct access to the block’s state.
Because the output expression involves no computations, it can be repeated
more than once without degrading the performance of the generated code.
A generic output expression is an expression that should be assumed to have a
performance penalty if repeated. As such, a generic output expression is not
suitable for repeating when the output port has multiple output destinations.
For instance, the output of a Sum block is a generic rather than a trivial
expression because it is costly to recompute a Sum block output expression as
an input to multiple blocks.
Examples of Trivial and Generic Output Expressions. Consider the
following block diagram. The Delay block has multiple destinations, yet its
output is designated as a trivial output expression, so that it can be used more
than once without degrading the efficiency of the code.

14-93

14

External Code Integration

The following code excerpt shows code generated from the Unit Delay block
in this block diagram. The three root outputs are directly assigned from the
state of the Unit Delay block, which is stored in a field of the global data
structure rtDWork. Since the assignment is direct, involving no expressions,
there is no performance penalty associated with using the trivial expression
for multiple destinations.
void MdlOutputs(int_T tid)
{
...
/* Outport: /Out1 incorporates:
*
UnitDelay: /Unit Delay */
rtY.Out1 = rtDWork.Unit_Delay_DSTATE;
/* Outport: /Out2 incorporates:
*
UnitDelay: /Unit Delay */
rtY.Out2 = rtDWork.Unit_Delay_DSTATE;
/* Outport: /Out3 incorporates:
*
UnitDelay: /Unit Delay */
rtY.Out3 = rtDWork.Unit_Delay_DSTATE;
...
}

On the other hand, consider the Sum blocks in the following model:

14-94

Insert S-Function Code

The upper Sum block in the preceding model generates the signal labeled
non_triv. Computation of this output signal involves two multiplications
and an addition. If the Sum block’s output were permitted to generate
an expression even when the block had multiple destinations, the block’s
operations would be duplicated in the generated code. In the case illustrated,
the generated expressions would proliferate to four multiplications and two
additions. This would degrade the efficiency of the program. Accordingly the
output of the Sum block is not allowed to be an expression because it has
multiple destinations
The code generated for the previous block diagram shows how code is
generated for Sum blocks with single and multiple destinations.
The Simulink engine does not permit the output of the upper Sum block
to be an expression because the signal non_triv is routed to two output
destinations. Instead, the result of the multiplication and addition operations
is stored in a temporary variable (rtb_non_triv) that is referenced twice in
the statements that follow, as seen in the code excerpt below.
In contrast, the lower Sum block, which has only a single output destination
(Out2), does generate an expression.
void MdlOutputs(int_T tid)
{
/* local block i/o variables */
real_T rtb_non_triv;
real_T rtb_Sine_Wave;

14-95

14

External Code Integration

/* Sum: /Sum incorporates:
*
Gain: /Gain
*
Inport: /u1
*
Gain: /Gain1
*
Inport: /u2
*
* Regarding /Gain:
*
Gain value: rtP.Gain_Gain
*
* Regarding /Gain1:
*
Gain value: rtP.Gain1_Gain
*/
rtb_non_triv = (rtP.Gain_Gain * rtU.u1) + (rtP.Gain1_Gain *
rtU.u2);
/* Outport: /Out1 */
rtY.Out1 = rtb_non_triv;
/* Sin Block: /Sine Wave */
rtb_Sine_Wave = rtP.Sine_Wave_Amp *
sin(rtP.Sine_Wave_Freq * rtmGetT(rtM_model) +
rtP.Sine_Wave_Phase) + rtP.Sine_Wave_Bias;
/* Outport: /Out2 incorporates:
*
Sum: /Sum1
*/
rtY.Out2 = (rtb_non_triv + rtb_Sine_Wave);
}

Specify the Category of an Output Expression. The S-Function API
provides macros that let you declare whether an output of a block should
be an expression, and if so, to specify the category of the expression. The
following table specifies when to declare a block output to be a constant,
trivial, or generic output expression.

14-96

Insert S-Function Code

Types of Output Expressions
Category of
Expression

When to Use

Constant

Use only if block output is a direct memory access to a
block parameter.

Trivial

Use only if block output is an expression that can appear
multiple times in the code without reducing efficiency
(for example, a direct memory access to a field of the
DWork vector, or a literal).

Generic

Use if output is an expression, but not constant or
trivial.

You must declare outputs as expressions in the mdlSetWorkWidths function
using macros defined in the S-Function API. The macros have the following
arguments:
• SimStruct *S: pointer to the block’s SimStruct.
• int idx: zero-based index of the output port.
• bool value: pass in TRUE if the port generates output expressions.
The following macros are available for setting an output to be a constant,
trivial, or generic expression:
• void ssSetOutputPortConstOutputExprInRTW(SimStruct *S, int
idx, bool value)

• void ssSetOutputPortTrivialOutputExprInRTW(SimStruct *S, int
idx, bool value)

• void ssSetOutputPortOutputExprInRTW(SimStruct *S, int idx,
bool value)

The following macros are available for querying the status set by any prior
calls to the macros above:

14-97

14

External Code Integration

• bool ssGetOutputPortConstOutputExprInRTW(SimStruct *S, int
idx)

• bool ssGetOutputPortTrivialOutputExprInRTW(SimStruct *S, int
idx)

• bool ssGetOutputPortOutputExprInRTW(SimStruct *S, int idx)
The set of generic expressions is a superset of the set of trivial expressions, and
the set of trivial expressions is a superset of the set of constant expressions.
Therefore, when you query an output that has been set to be a constant
expression with ssGetOutputPortTrivialOutputExprInRTW, it returns True.
A constant expression is considered a trivial expression, because it is a direct
memory access that can be repeated without degrading the efficiency of the
generated code.
Similarly, an output that has been configured to be a constant or trivial
expression returns True when queried for its status as a generic expression.

Acceptance or Denial of Requests for Input Expressions
A block can request that its output be represented in code as an expression.
Such a request can be denied if the destination block cannot accept expressions
at its input port. Furthermore, conditions independent of the requesting block
and its destination blocks can prevent acceptance of expressions.
This section discusses block-specific conditions under which requests for
input expressions are denied. For information on other conditions that
prevent acceptance of expressions, see “Denial of Block Requests to Output
Expressions” on page 14-99.
A block should not be configured to accept expressions at its input port under
the following conditions:
• The block must take the address of its input data. It is not possible to take
the address of most types of input expressions.
• The code generated for the block references the input more than once
(for example, the Abs or Max blocks). This would lead to duplication of
a potentially complex expression and a subsequent degradation of code
efficiency.

14-98

Insert S-Function Code

If a block refuses to accept expressions at an input port, then any block that
is connected to that input port is not permitted to output a generic or trivial
expression.
A request to output a constant expression is never denied, because there is no
performance penalty for a constant expression, and it is always possible to
take the parameter’s address.
S-Function API to Specify Input Expression Acceptance. The S-Function
API provides macros that let you:
• Specify whether a block input should accept nonconstant expressions (that
is, trivial or generic expressions)
• Query whether a block input accepts nonconstant expressions
By default, block inputs do not accept nonconstant expressions.
You should call the macros in your mdlSetWorkWidths function. The macros
have the following arguments:
• SimStruct *S: pointer to the block’s SimStruct.
• int idx:

zero-based index of the input port.

• bool value: pass in TRUE if the port accepts input expressions; otherwise
pass in FALSE.
The macro available for specifying whether or not a block input should accept
a nonconstant expression is as follows:
void ssSetInputPortAcceptExprInRTW(SimStruct *S, int portIdx, bool value)

The corresponding macro available for querying the status set by any prior
calls to ssSetInputPortAcceptExprInRTW is as follows:
bool ssGetInputPortAcceptExprInRTW(SimStruct *S, int portIdx)

Denial of Block Requests to Output Expressions. Even after a specific
block requests that it be allowed to generate an output expression, that
request can be denied for generic reasons. These reasons include, but are
not limited to

14-99

14

External Code Integration

• The output expression is nontrivial, and the output has multiple
destinations.
• The output expression is nonconstant, and the output is connected to at
least one destination that does not accept expressions at its input port.
• The output is a test point.
• The output has been assigned an external storage class.
• The output must be stored using global data (for example is an input to a
merge block or a block with states).
• The output signal is complex.
You do not need to consider these generic factors when deciding whether or
not to utilize expression folding for a particular block. However, these rules
can be helpful when you are examining generated code and analyzing cases
where the expression folding optimization is suppressed.

Expression Folding in a TLC Block Implementation
To take advantage of expression folding, you must modify the TLC block
implementation of an inlined S-Function such that it informs the Simulink
engine whether it generates or accepts expressions at its
• Input ports, as explained in “S-Function API to Specify Input Expression
Acceptance” on page 14-99.
• Output ports, as explained in “Categories of Output Expressions” on page
14-93.
This section discusses required modifications to the TLC implementation.
Expression Folding Compliance. In the BlockInstanceSetup function of
your S-function, register your block to be compliant with expression folding.
Otherwise, any expression folding requested or allowed at the block’s outputs
or inputs will be disabled, and temporary variables will be used.
To register expression folding compliance, call the TLC library function
LibBlockSetIsExpressionCompliant(block), which is defined in
matlabroot/rtw/c/tlc/lib/utillib.tlc. For example:

14-100

Insert S-Function Code

%% Function: BlockInstanceSetup ===========================================
%%
%function BlockInstanceSetup(block, system) void
%%
%
%%
%endfunction

You can conditionally disable expression folding at the inputs and outputs of a
block by making the call to this function conditionally.
If you have overridden one of the TLC block implementations provided by the
Simulink Coder product with your own implementation, you should not make
the preceding call until you have updated your implementation, as described
by the guidelines for expression folding in the following sections.
Output Expressions. The BlockOutputSignal function is used to
generate code for a scalar output expression or one element of a nonscalar
output expression. If your block outputs an expression, you should add a
BlockOutputSignal function. The prototype of the BlockOutputSignal is
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void

The arguments to BlockOutputSignal are as follows:
• block: the record for the block for which an output expression is being
generated
• system: the record for the system containing the block
• portIdx: zero-based index of the output port for which an expression is
being generated
• ucv: user control variable defining the output element for which code is
being generated
• lcv: loop control variable defining the output element for which code is
being generated
• idx: signal index defining the output element for which code is being
generated
• retType: string defining the type of signal access desired:

14-101

14

External Code Integration

"Signal" specifies the contents or address of the output signal.
"SignalAddr" specifies the address of the output signal

The BlockOutputSignal function returns a text string for the output signal
or address. The string should enforce the precedence of the expression by
using opening and terminating parentheses, unless the expression consists
of a function call. The address of an expression can only be returned for a
constant expression; it is the address of the parameter whose memory is being
accessed. The code implementing the BlockOutputSignal function for the
Constant block is shown below.
%% Function: BlockOutputSignal =================================================
%% Abstract:
%%

Return the reference to the parameter.

%%

be used by Simulink when optimizing the Block IO data structure.

This function *may*

%%
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void
%switch retType
%case "Signal"
%return LibBlockParameter(Value,ucv,lcv,idx)
%case "SignalAddr"
%return LibBlockParameterAddr(Value,ucv,lcv,idx)
%default
%assign errTxt = "Unsupported return type: %"
%
%endswitch
%endfunction

The code implementing the BlockOutputSignal function for the Relational
Operator block is shown below.
%% Function: BlockOutputSignal =================================================
%% Abstract:
%%

Return an output expression.

%%

be used by Simulink when optimizing the Block IO data structure.

This function *may*

%%
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void
%switch retType
%case "Signal"
%assign logicOperator = ParamSettings.Operator

14-102

Insert S-Function Code

%if ISEQUAL(logicOperator, "~=")
%assign op = "!="
elseif ISEQUAL(logicOperator, "==") %assign op = "=="
%else
%assign op = logicOperator
%endif
%assign u0 = LibBlockInputSignal(0, ucv, lcv, idx)
%assign u1 = LibBlockInputSignal(1, ucv, lcv, idx)
%return "(% % %)"
%default
%assign errTxt = "Unsupported return type: %"
%
%endswitch
%endfunction

Expression Folding for Blocks with Multiple Outputs. When a block has
a single output, the Outputs function in the block’s TLC file is called only if
the output port is not an expression. Otherwise, the BlockOutputSignal
function is called.
If a block has multiple outputs, the Outputs function is called if any output
port is not an expression. The Outputs function should guard against
generating code for output ports that are expressions. This is achieved by
guarding sections of code corresponding to individual output ports with calls
to LibBlockOutputSignalIsExpr().
For example, consider an S-Function with two inputs and two outputs, where
• The first output, y0, is equal to two times the first input.
• The second output, y1, is equal to four times the second input.
The Outputs and BlockOutputSignal functions for the S-function are shown
in the following code excerpt.
%% Function: BlockOutputSignal =================================================
%% Abstract:
%%

Return an output expression.

%%

be used by Simulink when optimizing the Block IO data structure.

This function *may*

%%
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void

14-103

14

External Code Integration

%switch retType
%case "Signal"
%assign u = LibBlockInputSignal(portIdx, ucv, lcv, idx)
%case "Signal"
%if portIdx == 0
%return "(2 * %)"
%elseif portIdx == 1
%return "(4 * %)"
%endif
%default
%assign errTxt = "Unsupported return type: %"
%
%endswitch
%endfunction
%%
%% Function: Outputs =================================================
%% Abstract:
%%

Compute output signals of block

%%
%function Outputs(block,system) Output
%assign rollVars = ["U", "Y"]
%roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
%assign u0 = LibBlockInputSignal(0, "", lcv, sigIdx)
%assign u1 = LibBlockInputSignal(1, "", lcv, sigIdx)
%assign y0 = LibBlockOutputSignal(0, "", lcv, sigIdx)
%assign y1 = LibBlockOutputSignal(1, "", lcv, sigIdx)
%if !LibBlockOutputSignalIsExpr(0)
% = 2 * %;
%endif
%if !LibBlockOutputSignalIsExpr(1)
% = 4 * %;
%endif
%endroll
%endfunction

Comments for Blocks That Are Expression-Folding-Compliant. In the
past, all blocks preceded their outputs code with comments of the form
/* % Block: % */

14-104

Insert S-Function Code

When a block is expression-folding-compliant, the initial line shown above
is generated automatically. You should not include the comment as part of
the block’s TLC implementation. Additional information should be registered
using the LibCacheBlockComment function.
The LibCacheBlockComment function takes a string as an input, defining the
body of the comment, except for the opening header, the final newline of a
single or multiline comment, and the closing trailer.
The following TLC code illustrates registering a block comment. Note the
use of the function LibBlockParameterForComment, which returns a string,
suitable for a block comment, specifying the value of the block parameter.
%openfile commentBuf
$c(*) Gain value: %
%closefile commentBuf
%

S-Functions That Specify Port Scope and Reusability
You can use the following SimStruct macros in the mdlInitializeSizes
method to specify the scope and reusability of the memory used for your
S-function’s input and output ports:
• ssSetInputPortOptimOpts: Specify the scope and reusability of the
memory allocated to an S-function input port
• ssSetOutputPortOptimOpts: Specify the scope and reusability of the
memory allocated to an S-function output port
• ssSetInputPortOverWritable: Specify whether one of your S-function’s
input ports can be overwritten by one of its output ports
• ssSetOutputPortOverwritesInputPort: Specify whether an output port
can share its memory buffer with an input port
You declare an input or output as local or global, and indicate its reusability,
by passing one of the following four options to the ssSetInputPortOptimOpts
and ssSetOutputPortOptimOpts macros:

14-105

14

External Code Integration

• SS_NOT_REUSABLE_AND_GLOBAL: Indicates that the input and output ports
are stored in separate memory locations in the global block input and
output structure
• SS_NOT_REUSABLE_AND_LOCAL: Indicates that the Simulink Coder software
can declare individual local variables for the input and output ports
• SS_REUSABLE_AND_LOCAL: Indicates that the Simulink Coder software can
reuse a single local variable for these input and output ports
• SS_REUSABLE_AND_GLOBAL: Indicates that these input and output ports are
stored in a single element in the global block input and output structure
Note Marking an input or output port as a local variable does not imply
that the code generator uses a local variable in the generated code. If your
S-function accesses the inputs and outputs only in its mdlOutputs routine, the
code generator declares the inputs and outputs as local variables. However,
if the inputs and outputs are used elsewhere in the S-function, the code
generator includes them in the global block input and output structure.
The reusability setting indicates if the memory associated with an input or
output port can be overwritten. To reuse input and output port memory:
1 Indicate the ports are reusable using either the SS_REUSABLE_AND_LOCAL

or SS_REUSABLE_AND_GLOBAL option in the ssSetInputPortOptimOpts and
ssSetOutputPortOptimOpts macros
2 Indicate the input port memory is overwritable using

ssSetInputPortOverWritable
3 If your S-function has multiple input and output ports, use

ssSetOutputPortOverwritesInputPort to indicate which output and

input ports share memory
The following example shows how different scope and reusability
settings effect the generated code. The following model contains
an S-function block pointing to the C MEX S-function
matlabroot/toolbox/simulink/simdemos/simfeatures/src/sfun_directlook.c,

which models a direct 1-D lookup table.

14-106

Insert S-Function Code

The S-function’s mdlInitializeSizes method declares the input port as
reusable, local, and overwritable and the output port as reusable and local, as
follows:
static void mdlInitializeSizes(SimStruct *S)
{
/* snip */
ssSetInputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
ssSetInputPortOverWritable(S, 0, TRUE);
/* snip */
ssSetOutputPortOptimOpts(S, 0, SS_REUSABLE_AND_LOCAL);
/* snip */
}

The generated code for this model stores the input and output signals in
a single local variable rtb_SFunction, as shown in the following output
function:
static void sl_directlook_output(int_T tid)
{
/* local block i/o variables */
real_T rtb_SFunction[2];
/* Sin: '/Sine Wave' */
rtb_SFunction[0] = sin(((real_T)sl_directlook_DWork.counter[0] +
sl_directlook_P.SineWave_Offset) * 2.0 * 3.1415926535897931E+000 /
sl_directlook_P.SineWave_NumSamp) * sl_directlook_P.SineWave_Amp[0] +
sl_directlook_P.SineWave_Bias;
rtb_SFunction[1] = sin(((real_T)sl_directlook_DWork.counter[1] +
sl_directlook_P.SineWave_Offset) * 2.0 * 3.1415926535897931E+000 /
sl_directlook_P.SineWave_NumSamp) * sl_directlook_P.SineWave_Amp[1] +
sl_directlook_P.SineWave_Bias;

14-107

14

External Code Integration

/* S-Function Block: /S-Function */
{
const real_T *xData = &sl_directlook_P.SFunction_XData[0];
const real_T *yData = &sl_directlook_P.SFunction_YData [0];
real_T spacing = xData[1] - xData[0];
if (rtb_SFunction[0] <= xData[0] ) {
rtb_SFunction[0] = yData[0];
} else if (rtb_SFunction[0] >= yData[20] ) {
rtb_SFunction[0] = yData[20];
} else {
int_T idx = (int_T)( ( rtb_SFunction[0] - xData[0] ) / spacing );
rtb_SFunction[0] = yData[idx];
}
if (rtb_SFunction[1] <= xData[0] ) {
rtb_SFunction[1] = yData[0];
} else if (rtb_SFunction[1] >= yData[20] ) {
rtb_SFunction[1] = yData[20];
} else {
int_T idx = (int_T)( ( rtb_SFunction[1] - xData[0] ) / spacing );
rtb_SFunction[1] = yData[idx];
}
}
/* Outport: '/Out1' */
sl_directlook_Y.Out1[0] = rtb_SFunction[0];
sl_directlook_Y.Out1[1] = rtb_SFunction[1];
UNUSED_PARAMETER(tid);
}

The following table shows variations of the code generated for this model
when using the generic real-time target (GRT). Each row explains a different
setting for the scope and reusability of the S-function’s input and output ports.

14-108

Insert S-Function Code

Scope and
reusability
Inputs: Local,
reusable,
overwritable
Outputs: Local,
reusable

S-function mdlInitializeSizes
code
ssSetInputPortOptimOpts(S, 0,

Generated code
The model.c file declares a local
variable in the output function.

SS_REUSABLE_AND_LOCAL);
/* local block i/o variables */
ssSetInputPortOverWritable(S, 0,

real_T rtb_SFunction[2];

TRUE);
ssSetOutputPortOptimOpts(S, 0,
SS_REUSABLE_AND_LOCAL);

Inputs: Global,
reusable,
overwritable
Outputs:
Global, reusable

ssSetInputPortOptimOpts(S, 0,
SS_REUSABLE_AND_GLOBAL);

The model.h file defines a block
signals structure with a single
element to store the S-function’s
input and output.

ssSetInputPortOverWritable(S, 0,
TRUE);

/* Block signals (auto storage) */
typedef struct {

ssSetOutputPortOptimOpts(S, 0,
SS_REUSABLE_AND_GLOBAL);

real_T SFunction[2];
} BlockIO_sl_directlook;

The model.c file uses this element
of the structure in calculations of the
S-function’s input and output signals.
/* Sin: '/Sine Wave' */
sl_directlook_B.SFunction[0] = sin ...
/* snip */
/*S-Function Block:/S-Function*/
{
const real_T *xData =
&sl_directlook_P.SFunction_XData[0]

14-109

14

External Code Integration

Scope and
reusability
Inputs: Local,
not reusable
Outputs: Local,
not reusable

S-function mdlInitializeSizes
code

Generated code

SS_NOT_REUSABLE_AND_LOCAL);

The model.c file declares local
variables for the S-function’s input
and output in the output function

ssSetInputPortOverWritable(S, 0,

/* local block i/o variables */

ssSetInputPortOptimOpts(S, 0,

FALSE);

real_T rtb_SineWave[2];
real_T rtb_SFunction[2];

ssSetOutputPortOptimOpts(S, 0,
SS_NOT_REUSABLE_AND_LOCAL);

Inputs: Global,
not reusable
Outputs:
Global, not
reusable

ssSetInputPortOptimOpts(S, 0,
SS_NOT_REUSABLE_AND_GLOBAL);

The model.h file defines a block
signal structure with individual
elements to store the S-function’s
input and output.

ssSetInputPortOverWritable(S, 0,
FALSE);

/* Block signals (auto storage) */
typedef struct {

ssSetOutputPortOptimOpts(S, 0,

real_T SineWave[2];

SS_NOT_REUSABLE_AND_GLOBAL);

real_T SFunction[2];
} BlockIO_sl_directlook;

The model.c file uses the different
elements in this structure when
calculating the S-function’s input
and output.
/* Sin: '/Sine Wave' */
sl_directlook_B.SineWave[0] = sin ...
/* snip */
/*S-Function Block:/S-Function*/
{
const real_T *xData =
&sl_directlook_P.SFunction_XData[0]

14-110

Insert S-Function Code

S-Functions That Specify Sample Time Inheritance
Rules
For the Simulink engine to determine whether a model can inherit
a sample time, the S-functions in the model need to specify how
they use sample times. You can specify this information by calling
the macro ssSetModelReferenceSampleTimeInheritanceRule from
mdlInitializeSizes or mdlSetWorkWidths. To use this macro:
1 Check whether the S-function calls any of the following macros:

• ssGetSampleTime
• ssGetInputPortSampleTime
• ssGetOutputPortSampleTime
• ssGetInputPortOffsetTime
• ssGetOutputPortOffsetTime
• ssGetSampleTimePtr
• ssGetInputPortSampleTimeIndex
• ssGetOutputPortSampleTimeIndex
• ssGetSampleTimeTaskID
• ssGetSampleTimeTaskIDPtr
2 Check for the following in your S-function TLC code:

• LibBlockSampleTime
• CompiledModel.SampleTime
• LibBlockInputSignalSampleTime
• LibBlockInputSignalOffsetTime
• LibBlockOutputSignalSampleTime
• LibBlockOutputSignalOffsetTime
3 Depending on your search results, use

ssSetModelReferenceSampleTimeInheritanceRule as indicated in the

following table.

14-111

14

External Code Integration

If...

Use...

None of the macros or functions
are present, the S-function does
not preclude the model from
inheriting a sample time.

ssSetModelReferenceSampleTimeInheritanceRule
(S, USE_DEFAULT_FOR_DISCRETE_INHERITANCE)

Any of the macros or functions
are used for

ssSetModelReferenceSampleTimeInheritanceRule...
(S,USE_DEFAULT_FOR_DISCRETE_INHERITANCE)

• Throwing errors if sample time
is inherited, continuous, or
constant
• Checking ssIsSampleHit
• Checking whether sample
time is inherited in either
mdlSetInputPortSampleTime

or
mdlSetOutputPortSampleTime

before setting
The S-function uses its sample
time for computing parameters,
outputs, and so on

ssSetModelReferenceSampleTimeInheritanceRule
(S, DISALLOW_SAMPLE_TIME_INHERITANCE)

Note If an S-function does not set the

ssSetModelReferenceSampleTimeInheritanceRule macro, by default the
Simulink engine assumes that the S-function does not preclude the model
containing that S-function from inheriting a sample time. However, the
engine issues a warning indicating that the model includes S-functions
for which this macro is not set.

You can use settings on the Diagnostics/Solver pane of the Configuration
Parameters dialog box or Model Explorer to control how the Simulink engine
responds when it encounters S-functions that have unspecified sample time
inheritance rules. Toggle the Unspecified inheritability of sample time
diagnostic to none, warning, or error. The default is warning.

14-112

Insert S-Function Code

S-Functions That Support Code Reuse
You can reuse the generated code for identical subsystems that occur in
multiple instances within a model and across referenced models. For more
information about code generation of subsystems for code reuse, see “Code
Generation of Subsystems” on page 2-2. If you want your S-function to
support code reuse for a subsystem, the S-function must meet the following
requirements:
• The S-function must be inlined.
• Code generated from the S-function must not use static variables.
• The S-function must initialize its pointer work vector in mdlStart and
not before.
• The S-function must not be a sink that logs data to the workspace.
• The S-function must register its parameters as run-time parameters in
mdlSetWorkWidths. (It must not use ssWriteRTWParameters in its mdlRTW
function for this purpose.)
• The S-function must not be a device driver.
In addition to meeting the preceding requirements, your S-function must
set the SS_OPTION_WORKS_WITH_CODE_REUSE flag (see the description of
ssSetOptions in the Simulink Writing S-Function documentation). This
flag indicates that your S-function meets the requirements for subsystem
code reuse.

S-Functions for Multirate Multitasking Environments
• “About S-Functions for Multirate Multitasking Environments” on page
14-113
• “Rate Grouping Support in S-Functions” on page 14-114
• “Create Multitasking, Multirate, Port-Based Sample Time S-Functions”
on page 14-115

About S-Functions for Multirate Multitasking Environments
S-functions can be used in models with multiple sample rates and deployed in
multitasking target environments. Likewise, S-functions themselves can have

14-113

14

External Code Integration

multiple rates at which they operate. The Embedded Coder product generates
code for multirate multitasking models using an approach called rate
grouping. In code generated for ERT-based targets, rate grouping generates
separate model_step functions for the base rate task and each subrate task
in the model. Although rate grouping is a code generation feature found in
ERT targets only, your S-functions can use it in other contexts when you
code them as explained below.

Rate Grouping Support in S-Functions
To take advantage of rate grouping, you must inline your multirate
S-functions if you have not done so. You need to follow certain Target
Language Compiler protocols to exploit rate grouping. Coding TLC to exploit
rate grouping does not prevent your inlined S-functions from functioning
properly in GRT. Likewise, your inlined S-functions will still generate valid
ERT code even if you do not make them rate-grouping-compliant. If you do so,
however, they will generate more efficient code for multirate models.
For instructions and examples of Target Language Compiler code illustrating
how to create and upgrade S-functions to generate rate-grouping-compliant
code, see “Rate Grouping Compliance and Compatibility Issues” in the
Embedded Coder documentation.
For each multirate S-function that is not rate grouping-compliant, the
Simulink Coder software issues the following warning when you build:
Warning:

Simulink Coder: Code of output function for multirate block

'/S-Function' is guarded by sample hit checks rather than being rate
grouped. This will generate the same code for all rates used by the block,
possibly generating dead code. To avoid dead code, you must update the TLC
file for the block.

You will also find a comment such as the following in code generated for each
noncompliant S-function:
/* Because the output function of multirate block
/S-Function is not rate grouped,
the following code might contain unreachable blocks of code.
To avoid this, you must update your block TLC file. */

14-114

Insert S-Function Code

The words “update function” are substituted for “output function” in these
warnings.

Create Multitasking, Multirate, Port-Based Sample Time
S-Functions
The following instructions show how to support both data determinism and
data integrity in multirate S-functions. They do not cover cases where there
is no determinism nor integrity. Support for frame-based processing does
not affect the requirements.
Note The slow rates must be multiples of the fastest rate. The instructions
do not apply when two rates being interfaced are not multiples or when the
rates are not periodic.
Rules for Properly Handling Fast-to-Slow Transitions. The rules that
multirate S-functions should observe for inputs are
• The input should only be read at the rate that is associated with the input
port sample time.
• Generally, the input data is written to DWork, and the DWork can then be
accessed at the slower (downstream) rate.
The input can be read at every sample hit of the input rate and written into
DWork memory, but this DWork memory cannot then be directly accessed
by the slower rate. Any DWork memory that will be read by the slow rate
must only be written by the fast rate when there is a special sample hit. A
special sample hit occurs when both this input port rate and rate to which
it is interfacing have a hit. Depending on their requirements and design,
algorithms can process the data in several locations.
The rules that multirate S-functions should observe for outputs are
• The output should not be written by any rate other than the rate assigned
to the output port, except in the optimized case described below.
• The output should always be written when the sample rate of the output
port has a hit.

14-115

14

External Code Integration

If these conditions are met, the S-Function block can specify that the input
port and output port can both be made local and reusable.
You can include an optimization when little or no processing needs to be done
on the data. In such cases, the input rate code can directly write to the output
(instead of by using DWork) when there is a special sample hit. If you do this,
however, you must declare the outport port to be global and not reusable.
This optimization results in one less memcpy but does introduce nonuniform
processing requirements on the faster rate.
Whether you use this optimization or not, the most recent input data, as
seen by the slower rate, is always the value when both the faster and slower
rate had their hits (and possible earlier input data as well, depending on
the algorithm). Any subsequent steps by the faster rate and the associated
input data updates are not seen by the slower rate until the next hit for the
slow rate occurs.
Pseudocode Examples of Fast-to-Slow Rate Transition. The pseudocode
below abstracts how you should write your C MEX code to handle fast-to-slow
transitions, illustrating with an input rate of 0.1 second driving an output
rate of one second. A similar approach can be taken when inlining the code.
The block has following characteristics:
• File: sfun_multirate_zoh.c, Equation: y = u(tslow)
• Input: local and reusable
• Output: local and reusable
• DirectFeedthrough: yes
OutputFcn
if (ssIsSampleHit(".1")) {
if (ssIsSepcialSampleHit("1")) {
DWork = u;
}
}
if (ssIsSampleHit("1")) {
y = DWork;
}

An alternative, slightly optimized approach for simple algorithms:

14-116

Insert S-Function Code

• Input: local and reusable
• Output: global and not reusable because it needs to persist between special
sample hits
• DirectFeedthrough: yes
OutputFcn
if (ssIsSampleHit(".1")) {
if (ssIsSpecialSampleHit("1")) {
y = u;
}
}

Example adding a simple algorithm:
• File: sfun_multirate_avg.c; Equation: y = average(u)
• Input: local and reusable
• Output: local and reusable
• DirectFeedthrough: yes
(Assume DWork[0:10] and DWork[mycounter] are initialized to zero)
OutputFcn
if (ssIsSampleHit(".1")) {
/* In general, processing on 'u' could be done here,
it runs on every hit of the fast rate. */
DWork[DWork[mycounter]++] = u;
if (ssIsSpecialSampleHit("1")) {
/* In general, processing on DWork[0:10] can be done
here, but it does cause the faster rate to have
nonuniform processing requirements (every 10th hit,
more code needs to be run).*/
DWork[10] = sum(DWork[0:9])/10;
DWork[mycounter] = 0;
}
}
if (ssIsSampleHit("1")) {
/* Processing on DWork[10] can be done here before
outputing. This code runs on every hit of the

14-117

14

External Code Integration

slower task. */
y = DWork[10];
}

Rules for Properly Handling Slow-to-Fast Transitions. When output
rates are faster than input rates, input should only be read at the rate that is
associated with the input port sample time, observing the following rules:
• Always read input from the update function.
• Use no special sample hit checks when reading input.
• Write the input to a DWork.
• When there is a special sample hit between the rates, copy the DWork into
a second DWork in the output function.
• Write the second DWork to the output at every hit of the output sample
rate.
The block can request that the input port be made local but it cannot be set to
reusable. The output port can be set to local and reusable.
As in the fast-to-slow transition case, the input should not be read by any rate
other than the one assigned to the input port. Similarly, the output should
not be written to at any rate other than the rate assigned to the output port.
An optimization can be made when the algorithm being implemented is only
required to run at the slow rate. In such cases, you use only one DWork.
The input still writes to the DWork in the update function. When there is a
special sample hit between the rates, the output function copies the same
DWork directly to the output. You must set the output port to be global
and not reusable in this case. This optimization results in one less memcpy
operation per special sample hit.
In either case, the data that the fast rate computations operate on is always
delayed, that is, the data is from the previous step of the slow rate code.
Pseudocode Examples of Slow-to-Fast Rate Transition. The pseudocode
below abstracts what your S-function needs to do to handle slow-to-fast
transitions, illustrating with an input rate of one second driving an output
rate of 0.1 second. The block has following characteristics:

14-118

Insert S-Function Code

• File: sfun_multirate_delay.c, Equation: y = u(tslow-1)
• Input: Set to local, will be local if output/update are combined (ERT)
otherwise will be global. Set to not reusable because input needs to be
preserved until the update function runs.
• Output: local and reusable
• DirectFeedthrough: no
OutputFcn
if (ssIsSampleHit(".1") {
if (ssIsSpecialSampleHit("1") {
DWork[1] = DWork[0];
}
y = DWork[1];
}
UpdateFcn
if (ssIsSampleHit("1")) {
DWork[0] = u;
}

An alternative, optimized approach can be used by some algorithms:
• Input: Set to local, will be local if output/update are combined (ERT)
otherwise will be global. Set to not reusable because input needs to be
preserved until the update function runs.
• Output: global and not reusable because it needs to persist between special
sample hits.
• DirectFeedthrough: no
OutputFcn
if (ssIsSampleHit(".1") {
if (ssIsSpecialSampleHit("1") {
y = DWork;
}
}
UpdateFcn
if (ssIsSampleHit("1")) {
DWork = u;
}

14-119

14

External Code Integration

Example adding a simple algorithm:
• File: sfun_multirate_modulate.c, Equation: y = sin(tfast) +
u(tslow-1)

• Input: Set to local, will be local if output/update are combined (an ERT
feature) otherwise will be global. Set to not reusable because input needs
to be preserved until the update function runs.
• Output: local and reusable
• DirectFeedthrough: no
OutputFcn
if (ssIsSampleHit(".1") {
if (ssIsSpecialSampleHit("1") {
/* Processing not likely to be done here. It causes
* the faster rate to have nonuniform processing
* requirements (every 10th hit, more code needs to
* be run).*/
DWork[1] = DWork[0];
}
/* Processing done at fast rate */
y = sin(ssGetTaskTime(".1")) + DWork[1];
}
UpdateFcn
if (ssIsSampleHit("1")) {
/* Processing on 'u' can be done here. There is a delay of
one slow rate period before the fast rate sees it.*/
DWork[0] = u;}

Build Support for S-Functions
• “About Build Support for S-Functions” on page 14-121
• “Implicit Build Support” on page 14-121
• “Specify Additional Source Files for an S-Function” on page 14-122
• “Use TLC Library Functions” on page 14-123
• “Use rtwmakecfg.m API to Customize Generated Makefiles” on page 14-124

14-120

Insert S-Function Code

• “Precompile S-Function Libraries” on page 14-129

About Build Support for S-Functions
User-written S-Function blocks provide a powerful way to incorporate
legacy and custom code into the Simulink and Simulink Coder development
environment. In most cases, you should use S-functions to integrate existing
code with Simulink Coder generated code. Several approaches to writing
S-functions are available as discussed in
• “Write Noninlined S-Functions” on page 14-52
• “Write Wrapper S-Functions” on page 14-54
• “Write Fully Inlined S-Functions” on page 14-64
• “Write Fully Inlined S-Functions with mdlRTW Routine” on page 14-65
• “S-Functions That Support Code Reuse” on page 14-113
• “S-Functions for Multirate Multitasking Environments” on page 14-113
S-functions also provide the most flexible and capable way of including build
information for legacy and custom code files in the Simulink Coder build
process.
This section discusses the different ways of adding S-functions to the Simulink
Coder build process.

Implicit Build Support
When building models with S-functions, the code generator automatically
adds rules, include paths, and source filenames to the generated makefile.
For this to occur, the source files (.h, .c, and .cpp) for the S-function must be
in the same folder as the S-function MEX-file. The code generator propagates
this information through the token expansion mechanism of converting a
template makefile (TMF) to a makefile. The propagation requires the TMF
to support the tokens.
Details of the implicit build support follow:
• If the file sfcnname.h exists in the same folder as the S-function MEX-file
(for example, sfcnname.mexext), the folder is added to the include path.

14-121

14

External Code Integration

• If the file sfcnname.c or sfcnname.cpp exists in the same folder as the
S-function MEX-file, the Simulink Coder code generator adds a makefile
rule for compiling files from that folder.
• When an S-function is not inlined with a TLC file, the Simulink Coder
code generator must compile the S-function’s source file. To determine
the name of the source file to add to the list of files to compile, the code
generator searches for sfcnname.cpp on the MATLAB path. If the source
file is found, the code generator adds the source filename to the makefile.
If sfcnname.cpp is not found on the path, the code generator adds the
filename sfcnname.c to the makefile, whether or not it is on the MATLAB
path.
Note For the Simulink engine to find the MEX-file for simulation and
code generation, it must exist on the MATLAB path or be in your current
MATLAB working folder.

Specify Additional Source Files for an S-Function
If your S-function has additional source file dependencies, you must add the
names of the additional modules to the build process. You can do this by
specifying the filenames
• In the S-function modules field of the S-Function block parameter dialog
box
• With the SFunctionModules parameter in a call to the set_param function
For example, suppose you build your S-function with multiple modules, as in
mex sfun_main.c sfun_module1.c sfun_module2.c

You can then add the modules to the build process by doing one of the
following:
• Specifying sfun_main, sfun_module1, and sfun_module2 in the
S-function modules field in the S-Function block dialog box
• Entering the following command at the MATLAB command prompt:

14-122

Insert S-Function Code

set_param(sfun_block,'SFunctionModules','sfun_module1 sfun_module2')

Alternatively, you can define a variable to represent the parameter value.
modules = 'sfun_module1 sfun_module2'
set_param(sfun_block,'SFunctionModules', modules)

Note The S-function modules field and SFunctionsModules parameter do
not support complete source file path specifications. To use the parameter,
the Simulink Coder software must be able to find the additional source files
when executing the makefile. For the Simulink Coder software to locate the
additional files, place them in the same folder as the S-function MEX-file.
This will enable you to leverage the implicit build support discussed in
“Implicit Build Support” on page 14-121.
For more complicated S-function file dependencies, such as specifying
source files in other locations or specifying libraries or object files, use the
rtwmakecfg.m API, as explained in “Use rtwmakecfg.m API to Customize
Generated Makefiles” on page 14-124.

Use TLC Library Functions
If you inline your S-function by writing a TLC file, you can add source
filenames to the build process by using the TLC library function
LibAddToModelSources. For details, see “LibAddSourceFileCustomSection
(file, builtInSection, newSection)” in the Target Language Compiler
documentation.
Note This function does not support complete source file path specifications
and assumes the Simulink Coder software can find the additional source
files when executing the makefile.
Another useful TLC library function is LibAddToCommonIncludes.
Use this function in a #include statement to include S-function
header files in the generated model.h header file. For details, see

14-123

14

External Code Integration

“LibAddToCommonIncludes(incFileName)” in the Target Language Compiler
documentation.
For more complicated S-function file dependencies, such as specifying
source files in other locations or specifying libraries or object files, use the
rtwmakecfg.m API, as explained in “Use rtwmakecfg.m API to Customize
Generated Makefiles” on page 14-124.

Use rtwmakecfg.m API to Customize Generated Makefiles
• “Overview” on page 14-124
• “Create the rtwmakecfg Function” on page 14-125
• “Modify the Template Makefile” on page 14-127
Overview. Simulink Coder TMFs provide tokens that let you add the
following items to generated makefiles:
• Source folders
• Include folders
• Run-time library names
• Run-time module objects
S-functions can add this information to the makefile by using an rtwmakecfg
function. This function is particularly useful when building a model that
contains one or more of your S-Function blocks, such as device driver blocks.
To add information pertaining to an S-function to the makefile,
1 Create the MATLAB language function rtwmakecfg in a file rtwmakecfg.m.

The Simulink Coder software associates this file with your S-function
based on its folder location. “Create the rtwmakecfg Function” on page
14-125 discusses the requirements for the rtwmakecfg function and the
data it should return.
2 Modify your target’s TMF such that it supports macro expansion for the

information returned by rtwmakecfg functions. “Modify the Template
Makefile” on page 14-127 discusses the required modifications.

14-124

Insert S-Function Code

After the TLC phase of the build process, when generating a makefile from
the TMF, the Simulink Coder code generator searches for an rtwmakecfg.m
file in the folder that contains the S-function component. If it finds the file,
the code generator calls the rtwmakecfg function.
Create the rtwmakecfg Function. Create the rtwmakecfg.m file containing
the rtwmakecfg function in the same folder as your S-function component
(sfcname.mexext on a Microsoft Windows system and sfcname and a
platform-specific extension on The Open Group UNIX system). The function
must return a structured array that contains the following fields:
Field

Description

makeInfo.includePath

A cell array that specifies additional include folder
names, organized as a row vector. The Simulink Coder
code generator expands the folder names into include
instructions in the generated makefile.

makeInfo.sourcePath

A cell array that specifies additional source folder names,
organized as a row vector. You must include the folder
names of files entered into the S-function modules field
on the S-Function Block Parameters dialog box or into the
block’s SFunctionModules parameter if they are not in the
same folder as the S-function. The Simulink Coder code
generator expands the folder names into make rules in the
generated makefile.

makeInfo.sources

A cell array that specifies additional source filenames (C or
C++), organized as a row vector. Do not include the name
of the S-function or any files entered into the S-function
modules field on the S-Function Block Parameters dialog
box or into the block’s SFunctionModules parameter. The
Simulink Coder code generator expands the filenames into
make variables that contain the source files. You should
specify only filenames (with extension). Specify path
information with the sourcePath field.

14-125

14

External Code Integration

Field

Description

makeInfo.linkLibsObjs

A cell array that specifies additional, fully qualified paths
to object or library files against which the Simulink
Coder generated code should link. The Simulink Coder
code generator does not compile the specified objects and
libraries. However, it includes them when linking the final
executable. This can be useful for incorporating libraries
that you do not want the Simulink Coder code generator to
recompile or for which the source files are not available.
You might also use this element to incorporate source files
from languages other than C and C++. This is possible if
you first create a C compatible object file or library outside
of the Simulink Coder build process.

makeInfo.precompile

A Boolean flag that indicates whether the libraries specified
in the rtwmakecfg.m file exist in a specified location
(precompile==1) or if the libraries need to be created in
the build folder during the Simulink Coder build process
(precompile==0).

makeInfo.library

A structure array that specifies additional run-time
libraries and module objects, organized as a row vector. The
Simulink Coder code generator expands the information
into make rules in the generated makefile. See the next
table for a list of the library fields.
The makeInfo.library field consists of the following elements:

Element

Description

makeInfo.library(n).Name

A character array that specifies the name of the library
(without an extension).

makeInfo.library(n).Location

A character array that specifies the folder in which
the library is located when precompiled. See the
description of makeInfo.precompile in the preceding
table for more information. A target can use the
TargetPreCompLibLocation parameter to override

14-126

Insert S-Function Code

Description

Element

this value. See “Specify the Location of Precompiled
Libraries” on page 22-8 for details.
makeInfo.library(n).Modules

A cell array that specifies the C or C++ source file base
names (without an extension) that comprise the library.
Do not include the file extension. The makefile appends
the object extension.

Note The makeInfo.library field must fully specify each library and
how to build it. The modules list in the makeInfo.library(n).Modules
element cannot be empty. If you need to specify a link-only library, use the
makeInfo.linkLibsObjs field instead.
Example:
disp(['Running rtwmakecfg from folder: ',pwd]);
makeInfo.includePath = { fullfile(pwd, 'somedir2') };
makeInfo.sourcePath = {fullfile(pwd, 'somedir2'), fullfile(pwd, 'somedir3')};
makeInfo.sources

= { 'src1.c', 'src2.cpp'};

makeInfo.linkLibsObjs = { fullfile(pwd, 'somedir3', 'src3.object'),...
fullfile(pwd, 'somedir4', 'mylib.library')};
makeInfo.precompile = 1;
makeInfo.library(1).Name

= 'myprecompiledlib';

makeInfo.library(1).Location = fullfile(pwd,'somdir2','lib');
makeInfo.library(1).Modules

= {'srcfile1' 'srcfile2' 'srcfile3' };

Note If a path that you specify in the rtwmakecfg.m API contains spaces,
the code generator does not automatically convert the path to its non-space
equivalent. If the build environments you intend to support do not support
spaces in paths, refer to “Enabling the Simulink® Coder™ Software to Build
When Path Names Contain Spaces” on page 9-44.
Modify the Template Makefile. To expand the information generated
by an rtwmakecfg function, you can modify the following sections of your
target’s TMF:

14-127

14

External Code Integration

• Include Path
• C Flags and/or Additional Libraries
• Rules
The TMF code examples below may not apply to your make utility.
For additional examples, see the GRT or ERT TMFs located in
matlabroot/rtw/c/grt/*.tmf or matlabroot/rtw/c/ert/*.tmf.

Add Folder Names to the Makefile Include Path
The following TMF code example adds folder names to the include path in
the generated makefile:
ADD_INCLUDES = \
|>START_EXPAND_INCLUDES<|

-I|>EXPAND_DIR_NAME<| \

|>END_EXPAND_INCLUDES<|

Additionally, the ADD_INCLUDES macro must be added to the INCLUDES line,
as shown below.
INCLUDES = -I. -I.. $(MATLAB_INCLUDES) $(ADD_INCLUDES) $(USER_INCLUDES)

Add Library Names to the Makefile
The following TMF code example adds library names to the generated
makefile.
LIBS =
|>START_PRECOMP_LIBRARIES<|
LIBS += |>EXPAND_LIBRARY_NAME<|.a |>END_PRECOMP_LIBRARIES<|
|>START_EXPAND_LIBRARIES<|
LIBS += |>EXPAND_LIBRARY_NAME<|.a |>END_EXPAND_LIBRARIES<|

For more information on how to use configuration parameters to control
library names and location during the build process, see “Control Library
Location and Naming During Build” on page 22-7.

14-128

Insert S-Function Code

Add Rules to the Makefile
The following TMF code example adds rules to the generated makefile.
|>START_EXPAND_RULES<|
$(BLD)/%.o: |>EXPAND_DIR_NAME<|/%.c $(SRC)/$(MAKEFILE) rtw_proj.tmw
@$(BLANK)
@echo ### "|>EXPAND_DIR_NAME<|\$*.c"
$(CC) $(CFLAGS) $(APP_CFLAGS) -o $(BLD)$(DIRCHAR)$*.o \
|>EXPAND_DIR_NAME<|$(DIRCHAR)$*.c > $(BLD)$(DIRCHAR)$*.lst
|>END_EXPAND_RULES<|
|>START_EXPAND_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \
|>START_EXPAND_MODULES<|

|>EXPAND_MODULE_NAME<|.o \

|>END_EXPAND_MODULES<|
|>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw
$(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o)
@$(BLANK)
@echo ### Creating $@
$(AR) -r $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o)
|>END_EXPAND_LIBRARIES<|
|>START_PRECOMP_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \
|>START_EXPAND_MODULES<|

|>EXPAND_MODULE_NAME<|.o \

|>END_EXPAND_MODULES<|
|>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw
$(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o)
@$(BLANK)
@echo ### Creating $@
$(AR) -r $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o)
|>END_PRECOMP_LIBRARIES<|

Precompile S-Function Libraries
You can precompile new or updated S-function libraries (MEX-files) for a
model by using the MATLAB language function rtw_precompile_libs.
Using a specified model and a library build specification, this function builds
and places the libraries in a precompiled library folder.

14-129

14

External Code Integration

By precompiling S-function libraries, you can optimize system builds. Once
your precompiled libraries exist, the Simulink Coder code generator can omit
library compilation from subsequent builds. For models that use numerous
libraries, the time savings for build processing can be significant.
To use rtw_precompile_libs,
1 Set the library file suffix, including the file type extension, based on the

platform in use.
2 Set the precompiled library folder.
3 Define a build specification.
4 Issue a call to rtw_precompile_libs.

The following procedure explains these steps in more detail.
1 Set the library file suffix, including the file type extension, based on the

platform in use.
Consider checking for the type of platform in use and then using the
TargetLibSuffix parameter to set the library suffix accordingly. For
example, you might set the suffix to .a for a UNIX platform and _vc.lib
otherwise.
if isunix
suffix = '.a';
else
suffix = '_vc.lib';
end
set_param(my_model,'TargetLibSuffix', suffix);
2 Set the precompiled library folder.

Use one of the following methods to set the precompiled library folder.
• Set the TargetPreCompLibLocation parameter, as explained in “Specify
the Location of Precompiled Libraries” on page 22-8.
• Set the makeInfo.precompile field in an rtwmakecfg.m function file.

14-130

Insert S-Function Code

If you set both TargetPreCompLibLocation and makeInfo.precompile,
the setting for TargetPreCompLibLocation takes precedence.
The following command sets the precompiled library folder for model
my_model to folder lib under the current working folder.
set_param(my_model,'TargetPreCompLibLocation', fullfile(pwd,'lib'));

Note If you set both the target folder for the precompiled library files and
a target library file suffix, the Simulink Coder code generator automatically
detects whether any precompiled library files are missing while processing
builds.
3 Define a build specification.

Set up a structure that defines a build specification. The following
table describes fields you can define in the structure. All fields except
rtwmakecfgDirs are optional.
Field

Description

rtwmakecfgDirs

A cell array of strings that name the folders containing rtwmakecfg
files for libraries to be precompiled. The function uses the Name and
Location elements of makeInfo.library, as returned by rtwmakecfg,
to specify the name and location of the precompiled libraries. If you
set the TargetPreCompLibLocation parameter to specify the library
folder, that setting overrides the makeInfo.library.Location setting.
Note: The specified model must contain blocks that use precompiled
libraries specified by the rtwmakecfg files because the TMF-to-makefile
conversion generates the library rules only if the libraries are used.

libSuffix

A string that specifies the suffix, including the file type extension, to
be appended to the name of each library (for example, .a or _vc.lib).
The string must include a period (.). You must set the suffix with either
this field or the TargetLibSuffix parameter. If you specify a suffix
with both mechanisms, the TargetLibSuffix setting overrides the
setting of this field.

14-131

14

External Code Integration

Field

Description

intOnlyBuild

A Boolean flag. When set to true, the flag indicates the libraries are to
be optimized such that they are compiled from integer code only. This
field applies to ERT targets only.

makeOpts

A string that specifies an option to be included in the rtwMake command
line.

addLibs

A cell array of structures that specify libraries to be built that are not
specified by an rtwmakecfg function. Each structure must be defined
with two fields that are character arrays:
• libName — the name of the library without a suffix
• libLoc — the location for the precompiled library
The TMF can specify other libraries and how those libraries are to be
built. Use this field if you need to precompile those libraries.
The following commands set up build specification build_spec, which
indicates that the files to be compiled are in folder src under the current
working folder.
build_spec = [];
build_spec.rtwmakecfgDirs = {fullfile(pwd,'src')};
4 Issue a call to rtw_precompile_libs.

Issue a call to rtw_precompile_libs that specifies the model for which
you want to build the precompiled libraries and the build specification.
For example:
rtw_precompile_libs(my_model,build_spec);

14-132

15
Program Building,
Interaction, and Debugging
• “Compiler or IDE Selection and Configuration” on page 15-2
• “Program Builds” on page 15-12
• “Build and Run a Program” on page 15-43
• “Profile Code Performance” on page 15-45
• “Data Exchange” on page 15-50

15

Program Building, Interaction, and Debugging

Compiler or IDE Selection and Configuration
In this section...
“Choose and Configure a Compiler” on page 15-2
“Troubleshoot Compiler Configurations” on page 15-9

Choose and Configure a Compiler
• “Compilers and the Build Process” on page 15-2
• “Simulink® Coder™ and ANSI C/C++ Compliance” on page 15-3
• “Support for C and C++ Code Generation” on page 15-4
• “Support for International (Non-US-ASCII) Characters” on page 15-5
• “C++ Target Language Considerations” on page 15-7
• “Choose and Configure Compiler on Microsoft Windows” on page 15-8
• “Choose and Configure Compiler on UNIX” on page 15-9
• “Include S-Function Source Code” on page 15-9

Compilers and the Build Process
The Simulink Coder build process depends upon the installation of one or
more supported compilers. Compiler, in this context, refers to a development
environment containing a linker and make utility, in addition to a high-level
language compiler. For details on supported compiler versions, see
http://www.mathworks.com/support/compilers/current_release

Most Simulink Coder targets create an executable that runs on your
workstation. When creating the executable, the Simulink Coder build
process must be able to access a supported compiler. The build process can
automatically find a compiler to use based on your default MEX compiler.
The build process also requires the selection of a template makefile. The
template makefile determines which compiler runs, during the make phase of
the build, to compile the generated code.

15-2

Compiler or IDE Selection and Configuration

To determine which template makefiles are for your compiler and target, see
Targets Available from the System Target File Browser on page 9-12.
For both Simulink Coder generated files and user-supplied files, the file
extension, .c or .cpp, determines whether a C or a C++ compiler will be used
in the Simulink Coder build process. If the file extension is .c, a C compiler
will be used to compile the file, and the symbols will use the C linkage
convention. If the file extension is .cpp, a C++ compiler will be used to compile
the file, and the symbols by default will use the C++ linkage specification.

Simulink Coder and ANSI C/C++ Compliance
The Simulink Coder software generates code that is compliant with the
following standards:
Language

Supported Standard

C

ISO/IEC 9899:1990, also known as C89/C90

C++

ISO/IEC 14882:2003

Code generated by the Simulink Coder software from the following sources is
ANSI C/C++ compliant:
• Simulink built-in block algorithmic code
• Simulink Coder and Embedded Coder system level code (task ID [TID]
checks, management, functions, and so on)
• Code from other blocksets, including the Simulink Fixed Point product, the
Communications System Toolbox product, and so on
• Code from other code generators, such as MATLAB functions
Additionally, the Simulink Coder software can incorporate code from
• Embedded targets (for example, startup code, device driver blocks)
• User-written S-functions or TLC files

15-3

15

Program Building, Interaction, and Debugging

Note Coding standards for these two sources are beyond the control of the
Simulink Coder software, and can be a source for compliance problems, such
as code that uses C99 features not supported in the ANSI C, C89/C90 subset.

Support for C and C++ Code Generation
Simulink Coder supports C and C++ code generation. Consider the following
as you choose a language for your generated code:
• Whether you need to configure Simulink Coder to use a specific compiler.
This is required to generate C++ code on Windows. See “Choose and
Configure a Compiler” on page 15-2.
• The language configuration setting for the model. See “Select the Target
Language” on page 9-71.
• Whether you need to integrate legacy or custom code with generated code.
For a summary of integration options, see “Integration Options” on page
14-2.
• Whether you need to integrate C and C++ code. If so, see “Integration
Options” on page 14-2.
Note You can mix C and C++ code when integrating Simulink Coder
generated code with custom code. However, you must be aware of the
differences between C and default C++ linkage conventions, and add
the extern "C"’ linkage specifier where required. For the details of the
differing linkage conventions and how to apply extern "C", refer to a C++
programming language reference book.
• “C++ Target Language Limitations” on page 15-4.
For an example, enter sfcndemo_cppcount in the MATLAB Command
Window. For a Stateflow example, enter sf_cpp.
C++ Target Language Limitations.
• Simulink Coder does not support C++ code generation for the following:

15-4

Compiler or IDE Selection and Configuration

SimDriveline
SimMechanics
SimPowerSystems
Embedded Targets in Embedded Coder
Desktop Targets in Simulink Coder
xPC Target
• The following Embedded Coder dialog box fields currently do not accept
the .cpp extension. However, a .cpp file will be generated if you specify
a filename without an extension in these fields, with C++ selected as the
target language for your generated code.

-

Data definition filename field on the Data Placement pane of the
Configuration Parameters dialog box

-

Definition file field for an mpt data object in the Model Explorer

These restrictions on specifying .cpp will be removed in a future release.

Support for International (Non-US-ASCII) Characters
Simulink Coder does not include non-US-ASCII characters in compilable
portions of source code. However, Simulink, Stateflow, Simulink Coder, and
Embedded Coder do support non-US-ASCII characters in certain ways. When
non-US-ASCII characters are encountered during code generation, they either
become comments in the generated code or do not propagate into the generated
source files. Sources of non-US-ASCII characters are described below:
• Simulink Block Names: The name of Simulink blocks are permitted to use
non-US-ASCII character sets. The block name can be output in a comment
above the generated code for that block when the Simulink block /
Stateflow object comments check box is selected. If Simulink Coder also
uses the block name in the generated code as an identifier, the identifier’s
name changes so only US-ASCII characters are present.
One exception to using non-US-ASCII characters in block names is for
nonvirtual subsystems configured to use the subsystem name as either the
function name or the filename. In this case, only US-ASCII characters
can be used to name the subsystem.
• User comments on Stateflow diagrams: These comments can contain
non-US-ASCII characters. They are written to the generated code when
the Include comments check box is selected.

15-5

15

Program Building, Interaction, and Debugging

• Custom TLC files (.tlc): User-created Target Language Compiler files
can have non-US-ASCII characters inside both TLC comments and in any
code comments which are output. The Target Language Compiler does not
support non-US-ASCII characters in TLC variable or function names.
Additional Support with Embedded Coder. Users of Embedded Coder
have additional international character support:
• Simulink Block Description: Embedded Coder propagates block
descriptions entered from Simulink Block Parameter dialog boxes
into the generated code as comments when the Simulink block
descriptions check box on the Code Generation > Comments pane
of the Configuration Parameters dialog box is selected. Non-US-ASCII
characters are supported for these descriptions.
• Embedded Coder code template file: Code Generation Template (.cgt) files
provide customization capability for the generated code. Any output lines
in the .cgt file which are C or C++ comments can contain non-US-ASCII
characters, for example the file banner and file trailer sections; these
comments are propagated to the generated code. However, although TLC
comments in .cgt files can contain non-US-ASCII characters, these TLC
comments are not propagated to the generated code.
• Stateflow object descriptions: Stateflow object descriptions can contain
non-US-ASCII characters. The description will appear as a comment
above the generated code for that chart when the Stateflow object
descriptions check box is selected.
• Simulink Parameter Object Description: Simulink Parameter Object
descriptions can contain non-US-ASCII characters. The description will
appear as a comment above the generated code when the Simulink data
object descriptions check box is selected.
• MPT Signal Object Description: MPT object descriptions can contain
non-US-ASCII characters. The description will appear as a comment above
the generated code when the Simulink data object descriptions check box
is selected.
Character Set Limitation. You can encounter problems with models
containing characters of a specific character set, such as Shift JIS, on a host
system for which that character set is not configured as the default.

15-6

Compiler or IDE Selection and Configuration

When models containing characters of a given character set are used on a host
system that is not configured with that character set as the default, Simulink
can incorrectly interpret characters during model loading and saving. This
can lead to corrupted characters being displayed in the model and possibly
the model failing to load. It can also lead to corrupted characters in the model
file if you save it.
This limitation does not exist when the characters used in the model are in
the default character set for the host system. For example, you can use Shift
JIS characters with no issues if the host system is configured to use Japanese
Windows.
Additionally, during code generation, the Target Language Compiler can
have similar problems reading characters from either the model.rtw or user
written .tlc files. This can result in corrupt characters in generated source
file comments or a Target Language Compiler error.
For an example of international character set support for code generation, run
the example model rtwdemo_international. This example model is set up
to work around the character limitations described above. If you run this
example from a non-Japanese MATLAB host machine, you must set up an
international character set for Simulink. For example, type
bdclose all; set_param(0, 'CharacterEncoding', 'Shift_JIS')
rtwdemo_international

Other uses of non-US-ASCII characters in models or in files used during the
build process are not supported; you should not depend on any incidental
functionality that may exist.
For additional information, see the slCharacterEncoding function.

C++ Target Language Considerations
To use the C++ target language support, you might need to configure the
Simulink Coder software to use a specific compiler. For example, on a
Microsoft Windows platform the default compiler is the Lcc C compiler
shipped with the MATLAB product, which does not support C++. If you do
not configure the Simulink Coder software to use a C++ compiler before you
specify C++ for code generation, the following build error message appears:

15-7

15

Program Building, Interaction, and Debugging

The specified target is configured to generate
C++, but the C-only compiler, LCC, is the default compiler.

To

specify a C++ compiler, enter 'mex -setup' at the command prompt.
To generate C code, click (Open) to open the Configuration
Parameters dialog and set the target language to C.

Choose and Configure Compiler on Microsoft Windows
On Windows platforms, you can use the Lcc C compiler shipped with the
MATLAB product, or you can install and use one of the supported Windows
compilers.
The Simulink Coder code generator will choose a compiler based on the
template makefile (TMF) name specified on the Code Generation pane of
the Configuration Parameters dialog box. The simplest approach is to let
the code generator pick a compiler based on your default compiler, as set up
using the mex -setup function. When you use this approach, you do not need
to define compiler-specific environment variables, and the Simulink Coder
code generator determines the location of the compiler using information
from the mexopts.bat file located in the preferences folder (use the prefdir
command to verify this location).
To use this approach, the TMF filename specified must be a MATLAB
language file that returns default compiler information by using the
mexopts.bat file. Most targets provided by the Simulink Coder product use
this approach, as when grt_default_tmf or ert_default_tmf is specified as
the TMF name.
Alternatively, the name provided for the TMF can be a compiler-specific
template makefile, for example grt_vc.tmf, which designates the Microsoft
Visual C++ compiler. When you provide a compiler-specific TMF filename,
the Simulink Coder code generator uses the default mexopts.bat information
to locate the compiler if mex has been set up for the same compiler as the
specified TMF. If mex is not set up with a default compiler, or if it does not
match the compiler specified by the TMF, then an environment variable
must exist for the compiler specified by the TMF. The environment variable
required depends on the compiler.

15-8

Compiler or IDE Selection and Configuration

Choose and Configure Compiler on UNIX
On a UNIX platform, the Simulink Coder build process uses the default
compiler. The default compiler is cc.
You should choose the UNIX template makefile for your target. For example,
grt_unix.tmf is the template makefile for building a generic real-time
program on a UNIX platform.

Include S-Function Source Code
When the Simulink Coder code generator builds models with S-functions,
source code for the S-functions can be either in the current folder or in the
same folder as their MEX-file. The code generator adds an include path to
the generated makefiles whenever it finds a file named sfncname.h in the
same folder that the S-function MEX-file is in. This folder must be on the
MATLAB path.
Similarly, the Simulink Coder code generator adds a rule for the folder when
it finds a file sfncname.c (or .cpp) in the same folder as the S-function
MEX-file is in.

Troubleshoot Compiler Configurations
• “Compiler Version Mismatch Errors” on page 15-9
• “Generated Executable Image Produces Incorrect Results” on page 15-10
• “Compile-Time Errors” on page 15-10

Compiler Version Mismatch Errors
Explanation. You received a version mismatch error when you compiled
code generated by the Simulink Coder software.
User Action.
1 Check the list of currently supported and compatible compilers available at

http://www.mathworks.com/support/compilers/current_release/.

15-9

15

Program Building, Interaction, and Debugging

2 If necessary, upgrade or change your compiler. For more information, see

“Choose and Configure a Compiler” on page 15-2.
3 Rebuild the model.

Generated Executable Image Produces Incorrect Results
Explanation. You applied compiler optimizations when you used Simulink
Coder to generate an executable image. However, the optimizations caused
the executable image to produce incorrect results, even though expected
code was generated.
User Action. Do one of the following:
• Lower the compiler optimization level.
1 Select Custom for the Model Configuration parameter Code

Generation > Compiler optimization level. The Custom compiler
optimization flags field appears.
2 Specify a lower optimization level in the Custom compiler

optimization flags field.
3 Rebuild the model.

• Disable compiler optimizations.
1 Select Optimizations off (faster builds) for the Model

Configuration parameter Code Generation > Compiler optimization
level.
2 Rebuild the model.

For more information, see “Control Compiler Optimizations” on page 16-6
and your compiler documentation.

Compile-Time Errors
Explanations.
• You received a compiler configuration error.

15-10

Compiler or IDE Selection and Configuration

• Environment variables for your make utility, compiler, or linker are set
up incorrectly. For example, installation of Cygwin tools on a Windows
platform might affect environment variables used by other compilers.
• Custom code specified as an S-function block or in the Code
Generation > Custom Code pane of the Configuration Parameters dialog
includes errors. For example, the code might refer to a header file that the
compiler cannot find.
• The model includes a block, such as a device driver block, that is not
intended for use with the currently selected target.
User Actions.
• Make sure that MATLAB supports the compiler and version that you want
to use. For a list of currently supported and compatible compilers, see
http://www.mathworks.com/support/compilers/current_release/. If
necessary, upgrade or change your compiler (see “Choose and Configure
a Compiler” on page 15-2).
• Review the environment variable settings for your system by using the set
command on a Windows platform or setenv on a UNIX platform. Make
sure the settings match what is required for the tools you are using.
• Remove the custom code from the model, to help isolate the source of the
problem, debug, and rebuild.
• Remove the target-specific block or configure the model for use with the
another target.

15-11

15

Program Building, Interaction, and Debugging

Program Builds
In this section...
“Configure the Build Process” on page 15-12
“Initiate the Build Process” on page 15-14
“Build a Generic Real-Time Program” on page 15-14
“Rebuild a Model” on page 15-27
“Control Regeneration of Top Model Code” on page 15-27
“Reduce Build Time for Referenced Models” on page 15-28
“Relocate Code to Another Development Environment” on page 15-33
“How Executable Programs Are Built From Models” on page 15-38

Configure the Build Process
• “Specify TLC Options” on page 15-12
• “Specify Whether To Generate a Makefile” on page 15-13
• “Specify a Make Command” on page 15-13
• “Specify the Template Makefile” on page 15-13

Specify TLC Options
You can enter Target Language Compiler (TLC) command line options in the
TLC options edit field, for example
• -aVarName=1 to declare a TLC variable and/or assign a value to it
• -IC:\Work to specify an include path
• -v to obtain verbose output from TLC processing (for example, when
debugging)
Specifying TLC options does not add any flags to the Make command field,
as do some of the targets available in the System Target File Browser.
For additional information, see “Target Language Compiler Overview”.

15-12

Program Builds

Specify Whether To Generate a Makefile
The Generate makefile option specifies whether the Simulink Coder build
process is to generate a makefile for a model. By default, the Simulink Coder
build process generates a makefile. You can suppress the generation of a
makefile, for example in support of custom build processing that is not based
on makefiles, by clearing Generate makefile . When you clear this option,
• The Make command and Template makefile options are unavailable.
• You must set up any post code generation build processing, using a
user-defined command, as explained in “Customize Post-Code-Generation
Build Processing” on page 22-13.

Specify a Make Command
A high-level MATLAB command, invoked when a build is initiated, controls
the Simulink Coder build process. Each target has an associated make
command. The Make command field displays this command.
Almost all targets use the default command, make_rtw. Third-party targets
might supply another make command. See the vendor’s documentation.
In addition to the name of the make command, you can supply arguments
in the Make command field. These arguments include compiler-specific
options, include paths, and other parameters. When the build process invokes
the make utility, these arguments are passed along in the make command line.
“Template Makefiles and Make Options” on page 9-38 lists the Make
command arguments you can use with each supported compiler.

Specify the Template Makefile
The Template makefile field has these functions:
• If you have selected a target configuration using the System Target File
Browser, this field displays the name of a MATLAB language file that
selects a template makefile for your development environment. For
example, in “Code Generation Pane: General”, the Template makefile
field displays grt_default_tmf, indicating that the build process invokes
grt_default_tmf.m.

15-13

15

Program Building, Interaction, and Debugging

“Template Makefiles and Make Options” on page 9-38 gives a detailed
description of the logic by which the Simulink Coder build process selects
a template makefile.
• Alternatively, you can explicitly enter the name of a specific template
makefile (including the extension) or a MATLAB language file that returns
a template make file in this field. You must do this if you are using a target
configuration that does not appear in the System Target File Browser.
For example, do this if you have written your own template makefile for a
custom target environment or you.
If you specify your own template makefile, be sure to include the filename
extension. If you omit the extension, the Simulink Coder build process
attempts to find and execute a file with the extension .m (that is, a MATLAB
language file). The template make file (or a MATLAB language file that
returns a template make file) must be on the MATLAB path. To determine
whether the file is on the MATLAB path, enter the following command in the
MATLAB Command Window:
which tmf_filename

Initiate the Build Process
You can initiate code generation and the build process by using the following
options:
• Clear the Generate code only option on the Code Generation pane of
the Configuration Parameters dialog box and click Build.
• Press Ctrl+B.
• Select Code > C/C++ Code > Build Model.
• Invoke the rtwbuild command from the MATLAB command line.
• Invoke the slbuild command from the MATLAB command line.

Build a Generic Real-Time Program
• “About Building a Program” on page 15-15
• “Working and Build Folders” on page 15-15
• “Set Program Parameters” on page 15-16

15-14

Program Builds

• “Select a Target Configuration” on page 15-18
• “Build and Run a Program” on page 15-23
• “Contents of the Build Folder” on page 15-25

About Building a Program
This section walks through the process of generating C code and building
an executable program from an example model. The resulting stand-alone
program runs on your workstation, independent of external timing and events.

Working and Build Folders
It is convenient to work with a local copy of the sldemo_f14 model, stored in
its own folder, f14example. Set up your working folder as follows:
1 In the MATLAB Current Folder browser, navigate to a folder where you

have write access.
2 Create the working folder from the MATLAB command line by typing:

mkdir f14example
3 Make f14example your working folder:

cd f14example
4 Open the sldemo_f14 model:

sldemo_f14

The model appears in the Simulink window.
5 In the model window, choose File > Save As. Navigate to your working

folder, f14example. Save a copy of the sldemo_f14 model.
During code generation, the Simulink Coder software creates a build folder
within your working folder. The build folder name is model_target_rtw,
derived from the name of the source model and the chosen target. The build
folder stores generated source code and other files created during the build
process. You examine the build folder contents at the end of this example.

15-15

15

Program Building, Interaction, and Debugging

Note When a model contains Model blocks (which enable one Simulink
model to include others), special project folders are created in your working
folder to organize code for referenced models. Project folders exist alongside
of Simulink Coder build folders, and are always named slprj. “Generate
Code for Referenced Models” on page 3-4 describes navigating project folder
structures in Model Explorer.

Set Program Parameters
To generate code from your sldemo_f14 model, you must change some of the
simulation parameters. In particular, note that generic real-time (GRT) and
most other targets require that the model specify a fixed-step solver.
Note The Simulink Coder software can generate code for models using
variable-step solvers for rapid simulation (rsim) and S-function targets only.
To set parameters, use the Model Explorer as follows:
1 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
2 In the Model Hierarchy pane, expand the model name node to reveal

its components.
3 Click Configuration (Active) in the left pane.
4 Click Solver in the center pane. The Solver pane appears at the right.
5 Enter the following parameter values on the Solver pane (some may

already be set):
• Start time: 0.0
• Stop time: 60
• Type: Fixed-step
• Solver: ode5 (Dormand-Prince)

15-16

Program Builds

• Fixed step size (fundamental sample time): 0.1
• Tasking mode for periodic sample times: SingleTasking
The Solver pane with the modified parameter settings is shown below.
Note the tan background color of the controls you just changed. The color
also appears on fields that were set automatically by your choices in other
fields. Use this visual feedback to verify that what you set is what you
intended. When you apply your changes, the background color reverts
to white.

6 Click Apply to register your changes.
7 Save the model. Simulation parameters persist with the model, for use in

future sessions.

15-17

15

Program Building, Interaction, and Debugging

Select a Target Configuration
Note Some of the steps in this section do not require you to make changes.
They are included to help you familiarize yourself with the Simulink Coder
user interface. As you step through the dialog boxes, place the mouse pointer
on any item of interest to see a tooltip describing its function.
To specify the desired target configuration, you choose a system target file, a
template makefile, and a make command.
In these examples (and in most applications), you do not need to specify these
parameters individually. Here, you use the ready-to-run generic real-time
target (GRT) configuration. The GRT target is designed to build a stand-alone
executable program that runs on your workstation.
To select the GRT target via the Model Explorer:
1 With the sldemo_f14 model open, select View > Model Explorer to open

the Model Explorer.
2 In the Model Hierarchy pane, expand the model node to reveal its

components.
3 Click Configuration (Active) in the left pane.
4 Click Code Generation in the center pane. The Code Generation pane

appears at the right. This pane has several tabs.
5 Click the General tab to activate the pane that controls target selection.

15-18

Program Builds

6 Click the Browse button next to the System target file field. This opens

the System Target File Browser, illustrated below. The browser displays
a list of all currently available target configurations. Your available
configurations may differ. When you select a target configuration, the
Simulink Coder software automatically chooses the system target file,
template makefile, and make command for that configuration. Their names
appear at the bottom left of the window.
Note The system target file browser lists all system target files found on
the MATLAB path. Using some of these might require additional licensed
products, such as the Embedded Coder product.

15-19

15

Program Building, Interaction, and Debugging

7 From the list of available configurations, select Generic Real-Time

Target (as shown above) and then click OK.

The Code Generation pane displays the system target file (grt.tlc),
make command (make_rtw), and template makefile (grt_default_tmf),
as shown below:

15-20

Program Builds

8 Select the Code Generation > Debug pane. The options displayed here

control build verbosity and debugging support, and are common to all
target configurations. Make sure that all options are set to their defaults,
as shown below.

15-21

15

Program Building, Interaction, and Debugging

9 Select the Code Generation > Symbols pane. The options on this pane

control the look and feel of generated code.

15-22

Program Builds

10 Select the Code Generation > Comments pane. The options displayed

here control the types of comments included in generated code. Make sure
that all options are set to their defaults, as shown below.

11 Make sure that the Generate code only check box at the bottom of the

pane is cleared.
12 Save the model.

Build and Run a Program
The Simulink Coder build process generates C code from the model, and then
compiles and links the generated program to create an executable image. To
build and run the program,
1 With the sldemo_f14 model open, go to the Model Explorer window. In the

Code Generation pane, click the Build button to start the build process.
A number of messages concerning code generation and compilation appear
in the MATLAB Command Window. The initial message is
### Starting build procedure for model: sldemo_f14

The contents of many of the succeeding messages depends on your compiler
and operating system. The final message is
### Successful completion of build procedure
for model: sldemo_f14

15-23

15

Program Building, Interaction, and Debugging

The working folder now contains an executable, sldemo_f14.exe (Microsoft
Windows platforms) or sldemo_f14 (UNIX platforms). In addition, the
Simulink Coder build process has created a project folder, slprj, and a
build folder, sldemo_f14_grt_rtw, in your working folder.
Note The Simulink Coder build process displays a code generation
report after generating the code for the sldemo_f14 model. The example
“Optimizing Generated Code” on page 18-2 provides more information
about how to create and use a code generation report.
2 To observe the contents of the working folder after the build, type the dir

command from the MATLAB Command Window.
dir
.
..

sldemo_f14.exe
sldemo_f14.slx

sldemo_f14_grt_rtw
slprj

3 To run the executable from the Command Window, type

!sldemo_f14

The ! character passes the command that follows it to the operating system,
which runs the stand-alone sldemo_f14 program.
The program produces one line of output in the Command Window:
**starting the model**

No data is output.
4 Finally, to see the files created in the build folder, type

dir sldemo_f14_grt_rtw

The exact list of files produced varies among MATLAB platforms and
versions. Here is a sample list from a Windows platform.
.
..

15-24

grt_main.obj
html

rt_nonfinite.h
rt_nonfinite.obj

Program Builds

buildInfo.mat
defines.txt
sldemo_f14.bat
sldemo_f14.c
sldemo_f14.h
sldemo_f14.mk
sldemo_f14.obj
sldemo_f14_private.h
sldemo_f14_ref.rsp
sldemo_f14_types.h

modelsources.txt
ode5.obj
rtGetInf.c
rtGetInf.h
rtGetInf.obj
rtGetNaN.c
rtGetNaN.h
rtGetNaN.obj
rt_logging.obj
rt_nonfinite.c

rt_rand.c
rt_rand.h
rt_rand.obj
rt_sim.obj
rtmodel.h
rtw_proj.tmw
rtwtypes.h
rtwtypeschksum.mat

Contents of the Build Folder
The build process creates a build folder and names it model_target_rtw,
where model is the name of the source model and target is the target
selected for the model. In this example, the build folder is named
sldemo_f14_grt_rtw.
The build folder includes the following generated files.
Note The code generation report you created for the sldemo_f14 model in
the previous section displays a link for each file listed below, which you can
click to explore the file contents.

File

Description

sldemo_f14.c

Standalone C code that implements the model

rt_nonfinite.c
rtGetInf.c
rtGetNaN.c

Functions to initialize nonfinite types (Inf,
NaN, and -Inf)

rt_rand.c

Random functions, included only if used by the
application

sldemo_f14.h

An include header file containing definitions of
parameters and state variables

sldemo_f14_private.h

Header file containing common include
definitions

15-25

15

Program Building, Interaction, and Debugging

File

Description

sldemo_f14_types.h

Forward declarations of data types used in the
code

rt_nonfinite.h
rtGetInf.h
rtGetNaN.h

Provides support for nonfinite numbers in the
generated code, dynamically generates Inf,
NaN, and -Inf

rt_rand.h

Imported declarations for random functions,
included only if used by the application

rtmodel.h

Master header file for including generated code
in the static main program (its name never
changes, and it simply includes sldemo_f14.h)

rtwtypes.h

Static include file for Simulink simstruct data
types; some embedded targets tailor this file to
reduce overhead, but GRT does not

The build folder contains other files used in the build process, most of which
you can disregard for the present:
• sldemo_f14.mk — Makefile generated from a template for the GRT target
• Object (.obj) files
• sldemo_f14.bat — Batch control file
• rtw_proj.tmw — Marker file
• buildInfo.mat — Build information for relocating generated code to
another development environment
• defines.txt — Preprocessor defines required for compiling the generated
code
• sldemo_f14_ref.rsp — Data to include as command-line arguments to
mex (Windows systems only)
The build folder also contains a subfolder, html, which contains the files that
make up the code generation report. For more information about the code
generation report, see “Reports for Code Generation” on page 11-2.

15-26

Program Builds

Rebuild a Model
If you update generated source code or makefiles manually to add
customizations, you can rebuild the files with the rtwrebuild command. This
command recompiles the modified files by invoking the generated makefile.
Alternatively, you can use this command from the Model Explorer,
1 In the Model Hierarchy pane, expand the node for the model of interest.
2 Click the Code for model node.
3 In the Code pane, click run rtwrebuild, listed to the right of the label

Code Recompile Command.

Control Regeneration of Top Model Code
When you rebuild a model, by default, the build process performs checks
to determine whether changes to the model or relevant settings require
regeneration of the top model code. Top model code is regenerated if any
of the following conditions is true:
• The structural checksum of the model has changed.
• The top-model-only checksum has changed. The top-model-only checksum
provides information about top model parameters, such as application
lifespan, maximum stack size, make command, verbose and .rtw file debug
settings, and the TLC options parameter.
• Any of the following TLC debugging model options, located on the Code
Generation > Debug pane of the Configuration Parameters dialog box,
is on:

-

Start TLC debugger when generating code (TLCDebug)
Start TLC coverage when generating code (TLCCoverage)
Enable TLC assertion (TLCAssert)
Profile TLC (ProfileTLC)

If the checks determine that top model code generation is required, the build
process fully regenerates and compiles the model code.

15-27

15

Program Building, Interaction, and Debugging

If the checks indicate that the top model generated code is current with
respect to the model, and no model settings require full regeneration, the
build process omits regeneration of the top model code. This can significantly
reduce model build times.
Regardless of whether the top model code is regenerated, the build process
subsequently calls all build process hooks, including STF_make_rtw_hook
functions and the post code generation command, and reruns the makefile so
that any external dependencies are recompiled and relinked.
Note Target authors can perform actions related to code regeneration,
including forcing or reacting to code regeneration, in the STF_make_rtw_hook
functions that are called by the build process. For more information, see
“Control Code Regeneration Using STF_make_rtw_hook.m” on page 22-26.
If you want to control or override the default top model build behavior, use
one of the following command-line options:
• To ignore the checksum and force regeneration of the top model code:

-

rtwbuild(model,'ForceTopModelbuild',true)
slbuild(model,'StandaloneRTWTarget','ForceTopModelBuild',true)

• To clean the model build area enough to trigger regeneration of the top
model code at the next build (slbuild only):
slbuild(model,'CleanTopModel')

Note You can also force regeneration of the top model code by deleting code
generation folders, for example, slprj or the generated model code folder.

Reduce Build Time for Referenced Models
• “Parallel Building For Large Model Reference Hierarchies” on page 15-29
• “Parallel Building Configuration Requirements” on page 15-30
• “Build Models In a Parallel Computing Environment” on page 15-30

15-28

Program Builds

• “Locate Parallel Build Logs” on page 15-31

Parallel Building For Large Model Reference Hierarchies
In a parallel computing environment, you can increase the speed of code
generation and compilation for models containing large model reference
hierarchies by building referenced models in parallel whenever conditions
allow. For example, if you have Parallel Computing Toolbox™ software, code
generation and compilation for each referenced model can be distributed
across the cores of a multicore host computer. If you additionally have
MATLAB Distributed Computing Server™ (MDCS) software, code generation
and compilation for each referenced model can be distributed across remote
workers in your MATLAB Distributed Computing Server configuration.
The performance gain realized by using parallel builds for referenced models
depends on several factors, including how many models can be built in
parallel for a given model referencing hierarchy, the size of the referenced
models, and parallel computing resources such as number of local and/or
remote workers available and the hardware attributes of the local and remote
machines (amount of RAM, number of cores, and so on).
For configuration requirements that might apply to your parallel computing
environment, see “Parallel Building Configuration Requirements” on page
15-30.
For a description of the general workflow for building referenced models
in parallel whenever conditions allow, see “Build Models In a Parallel
Computing Environment” on page 15-30.
For information on how to configure a custom embedded target to support
parallel builds, see “Support Model Referencing” on page 24-101.
Note In an MDCS parallel computing configuration, parallel building is
designed to work interactively with the MATLAB Distributed Computing
Server software. You can initiate builds from the Simulink user interface or
from the MATLAB Command Window using commands such as slbuild. You
cannot initiate builds using batch or other batch mode workflows.

15-29

15

Program Building, Interaction, and Debugging

Parallel Building Configuration Requirements
The following requirements apply to configuring your parallel computing
environment for building model reference hierarchies in parallel whenever
conditions allow:
• For local pools, the host machine must have enough RAM to support the
number of local workers (MATLAB sessions) that you plan to use. For
example, setting matlabpool to 4 results in five MATLAB sessions on your
machine, each using approximately 120 MB of memory at startup.
• Remote MDCS workers participating in a parallel build must use a common
platform and compiler.
• A consistent MATLAB environment must be set up in each MATLAB
worker session as in the MATLAB client session — for example, all
shared base workspace variables, MATLAB path settings, and so forth.
One approach is to use the PreLoadFcn callback of the top model. If you
configure your model to load the top model with each MATLAB worker
session, its preload function can be used for any MATLAB worker session
setup.

Build Models In a Parallel Computing Environment
To take advantage of parallel building for a model reference hierarchy:
1 Set up a pool of local and/or remote MATLAB workers in your parallel

computing environment.
a Make sure that Parallel Computing Toolbox software is licensed and

installed.
b To use remote workers, make sure that MATLAB Distributed Computing

Server software is licensed and installed.
c Issue MATLAB commands to set up the worker pool, for example,

matlabpool 4.
2 In the Configuration Parameters dialog box, go to the Model Referencing

pane and select the Enable parallel model reference builds option.
This selection enables the parameter MATLAB worker initialization
for builds.

15-30

Program Builds

For MATLAB worker initialization for builds, select one of the
following values:
• None if the software should perform no special worker initialization.
Specify this value if the child models in the model reference hierarchy do
not rely on anything in the base workspace beyond what they explicitly
set up (for example, with a model load function).
• Copy base workspace if the software should attempt to copy the base
workspace to each worker. Specify this value if you use a setup script to
prepare the base workspace for all models to use.
• Load top model if the software should load the top model on each
worker. Specify this value if the top model in the model reference
hierarchy handles all of the base workspace setup (for example, with a
model load function).
3 Optionally, inspect the model reference hierarchy to determine, based

on model dependencies, which models will be built in parallel. For
example, you can use the Model Dependency Viewer from the Simulink
Analysis > Model Dependencies menu.
4 Build your model. Messages in the MATLAB Command Window record

when each parallel or serial build starts and finishes. The order in which
referenced models build is nondeterministic. They might build in a
different order each time the model is built.
If you need more information about a parallel build, for example, if a build
fails, see “Locate Parallel Build Logs” on page 15-31.

Locate Parallel Build Logs
When you build a model for which referenced models are built in parallel,
messages in the MATLAB Command Window record when each parallel or
serial build starts and finishes. Any referenced models that build in parallel
have only summary log entries in the command window, even if verbose
builds are turned on. For example,
### Initializing parallel workers for parallel model reference build.

15-31

15

Program Building, Interaction, and Debugging

### Parallel worker initialization complete.
### Starting parallel model reference SIM build for 'bot_model001'
### Starting parallel model reference SIM build for 'bot_model002'
### Starting parallel model reference SIM build for 'bot_model003'
### Starting parallel model reference SIM build for 'bot_model004'
### Finished parallel model reference SIM build for 'bot_model001'
### Finished parallel model reference SIM build for 'bot_model002'
### Finished parallel model reference SIM build for 'bot_model003'
### Finished parallel model reference SIM build for 'bot_model004'
### Starting parallel model reference RTW build for 'bot_model001'
### Starting parallel model reference RTW build for 'bot_model002'
### Starting parallel model reference RTW build for 'bot_model003'
### Starting parallel model reference RTW build for 'bot_model004'
### Finished parallel model reference RTW build for 'bot_model001'
### Finished parallel model reference RTW build for 'bot_model002'
### Finished parallel model reference RTW build for 'bot_model003'
### Finished parallel model reference RTW build for 'bot_model004'

If a parallel builds fails, you might see output similar to the following:
### Initializing parallel workers for parallel model reference build.
### Parallel worker initialization complete.
...
### Starting parallel model reference RTW build for 'bot_model002'
### Starting parallel model reference RTW build for 'bot_model003'
### Finished parallel model reference RTW build for 'bot_model002'
### Finished parallel model reference RTW build for 'bot_model003'
### Starting parallel model reference RTW build for 'bot_model001'
### Starting parallel model reference RTW build for 'bot_model004'
### Finished parallel model reference RTW build for 'bot_model004'
### The following error occurred during the parallel model reference RTW build for
'bot_model001':
Error(s) encountered while building model "bot_model001"
### Cleaning up parallel workers.

To obtain more detailed information about the failed build, you can examine
the parallel build log. For each referenced model built in parallel, the build
process generates a file named model_buildlog.txt, where model is the

15-32

Program Builds

name of the referenced model. This file contains the full build log for that
model.
If a parallel build completes, the build log file is placed in the build
subfolder corresponding to the referenced model. For example,
for a build of referenced model bot_model004, you would look for
the build log file bot_model004_buildlog.txt in a referenced
model subfolder such as build_folder/slprj/grt/bot_model004,
build_folder/slprj/ert/bot_model004, or
build_folder/slprj/sim/bot_model004.
If a parallel build fails, the build log can be found in a referenced model
subfolder under the build subfolder /par_mdl_ref/model. For example,
for a failed parallel build of model bot_model001, you would look for
the build log file bot_model001_buildlog.txt in a subfolder such as
build_folder/par_mdl_ref/bot_model001/slprj/grt/bot_model001,
build_folder/par_mdl_ref/bot_model001/slprj/ert/bot_model001, or
build_folder/par_mdl_ref/bot_model001/slprj/sim/bot_model001.

Relocate Code to Another Development Environment
• “About Code Relocation” on page 15-33
• “Package Code Using the Graphical User Interface” on page 15-34
• “Package Code Using the Command-Line Interface” on page 15-34
• “packNGo Function Limitations” on page 15-38

About Code Relocation
If you need to relocate the static and generated code files for a model to
another development environment, such as a system or an integrated
development environment (IDE) that does not include MATLAB and Simulink
products, use the Simulink Coder pack-and-go utility. This utility uses the
tools for customizing the build process after code generation and a packNGo
function to find and package files for building an executable image. The files
are packaged in a compressed file that you can relocate and unpack using a
standard zip utility.
To package model code files, you can do either of the following:

15-33

15

Program Building, Interaction, and Debugging

• Use the model option Package code and artifacts on the Code
Generation pane of the Configuration Parameters dialog box. See
“Package Code Using the Graphical User Interface” on page 15-34.
• Use MATLAB commands to configure a PostCodeGenCommand parameter
with a call to the packNGo function. See “Package Code Using the
Command-Line Interface” on page 15-34. The command-line interface
provides more control over the details of code packaging.

Package Code Using the Graphical User Interface
To package and relocate code for your model using the graphical user interface:
1 Open the Configuration Parameters dialog box and select the Code

Generation pane.
2 Select the option Package code and artifacts. This option configures the

build process to run the packNGo function after code generation to package
generated code and artifacts for relocation.
3 In the Zip file name field, enter the name of the zip file in which to

package generated code and artifacts for relocation. The file name can be
specified with or without the .zip extension. If you specify no extension or
an extension other than .zip, the zip utility adds the.zip extension. If no
value is specified, the build process uses the name model.zip, where model
is the name of the top model for which code is being generated.

4 Apply changes and generate code for your model. Inspect the resulting zip

file to verify that it is ready for relocation. Depending on the zip tool you
use you might be able to open and inspect the file without unpacking it.
5 Relocate the zip file to the destination development environment and

unpack the file.

Package Code Using the Command-Line Interface
To package and relocate code for your model using the command-line interface:

15-34

Program Builds

1 Select a structure for the zip file.
2 Select a name for the zip file.
3 Package the model code files in the zip file.
4 Inspect the generated zip file.
5 Relocate and unpack the zip file.

Select a Structure for the Zip File. Before you generate and package the
files for a model build, decide whether you want the files to be packaged
in a flat or hierarchical folder structure. By default, the packNGo function
packages the files in a single, flat folder structure. This is the simplest
approach and might be the optimal choice.
If...

Then Use a...

You are relocating files to an IDE
that does not use the generated
makefile or the code is not dependent
on the relative location of required
static files

Single, flat folder structure

The target development environment
must maintain the folder structure
of the source environment because it
uses the generated makefile or the
code is dependent on the relative
location of files

Hierarchical structure

If you use a hierarchical structure, the packNGo function creates two levels of
zip files, a primary zip file, which in turn contains the following secondary
zip files:
• mlrFiles.zip — files in your matlabroot folder tree
• sDirFiles.zip — files in and under your build folder where you initiated
the model’s code generation
• otherFiles.zip — required files not in the matlabroot or start folder
trees

15-35

15

Program Building, Interaction, and Debugging

Paths for the secondary zip files are relative to the root folder of the primary
zip file, maintaining the source development folder structure.
Select a Name for the Zip File. By default, the packNGo function names
the primary zip file model.. You have the option of specifying a different
name. If you specify a file name and omit the file type extension, the function
appends . to the name you specify.
Package Model Code in a Zip File. You package model code files by using
the PostCodeGenCommand configuration parameter, packNGo function, and the
model’s build information object. You can set up the packaging operation
to use
• A system generated build information object.
In this case, use set_param to set the configuration parameter
PostCodeGenCommand to an explicit call to the packNGo function before
generating the model code. For example:
set_param(bdroot, 'PostCodeGenCommand', 'packNGo(buildInfo);');

This command instructs the Simulink Coder build process to evaluate the
call to packNGo, using the system generated build information object for the
currently selected model, after generating and writing the model’s code to
disk and before generating a makefile.
• A build information object that you construct programmatically, as
explained in “Customize Post-Code-Generation Build Processing” on page
22-13.
In this case, you might use other build information functions to selectively
include paths and files in the build information object that you then specify
with the packNGo function. For example:
.
.
.
myModelBuildInfo = RTW.BuildInfo;
addSourceFiles(myModelBuildInfo, {'test1.c' 'test2.c' 'driver.c'});
.
.
.

15-36

Program Builds

packNGo(myModelBuildInfo);

To change the default behavior of packNGo, see the following examples:
To...

Specify...

Change the structure of the
file packaging to hierarchical

packNGo(buildInfo, {'packType'
'hierarchical'});

Rename the primary zip file

packNGo(buildInfo, {'fileName'
'zippedsrcs'});

Change the structure of the
file packaging to hierarchical
and rename the primary zip
file

packNGo(buildInfo, {'packType'
'hierarchical'...
'fileName' 'zippedsrcs'});

Include all header files found
on the include path (rather
than the minimal header
files required to build the
code) in the zip file

packNGo(buildInfo, {'minimalHeaders'
false});

Note The packNGo function potentially can modify the build information
passed in the first packNGo argument. As part of packaging model code,
packNGo might find additional files from source and include paths recorded in
the model’s build information and add them to the build information.
Inspect a Generated Zip File. Inspect the generated zip file to verify that
it is ready for relocation. Depending on the zip tool you use you might be able
to open and inspect the file without unpacking it. If you need to unpack the
file and you packaged the model code files as a hierarchical structure, you will
need to unpack the primary and secondary zip files. When you unpack the
secondary zip files, relative paths of all files are preserved.
Relocate and Unpack a Zip File. Relocate the generated zip file to the
destination development environment and unpack the file.

15-37

15

Program Building, Interaction, and Debugging

Code Packaging Example. The following example guides you through
the steps for packaging code files generated for the example model
rtwdemo_rtwintro using the command-line interface:
1 Set your working folder to a writable folder.
2 Open the model rtwdemo_rtwintro and save a copy to your working folder.
3 Enter the following command in the MATLAB Command Window:

set_param('rtwdemo_rtwintro', 'PostCodeGenCommand',...
'packNGo(buildInfo, {''packType'' ''hierarchical''})');

You must double the single-quotes due to the nesting of character arrays
'packType' and 'hierarchical' within the character array that specifies
the call to packNGo.
4 Generate code for the model.
5 Inspect the generated zip file, rtwdemo_rtwintro.zip. The zip file

contains the two secondary zip files, mlrFiles.zip and sDirFiles.zip.
6 Inspect the zip files mlrFiles.zip and sDirFiles.zip.
7 Relocate the zip file to a destination environment and unpack it.

packNGo Function Limitations
The following limitations apply to use of the packNGo function:
• The function operates on source files, such as *.c, *.cpp, and *.h files,
only. The function does not support compile flags, defines, or makefiles.
• Unnecessary files might be included. The function might find additional
files from source and include paths recorded in the model’s build
information and include them, even if they are not used.

How Executable Programs Are Built From Models
• “Build Process Steps” on page 15-39
• “Customized Makefile Generation” on page 15-39

15-38

Program Builds

• “Executable Program Generation” on page 15-40

Build Process Steps
The Simulink Coder software generates C code only or generates the C code
and produces an executable image, depending on the level of processing you
choose. By default, a Build button appears on the Code Generation pane of
the Configuration Parameters dialog box. This button completes the entire
build process and an executable image results. If you select the Generate
code only check box to the left of the button, the button label changes to
Generate code.
When you click the Build or Generate code button, the Simulink Coder
software performs the following build process. If the software detects code
generation constraints for your model, it issues warning or error messages.
1 “Model Compilation” on page 10-31
2 “Code Generation” on page 10-31
3 “Customized Makefile Generation” on page 15-39
4 “Executable Program Generation” on page 15-40

For more information, see “Generate a Code Generation Report” on page 11-5.
You can also view an HTML report in Model Explorer.

Customized Makefile Generation
After generating the code, the Simulink Coder software generates a
customized makefile, model.mk. The generated makefile instructs the make
system utility to compile and link source code generated from the model, as
well as any required harness program, libraries, or user-provided modules.
The Simulink Coder software creates model.mk from a system template file,
system.tmf (where system stands for the selected target name). The system
template makefile is designed for your target environment. You have the
option of modifying the template makefile to specify compilers, compiler
options, and additional information used during the creation of the executable.

15-39

15

Program Building, Interaction, and Debugging

The Simulink Coder software creates the model.mk file by copying the
contents of system.tmf and expanding lexical tokens (symbolic names) that
describe your model’s configuration.
The Simulink Coder software provides many system template makefiles,
configured for specific target environments and development systems.
“Selecting a Target” on page 9-34 in the Simulink Coder documentation lists
all template makefiles that are bundled with the Simulink Coder software.
To see an example template makefile, navigate to matlabroot/rtw/c/grt,
and open with an editor the file grt_msvc.tmf. You can fully customize your
build process by modifying an existing template makefile or providing your
own template makefile.

Executable Program Generation
The following figure shows how the Simulink Coder software controls
automatic program building.

15-40

Program Builds

Click Build
Button

Simulink
Model

Generate
Code

Template
Makefile

Generate
Makefile

Create
Executable?

model.c
model.h
model_private.h

Custom
Makefile
model.mk

No

Yes
Invoke
make
Stop
During the final stage of processing, the Simulink Coder build process
invokes the generated makefile, model.mk, which in turn compiles and links
the generated code. On PC platforms, a batch file is created to invoke the
generated makefile. The batch file sets up the environment for invoking the
make utility and related compiler tools. To avoid recompilation of C files, the
make utility performs date checking on the dependencies between the object
and C files; only out-of-date source files are compiled. Optionally, the makefile
can download the resulting executable image to your target hardware.

15-41

15

Program Building, Interaction, and Debugging

This stage is optional, as illustrated by the control logic in the preceding
figure. You might choose to omit this stage, for example, if you are targeting
an embedded microcontroller or a digital signal processing (DSP) board.
To omit this stage of processing, select the Generate code only check box on
the Code Generation pane of the Configuration Parameters dialog box. You
can then cross-compile your code and download it to your target hardware.
If you select Create code generation report on the Code
Generation > Report pane, a navigable summary of source files is produced
when the model is built. The report files occupy a folder called html within
the build folder. The report contents vary depending on the target, but all
reports feature links to generated source files. The following display shows
an example of an HTML code generation report for a generic real-time (GRT)
target.

15-42

Build and Run a Program

Build and Run a Program
The Simulink Coder build process generates C code from the model, and then
compiles and links the generated program to create an executable image. To
build and run the program,
1 With the sldemo_f14 model open, go to the Model Explorer window. In the

Code Generation pane, click the Build button to start the build process.
A number of messages concerning code generation and compilation appear
in the MATLAB Command Window. The initial message is
### Starting build procedure for model: sldemo_f14

The contents of many of the succeeding messages depends on your compiler
and operating system. The final message is
### Successful completion of build procedure
for model: sldemo_f14

The working folder now contains an executable, sldemo_f14.exe (Microsoft
Windows platforms) or sldemo_f14 (UNIX platforms). In addition, the
Simulink Coder build process has created a project folder, slprj, and a
build folder, sldemo_f14_grt_rtw, in your working folder.
Note The Simulink Coder build process displays a code generation
report after generating the code for the sldemo_f14 model. The example
“Optimizing Generated Code” on page 18-2 provides more information
about how to create and use a code generation report.
2 To observe the contents of the working folder after the build, type the dir

command from the MATLAB Command Window.
dir
.
..

sldemo_f14.exe
sldemo_f14.slx

sldemo_f14_grt_rtw
slprj

3 To run the executable from the Command Window, type

15-43

15

Program Building, Interaction, and Debugging

!sldemo_f14

The ! character passes the command that follows it to the operating system,
which runs the stand-alone sldemo_f14 program.
The program produces one line of output in the Command Window:
**starting the model**

No data is output.
4 Finally, to see the files created in the build folder, type

dir sldemo_f14_grt_rtw

The exact list of files produced varies among MATLAB platforms and
versions. Here is a sample list from a Windows platform.
.
..
buildInfo.mat
defines.txt
sldemo_f14.bat
sldemo_f14.c
sldemo_f14.h
sldemo_f14.mk
sldemo_f14.obj
sldemo_f14_private.h
sldemo_f14_ref.rsp
sldemo_f14_types.h

15-44

grt_main.obj
html
modelsources.txt
ode5.obj
rtGetInf.c
rtGetInf.h
rtGetInf.obj
rtGetNaN.c
rtGetNaN.h
rtGetNaN.obj
rt_logging.obj
rt_nonfinite.c

rt_nonfinite.h
rt_nonfinite.obj
rt_rand.c
rt_rand.h
rt_rand.obj
rt_sim.obj
rtmodel.h
rtw_proj.tmw
rtwtypes.h
rtwtypeschksum.mat

Profile Code Performance

Profile Code Performance
In this section...
“About Profiling Code Performance” on page 15-45
“How to Profile Code Performance” on page 15-45
“Run Profiling Hooks for Generated Code” on page 15-48
“Profiling Limitation” on page 15-49

About Profiling Code Performance
By profiling the performance of generated code, you can help verify that the
code meets performance requirements. Profiling can be especially important
early in the development cycle for identifying potential architectural issues
that can be more expensive to address later in the process. Profiling can
also identify bottlenecks and procedural issues that indicate a need for
optimization, for example, with an inner loop or inline code.
Note If you have an Embedded Coder license, see “Code Execution Profiling”
for an alternative and simpler approach based on software-in-the-loop (SIL)
or processor-in-the-loop (PIL) simulations.

How to Profile Code Performance
You can profile code generated with code generation technology by using a
Target Language Compiler (TLC) hook function interface.
To use the profile hook function interface:
1 For your target, create a TLC file that defines the following hook functions.

Write the functions so that they specify profiling code. The code generator
adds the hook function code to code generated for atomic systems in the
model.

15-45

15

15-46

Program Building, Interaction, and Debugging

Function

Input Arguments

Output Type

Description

ProfilerHeaders

void

Array of header file
names

Return an array of
the header file names
to be included in the
generated code.

ProfilerTypedefs

void

typedefs

Generate code
statements for profiler
type definitions.

ProfilerGlobalData

system

Global data for the
specified system

Generate code
statements that declare
global data.

ProfilerExternDataDecls

system

extern declarations for
the specified system

Generate code
statements that
create global extern
declarations.

ProfilerSystemDecls

system,
functionType

Declarations for the
specified system for the
specified functionType

Generate code for
required variable
declarations within
the scope of an atomic
subsystem Output,
Update, OutputUpdate,
or Derivatives
function.

ProfilerSystemStart

system,
functionType

Profiler start commands
for the specified system
and functionType

Generate code that
starts the profiler
within the scope of an
atomic subsystem
Output, Update,
OutputUpdate, or
Derivatives function.

Profile Code Performance

Function

Input Arguments

Output Type

Description

ProfilerSystemFinish

system,
functionType

Profiler end commands
for the specified system
and functionType

Generate code that
stops the profiler
within the scope of an
atomic subsystem’s
Output, Update,
OutputUpdate, or
Derivatives function.

ProfilerSystemTerminate

system

Profiler termination
code for the specified

Generate code that
terminates profiling
(and possibly reports
results) for an atomic
subsystem.

system

For an example TLC file, see
matlabroot/toolbox/rtw/rtwdemos/rtwdemo_profile_hook.tlc.
2 In your target.tlc file, define the following global variables.

Define...

To Be...

ProfileGenCode

TLC_TRUE or 1 to turn on profiling
(TLC_FALSE or 0 to turn off profiling)

ProfilerTLC

The name of the TLC file that you created
in step 1

A quick way to define global variables is to define the parameters with the
-a option. You can do this in the Configuration Parameters dialog box, in
Code Generation > TLC options.

3 Consider setting configuration parameters for generating a code generation

report. You can then examine the profiling code in the context of the code
generated for the model.

15-47

15

Program Building, Interaction, and Debugging

4 Build the model. The build process embeds the profiling code in the hook

function locations in the generated code for the model.
5 Run the generated executable file. In the MATLAB Command Window,

enter !model-name . You see the profiling report you programmed in the
profiling TLC file that you created. For example, a profile report might list
the number of calls made to each system in a model and the number of
CPU cycles spent in each system.
For an example, see “Run Profiling Hooks for Generated Code” on page 15-48.
For details on programming a .tlc file and defining TLC configuration
variables, see “Target Language Compiler”.

Run Profiling Hooks for Generated Code
The example Profiling Hooks for Generated Code shows how to use special
hooks provided by Simulink Coder to add profiling code snippets to the
generated code for your models.
The basis for this example is the Target Language Compiler (TLC)
hook function interface described in “How to Profile Code Performance”
on page 15-45. The hooks allow you to add profiling code snippets
within nonvirtual (atomic) systems in the model, which allow
you to profile those atomic systems. For this example, the file
matlabroot/toolbox/rtw/rtwdemos/rtwdemo_profile_hook.tlc

implements the required profiling functions. You can inspect this file for more
information on each of the profiling functions.
Run the example as follows:
1 Open the model rtwdemo_profile; for example, you can enter the

command rtwdemo_profile in the MATLAB Command Window.
2 Change your working folder to one for which you have write permission.
3 Double-click one of the Generate Code blocks. This configures the selected

code generation target options with the profiling hooks and builds the
model. When the build process is completed, a window opens with a display
of the generated code. Browse through the code to see the profile-specific C
code that has been generated.

15-48

Profile Code Performance

4 Enter !rtwdemo_profile in the MATLAB Command Window to run the

generated executable file. This command displays a textual report of the
number of calls made to each system in the example model and the number
of CPU cycles that were spent in each system.

Profiling Limitation
The TLC hook function interface for profiling code performance does not
support the S-function target (rtwsfcn.tlc).

15-49

15

Program Building, Interaction, and Debugging

Data Exchange
In this section...
“Host/Target Communication” on page 15-50
“Logging” on page 15-105
“Parameter Tuning” on page 15-119
“Data Interchange Using the C API” on page 15-137
“ASAP2 Data Measurement and Calibration” on page 15-174
“Direct Memory Access to Generated Code” on page 15-189

Host/Target Communication
• “About Host/Target Communication” on page 15-50
• “Set Up an External Mode Communication Channel” on page 15-51
• “Use the External Mode User Interface” on page 15-63
• “External Mode Compatible Blocks and Subsystems” on page 15-83
• “External Mode Communication” on page 15-86
• “Choose Communication Protocol for Client and Server” on page 15-89
• “Use External Mode Programmatically” on page 15-98
• “External Mode Limitations” on page 15-103

About Host/Target Communication
External mode allows two separate systems, a host and a target, to
communicate. The host is the computer where the MATLAB and Simulink
environments execute. The target is the computer where the executable
created by the code generation and build process runs.
The host (the Simulink environment) transmits messages requesting the
target to accept parameter changes or to upload signal data. The target
responds by executing the request. External mode communication is based

15-50

Data Exchange

on a client/server architecture, in which the Simulink environment is the
client and the target is the server.
External mode lets you
• Modify, or tune, block parameters in real time. In External mode, whenever
you change parameters in the block diagram, the Simulink engine
downloads them to the executing target program. This lets you tune your
program’s parameters without recompiling.
• View and log block outputs in many types of blocks and subsystems. You
can monitor and/or store signal data from the executing target program,
without writing special interface code. You can define the conditions under
which data is uploaded from target to host. For example, data uploading
could be triggered by a selected signal crossing zero in a positive direction.
Alternatively, you can manually trigger data uploading.
External mode works by establishing a communication channel between the
Simulink engine and generated code. The channel’s low-level transport layer
handles the physical transmission of messages. The Simulink engine and the
generated model code are independent of this layer. The transport layer and
the code directly interfacing to it are isolated in separate modules that format,
transmit, and receive messages and data packets.
This design allows for different targets to use different transport layers. ERT,
GRT, GRT malloc, and RSim targets support External mode host/target
communication by using TCP/IP and RS-232 (serial) communication. The
xPC Target product uses a customized transport layer. The Wind River
Systems Tornado target supports TCP/IP only. The Real-Time Windows
Target product uses shared memory.

Set Up an External Mode Communication Channel
• “About Setting Up External Mode Communication Channels” on page 15-52
• “Set Up the Model” on page 15-52
• “Build the Target Executable” on page 15-54
• “Run the External Mode Target Program” on page 15-58
• “Tune Parameters” on page 15-62

15-51

15

Program Building, Interaction, and Debugging

About Setting Up External Mode Communication Channels. This
section provides step-by-step instructions for getting started with External
mode, a very useful environment for rapid prototyping. The example consists
of four parts, each of which depends on completion of the preceding ones, in
order. The four parts correspond to the steps that you follow in simulating,
building, and tuning an actual real-time application:
1 Set up the model.
2 Build the target executable.
3 Run the External mode target program.
4 Tune parameters.

The example presented uses the GRT target, and does not require hardware
other than the computer on which you run the Simulink and Simulink Coder
software. The generated executable in this example runs on the host computer
in a separate process from MATLAB and Simulink.
The procedures for building, running, and testing your programs are almost
identical in UNIX and PC environments. The discussion notes differences
where applicable.
Set Up the Model. In this part of the example, you create a simple model,

extmode_example, and a folder called ext_mode_example to store the model

and the generated executable:
1 Create the folder from the MATLAB command line by typing

mkdir ext_mode_example
2 Make ext_mode_example your working folder:

cd ext_mode_example

15-52

Data Exchange

3 Create a model in Simulink with a Sine Wave block for the input signal,

two Gain blocks in parallel, and two Scope blocks. The model is shown
below. Be sure to label the Gain and Scope blocks as shown, so that
subsequent steps will be clear to you.

4 Define and assign two variables A and B in the MATLAB workspace as

follows:
A = 2; B = 3;
5 Open Gain block A and set its Gain parameter to the variable A.

6 Similarly, open Gain block B and set its Gain parameter to the variable B.

15-53

15

Program Building, Interaction, and Debugging

When the target program is built and connected to Simulink in External
mode, you can download new gain values to the executing target program
by assigning new values to workspace variables A and B, or by editing
the values in the block parameters dialog. You explore this in “Tune
Parameters” on page 15-62.
7 Verify operation of the model. Open the Scope blocks and run the model.

When A = 2 and B = 3, the output looks like this.

8 From the File menu, choose Save As. Save the model as extmode_example.

Build the Target Executable. In this section, you set up the model and
code generation parameters required for an External mode compatible target
program. Then you generate code and build the target executable:
1 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
2 In the Model Hierarchy pane, click the + sign preceding the model name

to reveal its components.
3 Click Configuration (Active) in the left pane.
4 Select Solver in the center pane. The Solver pane appears at the right.

15-54

Data Exchange

5 In the Solver options subpane:
a Select Fixed-step in the Type field.
b Select discrete (no continuous states) in the Solver field.
c Specify 0.1 in the Fixed-step size field. (Otherwise, the Simulink

Coder build process posts a warning and supplies a value when you
generate code.)
6 Click Apply. The Solver options subpane appears below. Note that after

you click Apply, the controls you changed again have a white background
color.

7 Click Data Import/Export in the center pane, and clear the Time and

Output check boxes. In this example, data is not logged to the workspace
or to a MAT-file. Click Apply.
8 Click Optimization in the center pane and click the Signals and

Parameters tab in the right pane. Make sure that the Inline parameters
option is not selected. Although External mode supports inlined
parameters, you will not explore them in this example. Click Apply if
you have made any changes.
9 Click Code Generation in the center pane. By default, the generic

real-time (GRT) target is selected on the Code Generation pane. Select
the Interface tab. The Interface pane appears at the right.
10 On the Interface pane, select External mode from the Interface

pull-down menu in the Data exchange section. This enables generation
of External mode support code and reveals two more sections of controls:
Host/Target interface and Memory management.

15-55

15

Program Building, Interaction, and Debugging

11 In the Host/Target interface section, make sure that the value tcpip is

selected for the Transport layer parameter. The Data exchange section
now looks like this:

External mode supports communication via TCP/IP, serial, and custom
transport protocols. The MEX-file name field specifies the name of a
MEX-file that implements host and target communications on the host
side. The default for TCP/IP is ext_comm, a MEX-file provided with the
Simulink Coder software. You can override this default by supplying other
files. See “Create a Transport Layer for External Communication” on
page 23-14 in the Simulink Coder documentation for details if you need
to support other transport layers.
The MEX-file arguments field lets you specify arguments, such as a
TCP/IP server port number, to be passed to the external interface program.
Note that these arguments are specific to the external interface you
are using. For information on setting these arguments, see MEX-File
Optional Arguments for TCP/IP Transport on page 92 and MEX-File
Optional Arguments for Serial Transport on page 94 in the Simulink Coder
documentation.
This example uses the default arguments. Leave the MEX-file arguments
field blank.
12 Click Apply to save the Interface settings.
13 Save the model.

15-56

Data Exchange

14 Click Code Generation in the center pane of the Model Explorer. On

the right, make sure that Generate code only is cleared, then click the
Build button to generate code and create the target program. The content
of subsequent messages depends on your compiler and operating system.
The final message is
### Successful completion of build procedure for model: extmode_example

In the next section, you will run the extmode_example executable and use
Simulink as an interactive front end to the running target program.

15-57

15

Program Building, Interaction, and Debugging

Run the External Mode Target Program. The target executable,
extmode_example, is now in your working folder. In this section, you run
the target program and establish communication between Simulink and the
target.
Note An external-mode program like extmode_example is a host-based
executable. Its execution is not tied to RTOS or a periodic timer interrupt, and
it does not run in real time. The program just runs as fast as possible, and
the time units it counts off are simulated time units that do not correspond to
time in the world outside the program.
The External Signal & Triggering dialog box (accessed via the External
Mode Control Panel) displays a list of all the blocks in your model that
support External mode signal monitoring and logging. The dialog box also
lets you configure the signals that are viewed and how they are acquired and
displayed. You can use it to reconfigure signals while the target program runs.
In this example, you observe and use the default settings of the External
Signal & Triggering dialog box.

15-58

Data Exchange

1 From the Code menu of the model diagram, select External Mode

Control Panel, which lets you configure signal monitoring and data
archiving. It also lets you connect to the target program and start and
stop execution of the model code.

The top three buttons are for use after the target program has started. The
two lower buttons open separate dialog boxes:
• The Signal & triggering button opens the External Signal &
Triggering dialog box. This dialog box lets you select the signals that
are collected from the target system and viewed in External mode. It
also lets you select a signal that triggers uploading of data when certain
signal conditions are met, and define the triggering conditions.
• The Data archiving button opens the External Data Archiving
dialog box. Data archiving lets you save data sets generated by the
target program for future analysis. This example does not use data
archiving. See “Data Archiving” on page 15-79 in the Simulink Coder
documentation for more information.

15-59

15

Program Building, Interaction, and Debugging

2 In the External Mode Control Panel, click the Signal & Triggering

button. The External Signal & Triggering dialog box opens. The
default configuration of the External Signal & Triggering dialog box is
designed to select all signals for monitoring. The default configuration
sets signal monitoring to begin as soon as the host and target programs
have connected. The figure below shows the default configuration for
extmode_example.

15-60

Data Exchange

3 Make sure that the External Signal & Triggering dialog box is set to

the defaults as shown:
• Select all check box is selected. All signals in the Signal selection list
are marked with an X in the Block column.
• Trigger Source: manual
• Trigger Mode: normal
• Duration: 1000
• Delay: 0
• Arm when connecting to target: selected
Click Close, and then close the External Mode Control Panel.
For information on the options mentioned above, see “External Signal
Uploading and Triggering” on page 15-75 in the Simulink Coder
documentation.
4 To run the target program, you must open a command prompt window (on

UNIX systems, an Xterm window). At the command prompt, change to the
ext_mode_example folder that you created in step 1. The target program
is in this folder.
cd ext_mode_example

Next, type the following command:
extmode_example -tf inf -w

and press Return.
Note On Microsoft Windows platforms, you can also use the “bang”
command (!) in the MATLAB Command Window (note that the trailing
ampersand is required):
!extmode_example -tf inf -w &

15-61

15

Program Building, Interaction, and Debugging

The target program begins execution. Note that the target program is in a
wait state, so no activity occurs in the MATLAB Command Window.
The -tf switch overrides the stop time set for the model in Simulink. The
inf value directs the model to run indefinitely. The model code runs until
the target program receives a stop message from Simulink.
The -w switch instructs the target program to enter a wait state until it
receives a Start Real-Time Code message from the host. This switch is
required if you want to view data from time step 0 of the target program
execution, or if you want to modify parameters before the target program
begins execution of model code.
5 Open Scope blocks A and B. At this point, no signals are visible on the

scopes. When you connect Simulink to the target program and begin model
execution, the signals generated by the target program will be visible on
the scope displays.
6 The model itself must be in External mode before communication between

the model and the target program can begin. To enable External mode,
select External from the Simulation > Mode menu.
7 Reopen the External Mode Control Panel (found in the Code menu) and

click Connect. This initiates a handshake between Simulink and the
target program. When Simulink and the target are connected, the Start
Real-Time Code button becomes enabled, and the label of the Connect
button changes to Disconnect.
8 Click the Start Real-Time Code button. The outputs of Gain blocks A and

B are displayed on the two scopes in your model.
Having established communication between Simulink and the running target
program, you can tune block parameters in Simulink and observe the effects
the parameter changes have on the target program. You do this in the next
section.
Tune Parameters. You can change the gain factor of either Gain block by
assigning a new value to the variable A or B in the MATLAB workspace. When
you change block parameter values in the workspace during a simulation, you
must explicitly update the block diagram with these changes. When the block
diagram is updated, the new values are downloaded to the target program.

15-62

Data Exchange

To tune the variables A and B,
1 In the MATLAB Command Window, assign new values to both variables,

for example:
A = 0.5;B = 3.5;
2 Activate the extmode_example model window. Select Update Diagram

from the Simulation menu, or press Ctrl+D. As soon as Simulink has
updated the block parameters, the new gain values are downloaded to
the target program, and the effect of the gain change becomes visible on
the scopes.
3 You can also enter gain values directly into the Gain blocks. To do this,

open the Block Parameters dialog box for Gain block A or B in the model.
Enter a new numerical value for the gain and click Apply. As soon as
you click Apply, the new value is downloaded to the target program and
the effect of the gain change becomes visible on the scope. Similarly, you
can change the frequency, amplitude, or phase of the sine wave signal
by opening the Block Parameters dialog box for the Sine Wave block and
entering a new numerical value..
Note You cannot change the sample time of the Sine Wave block. Block
sample times are part of the structural definition of the model and are part
of the generated code. Therefore, if you want to change a block sample
time, you must stop the External mode simulation, reset the block’s sample
time, and rebuild the executable.
4 To simultaneously disconnect host/target communication and end execution

of the target program, pull down the Simulation menu and select Stop
Real-Time Code. You can also do this from the External Mode Control
Panel.

Use the External Mode User Interface
• “External Mode Interface Options” on page 15-64
• “External Mode Related Menu and Toolbar Items” on page 15-66

15-63

15

Program Building, Interaction, and Debugging

• “External Mode Control Panel” on page 15-70
• “Target Interfacing” on page 15-73
• “External Signal Uploading and Triggering” on page 15-75
• “Data Archiving” on page 15-79
• “Parameter Downloading” on page 15-82
External Mode Interface Options. The ERT, GRT, GRT malloc, RSim, and
Wind River Systems Tornado targets and the Real-Time Windows Target
product support External mode. All targets that support it feature a set of
External mode options on their respective target pane of the Configuration
Parameters dialog box. This pane is normally named Interface). The next
figure is the Data exchange section from the Interface pane of the GRT
target dialog box, and is discussed below.

Note The xPC Target product also uses External mode communications.
External mode in the xPC Target product is always on, and has no interface
options.
The Data exchange section at the bottom of the Interface pane includes
the following elements:
• Interface menu: Selects which of three mutually exclusive data interfaces
to include in the generated code. Options are

15-64

Data Exchange

-

None
C API
External mode
ASAP2

This chapter discusses only the External mode option. For information
on other options, see “Specifying Target Interfaces” on page 9-58.
Once you select External mode from the Interface menu, the following
options appear beneath:
• Transport layer menu: Identifies messaging protocol for host/target
communications; choices are tcpip and serial.
The default is tcpip. When you select a protocol, the MEX-file name that
implements the protocol is shown to the right of the menu.
• MEX-file arguments text field: Optionally enter a list of arguments to be
passed to the transport layer MEX-file for communicating with executing
targets; these will vary according to the protocol you use.
For more information on the transport options, see “Target Interfacing”
on page 15-73 and “Choose Communication Protocol for Client and
Server” on page 15-89. You can add other transport protocols yourself by
following instructions given in “Create a Transport Layer for External
Communication” on page 23-14.
• Static memory allocation check box: Controls how memory for External
mode communication buffers in the target is allocated. When you select
this option, the following one appears beneath it:
• Static memory buffer size text field: Number of bytes to preallocate for
External mode communications buffers in the target when Static memory
allocation is used.
Note Selecting External mode from the Interface menu does not cause
the Simulink model to operate in External mode (see “External Mode
Related Menu and Toolbar Items” on page 15-66, below). Its function is to
instrument the code generated for the target to support External mode.

15-65

15

Program Building, Interaction, and Debugging

The Static memory allocation check box (for GRT and ERT targets) directs
the Simulink Coder software to generate code for External mode that uses
only static memory allocation (“malloc-free” code). When selected, it activates
the Static memory buffer size edit field, in which you specify the size of the
static memory buffer used by External mode. The default value is 1,000,000
bytes. Should you enter too small a value for your application, External mode
issues an out-of-memory error when it tries to allocate more memory than you
allowed. In such cases, increase the value in the Static memory buffer
size field and regenerate the code.

Notes
• To determine how much memory you need to allocate, enable verbose mode
on the target (by including OPTS="-DVERBOSE" on the make command line).
As it executes, External mode displays the amount of memory it tries to
allocate and the amount of memory available to it each time it attempts an
allocation. Should an allocation fail, this console log can be used to adjust
the size entered in the Static memory buffer size field.
• When you create an ERT target, External mode can generate pure integer
code. Select this feature by clearing the Support floating-point numbers
option on the Interface pane of the Configuration Parameters dialog box
or Model Explorer. Clearing this option makes the code, including External
mode support code, free of doubles and floats. For more details, see “Code
Generation Pane: Interface”.

External Mode Related Menu and Toolbar Items. To communicate with
a target program, the model must be operating in External mode. To enable
External mode, select External from the Simulation > Mode menu.

15-66

Data Exchange

Simulation Mode Menu Options and Target Connection Control (Host
Disconnected from Target)

Once External mode is enabled, you can connect to and control the target
program by doing any of the following:
• Select Connect To Target from the Simulation menu.
• Click the Connect To Target toolbar button.
• Use the Ctrl+T keyboard shortcut.
Note When External mode is selected in the model window, the Ctrl+T
keyboard shortcut is remapped from a toggle for Start and Stop (simulation)
to a toggle for Connect To Target and Disconnect From Target.
Selecting External mode in the model window controls execution only, and
does not cause the Simulink Coder software to generate code for External
mode. To do this, you must select External mode from the Interface menu

15-67

15

Program Building, Interaction, and Debugging

on the Interface tab of the Configuration Parameters dialog box, as described
in “External Mode Interface Options” on page 15-64.
Note You can enable External mode, and simultaneously connect to the
target system, by using the External Mode Control Panel dialog box. See
“External Mode Control Panel” on page 15-70.

Simulation Menu
When a Simulink model is in External mode, the upper section of the
Simulation menu contains External mode options. Initially, the Simulink
model is disconnected from the target program, and the menu displays the
options shown in the next figure.

Simulation Menu External Mode Options (Host Disconnected from Target)

The Connect To Target option establishes communication with the target
program. When a connection is established, the target program might be
executing model code, or it might be awaiting a command from the host to
start executing model code. You can also accomplish this by clicking the
Connect To Target toolbar button, as shown in Simulation Mode Menu
Options and Target Connection Control (Host Disconnected from Target) on
page 15-67.
If the target program is executing model code, the Simulation menu contents
change, as shown in the next figure.

15-68

Data Exchange

Simulation Menu External Mode Options (Target Executing Model Code)

The Disconnect From Target option disconnects the Simulink model
from the target program, which continues to run. The Stop Real-Time
Code option terminates execution of the target program and disconnects the
Simulink model from the target system.
If the target program is in a wait state, the Start Real-Time Code option
is enabled, as shown in the next figure. The Start Real-Time Code option
instructs the target program to begin executing the model code.

Simulation Menu External Mode Options (Target Awaiting Start Command)

Toolbar Controls
The Simulink toolbar controls, shown in Simulation Mode Menu Options and
Target Connection Control (Host Disconnected from Target) on page 15-67,
let you control the same External mode functions as the Simulation menu.
The Simulink model editor displays External mode buttons to the left of the
Simulation mode menu. Initially, the toolbar displays a Connect To Target

15-69

15

Program Building, Interaction, and Debugging

button and a disabled Start Real-Time Code button. Click the Connect To
Target button to connect the Simulink engine to the target program.
When a connection is established, the target program might be executing
model code, or it might be awaiting a command from the host to start
executing model code.
If the target program is executing model code, the toolbar displays a Stop
Real-Time Code button and a Disconnect From Target button (shown in
). Click the Stop Real-Time Code button to command the target program
to stop executing model code and disconnect the Simulink engine from the
target system. Click the Disconnect From Target button to disconnect the
Simulink engine from the target program while leaving the target program
running.
If the target program is in a wait state, the toolbar displays a Start
Real-Time Code button and a Disconnect From Target button. Click
the Start Real-Time Code button to instruct the target program to start
executing model code. Click the Disconnect From Target button to
disconnect the Simulink engine from the target program.
External Mode Control Panel. The External Mode Control Panel,
illustrated in the next figure, provides centralized control of all External
mode features, including
• Host/target connection, disconnection, and target program start/stop
functions, and enabling of External mode
• Arming and disarming the data upload trigger
• External mode communications configuration
• Uploading data to Floating Scopes
• Timing of parameter downloads
• Selection of signals from the target program to be viewed and monitored
on the host
• Configuration of data archiving features
Select External Mode Control Panel from the Code menu on the Simulink
model editor to open the External Mode Control Panel dialog box.

15-70

Data Exchange

Control the connection between
host and manual arming of data
uploading trigger

Control timing of
parameter downloads

Control use of floating
scopes in external mode

Open dialog boxes that configure
external mode target interface,
signal properties, and data archiving

The following sections describe the features supported by the External Mode
Control Panel.

Connecting, Starting, and Stopping
The External Mode Control Panel performs the same connect/disconnect and
start/stop functions found in the Simulation menu and the Simulink toolbar
(see “External Mode Related Menu and Toolbar Items” on page 15-66).

15-71

15

Program Building, Interaction, and Debugging

The Connect/Disconnect button connects to or disconnects from the target
program. The button text changes in accordance with the state of the
connection.
If External mode is not enabled at the time the Connect button is clicked, the
External Mode Control Panel enables External mode automatically.
The Start/Stop Real-Time Code button commands the target to start or
terminate model code execution. The button is disabled until a connection to
the target is established. The button text changes in accordance with the
state of the target program.

Floating Scope Options
The Floating scope pane of the External Mode Control Panel controls when
and for how long data is uploaded to Floating Scope blocks. When used under
External mode, Floating Scopes
• Do not appear in the signal and triggering GUI
• Support manual triggering only
The behavior of wired scopes is not restricted in these ways.
The Floating scope pane contains a check box and an edit field:
• Enable data uploading check box, which functions as an Arm trigger
button for floating scopes. When the target is disconnected it controls
whether or not to arm when connecting the floating scopes. When already
connected it acts as a toggle button to arm/cancel the trigger.
• Duration edit field, which specifies the duration for floating scopes. By
default, it is set to auto, which causes whatever value is specified in the
signal and triggering GUI (which by default is 1000 base rate steps) to
be used.

15-72

Data Exchange

Target Interfacing. The Simulink Coder product lets you implement
client and server transport for External mode using either TCP/IP or serial
protocols. You can use the socket-based External mode implementation
provided by the Simulink Coder product with the generated code, provided
that your target system supports TCP/IP. Otherwise, use or customize the
serial transport layer option provided.
A low-level transport layer handles physical transmission of messages. Both
the Simulink engine and the model code are independent of this layer. Both
the transport layer and code directly interfacing to the transport layer are
isolated in separate modules that format, transmit, and receive messages
and data packets.
You specify the transport mechanism using the Transport layer menu in the
Host/Target interface subpane of the Interface pane of the Configuration
Parameters dialog box, shown below.

External interface MEX-file being used (specified
in extmode_transports.m or sl_customization.m)

Type optional arguments to the external interface
MEX-file here. This file must be in the current
directory or one that is on your MATLAB path.
The Host/Target interface subpane also displays MEX-file name, the
name of a MEX-file that implements host/target communications for the
selected External mode transport layer. This is known as the external
interface MEX-file. The default is ext_comm, the TCP/IP-based external

15-73

15

Program Building, Interaction, and Debugging

interface file provided for use with the GRT, GRT malloc, ERT, RSim, and
Tornado targets. If you select the serial transport option, the MEX-file name
ext_serial_win32_com is displayed in this location.
Note Custom or third-party targets can use a custom transport layer and
a different external interface MEX-file. For more information on creating
a custom transport layer, see “Create a Transport Layer for External
Communication” on page 23-14. For more information on specifying a
TCP/IP or serial transport layer for a custom target, see “Using the TCP/IP
Implementation” on page 15-90 or “Using the Serial Implementation” on
page 15-93.
The MEX-file arguments edit field lets you optionally specify arguments
that are passed to the External mode interface MEX-file for communicating
with executing targets. The meaning of the MEX-file arguments depends on
the MEX-file implementation.
For TCP/IP interfaces, ext_comm allows three optional arguments:
• Network name of your target (for example, 'myPuter' or '148.27.151.12')
• Verbosity level (0 for no information or 1 for detailed information)
• TCP/IP server port number (an integer value between 256 and 65535, with
a default of 17725)
For serial transport, ext_serial_win32_comm allows three optional
arguments:
• Verbosity level (0 for no information or 1 for detailed information)
• Serial port ID (for example, 1 for COM1, and so on)
• Baud rate (selected from the set 1200, 2400, 4800, 9600, 14400, 19200,
38400, 57600, 115200, with a default baud rate of 57600)
See “Choose Communication Protocol for Client and Server” on page 15-89 for
details on MEX-file transport architecture and arguments.

15-74

Data Exchange

External Signal Uploading and Triggering. Clicking the Signal &
Triggering button of the External Mode Control Panel activates the External
Signal & Triggering dialog box, as shown in the next figure.

The External Signal & Triggering dialog box displays a list of all blocks and
subsystems in your model that support External mode signal uploading.
See “External Mode Compatible Blocks and Subsystems” on page 15-83 for
information on which types of blocks are External mode compatible.
The External Signal & Triggering dialog box lets you select the signals that
are collected from the target system and viewed in External mode. It also
lets you select a signal that triggers uploading of data when certain signal
conditions are met, and define the triggering conditions.

Default Operation
The preceding figure shows the default settings of the External Signal
& Triggering dialog box. The default operation of the External Signal &
Triggering dialog box is designed to simplify monitoring the target program.

15-75

15

Program Building, Interaction, and Debugging

If you use the default settings, you do not need to preconfigure signals and
triggers. Simply start the target program and connect the Simulink engine
to it. All External mode compatible blocks will be selected and the trigger
will be armed. Signal uploading begins immediately upon connection to the
target program.
The default configuration is
• Arm when connecting to target: on
• Trigger Mode: normal
• Trigger Source: manual
• Select all: on

Signal Selection
All External mode compatible blocks in your model appear in the Signal
selection list of the External Signal & Triggering dialog box. You use this
list to select signals to be viewed. An X appears to the left of each selected
block’s name.
The Select all check box selects all signals. By default, Select all is on.
If Select all is off, you can select or deselect individual signals using the on
and off radio buttons. To select a signal, click the desired list entry and click
the on radio button. To deselect a signal, click the desired list entry and click
the off radio button. Alternatively, you can double-click a signal in the list to
toggle between selection and deselection.
The Clear all button deselects all signals.

Trigger Options
The Trigger panel located at the bottom left of the External Signal &
Triggering dialog contains options that control when and how signal data is
collected (uploaded) from the target system. These options are

15-76

Data Exchange

• Source: manual or signal. Selecting manual directs External mode to
start logging data when the Arm trigger button on the External Mode
Control Panel is clicked.
Selecting signal tells External mode to start logging data when a selected
trigger signal satisfies trigger conditions specified in the Trigger signal
panel. When the trigger conditions are satisfied (that is, the signal crosses
the trigger level in the specified direction) a trigger event occurs. If the
trigger is armed, External mode monitors for the occurrence of a trigger
event. When a trigger event occurs, data logging begins.
• Arm when connecting to target: If this option is selected, External
mode arms the trigger automatically when the Simulink engine connects to
the target. If the trigger source is manual, uploading begins immediately.
If the trigger mode is signal, monitoring of the trigger signal begins
immediately, and uploading begins upon the occurrence of a trigger event.
If Arm when connecting to target is not selected, you must manually
arm the trigger by clicking the Arm trigger button in the External Mode
Control Panel.
• Duration: The number of base rate steps for which External mode logs
data after a trigger event (default is 1000). For example, if the fastest
rate in the model is 1 second:

-

If a signal sampled at 1 Hz is logged for 10 base rate steps, External
mode will collect 10 samples.

-

If a signal sampled at 2 Hz is logged for 10 base rate steps, External
mode will collect 20 samples.

• Mode: normal or one-shot. In normal mode, External mode automatically
rearms the trigger after each trigger event. In one-shot mode, External
mode collects only one buffer of data each time you arm the trigger. See
“Data Archiving” on page 15-79 for more details on the effect of the Mode
setting.
• Delay: The delay represents the amount of time that elapses between a
trigger occurrence and the start of data collection. The delay is expressed
in base rate steps, and can be positive or negative (default is 0). A negative
delay corresponds to pretriggering. When the delay is negative, data from
the time preceding the trigger is collected and uploaded.

15-77

15

Program Building, Interaction, and Debugging

Trigger Signal Selection
You can designate one signal as a trigger signal. To select a trigger signal,
select signal from the Trigger Source menu. This activates the Trigger
signal panel (see the next figure). Then, click the desired entry in the Signal
selection list and click the Trigger signal button.
When a signal is selected as a trigger, a T appears to the left of the block’s
name in the Signal selection list. In the next figure, the Scope A signal is
the trigger. Scope B is also selected for viewing, as indicated by the X to the
left of the block name.

Trigger signal panel

External Signal & Triggering Window with Trigger Selected

After selecting the trigger signal, you can define the trigger conditions and set
the Port and Element fields in the Trigger signal panel.

15-78

Data Exchange

Setting Trigger Conditions
Note The Trigger signal panel and the Port and Element fields of the
External Signal & Triggering dialog box are enabled only when trigger
Source is set to signal.
By default, any element of the first input port of the specified trigger block
can cause the trigger to fire (that is, Port 1, any element). You can modify this
behavior by adjusting the Port and Element fields located on the right side
of the Trigger signal panel. The Port field accepts a number or the keyword
last. The Element field accepts a number or the keywords any and last.
The Trigger Signal panel defines the conditions under which a trigger
event will occur.
• Level: Specifies a threshold value. The trigger signal must cross this value
in a designated direction to fire the trigger. By default, the level is 0.
• Direction: rising, falling, or either. This specifies the direction in
which the signal must be traveling when it crosses the threshold value.
The default is rising.
• Hold-off: Applies only to normal mode. Expressed in base rate steps,
Hold-off is the time between the termination of one trigger event and
the rearming of the trigger.
Data Archiving. In External mode, you can use the Simulink Scope and
To Workspace blocks to archive data to disk. Clicking the Data Archiving
button of the External Mode Control Panel opens the External Data Archiving
dialog box, which supports the following features.

Folder Notes
Use this option to add annotations that pertain to a collection of related data
files in a folder. Clicking the Edit directory note button opens the MATLAB
editor. Place comments that you want saved to a file in the specified folder in
this window. By default, the comments are saved to the folder last written
to by data archiving.

15-79

15

Program Building, Interaction, and Debugging

File Notes
Clicking Edit file note opens a file finder window that is, by default, set to
the last file to which you have written. Selecting any MAT-file opens an edit
window. Add or edit comments in this window that you want saved with your
individual MAT-file.

Automated Data Archiving
Clicking the Enable Archiving check box activates the automated data
archiving features of External mode. To understand how the archiving
features work, consider the handling of data when archiving is not enabled.
There are two cases, one-shot and normal mode.
In one-shot mode, after a trigger event occurs, each selected block writes its
data to the workspace just as it would at the end of a simulation. If another
one-shot is triggered, the existing workspace data is overwritten.
In normal mode, External mode automatically rearms the trigger after each
trigger event. Consequently, you can think of normal mode as a series of
one-shots. Each one-shot in this series, except for the last, is referred to
as an intermediate result. Since the trigger can fire at any time, writing
intermediate results to the workspace generally results in unpredictable
overwriting of the workspace variables. For this reason, the default behavior
is to write only the results from the final one-shot to the workspace. The
intermediate results are discarded. If you know that enough time exists
between triggers for inspection of the intermediate results, then you can
override the default behavior by checking the Write intermediate results
to workspace check box. This option does not protect the workspace data
from being overwritten by subsequent triggers.
The options in the External Data Archiving dialog box support automatic
writing of logging results, including intermediate results, to disk. Data
archiving provides the following settings:
• Directory: Specifies the folder in which data is saved. External mode
appends a suffix if you select Increment directory when trigger armed.

15-80

Data Exchange

• File: Specifies the filename in which data is saved. External mode appends
a suffix if you select Increment file after one-shot.
• Increment directory when trigger armed: External mode uses a
different folder for writing log files each time that you click the Arm
trigger button. The folders are named incrementally, for example,
dirname1, dirname2, and so on.
• Increment file after one-shot: New data buffers are saved in incremental
files: filename1, filename2, and so on. This happens automatically in
normal mode.
• Append file suffix to variable names: Whenever External mode
increments filenames, each file contains variables with identical names.
Selecting Append file suffix to variable name results in each file
containing unique variable names. For example, External mode will save
a variable named xdata in incremental files (file_1, file_2, and so on)
as xdata_1, xdata_2, and so on. This is useful if you want to load the
MAT-files into the workspace and compare variables at the MATLAB
command prompt. Without the unique names, each instance of xdata
would overwrite the previous one in the MATLAB workspace.
• Write intermediate results to workspace: Select this option if you
want the Simulink Coder software to write all intermediate results to the
workspace.
The next figure shows the External Data Archiving dialog box with archiving
enabled.

15-81

15

Program Building, Interaction, and Debugging

Unless you select Enable archiving, entries for the Directory and File
fields are not accepted.
Parameter Downloading. The Batch download check box on the
External Mode Control Panel enables or disables batch parameter changes.
By default, batch download is not enabled. If batch download is not enabled,
changes made directly to block parameters by using parameter dialog boxes
are sent to the target when you click the OK or Apply button. Changes
to MATLAB workspace variables are sent when an Update diagram is
performed.
If batch download is enabled, the Download button is enabled. Changes
made to block parameters are stored locally until you click the Download
button. When you click the Download button, the changes are sent in a
single transmission.
When parameter changes have been made and are awaiting batch download,
the External Mode Control Panel displays the message Parameter changes
pending... to the right of the download button. (See the next figure.) This
message disappears after the Simulink engine receives notification from the
target that the new parameters have been installed in the parameter vector
of the target system.
The External Mode Control Panel with the batch download option activated
appears in the next figure.

15-82

Data Exchange

Parameter changes pending...

Parameter changes pending...
message appears if unsent
parameter value changes
are awaiting download
External Mode Control Panel in Batch Download Mode

External Mode Compatible Blocks and Subsystems
• “Compatible Blocks” on page 15-83
• “Signal Viewing Subsystems” on page 15-84
• “Supported Blocks for Data Archiving” on page 15-86
Compatible Blocks. In External mode, you can use the following types of
blocks to receive and view signals uploaded from the target program:

15-83

15

Program Building, Interaction, and Debugging

• Floating Scope and Scope blocks
• Spectrum Scope and Vector Scope blocks from the DSP System Toolbox
product
• Blocks from the Gauges Blockset product
• Display blocks
• To Workspace blocks
• User-written S-Function blocks
An External mode method is built into the S-function API. This
method allows user-written blocks to support External mode. See
matlabroot/simulink/simstruc.h.
• XY Graph blocks
In addition to these types of blocks, you can designate certain subsystems
as Signal Viewing Subsystems and use them to receive and view signals
uploaded from the target program. See “Signal Viewing Subsystems” on page
15-84 for more information.
You select External mode compatible blocks and subsystems, and arm the
trigger, by using the External Signal & Triggering dialog box. By default, all
such blocks in a model are selected, and a manual trigger is set to be armed
when connected to the target program.
Signal Viewing Subsystems. A Signal Viewing Subsystem is an atomic
subsystem that encapsulates processing and viewing of signals received
from the target system. A Signal Viewing Subsystem runs only on the host,
generating no code in the target system. Signal Viewing Subsystems run in
all simulation modes — normal, accelerated, and external.
Signal Viewing Subsystems are useful in situations where you want to
process or condition signals before viewing or logging them, but you do not
want to perform these tasks on the target system. By using a Signal Viewing
Subsystem, you can generate smaller and more efficient code on the target
system.
Like other External mode compatible blocks, Signal Viewing Subsystems are
displayed in the External Signal & Triggering dialog box.

15-84

Data Exchange

To declare a subsystem to be a Signal Viewing Subsystem,
1 Select the Treat as atomic unit option in the Block Parameters dialog box.

For more information on atomic subsystems, see “Code Generation of
Subsystems” on page 2-2.
2 Use the following set_param command to turn the SimViewingDevice

property on,
set_param('blockname', 'SimViewingDevice','on')

where 'blockname' is the name of the subsystem.
3 Make sure the subsystem meets the following requirements:

• It must be a pure sink block. That is, it must contain no Outport blocks
or Data Store blocks. It can contain Goto blocks only if the corresponding
From blocks are contained within the subsystem boundaries.
• It must have no continuous states.
The following model, sink_examp, contains an atomic subsystem, theSink.

The subsystem theSink, shown in the next figure, applies a gain and an offset
to its input signal and displays it on a Scope block.

15-85

15

Program Building, Interaction, and Debugging

If theSink is declared as a Signal Viewing Subsystem, the generated target
program includes only the code for the Sine Wave block. If theSink is selected
and armed in the External Signal & Triggering dialog box, the target program
uploads the sine wave signal to theSink during simulation. You can then
modify the parameters of the blocks within theSink and observe their effect
upon the uploaded signal.
If theSink were not declared as a Signal Viewing Subsystem, its Gain,
Constant, and Sum blocks would run as subsystem code on the target system.
The Sine Wave signal would be uploaded to the Simulink engine after being
processed by these blocks, and viewed on sink_examp/theSink/Scope2.
Processing demands on the target system would be increased by the additional
signal processing, and by the downloading of changes in block parameters
from the host.
Supported Blocks for Data Archiving. In External mode, you can use the
following types of blocks to archive data to disk:
• Scope blocks
• To Workspace blocks
You configure data archiving by using the External Data Archiving dialog
box, as described in “Data Archiving” on page 15-79.

External Mode Communication
• “About External Mode Communication” on page 15-86
• “Download Mechanism” on page 15-87
• “Inlined and Tunable Parameters” on page 15-88
About External Mode Communication. This section describes how the
Simulink engine and a target program communicate, and how and when they
transmit parameter updates and signal data to each other.
Depending on the setting of the Inline parameters option when the target
program is generated, there are differences in the way parameter updates
are handled. “Download Mechanism” on page 15-87 describes the operation
of External mode communications with Inline parameters off. “Inlined

15-86

Data Exchange

and Tunable Parameters” on page 15-88 describes the operation of External
mode with Inline parameters on.
Download Mechanism. In External mode, the Simulink engine does not
simulate the system represented by the block diagram. By default, when
External mode is enabled, the Simulink engine downloads all parameters to
the target system. After the initial download, the engine remains in a waiting
mode until you change parameters in the block diagram or until the engine
receives data from the target.
When you change a parameter in the block diagram, the Simulink engine
calls the external interface MEX-file, passing new parameter values (along
with other information) as arguments. The external interface MEX-file
contains code that implements one side of the interprocess communication
(IPC) channel. This channel connects the Simulink process (where the
MEX-file executes) to the process that is executing the external program.
The MEX-file transfers the new parameter values by using this channel to
the external program.
The other side of the communication channel is implemented within the
external program. This side writes the new parameter values into the target’s
parameter structure (model_P).
The Simulink side initiates the parameter download operation by sending a
message containing parameter information to the external program. In the
terminology of client/server computing, the Simulink side is the client and
the external program is the server. The two processes can be remote, or they
can be local. Where the client and server are remote, a protocol such as
TCP/IP is used to transfer data. Where the client and server are local, a serial
connection or shared memory can be used to transfer data.
The next figure shows this relationship. The Simulink engine calls the
external interface MEX-file whenever you change parameters in the block
diagram. The MEX-file then downloads the parameters to the external
program by using the communication channel.

15-87

15

Program Building, Interaction, and Debugging

Simulink Process

External Program Process
mexFunction
External Program
Client
IPC Code

Server
IPC Code

External Interface

ext_svr.

MEX-file (e.g., ext_comm)

Interprocess Communication Channel Transport Layer
External Mode Architecture

Inlined and Tunable Parameters. By default, all parameters (except those
listed in “External Mode Limitations” on page 15-103) in an External mode
program are tunable; that is, you can change them by using the download
mechanism described in this section.
If you select the Inline parameters option (on the Optimization > Signals
and Parameters pane of the Configuration Parameters dialog box), the
Simulink Coder code generator embeds the numerical values of model
parameters (constants), instead of symbolic parameter names, in the

15-88

Data Exchange

generated code. Inlining parameters generates smaller and more efficient
code. However, inlined parameters, because they effectively become
constants, are not tunable.
The Simulink Coder software lets you improve overall efficiency by inlining
most parameters, while at the same time retaining the flexibility of run-time
tuning for selected parameters that are important to your application. When
you inline parameters, you can use the Model Parameter Configuration dialog
box to remove individual parameters from inlining and declare them to be
tunable. In addition, the Model Parameter Configuration dialog box offers you
options for controlling how parameters are represented in the generated code.
For more information on tunable parameters, see “Parameters” on page 7-10.

Automatic Parameter Uploading on Host/Target Connection
Each time the Simulink engine connects to a target program that was
generated with Inline parameters on, the target program uploads the
current value of its tunable parameters (if any) to the host. These values are
assigned to the corresponding MATLAB workspace variables. This procedure
synchronizes the host and target with respect to parameter values.
All workspace variables required by the model must be initialized at the time
of host/target connection. Otherwise the uploading cannot proceed and an
error results. Once the connection is made, these variables are updated to
reflect the current parameter values on the target system.
Automatic parameter uploading takes place only if the target program was
generated with Inline parameters on. “Download Mechanism” on page
15-87 describes the operation of External mode communications with Inline
parameters off.

Choose Communication Protocol for Client and Server
• “Introduction” on page 15-90
• “Using the TCP/IP Implementation” on page 15-90
• “Using the Serial Implementation” on page 15-93

15-89

15

Program Building, Interaction, and Debugging

• “Run the External Program” on page 15-95
• “Implement an External Mode Protocol Layer” on page 15-98
Introduction. The Simulink Coder product provides code to implement
both the client and server side of External mode communication using
either TCP/IP or serial protocols. You can use the socket-based External
mode implementation provided by the Simulink Coder product with the
generated code, provided that your target system supports TCP/IP. If not, use
or customize the serial transport layer option provided.
A low-level transport layer handles physical transmission of messages. Both
the Simulink engine and the model code are independent of this layer. Both
the transport layer and code directly interfacing to the transport layer are
isolated in separate modules that format, transmit, and receive messages
and data packets.
See “Target Interfacing” on page 15-73 for information on selecting a
transport layer.
Using the TCP/IP Implementation. You can use TCP/IP-based client/server
implementation of External mode with real-time programs on The Open
Group UNIX or PC systems. For help in customizing External mode transport
layers, see “Create a Transport Layer for External Communication” on page
23-14.
To use Simulink External mode over TCP/IP, you must
• Make sure that the external interface MEX-file for your target’s TCP/IP
transport is specified.
Targets provided by MathWorks specify the
name of the external interface MEX-file in
matlabroot/toolbox/simulink/simulink/extmode_transports.m. The

name of the interface appears as uneditable text in the Host/Target
interface section of the Interface pane of the Configuration Parameters
dialog box. The TCP/IP default is ext_comm.
To specify a TCP/IP transport for a custom target, you must add an entry of
the following form to an sl_customization.m file on the MATLAB path:
function sl_customization(cm)

15-90

Data Exchange

cm.ExtModeTransports.add('stf.tlc', 'transport', 'mexfile', 'Level1');
%end function

where

-

stf.tlc is the name of the system target file for which the transport will
be registered (for example, 'mytarget.tlc')

-

transport is the transport name to display in the Transport layer

-

menu on the Interface pane of the Configuration Parameters dialog
box (for example, 'tcpip')
mexfile is the name of the transport’s associated external interface
MEX-file (for example, 'ext_comm')

You can specify multiple targets and/or transports with additional
cm.ExtModeTransports.add lines, for example:
function sl_customization(cm)
cm.ExtModeTransports.add('mytarget.tlc', 'tcpip', 'ext_comm', 'Level1');
cm.ExtModeTransports.add('mytarget.tlc', 'serial', ...
'ext_serial_win32_comm', 'Level1');
%end function

• Be sure that the template makefile is configured to link the source files for
the TCP/IP server code and that it defines the compiler flags when building
the generated code.
• Build the external program.
• Run the external program.
• Set the Simulink model to External mode and connect to the target.
The next figure shows the structure of the TCP/IP-based implementation.

15-91

15

Program Building, Interaction, and Debugging

Target

UNIX or PC Host
Simulink in External Mode

Target Code

Process block
parameter changes

ext_svr.c
Update block parameters

ext_comm

TCP/IP on Ethernet

External Mode Message Format
header

data in target format

TCP/IP-Based Client/Server Implementation for External Mode

MEX-File Optional Arguments for TCP/IP Transport
In the External Target Interface dialog box, you can specify optional
arguments that are passed to the External mode interface MEX-file for
communicating with executing targets.
• Target network name: the network name of the computer running the
external program. By default, this is the computer on which the Simulink
product is running. The name can be

15-92

String delimited by single quotes, such as 'myPuter'

Data Exchange

-

IP address delimited by single quotes, such as '148.27.151.12'

• Verbosity level: controls the level of detail of the information displayed
during the data transfer. The value is either 0 or 1 and has the following
meaning:
0 — No information
1 — Detailed information

• TCP/IP server port number: The default value is 17725. You can change
the port number to a value between 256 and 65535 to avoid a port conflict.
The arguments are positional and must be specified in order. For example, if
you want to specify the verbosity level (the second argument), then you must
also specify the target network name (the first argument). Arguments can be
delimited by white space or commas. For example:
'148.27.151.12' 1 30000

You can specify command-line options to the external program when
you launch it. See “Run the External Program” on page 15-95 for more
information.
Using the Serial Implementation. Controlling host/target communications
on a serial channel is similar to controlling host/target communications on a
TCP/IP channel.
To use Simulink External mode over a serial channel, you must
• Execute the target and host on a Microsoft Windows platform.
• Make sure that the external interface MEX-file for your target’s serial
transport is specified.
Targets provided by MathWorks specify the
name of the external interface MEX-file in
matlabroot/toolbox/simulink/simulink/extmode_transports.m. The

name of the interface appears as uneditable text in the Host/Target
interface section of the Interface pane of the Configuration Parameters
dialog box. The serial default is serial.
To specify a serial transport for a custom target, you must add an entry of
the following form to an sl_customization.m file on the MATLAB path:

15-93

15

Program Building, Interaction, and Debugging

function sl_customization(cm)
cm.ExtModeTransports.add('stf.tlc', 'transport', 'mexfile', 'Level1');
%end function

where

-

stf.tlc is the name of the system target file for which the transport will
be registered (for example, 'mytarget.tlc')

-

transport is the transport name to display in the Transport layer

-

menu on the Interface pane of the Configuration Parameters dialog
box (for example, 'serial')
mexfile is the name of the transport’s associated external interface
MEX-file (for example, 'ext_serial_win32_comm')

You can specify multiple targets and/or transports with additional
cm.ExtModeTransports.add lines, for example:
function sl_customization(cm)
cm.ExtModeTransports.add('mytarget.tlc', 'tcpip', 'ext_comm', 'Level1');
cm.ExtModeTransports.add('mytarget.tlc', 'serial', ...
'ext_serial_win32_comm', 'Level1');
%end function

• Be sure that the template makefile is configured to link the source files for
the serial server code and that it defines the compiler flags when building
the generated code.
• Build the external program.
• Run the external program.
• Set the Simulink model to External mode and connect to the target.

MEX-File Optional Arguments for Serial Transport
In the MEX-file arguments field of the Interface pane of the Configuration
Parameters dialog box, you can specify arguments that are passed
to the External mode interface MEX-file for communicating with the
executing targets. For serial transport, the optional arguments to
ext_serial_win32_comm are

15-94

Data Exchange

• Verbosity level: controls the level of detail of the information displayed
during the data transfer. The value is either 0 or 1 and has the following
meaning:
0 — No information
1 — Detailed information

• Serial port ID (for example, 1 for COM1, and so on)
If the target program is executing on the same machine as the host and
communications is through a loopback serial cable, the target’s port ID
must differ from that of the host (as specified in the MEX-file arguments
edit field).
When you start the target program using a serial connection, you must
specify the port ID to use to connect it to the host. Do this by including the
-port command-line option. For example,
mytarget.exe -port 2 -w

• Baud rate (selected from the set 1200, 2400, 4800, 9600, 14400, 19200,
38400, 57600, 115200, with a default baud rate of 57600)
The arguments are positional and must be specified in order. For example,
if you want to specify the serial port ID (the second argument), then you
must also specify the verbosity level (the first argument). Arguments can be
delimited by white space or commas. For example:
1 1 115200

You can specify command-line options to the external program when you
launch it. The following section provides details on using command-line
arguments.
Run the External Program. The external program must be running before
you can use the Simulink product in External mode. To run the external
program, you type a command of the form
model -opt1 ... -optN

where model is the name of the external program and -opt1 ... -optN
are options. (See Command-Line Options for the External Program on page

15-95

15

Program Building, Interaction, and Debugging

97.) In the examples in this section, the name of the external program is
assumed to be ext_example.

Running the External Program Under the Windows Environment
In the Windows environment, you can run the external programs in either
of the following ways:
• Open a Command Prompt window. At the command prompt, type the
name of the target executable, followed by any options, as in the following
example:
ext_example -tf inf -w

• Alternatively, you can launch the target executable from the MATLAB
command prompt. In this case the command must be preceded by an
exclamation point (!) and followed by an ampersand (&), as in the following
example:
!ext_example -tf inf -w &

The ampersand (&) causes the operating system to spawn another process
to run the target executable. If you do not include the ampersand, the
program still runs, but you will be unable to enter commands at the
MATLAB command prompt or manually terminate the executable.

Running the External Program Under the UNIX Environment
In the UNIX environment, you can run the external programs in either of the
following ways:
• Open an Xterm window. At the command prompt, type the name of the
target executable, followed by any options, as in the following example:
ext_example -tf inf -w

• Alternatively, you can launch the target executable from the MATLAB
command prompt. In the UNIX environment, if you start the external

15-96

Data Exchange

program from the MATLAB command prompt, you must run it in the
background so that you can still access the Simulink environment. The
command must be preceded by an exclamation point (!) and followed by
an ampersand (&), as in the following example:
!ext_example -tf inf -w &

runs the executable from the MATLAB command prompt by spawning
another process to run it.

Command-Line Options for the External Program
External mode target executables generated by the Simulink Coder code
generator support the following command-line options:
• -tf n option
The -tf option overrides the stop time set in the Simulink model. The
argument n specifies the number of seconds the program will run. The
value inf directs the model to run indefinitely. In this case, the model
code will run until the target program receives a stop message from the
Simulink engine.
The following example sets the stop time to 10 seconds.
ext_example -tf 10

When integer-only ERT targets are built and executed in External mode, the
stop time parameter (-tf) is interpreted by the target as the number of base
rate ticks rather than the number of seconds to execute.
Note The -tf option works with GRT, GRT malloc, ERT, RSim, and Tornado
targets. If you are creating a custom target and want to support the -tf
option, you must implement the option yourself. See “Create a Transport
Layer for External Communication” on page 23-14 for more information.
• -w option: Instructs the target program to enter a wait state until it
receives a message from the host. At this point, the target is running, but

15-97

15

Program Building, Interaction, and Debugging

not executing the model code. The start message is sent when you select
Start Real-Time Code from the Simulation menu or click the Start
Real-Time Code button in the External Mode Control Panel.
Use the -w option if you want to view data from time step 0 of the target
program execution, or if you want to modify parameters before the target
program begins execution of model code.
• -port n option: Specifies the TCP/IP port number, n, for the target
program. The port number of the target program must match that of the
host. The default port number is 17725. The port number must be a value
between 256 and 65535.
Note The -tf, -w, and -port options are supported by the TCP/IP and
serial transport layer modules shipped with the Simulink Coder product
(although -port is interpreted differently by each). The -baud option is
serial only. By default, these modules are linked into External mode target
executables. If you are implementing a custom External mode transport
layer and want to support these options, you must implement them in
your code.
Implement an External Mode Protocol Layer. If you want to implement
your own transport layer for External mode communication, you must modify
certain code modules provided by the Simulink Coder product and create a
new external interface MEX-file. This advanced topic is described in detail in
“Create a Transport Layer for External Communication” on page 23-14.

Use External Mode Programmatically
You can run external-mode applications from the MATLAB command line or
programmatically in scripts. Use the get_param and set_param commands to
retrieve and set the values of model simulation command-line parameters,
such as SimulationMode and SimulationCommand, and External mode
command-line parameters, such as ExtModeCommand and ExtModeTrigType.
(For more information on using get_param and set_param to tune model
parameters, see “Tune Parameters” on page 7-36.)

15-98

Data Exchange

The following sequence of model simulation commands assumes that a
Simulink model is open and that you have loaded a target program to which
the model will connect using External mode.
1 Change the Simulink model to External mode:

set_param(gcs, 'SimulationMode', 'external')
2 Connect the open model to the loaded target program:

set_param(gcs, 'SimulationCommand', 'connect')
3 Start running the target program:

set_param(gcs, 'SimulationCommand', 'start')
4 Stop running the target program:

set_param(gcs, 'SimulationCommand', 'stop')
5 Disconnect the target program from the model:

set_param(gcs, 'SimulationCommand', 'disconnect')

The next table lists External mode command-line parameters that you
can use in get_param and set_param commands. The table provides brief
descriptions, valid values (bold type highlights defaults), and a mapping to
External Mode dialog box equivalents.
Note For External mode parameters that are equivalent to Interface pane
options in the Configuration Parameters dialog box, see the ExtMode table
entries in “Parameter Command-Line Information Summary”.

15-99

15

Program Building, Interaction, and Debugging

External Mode Command-Line Parameters
Parameter and Values

Dialog Box Equivalent

Description

ExtModeAddSuffixToVar
off, on

External Data Archiving:
Append file suffix to
variable names check box

Increment variable names
for each incremented
filename.

ExtModeArchiveDirName
string

External Data Archiving:
Directory text field

Save data in specified
folder.

ExtModeArchiveFileName
string

External Data Archiving:
File text field

Save data in specified file.

ExtModeArchiveMode
string - off, on

External Data Archiving:
Enable archiving check
box

Activate automated data
archiving features.

ExtModeArmWhenConnect
off, on

External Signal &
Triggering: Arm when
connecting to target
check box

Arm the trigger as soon
as the Simulink Coder
software connects to the
target.

ExtModeAutoIncOneShot
off, on

External Data Archiving:
Increment file after
one-shot check box

Save new data buffers in
incremental files.

ExtModeAutoUpdateStatusClock

Not available

Continuously upload and
display target time on the
model window status bar.

ExtModeBatchMode
off, on

External Mode Control
Panel: Batch download
check box

Enable or disable
downloading of parameters
in batch mode.

ExtModeChangesPending
off, on

Not available

When ExtModeBatchMode
is enabled, indicates
whether any parameters
remain in the queue
of parameters to be
downloaded to the target.

ExtModeCommand
string

Not available

Issue an External mode
command to the target
program.

(Microsoft Windows platforms only)
off, on

15-100

Data Exchange

External Mode Command-Line Parameters (Continued)
Parameter and Values

Dialog Box Equivalent

Description

ExtModeConnected
off, on

External Mode
Control Panel:
Connect/Disconnect
button

Indicate the state of the
connection with the target
program.

ExtModeEnableFloating
off, on

External Mode Control
Panel: Enable data
uploading check box

Enable or disable the
arming and canceling of
triggers when a connection
is established with floating
scopes.

ExtModeIncDirWhenArm
off, on

External Data Archiving:
Increment directory
when trigger armed
check box

Write log files to
incremental folders each
time the trigger is armed.

ExtModeLogAll
off, on

External Signal &
Triggering: Select all
check box

Upload all available
signals from the target to
the host.

ExtModeLogCtrlPanelDlg
string

Not available

Return a handle to the
External Mode Control
Panel dialog box or –1 if
the dialog box does not
exist.

ExtModeParamChangesPending
off, on

Not available

When the Simulink Coder
software is connected
to the target and
ExtModeBatchMode is
enabled, indicates whether
any parameters remain in
the queue of parameters
to be downloaded to the
target. More efficient than
ExtModeChangesPending,
because it checks for a
connection to the target.

15-101

15

Program Building, Interaction, and Debugging

External Mode Command-Line Parameters (Continued)
Parameter and Values

Dialog Box Equivalent

Description

ExtModeSkipDownloadWhenConnect
off, on

Not available

Connect to the target
program without
downloading parameters.

ExtModeTrigDelay
integer (0)

External Signal &
Triggering: Delay text
field

Specify the amount of time
(expressed in base rate
steps) that elapses between
a trigger occurrence and
the start of data collection.

ExtModeTrigDirection
string - rising, falling, either

External Signal &
Triggering: Direction
menu

Specify the direction in
which the signal must be
traveling when it crosses
the threshold value.

ExtModeTrigDuration
integer (1000)

External Signal &
Triggering: Duration
text field

Specify the number of
base rate steps for which
External mode is to log
data after a trigger event.

ExtModeTrigDurationFloating
string - integer (auto)

External Mode Control
Panel: Duration text field

Specify the duration for
floating scopes. If auto
is specified, the value of
ExtModeTrigDuration is
used.

ExtModeTrigElement
string - integer, any, last

External Signal &
Triggering: Element
text field

Specify the elements of the
input port of the specified
trigger block that can
cause the trigger to fire.

ExtModeTrigHoldOff
integer (0)

External Signal &
Triggering: Hold-off
text field

Specify the base rate steps
between when a trigger
event terminates and the
trigger is rearmed.

ExtModeTrigLevel
integer (0)

External Signal &
Triggering: Level text
field

Specify the threshold value
the trigger signal must
cross to fire the trigger.

15-102

Data Exchange

External Mode Command-Line Parameters (Continued)
Parameter and Values

Dialog Box Equivalent

Description

ExtModeTrigMode
string - normal, oneshot

External Signal &
Triggering: Mode menu

Specify whether the trigger
is to rearm automatically
after each trigger event or
whether only one buffer of
data is to be collected each
time the trigger is armed.

ExtModeTrigPort
string - integer (1), last

External Signal &
Triggering: Port text
field

Specify the input port of
the specified trigger block
for which elements can
cause the trigger to fire.

ExtModeTrigType
string - manual, signal

External Signal &
Triggering: Source menu

Specify whether to start
logging data when the
trigger is armed or when
a specified trigger signal
satisfies trigger conditions.

ExtModeUploadStatus
string - inactive, armed,
uploading

Not available

Return the status of the
External mode upload
mechanism — inactive,
armed, or uploading.

ExtModeWriteAllDataToWs
off, on

External Data Archiving:
Write intermediate
results to workspace
check box

Write all intermediate
results to the workspace.

External Mode Limitations
• “Limitation on Changing Parameters” on page 15-104
• “Limitation on Mixing 32-bit and 64-bit Architectures” on page 15-105
• “Limitation on Uploading Data” on page 15-105
• “Limitation on Uploading Variable-Size Signals” on page 15-105
• “Limitation on Archiving Data” on page 15-105

15-103

15

Program Building, Interaction, and Debugging

• “Limitation on Scopes in Referenced Models” on page 15-105
Limitation on Changing Parameters. In general, you cannot change a
parameter if doing so results in a change in the structure of the model. For
example, you cannot change
• The number of states, inputs, or outputs of any block
• The sample time or the number of sample times
• The integration algorithm for continuous systems
• The name of the model or of any block
• The parameters to the Fcn block
If you cause any of these changes to the block diagram, then you must rebuild
the program with newly generated code.
However, you can change parameters in transfer function and state space
representation blocks in specific ways:
• The parameters (numerator and denominator polynomials) for the Transfer
Fcn (continuous and discrete) and Discrete Filter blocks can be changed (as
long as the number of states does not change).
• Zero entries in the State-Space and Zero Pole (both continuous and discrete)
blocks in the user-specified or computed parameters (that is, the A, B,
C, and D matrices obtained by a zero-pole to state-space transformation)
cannot be changed once external simulation is started.
• In the State-Space block, if you specify the matrices in the controllable
canonical realization, then all changes to the A, B, C, D matrices that
preserve this realization and the dimensions of the matrices are allowed.
If the Simulink block diagram does not match the external program, the
Simulink engine displays an error informing you that the checksums do not
match (that is, the model has changed since you generated code). This means
that you must rebuild the program from the new block diagram (or reload
another one) to use External mode.
If the external program is not running, the Simulink engine displays an error
informing you that it cannot connect to the external program.

15-104

Data Exchange

Limitation on Mixing 32-bit and 64-bit Architectures. When you use
External mode, the machine running the Simulink product and the machine
running the target executable must have matching bit architectures, either
32-bit or 64-bit. This is because the Simulink Coder software varies a model’s
checksum based on whether it is configured for a 32-bit or 64-bit platform.
If you attempt to connect from a 32-bit machine to a 64-bit machine or vice
versa, the External mode connection fails.
Limitation on Uploading Data. External mode does not support uploading
data values for fixed-point or enumerated types into workspace parameters.
Limitation on Uploading Variable-Size Signals. External mode does not
support uploading variable-size signals for the following targets:
• xPC Target
• Texas Instruments C2000™
Limitation on Archiving Data. External mode supports the Scope and
To Workspace blocks for archiving data to disk. However, External mode
does not support scopes other than the Scope block for archiving data. For
example, you cannot use Floating Scope blocks or Signal and Scope Manager
viewer objects to archive data in External mode.
Limitation on Scopes in Referenced Models. In a model hierarchy, if the
top model simulates in External mode and a referenced model simulates in
Normal or Accelerator mode, scopes in the referenced model do not display.
However, if the top model is changed to simulate in Normal mode, the behavior
of scopes in the referenced models differs between Normal and Accelerator
mode. Scopes in a referenced model simulating in Normal mode display, while
scopes in a referenced model simulating in Accelerator mode do not display.

Logging
• “Log Data for Analysis” on page 15-106
• “About Logging to MAT-Files” on page 15-115
• “Configure State, Time, and Output Logging” on page 15-116

15-105

15

Program Building, Interaction, and Debugging

• “Log Data with Scope and To Workspace Blocks” on page 15-117
• “Log Data with To File Blocks” on page 15-118
• “Data Logging Differences Between Single- and Multitasking” on page
15-118

Log Data for Analysis
• “About Logging Data” on page 15-106
• “Data Logging During Simulation” on page 15-107
• “Data Logging from Generated Code” on page 15-111
About Logging Data. Simulink Coder MAT-file data logging facility
enables a generated program to save system states, outputs, and simulation
time at each model execution time step. The data is written to a MAT-file,
named (by default) model.mat, where model is the name of your model. In
this example, data generated by the model rtwdemo_f14 is logged to the file
rtwdemo_f14.mat. Refer to “Build a Generic Real-Time Program” on page
15-14 for instructions on setting up rtwdemo_f14 in a working folder if you
have not done so already.
To configure data logging, click Data Import/Export in the center pane
of the Model Explorer. The process is the same as configuring a Simulink
model to save output to the MATLAB workspace. For each workspace
return variable you define and enable, the Simulink Coder software defines
a parallel MAT-file variable. For example, if you save simulation time to
the variable tout, your generated program logs the same data to a variable
named rt_tout. You can change the prefix rt_ to a suffix (_rt), or eliminate
it entirely. You do this by selecting Code Generation in the center pane of
the Model Explorer, then clicking the Interface tab.

15-106

Data Exchange

Note Simulink lets you log signal data from anywhere in a model via the
Log signal data option in the Signal Properties dialog box (accessed via
context menu by right-clicking signal lines). The Simulink Coder software
does not use this method of signal logging in generated code. To log signals
in generated code, you must either use the Data Import/Export options
described below or include To File or To Workspace blocks in your model.
In this example, you modify the rtwdemo_f14 model so that the generated
program saves the simulation time and system outputs to the file
rtwdemo_f14.mat. Then you load the data into the MATLAB workspace and
plot simulation time against one of the outputs. The rtwdemo_f14 model
should be open and configured as described in “Build a Generic Real-Time
Program” on page 15-14.
Data Logging During Simulation. To use the data logging feature:
1 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
2 In the Model Hierarchy pane, click the + sign preceding the model name

to reveal its components.
3 Click Configuration (Active) in the left pane.
4 Click Data Import/Export in the center pane. The Data Import/Export

pane, which appears at the right, lets you specify which outport data is to
be saved to the workspace and what variable names to use for it.
5 Select the Time option. This tells Simulink to save time step data during

simulation as a variable named tout. You can enter a different name to
distinguish different simulation runs (for example using different step
sizes), but take the default for this example. Selecting Time enables the
Simulink Coder code generator to create code that logs the simulation time
to a MAT-file.
6 Select the Output option. This tells Simulink to save output signal data

during simulation as a variable named yout. Selecting Output enables
the Simulink Coder code generator to create code that logs the root Output
blocks (Angle of Attack and Pilot G Force) to a MAT-file.

15-107

15

Program Building, Interaction, and Debugging

Note The sort order of the yout array is based on the port number of the
Outport blocks, starting with 1. Angle of Attack and Pilot G Force are
logged to yout(:,1) and yout(:,2), respectively.

15-108

Data Exchange

7 If any other options are enabled, clear them. Set Decimation to 1 and

Format to Array. The figure below shows the dialog.

15-109

15

Program Building, Interaction, and Debugging

8 Click Apply to register your changes.
9 Save the model.
10 Open the Pilot G Force Scope block of the model, then run the model by

choosing Simulation > Run in the model window. The resulting Pilot G
Force scope display is shown below.

11 Verify that the simulation time and outputs have been saved to the

MATLAB workspace in MAT-files. At the MATLAB prompt, type:
whos *out

Simulink displays:
Name
tout
yout

15-110

Size
601x1
601x2

Bytes
4808
9616

Class Attributes
double
double

Data Exchange

12 Verify that Pilot G Force was logged by plotting simulation time versus

that variable. At the MATLAB prompt, type:
plot(tout,yout(:,2))

The resulting plot is shown below.

Data Logging from Generated Code. In the second part of this example,
you build and run a Simulink Coder executable of the rtwdemo_f14 model that
outputs a MAT-file containing the simulation time and outputs you previously
examined. Even though you have already generated code for the rtwdemo_f14
model, you must now regenerate that code because you have changed the
model by enabling data logging. The steps below explain this procedure.
To avoid overwriting workspace data with data from simulation runs, the
Simulink Coder code generator modifies identifiers for variables logged by
Simulink. You can control these modifications from the Model Explorer:
1 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
2 In the Model Hierarchy pane, click the + sign preceding the model name

to reveal its components.

15-111

15

Program Building, Interaction, and Debugging

3 Click Configuration (Active) in the left pane.
4 In the center pane, click Code Generation. The Code Generation pane

appears to the right.
5 Click the Interface tab.
6 Set MAT-file variable name modifier to _rt. This adds the suffix _rt

to each variable that you selected to be logged in the first part of this
example (tout, yout).

15-112

Data Exchange

7 Clear the Generate code only check box, if it is currently selected. The

pane should look like this:

8 Click Apply to register your changes.
9 Save the model.
10 To generate code and build an executable, click the Build button.
11 When the build concludes, run the executable with the command:

!rtwdemo_f14

15-113

15

Program Building, Interaction, and Debugging

12 The program now produces two message lines, indicating that the MAT-file

has been written.
** starting the model **
** created rtwdemo_f14.mat **
13 Load the MAT-file data created by the executable and look at the workspace

variables from simulation and the generated program by typing:
load rtwdemo_f14.mat
whos tout* yout*

Simulink displays:
Name
tout
tout_rt
yout
yout_rt

Size
601x1
601x1
601x2
601x2

Bytes
4808
4808
9616
9616

Class Attribute
double
double
double
double

Note that all arrays have the same number of elements.

15-114

Data Exchange

14 Observe that the variables tout_rt (time) and yout_rt (Pilot G Force

and Angle of Attack) have been loaded from the file. Plot Pilot G Force
as a function of time.
plot(tout_rt,yout_rt(:,2))

The resulting plot is identical to the plot you produced in step 10 of the
previous part of this example:

About Logging to MAT-Files
Multiple techniques are available by which a program generated by the
Simulink Coder software can save data to a MAT-file for analysis. See also
“Log Data for Analysis” on page 15-106 for a data logging tutorial.
Note Data logging is available only for targets that have access to a file
system. In addition, only the RSim target executables are capable of accessing
MATLAB workspace data.

15-115

15

Program Building, Interaction, and Debugging

Configure State, Time, and Output Logging
The Data Import/Export pane enables a generated program to save system
states, outputs, and simulation time at each model execution time step. The
data is written to a MAT-file, named (by default) model.mat.
Before using this data logging feature, you should learn how to configure
a Simulink model to return output to the MATLAB workspace. This is
discussed in “Export Simulation Data”.
For each workspace return variable that you define and enable, the code
generator defines a MAT-file variable. For example, if your model saves
simulation time to the workspace variable tout, your generated program logs
the same data to a variable named (by default) rt_tout.
The code generated by the code generator logs the following data:
• All root Outport blocks
The default MAT-file variable name for system outputs is rt_yout.
The sort order of the rt_yout array is based on the port number of the
Outport block, starting with 1.
• All continuous and discrete states in the model
The default MAT-file variable name for system states is rt_xout.
• Simulation time
The default MAT-file variable name for simulation time is rt_tout.
• “Override the Default MAT-File Name” on page 15-116
• “Override the Default MAT-File Variable Names” on page 15-117
• “Override the Default MAT-File Buffer Size” on page 15-117
Override the Default MAT-File Name. The MAT-file name defaults to
model.mat. To specify a different file name,
1 In the model window, select Simulation > Model Configuration

Parameters. The dialog box opens.
2 Click Code Generation.

15-116

Data Exchange

3 Append the following option to the existing text in the Make command

field:
OPTS="-DSAVEFILE=filename"

Override the Default MAT-File Variable Names. By default, the code
generation software prefixes the string rt_ to the variable names for system
outputs, states, and simulation time to form MAT-file variable names. To
change this prefix,
1 In the model window, select Simulation > Model Configuration

Parameters. The dialog box opens.
2 Click Code Generation.
3 Select grt.tlc for System target file.
4 Select Code Generation > Interface
5 Select a prefix (rt_) or suffix (_rt) from the MAT-file variable name

modifier field, or choose none for no prefix (other targets may or may
not have this option).
Override the Default MAT-File Buffer Size. The size of the buffer for
MAT-file data logging defaults to 1024 bytes. To specify a different buffer size,
1 In the model window, select Simulation > Model Configuration

Parameters. The dialog box opens.
2 Click Code Generation.
3 Append the following option to the existing text in the Make command

field:
OPTS="-DDEFAULT_BUFFER_SIZE=n"

where n specifies a buffer size in bytes.

Log Data with Scope and To Workspace Blocks
The code generated by the code generator also logs data from these sources:

15-117

15

Program Building, Interaction, and Debugging

• All Scope blocks that have the Save data to workspace parameter enabled
You must specify the variable name and data format in each Scope block’s
dialog box.
• All To Workspace blocks in the model
You must specify the variable name and data format in each To Workspace
block’s dialog box.
The variables are written to model.mat, along with any variables logged from
the Workspace I/O pane.

Log Data with To File Blocks
You can also log data to a To File block. The generated program creates a
separate MAT-file (distinct from model.mat) for each To File block in the
model. The file contains the block’s time and input variable(s). You must
specify the filename, variable names, decimation, and sample time in the To
File block’s dialog box.
Note Models referenced by Model blocks do not perform data logging in
that context except for states, which you can include in the state logged for
top models. Code generated by the Simulink Coder software for referenced
models does not perform data logging to MAT-files.

Data Logging Differences Between Single- and Multitasking
When logging data in single-tasking and multitasking systems, you will notice
differences in the logging of
• Noncontinuous root Outport blocks
• Discrete states
In multitasking mode, the logging of states and outputs is done after the first
task execution (and not at the end of the first time step). In single-tasking
mode, the code generated by the build procedure logs states and outputs after
the first time step.

15-118

Data Exchange

See Data Logging in Single-Tasking and Multitasking Model Execution for
more details on the differences between single-tasking and multitasking data
logging.
Note The rapid simulation target (RSim) provides enhanced logging options.
See “Rapid Simulations” on page 12-2 for more information.

Parameter Tuning
• “Tunable Parameter Storage” on page 15-119
• “Tunable Parameter Storage Classes” on page 15-121
• “Declare Tunable Parameters” on page 15-124
• “Tunable Expressions” on page 15-128
• “Linear Block Parameter Tunability” on page 15-132
• “Tunable Workspace Parameter Data Type Considerations” on page 15-133
• “Tune Parameters from the Command Line” on page 15-135
• “Interfaces for Tuning Parameters” on page 15-137

Tunable Parameter Storage
A tunable parameter is a block parameter whose value can be changed at
run-time. A tunable parameter is inherently noninlined. Consequently, when
Inlined parameters is off, all parameters are members of model_P, and thus
are tunable. A tunable expression is an expression that contains one or more
tunable parameters.
When you declare a parameter tunable, you control whether or not the
parameter is stored within model_P. You also control the symbolic name of
the parameter in the generated code.
When you declare a parameter tunable, you specify
• The storage class of the parameter.

15-119

15

Program Building, Interaction, and Debugging

The storage class property of a parameter specifies how the Simulink Coder
product declares the parameter in generated code.
The term “storage class,” as used in the Simulink Coder product, is not
synonymous with the term storage class specifier, as used in the C language.
• A storage type qualifier, such as const or volatile. This is simply a string
that is included in the variable declaration.
• (Implicitly) the symbolic name of the variable or field in which the
parameter is stored. The Simulink Coder product derives variable and field
names from the names of tunable parameters.
The Simulink Coder product generates a variable or struct storage
declaration for each tunable parameter. Your choice of storage class controls
whether the parameter is declared as a member of model_P or as a separate
global variable.
You can use the generated storage declaration to make the variable visible
to external legacy code. You can also make variables declared in your code
visible to the generated code. You are responsible for linking your code to
generated code modules.
You can use tunable parameters or expressions in your root model and
in masked or unmasked subsystems, subject to certain restrictions. (See
“Tunable Expressions” on page 15-128.)
Override Inlined Parameters for Tuning. When the Inline parameters
option is selected, you can use the Model Parameter Configuration dialog box
to remove individual parameters from inlining and declare them to be tunable.
This allows you to improve overall efficiency by inlining most parameters,
while at the same time retaining the flexibility of run-time tuning for selected
parameters. Another way you can achieve the same result is by using
Simulink data objects; see “Parameters” on page 7-10 for specific details.
The mechanics of declaring tunable parameters are discussed in “Declare
Tunable Parameters” on page 15-124.

15-120

Data Exchange

Tunable Parameter Storage Classes
The Simulink Coder product defines four storage classes for tunable
parameters. You must declare a tunable parameter to have one of the
following storage classes:
• SimulinkGlobal (Auto): This is the default storage class. The Simulink
Coder product stores the parameter as a member of model_P. Each member
of model_P is initialized to the value of the corresponding workspace
variable at code generation time.
• ExportedGlobal: The generated code instantiates and initializes the
parameter and model.h exports it as a global variable. An exported global
variable is independent of the model_P data structure. Each exported
global variable is initialized to the value of the corresponding workspace
variable at code generation time.
• ImportedExtern: model_private.h declares the parameter as an extern
variable. Your code must supply the variable definition and initializer.
• ImportedExternPointer: model_private.h declares the variable as an
extern pointer. Your code must supply the pointer variable definition
and initializer, if any.
The generated code for model.h includes model_private.h to make the
extern declarations available to subsystem files.
As an example of how the storage class declaration affects the code generated
for a parameter, consider the next figure.

15-121

15

Program Building, Interaction, and Debugging

The workspace variable Kp sets the gain of the Gain1 block. Assume that
the value of Kp is 3.14. The following table shows the variable declarations
and the code generated for the gain block when Kp is declared as a tunable
parameter. An example is shown for each storage class.
Note The Simulink Coder product uses column-major ordering for
two-dimensional signal and parameter data. When interfacing your
hand-written code to such signals or parameters by using ExportedGlobal,
ImportedExtern, or ImportedExternPointer declarations, make sure that
your code observes this ordering convention.
The symbolic name Kp is preserved in the variable and field names in the
generated code.

15-122

Data Exchange

Storage Class
SimulinkGlobal
(Auto)

Generated Variable Declaration and Code
typedef struct _Parameters_tunable_sin
Parameters_tunable_sin;
struct _Parameters_tunable_sin {
real_T Kp;
};
Parameters_tunable_sin tunable_sin_P = {
3.14
};
.
.
tunable_sin_Y.Out1 = rtb_u *
tunable_sin_P.Kp;

ExportedGlobal
real_T Kp = 3.14;
.
.
tunable_sin_Y.Out1 = rtb_u * Kp;
ImportedExtern
extern real_T Kp;
.
.
tunable_sin_Y.Out1 = rtb_u * Kp;
ImportedExtern
Pointer

extern real_T *Kp;
.
.
tunable_sin_Y.Out1 = rtb_u * (*Kp);

15-123

15

Program Building, Interaction, and Debugging

Declare Tunable Parameters
• “Declare Workspace Variables as Tunable Parameters” on page 15-124
• “Declare New Tunable Parameters” on page 15-124
• “Declare Tunable Parameters Using Configuration Parameter Dialog” on
page 15-125
• “Select Workspace Variables” on page 15-126
• “Create New Tunable Parameters” on page 15-127
• “Set Tunable Parameter Properties” on page 15-128
• “Remove Unused Tunable Parameters” on page 15-128
Declare Workspace Variables as Tunable Parameters. To declare
tunable parameters,
1 Open the Model Parameter Configuration dialog box.
2 In the Source list pane, select one or more variables.
3 Click Add to table . The variables then appear as tunable parameters in

the Global (tunable) parameters pane.
4 Select a parameter in the Global (tunable) parameters pane.
5 Select a storage class from the Storage class menu.
6 Optionally, select (or enter) a storage type qualifier, such as const or

volatile for the parameter.
7 Click Apply, or click OK to apply changes and close the dialog box.

Declare New Tunable Parameters. To declare tunable parameters,
1 Open the Model Parameter Configuration dialog box.
2 In the Global (tunable) parameters pane, click New.
3 Specify a name for the parameter.

15-124

Data Exchange

4 Select a storage class from the Storage class menu.
5 Optionally, select (or enter) a storage type qualifier, such as const or

volatile for the parameter.
6 Click Apply, or click OK to apply changes and close the dialog box.

Declare Tunable Parameters Using Configuration Parameter Dialog.
The Model Parameter Configuration dialog box lets you select base workspace
variables and declare them to be tunable parameters in the current model.
Using controls in the dialog box, you move variables from a source list to a
global (tunable) parameter list for a model.
To open the dialog box,
1 Select the Inline parameters check box on the Optimization > Signals

and Parameters pane of the Configuration Parameters dialog box. This
activates a Configure button, as shown below.

2 Click Configure to open the Model Configuration Parameter dialog box.

15-125

15

Program Building, Interaction, and Debugging

Note The Model Configuration Parameter dialog box cannot tune parameters
within referenced models. See “Parameterize Model References” for tuning
techniques that work with referenced models.
Select Workspace Variables. The Source list pane displays a menu and
a scrolling table of numerical workspace variables. To select workspace
variables,
1 From the menu, select the source of variables you want listed.

15-126

To List...

Choose...

All variables in the MATLAB
workspace that have numeric
values

MATLAB workspace

Only variables in the MATLAB
workspace that have numeric
values and are referenced by the
model

Referenced workspace
variables

Data Exchange

A list of workspace variables appear in the Source List pane.
2 Select one or more variables from the source list. This enables the Add

to table button.
3 Click Add to table to add the selected variables to the tunable parameters

list in the Global (tunable) parameters pane. In the Source list, the
names of variables added to the tunable parameters list are displayed in
bold type (see the preceding figure).
Note If you selected a variable with a name that matches a block
parameter that is not tunable and you click Add to table , a warning
appears during simulation and code generation.
To update the list of variables to reflect the current state of the workspace,
at any time, click Refresh list . For example, you might use Refresh list if
you define or remove variables in the workspace while the Model Parameter
Configuration dialog box is open.
Create New Tunable Parameters. To create a new tunable parameter,
1 In the Global (tunable) parameters pane, click New.
2 In the Name field, enter a name for the parameter.

If you enter a name that matches the name of a workspace variable in
the Source list pane, that variable is declared tunable and appears in
italics in the Source list.
3 Click Apply.

The model does not need to be using a parameter before you create it. You can
add references to the parameter later.
Note If you edit the name of an existing variable in the list, you actually
create a new tunable variable with the new name. The previous variable is
removed from the list and loses its tunability (that is, it is inlined).

15-127

15

Program Building, Interaction, and Debugging

Set Tunable Parameter Properties. To set the properties of tunable
parameters listed in the Global (tunable) parameters pane, select a
parameter and then specify a storage class and, optionally, a storage type
qualifier.
Property

Description

Storage class

Select one of the following to be used for code
generation:
• SimulinkGlobal (Auto)
• ExportedGlobal
• ImportedExtern
• ImportedExternPointer
See “Tunable Parameter Storage Classes” on
page 15-121 for definitions.

Storage type qualifier

For variables with any storage class except
SimulinkGlobal (Auto), you can add a
qualifier (such as const or volatile) to the

generated storage declaration. To do so, you
can select a predefined qualifier from the list
or add qualifiers not in the list. The code
generator does not check the storage type
qualifier for validity, and includes the qualifier
string in the generated code without checking
syntax .
Remove Unused Tunable Parameters. To remove unused tunable
parameters from the table in the Global (tunable) parameters pane, click
Remove. All removed variables are inlined if the Inlined parameters
option is enabled.

Tunable Expressions
• “Tunable Expressions in Masked Subsystems” on page 15-129
• “Tunable Expression Limitations” on page 15-131

15-128

Data Exchange

The Simulink Coder product supports the use of tunable variables in
expressions. An expression that contains one or more tunable parameters is
called a tunable expression.
Tunable Expressions in Masked Subsystems. Tunable expressions are
allowed in masked subsystems. You can use tunable parameter names or
tunable expressions in a masked subsystem dialog box. When referenced in
lower-level subsystems, such parameters remain tunable.
As an example, consider the masked subsystem in the next figure. The
masked variable k sets the gain parameter of theGain.

Suppose that the base workspace variable b is declared tunable with
SimulinkGlobal (Auto) storage class. The next figure shows the tunable
expression b*3 in the subsystem’s mask dialog box.

Tunable Expression in Subsystem Mask Dialog Box

The Simulink Coder product produces the following output computation for
theGain. The variable b is represented as a member of the global parameters
structure, model_P. (For clarity in showing the individual Gain block
computation, expression folding is off in this example.)
/* Gain: '/theGain' */

15-129

15

Program Building, Interaction, and Debugging

rtb_theGain_C = rtb_SineWave_n * ((subsys_mask_P.b * 3.0));
/* Outport: '/Out1' */
subsys_mask_Y.Out1 = rtb_theGain_C;

As this example shows, for GRT targets, the parameter structure is mangled
to create the structure identifier model_P (subject to the identifier length
constraint). This is done to avoid namespace clashes in combining code from
multiple models using model reference. ERT-based targets provide ways to
customize identifier names.
When expression folding is on, the above code condenses to
/* Outport: '/Out1' incorporates:
*

Gain: '/theGain'

*/
subsys_mask_Y.Out1 = rtb_SineWave_n * ((subsys_mask_P.b * 3.0));

Expressions that include variables that were declared or modified in mask
initialization code are not tunable.
As an example, consider the subsystem above, modified as follows:
• The mask initialization code is
t = 3 * k;

• The parameter k of the myGain block is 4 + t.
• Workspace variable b = 2. The expression b * 3 is plugged into the mask
dialog box as in the preceding figure.
Since the mask initialization code can run only once, k is evaluated at code
generation time as
4 + (3 * (2 * 3) )

The Simulink Coder product inlines the result. Therefore, despite the fact
that b was declared tunable, the code generator produces the following output
computation for theGain. (For clarity in showing the individual Gain block
computation, expression folding is off in this example.)

15-130

Data Exchange

/* Gain Block: /theGain */
rtb_temp0 *= (22.0);

Tunable Expression Limitations. Currently, there are certain limitations
on the use of tunable variables in expressions. When an unsupported
expression is encountered during code generation a warning is issued and the
equivalent numeric value is generated in the code. The limitations on tunable
expressions are
• Complex expressions are not supported, except where the expression is
simply the name of a complex variable.
• The use of certain operators or functions in expressions containing tunable
operands is restricted. Restrictions are applied to four categories of
operators or functions, classified in the following table:
Category

Operators or Functions

1

+ - .* ./ < > <= >= == ~= & |

2

* /

3

abs, acos, asin, atan, atan2, boolean, ceil, cos, cosh,
exp, floor, log, log10, sign, sin, sinh, sqrt, tan, tanh,

4

single, int8, int16, int32, uint8, uint16, uint32

5

: .^ ^ [] {} .

\ .\ ' .'

; ,

The rules applying to each category are as follows:

-

Category 1 is unrestricted. These operators can be used in tunable
expressions with any combination of scalar or vector operands.

-

Category 2 operators can be used in tunable expressions where at least
one operand is a scalar. That is, scalar/scalar and scalar/matrix operand
combinations are supported, but not matrix/matrix.

-

Category 3 lists all functions that support tunable arguments. Tunable
arguments passed to these functions retain their tunability. Tunable
arguments passed to any other functions lose their tunability.

-

Category 4 lists the casting functions that do not support tunable
arguments. Tunable arguments passed to these functions lose their
tunability.

15-131

15

Program Building, Interaction, and Debugging

Note The Simulink Coder product casts values using MATLAB
typecasting rules. The MATLAB typecasting rules are different from C
code typecasting rules. For example, using the MATLAB typecasting
rules, int8(3.7) returns the result 4, while in C code int8(3.7) returns
the result 3. See “Data Type Conversion” for more information on
MATLAB typecasting.

-

Category 5 operators are not supported.

• Expressions that include variables that were declared or modified in mask
initialization code are not tunable.
• The Fcn block does not support tunable expressions in code generation.
• Model workspace parameters can take on only the Auto storage class, and
thus are not tunable. See “Parameterize Model References” for tuning
techniques that work with referenced models.
• Non-double expressions are not supported.
• Blocks that access parameters only by address support the use of tunable
parameters, if the parameter expression is a simple variable reference.
When an operation such as a data type conversion or a math operation
is applied, the Simulink Coder product creates a nontrivial expression
that cannot be accessed by address, resulting in an error during the build
process.

Linear Block Parameter Tunability
The following blocks have a Realization parameter that affects the
tunability of their parameters:
• Transfer Fcn
• State-Space
• Discrete State-Space
The Realization parameter must be set by using the MATLAB set_param
function, as in the following example.
set_param(gcb,'Realization','auto')

15-132

Data Exchange

The following values are defined for the Realization parameter:
• general: The block’s parameters are preserved in the generated code,
permitting parameters to be tuned.
• sparse: The block’s parameters are represented in the code by transformed
values that increase the computational efficiency. Because of the
transformation, the block’s parameters are no longer tunable.
• auto: This setting is the default. A general realization is used if one or
more of the block’s parameters are tunable. Otherwise sparse is used.
Note To tune the parameter values of a block of one of the above types
without restriction during an External mode simulation, you must set
Realization to general.
Code Reuse for Subsystems with Mask Parameters. The Simulink
Coder product can generate reusable (reentrant) code for a model containing
identical atomic subsystems. Selecting the Reusable function option for
Function packaging enables such code reuse, and causes a single function
with arguments to be generated that is called when any of the identical
atomic subsystem executes. See “Subsystems” for details and restrictions on
the use of this option.
Mask parameters become arguments to reusable functions. However, for
reuse to occur, each instance of a reusable subsystem must declare the same
set of mask parameters. If, for example subsystem A has mask parameters b
and K, and subsystem B has mask parameters c and K, then code reuse is not
possible, and the Simulink Coder product will generate separate functions
for A and B.

Tunable Workspace Parameter Data Type Considerations
If you are using tunable workspace parameters, you need to be aware of
potential issues regarding data types. A workspace parameter is tunable
when the following conditions exist:
• You select the Inline parameters option on the Optimization > Signals
and Parameters pane of the Configuration Parameters dialog box

15-133

15

Program Building, Interaction, and Debugging

• The parameter has a storage class other than Auto
When generating code for tunable workspace parameters, the Simulink Coder
product checks and compares the data types used for a particular parameter
in the workspace and in Block Parameter dialog boxes.
If...

The Simulink Coder Product...

The data types match

Uses that data type for the parameter in the
generated code.

You do not explicitly
specify a data type
other than double in
the workspace

Uses the data type specified by the block in
the generated code. If multiple blocks share a
parameter, they must all specify the same data
type. If the data type varies between blocks,
the product generates an error similar to the
following:
Variable 'K' is used in incompatible ways
in the dialog fields of the following:
cs_params/Gain, cs_params/Gain1. The
variable'value is being used both directly
and after a transformation. Only one of
these usages is permitted for any given
variable.

You explicitly specify
a data type other
than double in the
workspace

Uses the data type from the workspace for the
parameter. The block typecasts the parameter to
the block specific data type before using it.

Guidelines for Specifying Data Types. The following table provides
guidelines on specifying data types for tunable workspace parameters.

15-134

If You Want to...

Then Specify Data Types in...

Minimize memory usage (int8
instead of single)

The workspace explicitly

Avoid typecasting

Blocks only

Data Exchange

If You Want to...

Then Specify Data Types in...

Interface to legacy or custom code

The workspace explicitly

Use the same parameter for
multiple blocks that specify
different data types

The workspace explicitly

The Simulink Coder product enforces limitations on the use of data types
other than double in the workspace, as explained in “Limitations on
Specifying Workspace Data Types Explicitly” on page 15-135.
Limitations on Specifying Workspace Data Types Explicitly. When you
explicitly specify a data type other than double in the workspace, blocks
typecast the parameter to another data type. This is an issue for blocks that
use pointer access for their parameters. Blocks cannot use pointer access if
they need to typecast the parameter before using it (because of a data type
mismatch). Another case in which this occurs is for workspace variables with
bias or fractional slope. Two possible solutions to these problems are
• Remove the explicit data type specification in the workspace for parameters
used in such blocks.
• Modify the block so that it uses the parameter with the same data type
as specified in the workspace. For example, the Lookup Table block uses
the data types of its input signal to determine the data type that it uses
to access the X-breakpoint parameter. You can prevent the block from
typecasting the run-time parameter by converting the input signal to the
data type used for X-breakpoints in the workspace. (Similarly, the output
signal is used to determine the data types used to access the lookup table
Y data.)

Tune Parameters from the Command Line
When parameters are MATLAB workspace variables, the Model Parameter
Configuration dialog box is the recommended way to see or set the properties
of tunable parameters. In addition to that dialog box, you can also use
MATLAB get_param and set_param commands.

15-135

15

Program Building, Interaction, and Debugging

Note You can also use Simulink.Parameter objects for tunable parameters.
See “Configure Parameter Objects for Code Generation” on page 7-39 for
details.
The following commands return the tunable parameters and corresponding
properties:
• get_param(gcs, 'TunableVars')
• get_param(gcs, 'TunableVarsStorageClass')
• get_param(gcs, 'TunableVarsTypeQualifier')
The following commands declare tunable parameters or set corresponding
properties:
• set_param(gcs, 'TunableVars', str)
The argument str (string) is a comma-separated list of variable names.
• set_param(gcs, 'TunableVarsStorageClass', str)
The argument str (string) is a comma-separated list of storage class
settings.
The valid storage class settings are

-

Auto
ExportedGlobal
ImportedExtern
ImportedExternPointer

• set_param(gcs, 'TunableVarsTypeQualifier', str)
The argument str (string) is a comma-separated list of storage type
qualifiers.
The following example declares the variable k1 to be tunable, with storage
class ExportedGlobal and type qualifier const. The number of variables and
number of specified storage class settings must match. If you specify multiple
variables and storage class settings, separate them with a comma.

15-136

Data Exchange

set_param(gcs, 'TunableVars', 'k1')
set_param(gcs, 'TunableVarsStorageClass','ExportedGlobal')
set_param(gcs, 'TunableVarsTypeQualifier','const')

Other configuration parameters you can get and set are listed in “Parameter
Reference”.

Interfaces for Tuning Parameters
The Simulink Coder product includes
• Support for developing a Target Language Compiler API for tuning
parameters independent of External mode. See “Parameter Functions” in
the Target Language Compiler documentation for information.
• A C application program interface (API) for tuning parameters independent
of External mode. See “Data Interchange Using the C API” on page 15-137
for information.
• An interface for exporting ASAP2 files, which you customize to use
parameter objects. For details, see “ASAP2 Data Measurement and
Calibration” on page 15-174.

Data Interchange Using the C API
The C API allows you to write host-based or target-based code that interacts
with signals, states, root-level inputs/outputs, and parameters in your
target-based application code.
• “About Data Exchange and C API” on page 15-137
• “Generate C API Files” on page 15-138
• “Description of C API Files” on page 15-141
• “Use the C API in an Application” on page 15-160
• “C API Limitations” on page 15-173

About Data Exchange and C API
Some Simulink Coder applications must interact with signals, states,
root-level inputs/outputs, or parameters in the generated code for a model.
For example, calibration applications monitor and modify parameters. Signal

15-137

15

Program Building, Interaction, and Debugging

monitoring or data logging applications interface with signal, state, and
root-level input/output data. Using the Simulink Coder C API, you can build
target applications that log signals, states, and root-level inputs/outputs,
monitor signals, states, and root-level inputs/outputs, and tune parameters,
while the generated code executes.
The C API minimizes its memory footprint by sharing information common
to signals, states, root-level inputs/outputs, and parameters in smaller
structures. Signal, state, root-level input/output, and parameter structures
include an index into the structure map, allowing multiple signals, states,
root-level inputs/outputs, or parameters to share data.
When you configure a model to use the C API, the Simulink Coder
code generator generates two additional files, model_capi.c (or .cpp)
and model_capi.h, where model is the name of the model. The code
generator places the two C API files in the build folder, based on settings
in the Configuration Parameters dialog box. The C API source code file
contains information about global block output signals, states, root-level
inputs/outputs, and global parameters defined in the generated code model
source code. The C API header file is an interface header file between the
model source code and the generated C API. You can use the information in
these C API files to create your application. Among the files generated are
those shown in the next figure.

model.c

model.h

model.mdl
Generate code

Generated Files with C API Selected

Generate C API Files
To generate C API files for your model:

15-138

model_capi.c model_capi.h

Data Exchange

1 Select the C API interface for your model. There are two ways to select the

C API interface for your model, as described in the following sections.
• “Select C API with Configuration Parameters Dialog” on page 15-139
• “Select C API from the Command Line” on page 15-140
2 Generate code for your model.

After generating code, you can examine the files model_capi.c (or .cpp) and
model_capi.h in the model build folder.

Select C API with Configuration Parameters Dialog.
1 Open your model, and launch either the Configuration Parameters dialog

box or Model Explorer.
2 Go to the Code Generation > Interface pane and, in the Data exchange

section, select C API as the value for the Interface parameter. The
Generate C API for: signals, Generate C API for: parameters,
Generate C API for: states, and Generate C API for: root-level I/O
check boxes are displayed.

3 Select options:

• If you want to generate C API code for global block output signals, select
the Generate C API for: signals check box.
• If you want to generate C API code for global block parameters, select
the Generate C API for: parameters check box.
• If you want to generate C API code for discrete and continuous states,
select the Generate C API for: states check box.
• If you want to generate C API code for root-level inputs and outputs,
select the Generate C API for: root-level I/O check box.

15-139

15

Program Building, Interaction, and Debugging

If you select all four check boxes, support for accessing signals, parameters,
states, and root-level I/O will appear in the C API generated code.
Select C API from the Command Line. From the MATLAB command line,
you can use the set_param function to select or clear the C API check boxes
on the Interface pane of the Configuration Parameters dialog box. At the
MATLAB command line, enter one or more of the following commands, where
modelname is the name of your model.
To select Generate C API for: signals, enter:
set_param('modelname','RTWCAPISignals','on')

To clear Generate C API for: signals, enter:
set_param('modelname','RTWCAPISignals','off')

To select Generate C API for: parameters, enter:
set_param('modelname','RTWCAPIParams','on')

To clear Generate C API for: parameters, enter:
set_param('modelname','RTWCAPIParams','off')

To select Generate C API for: states, enter:
set_param('modelname','RTWCAPIStates','on')

To clear Generate C API for: states, enter:
set_param('modelname','RTWCAPIStates','off')

To select Generate C API for: root-level I/O, enter:
set_param('modelname','RTWCAPIRootIO','on')

To clear Generate C API for: root-level I/O, enter:
set_param('modelname','RTWCAPIRootIO','off')

15-140

Data Exchange

Generate C API and ASAP2 Files. The C API and ASAP2 interfaces
are not mutually exclusive. Although the Interface option on the Code
Generation > Interface pane of the Configuration Parameters dialog box
allows you to select either the ASAP2 or C API interface, you can instruct
the Simulink Coder code generator to generate files for both interfaces. For
details, see “Generate ASAP2 and C API Files” on page 15-188.

Description of C API Files
• “About C API Files” on page 15-141
• “Structure Arrays Generated in C API Files” on page 15-144
• “Generate Example C API Files” on page 15-146
• “C API Signals” on page 15-149
• “C API States” on page 15-153
• “C API Root-Level Inputs and Outputs” on page 15-154
• “C API Parameters” on page 15-156
• “Map C API Data Structures to rtModel” on page 15-158
About C API Files. The model_capi.c (or .cpp) file provides external
applications with a consistent interface to model data. Depending on your
configuration settings, the data could be a signal, state, root-level input or
output, or parameter. In this document, the term data item refers to either
a signal, a state, a root-level input or output, or a parameter. The C API
uses structures that provide an interface to the data item properties. The
interface packages the properties of each data item in a data structure. If the
model contains multiple data items, the interface generates an array of data
structures. The members of a data structure map to data properties.
To interface with data items, an application requires the following properties
for each data item:
• Name
• Block path
• Port number (for signals and root-level inputs/outputs only)

15-141

15

Program Building, Interaction, and Debugging

• Address
• Data type information: native data type, data size, complexity, and other
attributes
• Dimensions information: number of rows, number of columns, and data
orientation (scalar, vector, matrix, or n-dimensional)
• Fixed-point information: slope, bias, scale type, word length, exponent,
and other attributes
• Sample-time information (for signals, states, and root-level inputs/outputs
only): sample time, task identifier, frames
As illustrated in the next figure, the properties of data item A, for example,
are located in data structure DS_A. The properties of data item B are located
in data structure DS_B.

DS_A
Property 1
Property 2
Pointer
Property 3
...

DS_B
Property 1
Property 2
Pointer
Property 3
...

Unique value located here
Shared value located in DS_C
Pointer value located here
Unique value located here

Unique value located here
Shared value located in DS_C
Pointer value located here
Unique value located here

DS_C
Shared value of Property 2
Shared values of other properties ...
Some property values can be unique to each data item, and there are some
property values that several data items can share in common. Name, for
example, has a unique value for each data item. The interface places the
unique property values directly in the structure for the data item. The name
value of data item A is in DS_A, and the name value of data item B is in DS_B.
But data type could be a property whose value several data items have in
common. The ability of some data items to share a property allows the C API
to have a reuse feature. In this case, the interface places only an index value

15-142

Data Exchange

in DS_A and an index value in DS_B. These indices point to a different data
structure, DS_C, that contains the actual data type value. The next figure
shows this scheme with more detail.

Array of Signal Structures
rtwCapi_Signals rtBlockSignals[]
{

Array of Data Type Structures

{

rtwCAPI_DataTypeMap rtDataTypeMap[]

...
blockPath

sys/blk1

signalName

signal1

portNumber

0

dataTypeIndex

0

...
},
{
...
blockPath

sys/blk2

signalName

signal2

portNumber

1

dataTypeIndex

0

{
{

These indices of
0 point to the first
element in the
rtDataTypeMap
array.

{
...
signalName

signal3

portNumber

0

dataTypeIndex

1

...
}
};

"real_T"

numElements

0

elemMapIndex

0

dataSize

sizeof(real_T)

slDataId

SS_DOUBLE

isComplex

0

isPointer

0

{

},

sys/blk3

"double"

mwName

};

...

blockPath

cName

cName

"int"

mwName

"int32_T"

numElements

0

elemMapIndex

0

dataSize

sizeof(int32_T)

slDataId

SS_INT32

...
}

The index of 1 points
to the second element
in the rtDataTypeMap
array.

};

15-143

15

Program Building, Interaction, and Debugging

The figure shows three signals. signal1 and signal2 share the same data
type, double. Instead of specifying this data type value in each signal data
structure, the interface provides only an index value, 0, in the structure.
"double" is described by entry 0 in the rtDataTypeMap array, which is
referenced by both signals. Additionally, property values can be shared
between signals, states, root-level inputs/outputs, and parameters, so states,
root-level inputs/outputs, and parameters also might reference the double
entry in the rtDataTypeMap array. This reuse of information reduces the
memory size of the generated interface.
Structure Arrays Generated in C API Files. As with data type, the
interface maps other common properties (such as address, dimension,
fixed-point scaling, and sample time) into separate structures and provides
an index in the structure for the data item. For a complete list of structure
definitions, refer to the file matlabroot/rtw/c/src/rtw_capi.h (where
matlabroot represents the root of your MATLAB installation folder). This file
also describes each member in a structure. The structure arrays generated
in the model_capi.c (or .cpp) file are of structure types defined in the
rtw_capi.h file. Here is a brief description of the structure arrays generated
in model_capi.c (or .cpp):
• rtBlockSignals is an array of structures that contains information about
global block output signals in the model. Each element in the array is of
type struct rtwCAPI_Signals. The members of this structure provide the
signal name, block path, block port number, address, and indices to the
data type, dimension, fixed-point, and sample-time structure arrays.
• rtBlockParameters is an array of structures that contains information
about the tunable block parameters in the model by block name
and parameter name. Each element in the array is of type struct
rtwCAPI_BlockParameters. The members of this structure provide the
parameter name, block path, address, and indices to data type, dimension,
and fixed-point structure arrays.
• rtBlockStates is an array of structures that contains information about
discrete and continuous states in the model. Each element in the array is
of type struct rtwCAPI_States. The members of this structure provide
the state name, block path, type (continuous or discrete), and indices to
the address, data type, dimension, fixed-point, and sample-time structure
arrays.

15-144

Data Exchange

• rtRootInputs is an array of structures that contains information about
root-level inputs in the model. Each element in the array is of type struct
rtwCAPI_Signals. The members of this structure provide the root-level
input name, block path, block port number, address, and indices to the data
type, dimension, fixed-point, and sample-time structure arrays.
• rtRootOutputs is an array of structures that contains information about
root-level outputs in the model. Each element in the array is of type struct
rtwCAPI_Signals. The members of this structure provide the root-level
output name, block path, block port number, address, and indices to the
data type, dimension, fixed-point, and sample-time structure arrays.
• rtModelParameters is an array of structures that contains information
about all workplace variables that one or more blocks or Stateflow charts
in the model reference as block parameters. Each element in the array is
of data type rtwCAPI_ModelParameters. The members of this structure
provide the variable name, address, and indices to data type, dimension,
and fixed-point structure arrays.
• rtDataAddrMap is an array of base addresses of signals, states, root-level
inputs/outputs, and parameters that appear in the rtBlockSignals,
rtBlockParameters, rtBlockStates, and rtModelParameters arrays.
Each element of the rtDataAddrMap array is a pointer to void (void*).
• rtDataTypeMap is an array of structures that contains information about
the various data types in the model. Each element of this array is of type
struct rtwCAPI_DataTypeMap. The members of this structure provide the
data type name, size of the data type, and information on whether or not
the data is complex.
• rtDimensionMap is an array of structures that contains information
about the various data dimensions in the model. Each element of this
array is of type struct rtwCAPI_DimensionMap. The members of this
structure provide information on the number of dimensions in the data,
the orientation of the data (whether it is scalar, vector, or a matrix), and
the actual dimensions of the data.
• rtFixPtMap is an array of structures that contains fixed-point information
about the signals, states, root-level inputs/outputs, and parameters. Each
element of this array is of type struct rtwCAPI_FixPtMap. The members
of this structure provide information about the data scaling, bias, exponent,
and whether or not the fixed-point data is signed. If the model does not
have fixed-point data (signal, state, root-level input/output, or parameter),

15-145

15

Program Building, Interaction, and Debugging

the Simulink Coder software assigns NULL or zero values to the elements of
the rtFixPtMap array.
• rtSampleTimeMap is an array of structures that contains sampling
information about the global signals, states, and root-level inputs/outputs
in the model. (This array contains no information about parameters.) Each
element of this array is of type struct rtwCAPI_SampleTimeMap. The
members of this structure provide information about the sample period,
offset, and whether or not the data is frame-based or sample-based.
Generate Example C API Files. The next three sections, “C API Signals”
on page 15-149, “C API States” on page 15-153, “C API Root-Level Inputs and
Outputs” on page 15-154, and “C API Parameters” on page 15-156, discuss
generated C API structures using the example model rtwdemo_capi as an
example. To generate code from the example model, do the following:
1 Open the model by clicking the rtwdemo_capi link above or by typing

rtwdemo_capi on the MATLAB command line. The model appears as

shown in the next figure.

15-146

Data Exchange

2 If you want to generate C API structures for root-level inputs/outputs

in rtwdemo_capi, open the Configuration Parameters dialog box, go to
the Code Generation > Interface pane, and make sure that the option
Generate C API for: root-level I/O is selected.

15-147

15

Program Building, Interaction, and Debugging

Note The setting of Generate C API for: root-level I/O must match
between the top model and the referenced model.
3 Generate code for the model by double-clicking Generate Code Using

Simulink Coder.
Note The C API code examples in the next four sections are generated with
C as the target language.
This model has three global block output signals that will appear in C API
generated code:
• top_sig1, which is a test point at the output of the Gain1 block in the
top model
• sig2_eg, which appears in the top model and is defined in the
base workspace as a Simulink.Signal object having storage class
ExportedGlobal

• bot_sig1, which appears in the submodel rtwdemo_capi_bot and is
defined as a Simulink.Signal object having storage class SimulinkGlobal
The model also has two discrete states that will appear in the C API generated
code:
• top_state, which is defined for the Delay1 block in the top model
• bot_state, which is defined for the Discrete Filter block in the submodel
The model has root-level inputs/outputs that will appear in the C API
generated code if you select the option Generate C API for: root-level I/O:
• Four root-level inputs, In1 through In4
• Six root-level outputs, Out1 through Out6
Additionally, the model has five global block parameters that will appear in C
API generated code:

15-148

Data Exchange

• Kp (top model Gain1 block and submodel Gain2 block share)
• Ki (submodel Gain3 block)
• p1 (lookup table lu1d)
• p2 (lookup table lu2d)
• p3 (lookup table lu3d)
C API Signals. The rtwCAPI_Signals structure captures signal information
including the signal name, address, block path, output port number, data
type information, dimensions information, fixed-point information, and
sample-time information.
Here is the section of code in rtwdemo_capi_capi.c that provides information
on C API signals for the top model in rtwdemo_capi:
/* Block output signal information */
static const rtwCAPI_Signals rtBlockSignals[] = {
/* addrMapIndex, sysNum, blockPath,
* signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
*/
{ 0, 0, "rtwdemo_capi/Gain1",
"top_sig1", 0, 0, 0, 0, 0 },
{ 1, 0, "rtwdemo_capi/lu2d",
"sig2_eg", 0, 0, 1, 0, 0 },
{
0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
}
};

15-149

15

Program Building, Interaction, and Debugging

Note To better understand the code, read the comments in the file. For
example, notice the comment that begins on the third line in the preceding
code. This comment lists the members of the rtwCAPI_Signals structure, in
order. This tells you the order in which the assigned values for each member
appear for a signal. In this example, the comment tells you that signalName
is the fourth member of the structure. The following lines describe the first
signal:
{ 0, 0, "rtwdemo_capi/Gain1",
"top_sig1", 0, 0, 0, 0, 0 },

From these lines you infer that the name of the first signal is top_sig1.
Each array element, except the last, describes one output port for a block
signal. The final array element is a sentinel, with all elements set to null
values. For example, examine the second signal, described by the following
code:
{ 1, 0, "rtwdemo_capi/lu2d",
"sig2_eg", 0, 0, 1, 0, 0 },

This signal, named sig2_eg, is the output signal of the first port of the block
rtwdemo_capi/lu2d. (This port is the first port because the zero-based index
for portNumber displayed on the second line is assigned the value 0.)
The address of this signal is given by addrMapIndex, which, in this example, is
displayed on the first line as 1. This provides an index into the rtDataAddrMap
array, found later in rtwdemo_capi_capi.c:
/* Declare Data Addresses statically */
static void* rtDataAddrMap[] = {
&rtwdemo_capi_B.top_sig1,

15-150

/* 0: Signal */

&sig2_eg[0],

/* 1: Signal */

&rtwdemo_capi_DWork.top_state,

/* 2: Discrete State */

&rtP_Ki,

/* 3: Model Parameter */

&rtP_Kp,

/* 4: Model Parameter */

&rtP_p1[0],

/* 5: Model Parameter */

&rtP_p2[0],

/* 6: Model Parameter */

&rtP_p3[0],

/* 7: Model Parameter */

Data Exchange

};

The index of 1 points to the second element in the rtDataAddrMap array.
From the rtDataAddrMap array, you can infer that the address of this signal
is &sig2_eg[0].
This level of indirection supports multiple code instances of the same model.
For multiple instances, the signal information remains constant, except for
the address. In this case, the model is a single instance. Therefore, the
rtDataAddrMap is declared statically. If you choose to generate reusable code,
an initialize function is generated that initializes the addresses dynamically
per instance. (For details on generating reusable code, see “Set Up Support for
Code Reuse” and “Entry Point Functions and Scheduling” in the Embedded
Coder documentation.)
The dataTypeIndex provides an index into the rtDataTypeMap array, found
later in rtwdemo_capi_capi.c, indicating the data type of the signal:
/* Data Type Map - use dataTypeMapIndex to access this structure */
static const rtwCAPI_DataTypeMap rtDataTypeMap[] = {
/* cName, mwName, numElements, elemMapIndex, dataSize, slDataId, *
* isComplex, isPointer */
{ "double", "real_T", 0, 0, sizeof(real_T), SS_DOUBLE, 0, 0 }
};

Because the index is 0 for sig2_eg, the index points to the first structure
element in the array. You can infer that the data type of the signal is double.
The value of isComplex is 0, indicating that the signal is not complex. Rather
than providing the data type information directly in the rtwCAPI_Signals
structure, a level of indirection is introduced. The indirection allows multiple
signals that share the same data type to point to one map structure, saving
memory for each signal.
The dimIndex (dimensions index) provides an index into the rtDimensionMap
array, found later in rtwdemo_capi_capi.c, indicating the dimensions of the
signal. Because this index is 1 for sig2_eg, the index points to the second
element in the rtDimensionMap array:
/* Dimension Map - use dimensionMapIndex to access elements of ths structure*/
static const rtwCAPI_DimensionMap rtDimensionMap[] = {
/* dataOrientation, dimArrayIndex, numDims, vardimsIndex */

15-151

15

Program Building, Interaction, and Debugging

{ rtwCAPI_SCALAR, 0, 2, 0 },
{ rtwCAPI_VECTOR, 2, 2, 0 },
...
};

From this structure, you can infer that this is a nonscalar signal having
a dimension of 2. The dimArrayIndex value, 2, provides an index into
rtDimensionArray, found later in rtwdemo_capi_capi.c:
/* Dimension Array- use dimArrayIndex to access elements of this array */
static const uint_T rtDimensionArray[] = {
1,

/* 0 */

1,

/* 1 */

2,

/* 2 */

...
};

The fxpIndex (fixed-point index) provides an index into the rtFixPtMap
array, found later in rtwdemo_capi_capi.c, indicating any fixed-point
information about the signal. Your code can use the scaling information
to compute the real-world value of the signal, using the equation V=SQ+B,
where V is “real-world” (that is, base-10) value, S is user-specified slope, Q is
“quantized fixed-point value” or “stored integer,” and B is user-specified bias.
(For details, see “Scaling” in the Fixed-Point Toolbox™ documentation.)
Because this index is 0 for sig2_eg, the signal has no fixed-point information.
A fixed-point map index of zero always means that the signal has no
fixed-point information.
The sTimeIndex (sample-time index) provides the index to the
rtSampleTimeMap array, found later in rtwdemo_capi_capi.c, indicating
task information about the signal. If you log multirate signals or conditionally
executed signals, the sampling information can be useful.
Note model_capi.c (or .cpp) includes rtw_capi.h. Any source file that
references the rtBlockSignals array also must include rtw_capi.h.

15-152

Data Exchange

C API States. The rtwCAPI_States structure captures state information
including the state name, address, block path, type (continuous or discrete),
data type information, dimensions information, fixed-point information, and
sample-time information.
Here is the section of code in rtwdemo_capi_capi.c that provides information
on C API states for the top model in rtwdemo_capi:
/* Block states information */
static const rtwCAPI_States rtBlockStates[] = {
/* addrMapIndex, contStateStartIndex, blockPath,
* stateName, pathAlias, dWorkIndex, dataTypeIndex, dimIndex,
* fixPtIdx, sTimeIndex, isContinuous
*/
{ 2, -1, "rtwdemo_capi/Delay1",
"top_state", "", 0, 0, 0, 0, 0, 0 },
{
0, -1, (NULL), (NULL), (NULL), 0, 0, 0, 0, 0, 0
}
};

Each array element, except the last, describes a state in the model. The final
array element is a sentinel, with all elements set to null values. In this
example, the C API code for the top model displays one state:
{ 2, -1, "rtwdemo_capi/Delay1",
"top_state", "", 0, 0, 0, 0, 0, 0 },

This state, named top_state, is defined for the block rtwdemo_capi/Delay1.
The value of isContinuous is zero, indicating that the state is discrete
rather than continuous. The other fields correspond to the like-named signal
equivalents described in “C API Signals” on page 15-149, as follows:
• The address of the signal is given by addrMapIndex, which, in this
example, is 2. This is an index into the rtDataAddrMap array, found
later in rtwdemo_capi_capi.c. Because the index is zero based,
2 corresponds to the third element in rtDataAddrMap, which is
&rtwdemo_capi_DWork.top_state.

15-153

15

Program Building, Interaction, and Debugging

• The dataTypeIndex provides an index into the rtDataTypeMap array, found
later in rtwdemo_capi_capi.c, indicating the data type of the parameter.
The value 0 corresponds to a double, noncomplex parameter.
• The dimIndex (dimensions index) provides an index into the
rtDimensionMap array, found later in rtwdemo_capi_capi.c. The value 0
corresponds to the first entry, which is { rtwCAPI_SCALAR, 0, 2, 0 }.
• The fixPtIndex (fixed-point index) provides an index into the rtFixPtMap
array, found later in rtwdemo_capi_capi.c, indicating any fixed-point
information about the parameter. As with the corresponding signal
attribute, a fixed-point map index of zero always means that the parameter
has no fixed-point information.
C API Root-Level Inputs and Outputs. The rtwCAPI_Signals structure
captures root-level input/output information including the input/output
name, address, block path, port number, data type information, dimensions
information, fixed-point information, and sample-time information. (This
structure also is used for block output signals, as previously described in “C
API Signals” on page 15-149.)
Here is the section of code in rtwdemo_capi_capi.c that provides information
on C API root-level inputs/outputs for the top model in rtwdemo_capi:
/* Root Inputs information */
static const rtwCAPI_Signals rtRootInputs[] = {
/* addrMapIndex, sysNum, blockPath,
* signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
*/
{ 3, 0, "rtwdemo_capi/In1",
"", 1, 0, 0, 0, 0 },
{ 4, 0, "rtwdemo_capi/In2",
"", 2, 0, 0, 0, 0 },
{ 5, 0, "rtwdemo_capi/In3",
"", 3, 0, 0, 0, 0 },
{ 6, 0, "rtwdemo_capi/In4",
"", 4, 0, 0, 0, 0 },

15-154

Data Exchange

{
0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
}
};
/* Root Outputs information */
static const rtwCAPI_Signals rtRootOutputs[] = {
/* addrMapIndex, sysNum, blockPath,
* signalName, portNumber, dataTypeIndex, dimIndex, fxpIndex, sTimeIndex
*/
{ 7, 0, "rtwdemo_capi/Out1",
"", 1, 0, 0, 0, 0 },
{ 8, 0, "rtwdemo_capi/Out2",
"", 2, 0, 0, 0, 0 },
{ 9, 0, "rtwdemo_capi/Out3",
"", 3, 0, 0, 0, 0 },
{ 10, 0, "rtwdemo_capi/Out4",
"", 4, 0, 0, 0, 0 },
{ 11, 0, "rtwdemo_capi/Out5",
"sig2_eg", 5, 0, 1, 0, 0 },
{ 12, 0, "rtwdemo_capi/Out6",
"", 6, 0, 1, 0, 0 },
{
0, 0, (NULL), (NULL), 0, 0, 0, 0, 0
}
};

For information about interpreting the values in the rtwCAPI_Signals
structure, see the previous section “C API Signals” on page 15-149.

15-155

15

Program Building, Interaction, and Debugging

C API Parameters. The rtwCAPI_BlockParameters and
rtwCAPI_ModelParameters structures capture parameter information
including the parameter name, block path (for block parameters), address,
data type information, dimensions information, and fixed-point information.
Each element in an rtBlockParameters or rtModelParameters array (except
the last element) corresponds to a tunable parameter in the model.
The setting of the Inline parameters option on the Optimization > Signals
and Parameters pane of the Configuration Parameters dialog box
determines how information is generated into the rtBlockParameters and
rtModelParameters arrays in model_capi.c (or .cpp), as follows:
• If you clear Inline parameters:

-

The rtBlockParameters array contains an entry for every modifiable
parameter of every block in the model.

-

The rtModelParameters array contains only Stateflow data of machine
scope. The Simulink Coder software assigns its elements only NULL or
zero values in the absence of such data.

• If you select Inline parameters:

-

The rtBlockParameters array is empty. The Simulink Coder software
assigns its elements only NULL or zero values.

-

The rtModelParameters array contains entries for all workspace
variables that are referenced as tunable Simulink block parameters or
Stateflow data of machine scope.

Here is the rtBlockParameters array that is generated by default in
rtwdemo_capi_capi.c:
/* Individual block tuning is not valid when inline parameters is *
* selected. An empty map is produced to provide a consistent

*

* interface independent

*

of inlining parameters.

*/
static const rtwCAPI_BlockParameters rtBlockParameters[] = {
/* addrMapIndex, blockPath,
* paramName, dataTypeIndex, dimIndex, fixPtIdx
*/
{
0, (NULL), (NULL), 0, 0, 0

15-156

Data Exchange

}
};

In this example, only the final, sentinel array element is generated, with all
members of the structure rtwCAPI_BlockParameters set to NULL and zero
values. This is because the Inline parameters option is selected by default
for the rtwdemo_capi example model. If you clear this check box, the block
parameters are generated in the rtwCAPI_BlockParameters structure.
Here is the rtModelParameters array that is generated by default in
rtwdemo_capi_capi.c:
/* Tunable variable parameters */
static const rtwCAPI_ModelParameters rtModelParameters[] = {
/* addrMapIndex, varName, dataTypeIndex, dimIndex, fixPtIndex */
{ 3, "Ki", 0, 0, 0 },
{ 4, "Kp", 0, 0, 0 },
{ 5, "p1", 0, 2, 0 },
{ 6, "p2", 0, 3, 0 },
{ 7, "p3", 0, 4, 0 },
{ 0, (NULL), 0, 0, 0 }
};

In this example, the rtModelParameters array contains entries for each
variable that is referenced as a tunable Simulink block parameter.
For example, the varName (variable name) of the fourth parameter is p2. The
other fields correspond to the like-named signal equivalents described in “C
API Signals” on page 15-149, as follows:
• The address of the fourth parameter is given by addrMapIndex, which,
in this example, is 6. This is an index into the rtDataAddrMap array,
found later in rtwdemo_capi_capi.c. Because the index is zero based,
6 corresponds to the seventh element in rtDataAddrMap, which is
&rtwP_p2[0].

15-157

15

Program Building, Interaction, and Debugging

• The dataTypeIndex provides an index into the rtDataTypeMap array, found
later in rtwdemo_capi_capi.c, indicating the data type of the parameter.
The value 0 corresponds to a double, noncomplex parameter.
• The dimIndex (dimensions index) provides an index into the
rtDimensionMap array, found later in rtwdemo_capi_capi.c. The value 3
corresponds to the fourth entry, which is { rtwCAPI_MATRIX_COL_MAJOR,
6, 2, 0 }.
• The fixPtIndex (fixed-point index) provides an index into the rtFixPtMap
array, found later in rtwdemo_capi_capi.c, indicating any fixed-point
information about the parameter. As with the corresponding signal
attribute, a fixed-point map index of zero always means that the parameter
has no fixed-point information.
Map C API Data Structures to rtModel. The real-time model data
structure encapsulates model data and associated information that describes
the model fully. When you select the C API feature and generate code, the
Simulink Coder code generator adds another member to the real-time model
data structure generated in model.h:
/*
* DataMapInfo:
* The following substructure contains information regarding
* structures generated in the model's C API.
*/
struct {
rtwCAPI_ModelMappingInfo mmi;
} DataMapInfo;

This member defines mmi (for model mapping information) of type
struct rtwCAPI_ModelMappingInfo. The structure is located in
matlabroot/rtw/c/src/rtw_modelmap.h (where matlabroot represents
the root of your MATLAB installation folder). The mmi substructure defines
the interface between the model and the C API files. More specifically,
members of mmi map the real-time model data structure to the structures
in model_capi.c (or .cpp).
Initializing values of mmi members to the arrays accomplishes the mapping,
as shown in Map Model to C API Arrays of Structures on page 15-160. Each
member points to one of the arrays of structures in the generated C API

15-158

Data Exchange

file. For example, the address of the rtBlockSignals array of structures is
allocated to the first member of the mmi substructure in model.c (or .cpp),
using the following code in the rtw_modelmap.h file:
/* signals */
struct {
rtwCAPI_Signals const *signals;
/*
uint_T
numSignals;
/*
rtwCAPI_Signals const *rootInputs; /*
uint_T
numRootInputs; /*
rtwCAPI_Signals const *rootOutputs; /*
uint_T
numRootOutputs;/*
} Signals;

Signals Array */
Num Signals
*/
Root Inputs array */
Num Root Inputs */
Root Outputs array */
Num Root Outputs */

The model initialize function in model.c (or .cpp) performs the initializing
by calling the C API initialize function. For example, the following code is
generated in the model initialize function for example model rtwdemo_capi:
/* Initialize DataMapInfo substructure containing ModelMap for C API */
rtwdemo_capi_InitializeDataMapInfo(rtwdemo_capi_M);

15-159

15

Program Building, Interaction, and Debugging

model_capi.c

matlabroot/rtw/c/src/rtw_modelmap.h

model.h
struct rtModel_model {
.
.
.

rtwCAPI_Signals const *signals;
rtwCAPI_Signals const *rootInputs;
rtwCAPI_Signals const *rootOutputs;
.

rtBlockSignals
rtRootInputs
rtRootOutputs
.

rtwCAPI_BlockParameters const *blockParameters;

rtBlockParameters

.

.

rtwCAPI_ModelParameters const *modelParameters;

rtModelParameters

.

.

struct {

rtwCAPI_States const *states;

rtBlockStates

rtwCAPI_ModelMappingInfo mmi;

.

.

} DataMapInfo:

rtwCAPI_DataTypeMap const *dataTypeMap;

rtDataTypeMap

.

.

rtwCAPI_DimensionMap const *dimensionMap;

rtDimensionMap

.

.

rtwCAPI_FixPtMap const *fixPtMap;

rtFixPtMap

.

.

rtwCAPI_SampleTimeMap const *sampleTimeMap;

rtSampleTimeMap

.

.

void** dataAddrMap;

rtDataAddrMap

.

.

.
.
.
}

Map Model to C API Arrays of Structures

Note This figure lists the arrays in the order that their structures appear
in rtw_modelmap.h, which differs slightly from their generated order in
model_capi.c.

Use the C API in an Application
The C API provides you with the flexibility of writing your own application
code to interact with model signals, states, root-level inputs/outputs, and
parameters. Your target-based application code is compiled with the Simulink
Coder generated code into an executable. The target-based application
code accesses the C API structure arrays in model_capi.c (or .cpp). You

15-160

Data Exchange

might have host-based code that interacts with your target-based application
code. Or, you might have other target-based code that interacts with your
target-based application code. The files rtw_modelmap.h and rtw_capi.h,
located in matlabroot/rtw/c/src (where matlabroot represents the root of
your MATLAB installation folder), provide macros for accessing the structures
in these arrays and their members.
This section provides examples to help you get started writing application
code to interact with model signals, states, root-level inputs/outputs, and
parameters.
• “Use C API to Access Model Signals and States” on page 15-161
• “Use C API to Access Model Parameters” on page 15-168
Use C API to Access Model Signals and States. Here is an example
application that logs global signals and states in a model to a text file. This
code is intended as a starting point for accessing signal and state addresses.
You can extend the code to perform signal logging and monitoring, state
logging and monitoring, or both.
This example uses the following macro and function interfaces:
• rtmGetDataMapInfo macro
Accesses the model mapping information (MMI) substructure of the
real-time model structure. In the following macro call, rtM is the pointer to
the real-time model structure in model.c (or .cpp):
rtwCAPI_ModelMappingInfo* mmi = &(rtmGetDataMapInfo(rtM).mmi);

• rtmGetTPtr macro
Accesses the absolute time information for the base rate from the timing
substructure of the real-time model structure. In the following macro call,
rtM is the pointer to the real-time model structure in model.c (or .cpp):
rtmGetTPtr(rtM)

• Custom functions capi_StartLogging, capi_UpdateLogging, and
capi_TerminateLogging, provided via the files rtwdemo_capi_datalog.h
and rtwdemo_capi_datalog.c. These files are located in

15-161

15

Program Building, Interaction, and Debugging

matlabroot/toolbox/rtw/rtwdemos, where matlabroot represents the
root of your MATLAB installation folder.

-

capi_StartLogging initializes signal and state logging.
capi_UpdateLogging logs a signal and state value at each time step.
capi_TerminateLogging terminates signal and state logging and writes

the logged values to a text file.

You can integrate these custom functions into generated model code using
any or all of the following methods:

-

Code Generation > Custom Code pane of the Configuration
Parameters dialog box

-

Custom Code library blocks
TLC custom code functions

This tutorial uses the Code Generation > Custom Code pane and the
System Outputs block from the Custom Code library to insert calls to the
custom functions into model.c (or .cpp), as follows:

-

capi_StartLogging is called in the MdlStart function (or if an ert.tlc
target is selected for the model, in the model_initialize function).

-

capi_UpdateLogging is called in the model_output function.
capi_TerminateLogging is called in the model_terminate function.

The following excerpts of generated code from model.c (rearranged to reflect
their order of execution) show how the function interfaces are used.
void MdlStart(void)
{
/* user code (Start function Trailer) */
/* C API Custom Logging Function: Start Signal and State logging via C-API.
* capi_StartLogging: Function prototype in rtwdemo_capi_datalog.h
*/
{
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_capi_M).mmi);
printf("** Started state/signal logging via C API **\n");
capi_StartLogging(MMI, MAX_DATA_POINTS);
}

15-162

Data Exchange

...
}
...
/* Model output function */
static void rtwdemo_capi_output(int_T tid)
{
...
/* user code (Output function Trailer) */
/* C API Custom Logging Function: Update Signal and State logging buffers.
* capi_UpdateLogging: Function prototype in rtwdemo_capi_datalog.h
*/
{
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_capi_M).mmi);
capi_UpdateLogging(MMI, rtmGetTPtr(rtwdemo_capi_M));
}
...
}
...
/* Model terminate function */
void rtwdemo_capi_terminate(void)
{
/* user code (Terminate function Trailer) */
/* C API Custom Logging Function: Dump Signal and State buffers into a text file.
* capi_TerminateLogging: Function prototype in rtwdemo_capi_datalog.h
*/
{
capi_TerminateLogging("rtwdemo_capi_ModelLog.txt");
printf("** Finished state/signal logging. Created rtwdemo_capi_ModelLog.txt **\n");
}
}

The following procedure illustrates how you can use the C API macro and
function interfaces to log global signals and states in a model to a text file.
1 At the MATLAB command line, enter rtwdemo_capi to open the example

model.
2 Open the Configuration Parameters dialog box and go to the Code

Generation pane.

15-163

15

Program Building, Interaction, and Debugging

3 For the System target file parameter, select grt.tlc. (Alternatively, if

you are licensed for Embedded Coder software, you can select ert.tlc.
Make sure that you also select ert.tlc for the referenced model
rtwdemo_capi_bot.)
Note Selecting a system target file other than grt.tlc or disabling some
C API options (signals, parameters, or states) in the top model requires
corresponding changes in the referenced model. Because the example
models have read-only access, you must save the updated referenced model
with a different name and modify the top model to reference the renamed
model.
4 Go to the Interface pane.
a In the Data exchange subpane, for the Interface parameter, verify

that C API is selected.
b Additionally, verify that the options Generate C API for: signals and

Generate C API for: states are selected. This example also leaves
Generate C API for: parameters selected. If you clear any of the
options, make sure that the settings match between the top model and
the referenced model.

c If you are using the ert.tlc target, verify that the options MAT-file

logging and Support: complex numbers are selected.
d If you modified any option settings in this step, click Apply.
5 Use the Custom Code pane to embed your custom application code in the

generated code. Select the Custom Code pane, and then click Include
directories. The Include directories input field is displayed.

15-164

Data Exchange

6 In the Include directories field, type

matlabroot/toolbox/rtw/rtwdemos, where matlabroot represents the
root of your MATLAB installation folder.
7 In the Include list of additional subpane, click Source files, and type

rtwdemo_capi_datalog.c, as shown below.

15-165

15

Program Building, Interaction, and Debugging

8 In the Include custom C code in generated subpane, click Source file,

and type or copy and paste the following include statement:
#include "rtwdemo_capi_datalog.h"

9 In the Initialize function field, type or copy and paste the following

application code:
/* C API Custom Logging Function: Start Signal and State logging via C-API.
* capi_StartLogging: Function prototype in rtwdemo_capi_datalog.h
*/
{
rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_capi_M).mmi);
printf("** Started state/signal logging via C API **\n");
capi_StartLogging(MMI, MAX_DATA_POINTS);
}

10 In the Terminate function field, type or copy and paste the following

application code:
/* C API Custom Logging Function: Dump Signal and State buffers into a text file.
* capi_TerminateLogging: Function prototype in rtwdemo_capi_datalog.h
*/
{
capi_TerminateLogging("rtwdemo_capi_ModelLog.txt");
printf("** Finished state/signal logging. Created rtwdemo_capi_ModelLog.txt **\n");
}

11 Click Apply.
12 In the MATLAB Command Window, enter custcode to open the Simulink

Coder Custom Code library. At the top level of the rtwdemo_capi model,
add a System Outputs block.
13 Double-click the System Outputs block to open the System Outputs

Function Custom Code dialog box. In the System Outputs Function Exit
Code field, type or copy and paste the following application code:
/* C API Custom Logging Function: Update Signal and State logging buffers.
* capi_UpdateLogging: Function prototype in rtwdemo_capi_datalog.h
*/
{

15-166

Data Exchange

rtwCAPI_ModelMappingInfo *MMI = &(rtmGetDataMapInfo(rtwdemo_capi_M).mmi);
capi_UpdateLogging(MMI, rtmGetTPtr(rtwdemo_capi_M));
}

Click OK.
14 On the Code Generation pane, verify that the Build button is visible. If

it is not visible, clear the option Generate code only and click Apply.
Click Build to build the model and generate an executable file. For
example, on a Windows system, the build generates the executable file
rtwdemo_capi.exe.
15 In the MATLAB Command Window, enter the command !rtwdemo_capi

to run the executable file. During execution, signals and states
are logged using the C API and then written to the text file
rtwdemo_capi_ModelLog.txt in your working folder.
>> !rtwdemo_capi
** starting the model **
** Started state/signal logging via C API **
** Logging 2 signal(s) and 2 state(s). In this example, only scalar named
signals/states are logged **
** Finished state/signal logging. Created rtwdemo_capi_ModelLog.txt **

16 Examine the text file in the MATLAB editor or any text editor. Here is an

excerpt of the signal and state logging output.
******** Signal Log File ********
Number of Signals Logged: 2
Number of points (time steps) logged: 51
Time

bot_sig1 (Referenced Model)

0

70

top_sig1
4

0.2

70

4

0.4

70

4

0.6

70

4

0.8

70

4

1

70

4

15-167

15

Program Building, Interaction, and Debugging

1.2

70

4

1.4

70

4

1.6

70

4

1.8

70

4

2

70

4

...
******** State Log File ********
Number of States Logged: 2
Number of points (time steps) logged: 51
Time

bot_state (Referenced Model)

0

0

top_state
0

0.2

70

4

0.4

35

4

0.6

52.5

4

0.8

43.75

4

1

48.13

4

1.2

45.94

4

1.4

47.03

4

1.6

46.48

4

1.8

46.76

4

2

46.62

4

...

Use C API to Access Model Parameters. Here is an example application
that prints the parameter values of all tunable parameters in a model to
the standard output. This code is intended as a starting point for accessing
parameter addresses. You can extend the code to perform parameter tuning.
The application:
• Uses the rtmGetDataMapInfo macro to access the mapping information in
the mmi substructure of the real-time model structure
rtwCAPI_ModelMappingInfo* mmi = &(rtmGetDataMapInfo(rtM).mmi);

where rtM is the pointer to the real-time model structure in model.c (or
.cpp).
• Uses rtwCAPI_GetNumModelParameters to get the number of model
parameters in mapped C API:

15-168

Data Exchange

uint_T nModelParams = rtwCAPI_GetNumModelParameters(mmi);

• Uses rtwCAPI_GetModelParameters to access the array of all model
parameter structures mapped in C API:
rtwCAPI_ModelParameters* capiModelParams = \
rtwCAPI_GetModelParameters(mmi);

• Loops over the capiModelParams array to access individual parameter
structures. A call to the function capi_PrintModelParameter displays
the value of the parameter.
The example application code is provided below:
{
/* Get CAPI Mapping structure from Real-Time Model structure */
rtwCAPI_ModelMappingInfo* capiMap = \
&(rtmGetDataMapInfo(rtwdemo_capi_M).mmi);
/* Get number of Model Parameters from capiMap */
uint_T nModelParams = rtwCAPI_GetNumModelParameters(capiMap);
printf("Number of Model Parameters: %d\n", nModelParams);
/* If the model has Model Parameters, print them using the
application capi_PrintModelParameter */
if (nModelParams == 0) {
printf("No Tunable Model Parameters in the model \n");
}
else {
unsigned int idx;
for (idx=0; idx < nModelParams; idx++) {
/* call print utility function */
capi_PrintModelParameter(capiMap, idx);
}
}
}

The print utility function is located in
matlabroot/rtw/c/src/rtw_capi_examples.c (where matlabroot

15-169

15

Program Building, Interaction, and Debugging

represents the root of your MATLAB installation folder). This file contains
utility functions for accessing the C API structures.
To become familiar with the example code, try building a model that displays
all the tunable block parameters and MATLAB variables. You can use
rtwdemo_capi, the C API example model. The following steps apply to both
grt.tlc and ert.tlc targets, unless otherwise indicated.
1 At the MATLAB command line, enter rtwdemo_capi to open the example

model.
2 Open the Configuration Parameters dialog box and go to the

Optimization > Signals and Parameters pane.
3 Verify that the Inline parameters option is selected.
4 If you are licensed for Embedded Coder software and you want to use the

ert.tlc target instead of the default grt.tlc, go to the Code Generation
pane and use the System target file field to select an ert.tlc target.
5 Use the Custom Code pane to embed your custom application code in the

generated code. Select the Custom Code pane, and then click Initialize
function. The Initialize function input field is displayed.
6 In the Initialize function input field, type or copy and paste the example

application code shown above step 1. This embeds the application code in
the MdlStart function. (If you are using ert.tlc, the code appears in the
model_initialize function.)
7 Click Include directories, and type matlabroot/rtw/c/src, where

matlabroot represents the root of your MATLAB installation folder.
8 In the Include list of additional subpane, click Source files, and type

rtw_capi_examples.c.

15-170

Data Exchange

Click Apply.
9 If you are using the ert.tlc target, go to the Code

Generation > Interface pane, select the following options, and
then click Apply.
• In the Interface list, C API

15-171

15

Program Building, Interaction, and Debugging

• MAT-file logging
• Support: complex numbers
10 Go to the Code Generation pane and clear the Generate code only

check box if it is not already cleared.
11 Click Build. The Simulink Coder code generator generates the executable

file rtwdemo_capi.exe in your current working folder.
12 At the MATLAB command line, enter !rtwdemo_capi to run the executable

file. Running the program displays parameter information in the Command
Window.
>> !rtwdemo_capi
** starting the model **
Number of Model Parameters: 5
Ki =
7
Kp =
4
p1 =
0.8147
0.9058
0.127
p2 =
0.9649 0.9706 0.4854
0.1576 0.9572 0.8003
p3 =
ans(:,:,1) =
0.1419 0.9157 0.9595 0.03571
0.4218 0.7922 0.6557 0.8491
ans(:,:,2) =
0.934 0.7577 0.3922 0.1712
0.6787 0.7431 0.6555 0.706
>>

15-172

Data Exchange

C API Limitations
The C API feature has the following limitations.
• The following code formats are not supported:

-

S-function
Accelerated simulation

• For ERT-based targets, the C API requires that support for floating-point
code be enabled.
• Local block output signals are not supported.
• Local Stateflow parameters are not supported.
• The following custom storage class objects are not supported:

-

Objects without the package csc_registration file
BitPackBoolean objects, grouped custom storage classes, and objects
defined by using macros

• Customized data placement is disabled when you are using the C
API. The interface looks for global data declaration in model.h and
model_private.h. Declarations placed in any other file by customized data
placement result in code that does not compile.
Note Custom Storage Class objects take effect in code generation only if you
use the ERT target and clear the Ignore custom storage classes check box
in the Configuration Parameters dialog box.

15-173

15

Program Building, Interaction, and Debugging

ASAP2 Data Measurement and Calibration
ASAP2 is a data definition standard proposed by the Association for
Standardization of Automation and Measuring Systems (ASAM). ASAP2 is a
non-object-oriented description of the data used for measurement, calibration,
and diagnostic systems. For more information on ASAM and the ASAP2
standard, see the ASAM Web site at http://www.asam.net.
• “About ASAP2 Data Measurement and Calibration” on page 15-174
• “Targets Supporting ASAP2” on page 15-175
• “Define ASAP2 Information” on page 15-175
• “Generate an ASAP2 File” on page 15-182
• “Structure of the ASAP2 File” on page 15-187
• “Generate ASAP2 and C API Files” on page 15-188

About ASAP2 Data Measurement and Calibration
The Simulink Coder product lets you export an ASAP2 file containing
information about your model during the code generation process.
To make use of ASAP2 file generation, you should become familiar with the
following topics:
• ASAM and the ASAP2 standard and terminology. See the ASAM Web site
at http://www.asam.net.
• Simulink data objects. Data objects are used to supply information not
contained in the model. For an overview, see “Data Objects”.
• Storage and representation of signals and parameters in generated code.
See “Data Representation”.
• If you are licensed for Embedded Coder, see also the Embedded Coder
topic “Data Representation ”.
You can run an interactive example of ASAP2 file generation. To open the
example at the MATLAB command prompt, enter the following command:
rtwdemo_asap2

15-174

Data Exchange

Note Simulink Coder support for ASAP2 file generation is version-neutral.
By default, the software generates ASAP2 version 1.31 format, but the
generated model information is generally compatible with all ASAP2
versions. ASAP2 file generation also is neutral with respect to the specific
needs of ASAP2 measurement and calibration tools. The software provides
customization APIs that you can use to customize ASAP2 file generation to
generate any ASAP2 version and to meet the specific needs of your ASAP2
tools.

Targets Supporting ASAP2
ASAP2 file generation is available to all Simulink Coder target configurations.
You can select these target configurations from the System Target File
Browser. For example,
• The Generic Real-Time Target (grt.tlc) lets you generate an ASAP2
file as part of the code generation and build process.
• Any of the Embedded Coder (ert.tlc) target selections also lets you
generate an ASAP2 file as part of the code generation and build process.
• The ASAM-ASAP2 Data Definition Target (asap2.tlc) lets you generate
only an ASAP2 file, without building an executable.
Procedures for generating ASAP2 files by using these target configurations
are given in “Generate an ASAP2 File” on page 15-182.

Define ASAP2 Information
• “Define ASAP2 Information for Parameters and Signals” on page 15-176
• “Memory Address Attribute” on page 15-177
• “Automatic ECU Address Replacement for ASAP2 Files (Embedded Coder)”
on page 15-178
• “Define ASAP2 Information for Lookup Tables” on page 15-180

15-175

15

Program Building, Interaction, and Debugging

Define ASAP2 Information for Parameters and Signals. The ASAP2 file
generation process requires information about your model’s parameters and
signals. Some of this information is contained in the model itself. You must
supply the rest by using Simulink data objects and corresponding properties.
You can use built-in Simulink data objects to provide the information. For
example, you can use Simulink.Signal objects to provide MEASUREMENT
information and Simulink.Parameter objects to provide CHARACTERISTIC
information. Also, you can use data objects from data classes that are derived
from Simulink.Signal and Simulink.Parameter to provide the information.
For details, see “Data Objects”.
The following table contains the minimum set of data attributes required
for ASAP2 file generation. Some data attributes are defined in the model;
others are supplied in the properties of objects. For attributes that are
defined in Simulink.Signal or Simulink.Parameter objects, the table gives
the associated property name.

15-176

Data Attribute

Defined In

Property Name

Name (symbol)

Data object

Inherited from the
handle of the data object
to which parameter or
signal name resolves

Description

Data object

Description

Data type

Model

Not applicable

Scaling
(if fixed-point data type)

Model

Data type (for signals)

Minimum allowable
value

Data object

Min

Maximum allowable
value

Data object

Max

Inherited from value (for
parameters)

Data Exchange

Data Attribute

Defined In

Property Name

Units

Data object

DocUnits

Memory address
(optional)

Data object

MemoryAddress_ASAP2

(optional; see “Memory
Address Attribute” on
page 15-177.)

Memory Address Attribute. If the memory address attribute is
unknown before code generation, the code generator inserts an ECU Address
placeholder string in the generated ASAP2 file. You can substitute an actual
address for the placeholder by postprocessing the generated file. See the
file matlabroot/toolbox/rtw/targets/asap2/asap2/asap2post.m for an
example. asap2post.m parses through the linker map file that you provide
and replaces the placeholder strings in the ASAP2 file with the actual
memory addresses. Since linker map files vary from compiler to compiler, you
might need to modify the regular expression code in asap2post.m to match
the format of the linker map you use.
Note If Embedded Coder is licensed and installed on your system, and
if you are generating ELF (Executable and Linkable Format) files for your
embedded target, you can use the rtw.asap2SetAddress function to automate
ECU address replacement. For more information, see “Automatic ECU
Address Replacement for ASAP2 Files (Embedded Coder)” on page 15-178.
If the memory address attribute is known before code generation, it can
be defined in the data object. By default, the MemoryAddress_ASAP2
property does not exist in the Simulink.Signal or Simulink.Parameter
data object classes. If you want to add the attribute, add a property called
MemoryAddress_ASAP2 to a custom class that is a subclass of the Simulink
or ASAP2 class. For information on subclassing Simulink data classes, see
“Define Level-1 Data Classes” in the Simulink documentation.

15-177

15

Program Building, Interaction, and Debugging

Note In previous releases, for ASAP2 file generation, you had to define
objects explicitly as ASAP2.Signal and ASAP2.Parameter. This is no longer
a limitation. As explained above, you can use built-in Simulink objects for
generating an ASAP2 file. If you have been using an earlier release, you can
continue to use the ASAP2 objects. If one of these ASAP2 objects was created
in the previous release, and you use it in this release, the MATLAB Command
Window displays a warning the first time the objects are loaded.
The following table indicates the Simulink object properties that have
replaced the ASAP2 object properties of the previous release:
Differences Between ASAP2 and Simulink Parameter and Signal
Object Properties
ASAP2 Object Properties
(Previous)

Simulink Object Properties
(Current)

LONGIG_ASAP2

Description

PhysicalMin_ASAP2

Min

PhysicalMax_ASAP2

Max

Units_ASAP2

DocUnits

Automatic ECU Address Replacement for ASAP2 Files (Embedded
Coder). If Embedded Coder is licensed and installed on your system, and
if you are generating ELF (Executable and Linkable Format) files for your
embedded target, you can use the rtw.asap2SetAddress function to automate
the replacement of ECU Address placeholder memory address values with
actual addresses in the generated ASAP2 file.
If the memory address attribute is unknown before code generation, the code
generator inserts an ECU Address placeholder string in the generated ASAP2
file, as shown in the example below.
/begin CHARACTERISTIC
/* Name
*/ Ki
/* Long Identifier */ ""
/* Type
*/ VALUE

15-178

Data Exchange

/* ECU Address

*/ 0x0
/*ECU_Address@Ki@ */

To substitute actual addresses for the ECU Address placeholders, postprocess
the generated ASAP2 file using the rtw.asap2SetAddress function. The
general syntax is as follows:
rtw.asap2SetAddress(ASAP2File, InfoFile)

where the arguments are strings specifying the name of the generated ASAP2
file and the name of the generated executable ELF file or DWARF debug
information file for the model. When called, rtw.asap2SetAddress extracts
the actual ECU address from the specified ELF or DWARF file and replaces
the placeholder in the ASAP2 file with the actual address, for example:
/begin CHARACTERISTIC
/* Name
*/
/* Long Identifier */
/* Type
*/
/* ECU Address
*/

Ki
""
VALUE
0x40009E60

15-179

15

Program Building, Interaction, and Debugging

Define ASAP2 Information for Lookup Tables. Simulink Coder software
generates ASAP2 descriptions for lookup table data and its breakpoints.
The software represents 1-D table data as CURVE information, 2-D table
data as MAP information, and breakpoints as AXIS_DESCR and AXIS_PTS
information. You can model lookup tables using any of the following Simulink
Lookup Table blocks:
• Direct Lookup Table (n-D) — 1 and 2 dimensions
• Interpolation Using Prelookup — 1 and 2 dimensions
• 1–D Lookup Table
• 2–D Lookup Table
• n-D Lookup Table — 1 and 2 dimensions
The software supports the following types of lookup table breakpoints (axis
points):
Breakpoint Type

Generates

Tunable and shared
among multiple table
axes (common axis)

COM_AXIS

Fixed and nontunable
(fixed axis)

One of these variants of FIX_AXIS:
• FIX_AXIS_PAR if breakpoints are integers
with equidistant spacing
• FIX_AXIS_PAR_DIST if breakpoints are
integers with equidistant spacing and the
equidistant spacing is a power of two
• FIX_AXIS_PAR_LIST if breakpoints are
integers with non-equidistant spacing

Tunable but not shared
among multiple tables
(standard axis)

15-180

STD_AXIS

Data Exchange

When you configure the blocks for ASAP2 code generation:
• For table data, use a Simulink.Parameter data object with a non-Auto
storage class.
• For tunable breakpoint data that is shared among multiple table axes
(COM_AXIS), use a Simulink.Parameter data object with a non-Auto
storage class.
• For fixed, nontunable breakpoint data (FIX_AXIS), use workspace variables
or arrays specified in the block parameters dialog box. The breakpoints
should be stored as integers in the code, so the data type should be a
built-in integer type (int8, int16, int32, uint8, uint16, or uint32), a
fixed-point data type, or an equivalent alias type.
• For tunable breakpoint data that is not shared among multiple tables
(STD_AXIS):
1 Create a Simulink.Bus object to define the struct packaging (names

and order of the fields). The fields of the parameter structure must
correspond to the lookup table data and each axis of the lookup table
block. For example, in an n-D Lookup Table block with 2 dimensions,
the structure must contain only three fields. This bus object describes
the record layout for the lookup characteristic.
2 Create a Simulink.Parameter object to represent a tunable parameter.
3 Create table and axis values.
4 Optionally, specify the Units, Minimum, and Maximum properties for

the parameter object. The properties will be applied to table data only.
Here is an example of an n-D Lookup Table record generated into an ASAP2
file in Standard Axis format:
/begin CHARACTERISTIC
/* Name */ STDAxisParam
...
/* Record Layout */
Lookup1D_X_WORD_Y_FLOAT32_IEEE
...
begin AXIS_DESCR
/* Description of X-Axis Points */
/* Axis Type */
STD_AXIS
...

15-181

15

Program Building, Interaction, and Debugging

/end AXIS_DESCR
/end CHARACTERISTIC
/begin RECORD_LAYOUT Lookup1D_X_WORD_Y_FLOAT32_IEEE
AXIS_PTS_X 1 WORD INDEX_INCR DIRECT
FNC_VALUES 2 FLOAT32_IEEE COLUMN_DIR DIRECT
/end
RECORD_LAYOUT

Note The example model rtwdemo_asap2 illustrates ASAP2 file generation
for Lookup Table blocks, including both tunable (COM_AXIS) and fixed
(FIX_AXIS) lookup table breakpoints.

Generate an ASAP2 File
• “About Generating ASAP2 Files” on page 15-182
• “Use GRT or ERT Target” on page 15-182
• “Use the ASAM-ASAP2 Data Definition Target” on page 15-184
• “Generate ASAP2 Files for Referenced Models” on page 15-186
• “Merge ASAP2 Files for Top and Referenced Models” on page 15-186
About Generating ASAP2 Files. You can generate an ASAP2 file from your
model in one of the following ways:
• Use the Generic Real-Time Target or a Embedded Coder target to generate
an ASAP2 file as part of the code generation and build process.
• Use the ASAM-ASAP2 Data Definition Target to generate only an ASAP2
file, without building an executable.
This section discusses how to generate an ASAP2 file by using the targets
that have built-in ASAP2 support. For an example, see the ASAP2 example
model rtwdemo_asap2.
Use GRT or ERT Target. The procedure for generating a model’s data
definition in ASAP2 format using the Generic Real-Time Target or an
Embedded Coder target is as follows:

15-182

Data Exchange

1 Create the desired model. Use parameter names and signal labels to refer

to corresponding CHARACTERISTIC records and MEASUREMENT
records , respectively.
2 Define the desired parameters and signals in the model to be

Simulink.Parameter and Simulink.Signal objects in the MATLAB

workspace. A convenient way of creating multiple signal and parameter
data objects is to use the Data Object Wizard. Alternatively, you can create
data objects one at a time from the MATLAB command line. For details
on how to use the Data Object Wizard, see “Data Object Wizard” in the
Simulink documentation.
3 For each data object, configure the Storage class property to a setting

other than Auto or SimulinkGlobal. This declares the data object as
global in the generated code. For example, a storage class setting of
ExportedGlobal configures the data object as unstructured global in the
generated code.
Note If you set the storage class to Auto or SimulinkGlobal, or if you set
the storage class to Custom and custom storage class settings cause the
Simulink Coder code generator to generate a macro or non-addressable
variable, the data object is not represented in the ASAP2 file.
4 Configure the remaining properties as desired for each data object.
5 On the Optimization > Signals and Parameters pane of the

Configuration Parameters dialog box, select the Inline parameters check
box.
You should not configure the parameters associated with your data
objects as Simulink global (tunable) parameters in the Model Parameter
Configuration dialog box. If a parameter that resolves to a Simulink data
object is configured using the Model Parameter Configuration dialog box,
the dialog box configuration is ignored. You can, however, use the Model
Parameter Configuration dialog box to configure other parameters in your
model.

15-183

15

Program Building, Interaction, and Debugging

6 On the Code Generation pane, click Browse to open the System Target

File Browser. In the browser, select Generic Real-Time Target or any
embedded real-time target and click OK.
7 In the Interface field on the Interface pane, select ASAP2.

8 Select the Generate code only check box on the Code Generation pane.
9 Click Apply.
10 Click Generate code.

The Simulink Coder code generator writes the ASAP2 file to the build
folder. By default, the file is named model.a2l, where model is the name of
the model. The ASAP2 filename is controlled by the ASAP2 setup file. For
details see “Customize an ASAP2 File” on page 23-2.
Use the ASAM-ASAP2 Data Definition Target. The procedure for
generating a model’s data definition in ASAP2 format using the ASAM-ASAP2
Data Definition Target is as follows:
1 Create the desired model. Use parameter names and signal labels to refer

to corresponding CHARACTERISTIC records and MEASUREMENT
records , respectively.
2 Define the desired parameters and signals in the model to be

Simulink.Parameter and Simulink.Signal objects in the MATLAB

workspace. A convenient way of creating multiple signal and parameter
data objects is to use the Data Object Wizard. Alternatively, you can create
data objects one at a time from the MATLAB command line. For details
on how to use the Data Object Wizard, see “Data Object Wizard” in the
Simulink documentation.
3 For each data object, configure the Storage class property to a setting

other than Auto or SimulinkGlobal. This causes the data object to be
declared as global in the generated code. For example, a storage class

15-184

Data Exchange

setting of ExportedGlobal configures the data object as unstructured
global in the generated code.
Note If you set the storage class to Auto or SimulinkGlobal, or if you set
the storage class to Custom and custom storage class settings cause the
Simulink Coder code generator to generate a macro or non-addressable
variable, the data object is not represented in the ASAP2 file.
4 Configure the remaining properties as desired for each data object.
5 On the Optimization > Signals and Parameters pane of the

Configuration Parameters dialog box, select the Inline parameters check
box.
You should not configure the parameters associated with your data
objects as Simulink global (tunable) parameters in the Model Parameter
Configuration dialog box. If a parameter that resolves to a Simulink data
object is configured using the Model Parameter Configuration dialog box,
the dialog box configuration is ignored. You can, however, use the Model
Parameter Configuration dialog box to configure other parameters in your
model.
6 On the Code Generation pane, click Browse to open the System Target

File Browser. In the browser, select ASAM-ASAP2 Data Definition
Target and click OK.
7 Select the Generate code only check box on the Code Generation pane.
8 Click Apply.
9 Click Generate code.

The Simulink Coder code generator writes the ASAP2 file to the build
folder. By default, the file is named model.a2l, where model is the name of
the model. The ASAP2 filename is controlled by the ASAP2 setup file. For
details see “Customize an ASAP2 File” on page 23-2.

15-185

15

Program Building, Interaction, and Debugging

Generate ASAP2 Files for Referenced Models. The build process can
generate an ASAP2 file for each referenced model in a model reference
hierarchy. In the generated ASAP2 file, MEASUREMENT records represent
signals and states inside the referenced model.
To generate ASAP2 files for referenced models, select ASAP2 file generation
for the top model and for each referenced model in the reference hierarchy.
For example, if you are using the Generic Real-Time Target or an Embedded
Coder target, follow the procedure described in “Use GRT or ERT Target” on
page 15-182 for the top model and each referenced model.
Merge ASAP2 Files for Top and Referenced Models. Use function
rtw.asap2MergeMdlRefs to merge the ASAP2 files generated for top and
referenced models. The function has the following syntax:
[status,info]=rtw.asap2MergeMdlRefs(topModelName,asap2FileName)

• topModelName is the name of the model containing one or more referenced
models.
• asap2FileName is the name you specify for the merged ASAP2 file.
• Optional:: status returns false (logical 0) if the merge completes and true
(logical 1) otherwise.
• Optional:: info returns additional information about merge failure if
status is true. Otherwise, it returns an empty string.
Consider the following example.
[status,info]=rtw.asap2MergeMdlRefs('myTopMdl','merged.a2l')

This command merges the ASAP2 files generated for the top model myTopMdl
and its referenced models in the file merged.a2l.
The example model rtwdemo_asap2 includes an example of merging ASAP2
files.

15-186

Data Exchange

Structure of the ASAP2 File
The following table outlines the basic structure of the ASAP2 file and
describes the Target Language Compiler (TLC) functions and files used to
create each part of the file:
• Static parts of the ASAP2 file are shown in bold.
• Function calls are indicated by %.

File Section

Contents of asap2main.tlc

TLC File Containing
Function Definition

File header

%

asap2userlib.tlc

/begin PROJECT ""

/begin PROJECT "%"

asap2setup.tlc

/begin HEADER ""
HEADER contents

/begin HEADER"%"
%

asap2setup.tlc
asap2userlib.tlc

/end HEADER

/end HEADER

/begin MODULE ""
MODULE contents:

/begin MODULE "%"}

- A2ML
- MOD_PAR
- MOD_COMMON

%

asap2setup.tlc
asap2userlib.tlc

...
Model-dependent
MODULE contents:

%

-

...WriteRecordLayout_TemplateName()

RECORD_LAYOUT
CHARACTERISTIC
ParameterGroups
ModelParameters

asap2lib.tlc

Calls user-defined functions:
user/templates/...

...WriteCharacteristic_TemplateName()
...WriteCharacteristic_Scalar()

- MEASUREMENT
- ExternalInputs
- BlockOutputs

...WriteMeasurement()

asap2userlib.tlc

- COMPU_METHOD

...WriteCompuMethod()

asap2userlib.tlc

15-187

15

Program Building, Interaction, and Debugging

File Section

Contents of asap2main.tlc

/end MODULE

/end MODULE

File footer/tail

%

TLC File Containing
Function Definition
asap2userlib.tlc

Generate ASAP2 and C API Files
The ASAP2 and C API interfaces are not mutually exclusive. Although
the Interface option on the Code Generation > Interface pane of the
Configuration Parameters dialog box allows you to select either the ASAP2 or
C API interface, you can instruct the Simulink Coder product to generate files
for both interfaces by doing the following:
1 On the Code Generation > Interface pane of the Configuration

Parameters dialog box, select C API for the Interface option.

2 In the MATLAB Command Window, with the model open, specify the

following command:
>>

set_param(gcs,'GenerateASAP2','on')

Note If you select both the C API and ASAP2 data interfaces, only the C
API options are displayed in the Configuration Parameters dialog box.
3 Click Generate or Build. The code generator generates the following

ASAP2 and C API files:
• model.a2l — ASAP2 description file
• model_capi.c — C API source file

15-188

Data Exchange

• model_capi.h — C API header file
For more information about using the C API interface, see “Data Interchange
Using the C API” on page 15-137.

Direct Memory Access to Generated Code
The Simulink Coder product provides a TLC function library that lets
you create a global data map record. The global data map record, when
generated, is added to the CompiledModel structure in the model.rtw file.
The global data map record is a database containing all information required
for accessing memory in the generated code, including
• Signals (Block I/O)
• Parameters
• Data type work vectors (DWork)
• External inputs
• External outputs
Use of the global data map requires knowledge of the Target Language
Compiler and of the structure of the model.rtw file. See “Target Language
Compiler Overview” for information on these topics.
The TLC functions that are required to generate and access the global data
map record are contained in matlabroot/rtw/c/tlc/mw/globalmaplib.tlc.
The comments in the source code fully document the global data map
structures and the library functions.
The global data map structures and functions might be modified or enhanced
in future releases.

15-189

15

Program Building, Interaction, and Debugging

15-190

Performance
• Chapter 16, “Optimizations for Generated Code”
• Chapter 17, “Defensive Programming”
• Chapter 18, “Data Copy Reduction”
• Chapter 19, “Execution Speed”
• Chapter 20, “Memory Usage”

16
Optimizations for
Generated Code
• “Optimization Parameters” on page 16-2
• “Advice About Optimizing Models for Code Generation” on page 16-5
• “Control Compiler Optimizations” on page 16-6
• “Optimization Tools and Techniques” on page 16-7
• “Control Memory Allocation for Time Counters” on page 16-9
• “Optimization Dependencies” on page 16-10

16

Optimizations for Generated Code

Optimization Parameters
Many options on the Optimization and Optimization > Signals and
Parameters panes of the Configuration Parameters dialog box affect
generated code. The following figures shows the default optimization settings,
except that Inline parameters and Inline invariant signals, which are
cleared by default, are selected.

Some basic optimization suggestions are given below, cross-referenced to
more extensive relevant discussions in the documentation.
• Selecting the Signal storage reuse check box directs the Simulink Coder
code generator to store signals in reusable memory locations. It also enables

16-2

Optimization Parameters

the Enable local block outputs, Reuse block outputs, Eliminate
superfluous local variables (expression folding), and Minimize data
copies between local and global variables options (see below).
Disabling Signal storage reuse makes all block outputs global and
unique, which in many cases significantly increases RAM and ROM usage.
See “Reduce Memory Requirements for Signals” on page 20-4 for more
details.
• Selecting the Inline parameters check box reduces global RAM usage,
because parameters are not declared in the global parameters structure.
You can override the inlining of individual parameters by using the
Model Parameter Configuration dialog box. You tune parameters used in
referenced models differently, by declaring them as Model block parameter
arguments, rather than using the Model Parameter Configuration dialog
box. See “Inline Parameters” on page 19-2 and “Using Model Arguments”
in the Simulink documentation for more details.
• Selecting the Enable local block outputs check box declares block signals
locally in functions instead of being declared globally (when possible). You
must select Signal storage reuse to enable Enable local block outputs.
See “Declare Signals as Local Function Data” on page 18-17.
• Selecting the Reuse block outputs check box reduces stack size where
signals are buffered in local variables. You must select Signal storage
reuse to enable Reuse block outputs. See “Reuse Memory Allocated
for Signals” on page 20-5.
• Selecting the Inline invariant signals check box makes the Simulink
Coder code generator not generate code for blocks with a constant
(invariant) sample time. You must select Inline parameters to enable
Inline invariant signals. See “Inline Invariant Signals” on page 18-18.
• Selecting the Eliminate superfluous local variables (expression
folding) check box minimizes the computation of intermediate results
at block outputs and the storage of such results in temporary buffers or
variables. See “Minimize Computations and Storage for Intermediate
Results” on page 18-11.
• Selecting the Minimize data copies between local and global
variables check box reuses existing global variables to store temporary
results. You must select Signal storage reuse to enable Minimize

16-3

16

Optimizations for Generated Code

data copies between local and global variables. See “Reuse Memory
Allocated for Signals” on page 20-5.
• Set a Loop unrolling threshold. The loop unrolling threshold determines
when a wide signal should be wrapped into a for loop and when it should
be generated as a separate statement for each element of the signal. See
“Configure Loop Unrolling Threshold” on page 19-4 for details on this
feature.
• Specifying a Maximum stack size (bytes) provides control of the number
of local and global variables, which determine the amount of stack space
required for an application. See “Use Stack Space Allocation” on page 20-6
for more information.
• If your target environment supports the memcpy function, and if your model
uses signal vector assignments to move large amounts of data, selecting
the Use memcpy for vector assignment check box can improve the
execution speed of vector assignments by replacing for loops with memcpy
function calls in the generated code. Set a Memcpy threshold (bytes).
See “Optimize Code Generated for Vector Assignments” on page 19-6 for
details.
Note The rtwdemos example suite includes a set of models that illustrate
optimization settings and techniques. To access these examples, type
rtwdemos

or click the above command. The MATLAB Help browser opens the Simulink
Coder examples page. Click Optimizations in the navigation pane. Use the
examples to learn about the specific effects that optimization parameters and
techniques have on models.

16-4

Advice About Optimizing Models for Code Generation

Advice About Optimizing Models for Code Generation
Using the Model Advisor, you can quickly analyze a model for code generation
and identify aspects of your model that impede production deployment or
limit code efficiency. You can select from a set of checks to run on a model’s
current configuration. The Model Advisor analyzes the model and generates
check results providing suggestions for improvements in each area. Most
Model Advisor diagnostics do not require the model to be in a compiled state;
those that do are noted.
Before running the Model Advisor, select the target you plan to use for
code generation. The Model Advisor works most effectively with ERT and
ERT-based targets (targets based on the Embedded Coder software).
Use the following Model Advisor examples to investigate optimizing models
for code generation using the Model Advisor:
• rtwdemo_advisor1
• rtwdemo_advisor2
• rtwdemo_advisor3
Note Example models rtwdemo_advisor2 and rtwdemo_advisor3 require
Stateflow and Fixed-Point Toolbox software.
For more information on using the Model Advisor, see “Consult the Model
Advisor” in the Simulink documentation. For more information about the
checks in the Model Advisor, see “Embedded Coder Checks” in the Simulink
Coder documentation.

16-5

16

Optimizations for Generated Code

Control Compiler Optimizations
To control compiler optimizations for your Simulink Coder makefile build at
the Simulink GUI level, use the Compiler optimization level parameter.
The Compiler optimization level parameter provides
• Target-independent values Optimizations on (faster runs) and
Optimizations off (faster builds), which allow you to easily toggle
compiler optimizations on and off during code development
• The value Custom for entering custom compiler optimization flags at the
Simulink GUI level, rather than editing compiler flags into template
makefiles (TMFs) or supplying compiler flags to Simulink Coder make
commands
The default setting is Optimizations off (faster builds). Selecting the
value Custom enables the Custom compiler optimization flags field, in
which you can enter custom compiler optimization flags (for example, -O2).
Note If you specify compiler options for your Simulink Coder makefile build
using OPT_OPTS, MEX_OPTS (except MEX_OPTS="-v"), or MEX_OPT_FILE, the
value of Compiler optimization level is ignored and a warning is issued
about the ignored parameter.
For more information about the Compiler optimization level parameter
and its values, see “Compiler optimization level” and “Custom compiler
optimization flags”.

16-6

Optimization Tools and Techniques

Optimization Tools and Techniques
In addition to analyzing models with Model Advisor (see “Advice About
Optimizing Models for Code Generation” on page 16-5), you can use a variety
of other tools and techniques that work with any code format. Here are some
particularly useful ones:
• Run the slupdate command to automatically convert older models (saved
by prior versions or by the current one) to use current features. For details
about what slupdate does, type
help slupdate

• Before building, set optimization flags for the compiler (for example, -O2
for gcc, -Ot for the Microsoft Visual C++ compiler).
• Directly inline C/C++ S-functions into the generated code by writing a TLC
file for the S-function. See “Generated S-Function Block” on page 12-34
and the Target Language Compiler documentation for more information on
inlining S-functions.
• Use a Simulink data type other than double when possible. The
available data types are Boolean, signed and unsigned 8-, 16-, and 32-bit
integers, and 32- and 64-bit floats (a double is a 64-bit float). For more
information, see “Data Types”. For a block-by-block summary, click
showblockdatatypetable or type the command in the MATLAB Command
Window.
• Remove repeated values in lookup table data.
• Use the Merge block to merge the output of signals wherever possible.
This block is particularly helpful when you need to control the execution
of function-call subsystems with a Stateflow chart. The following model
shows an example of how to use the Merge block.

16-7

16

Optimizations for Generated Code

When more than one signal connected to a Merge block has a non-Auto
storage class, all non-Auto signals connected to that block must be
identically labeled and have the same storage class. When Merge blocks
connect directly to one another, these rules apply to all signals connected to
any of the Merge blocks in the group.
If you are licensed to use the Embedded Coder product, see also “Configure
Code Optimizations” in the Embedded Coder documentation.

16-8

Control Memory Allocation for Time Counters

Control Memory Allocation for Time Counters
The Application lifespan (days) parameter lets you control the allocation
of memory for absolute and elapsed time counters. Such counters exist in the
code for blocks that use absolute or elapsed time. For a list of such blocks, see
“Limitations on the Use of Absolute Time” on page 1-88.
The size of the time counters in generated code is 8, 16, 32, or 64 bits. The
size is set automatically to the minimum that can accommodate the duration
value specified by Application lifespan (days) given the step size specified
in the Configuration Parameters Solver pane. To minimize the amount of
RAM used by time counters, specify the smallest lifespan possible and the
largest step size possible.
An application runs to its specified lifespan. It may be able to run longer. For
example, running a model with a step size of one millisecond (0.001 seconds)
for one day requires a 32-bit timer, which could continue running without
overflow for 49 days more.
To maximize application lifespan, specify Application lifespan (days) as
inf. This value allocates 64 bits (two uint32 words) for each timer. Using
64 bits to store timing data would allow a model with a step size of 0.001
microsecond (10E-09 seconds) to run for more than 500 years, which would
rarely be required. 64-bit counters do not violate the usual Simulink Coder
length limitation of 32 bits because the value of a time counter never provides
the value of a signal, state, or parameter.
For information about the allocation and operation of absolute and
elapsed time counters, see “Timers” on page 1-79. For information about
asynchronous timing, see “Use Timers in Asynchronous Tasks” on page
1-58. For information about the effect of the Application lifespan (days)
parameter on simulation, see “Application lifespan (days)” in the Simulink
documentation.

16-9

16

Optimizations for Generated Code

Optimization Dependencies
Several parameters available on the Optimization panes have dependencies
on settings of other options. The following table summarizes the dependencies.

16-10

Option

Dependencies?

Block reduction

No

Conditional input branch
execution

No

Implement logic signals as
Boolean data (versus double)

Yes

Signal storage reuse

No

Inline parameters

Yes

Application lifespan (days)

No

Parameter structure (ERT
targets only)

Yes

Enabled by Inline parameters

Enable local block outputs

Yes

Enabled by Signal storage reuse

Reuse block outputs

Yes

Enabled by Signal storage reuse

Inline invariant signals

Yes

Enabled by Inline parameters

Eliminate superfluous local
variables (expression folding)

Yes

Enabled by Signal storage reuse

Pack Boolean data into bitfields
(ERT targets only)

No

Bitfield declarator type
specifier (ERT targets only)

Yes

Enabled by Pack Boolean data into
bitfields

Minimize data copies between
local and global variables

Yes

Enabled by Signal storage reuse

Simplify array indexing (ERT
targets only)

No

Loop unrolling threshold

No

Dependency Details

Disable for models created with a
Simulink version that supports only
signals of type double
Disable for referenced models in a
model reference hierarchy

Optimization Dependencies

Option

Dependencies?

Maximum stack size (bytes)

No

Use memcpy for vector
assignment

No

Memcpy threshold (bytes)

Yes

Pass reusable subsystem output
as (ERT targets only)

No

Remove root level I/O zero
initialization (ERT targets only)

No

Use memset to initialize floats
and doubles to 0.0

No

Remove internal data zero
initialization (ERT targets only)

No

Optimize initialization code for
model reference (ERT targets
only)

Yes

Remove code from
floating-point to integer
conversions that wrap
out-of-range values

No

Remove code from
floating-point to integer
conversions with saturation
that maps NaN to zero

Yes (ERT targets)
No (GRT targets)

Remove code that protects
against division arithmetic
exceptions (ERT targets only)

No

Dependency Details

Enabled by Use memcpy for vector
assignment

Disable if model includes an enabled
subsystem and the model is referred to
from another model with a Model block

For ERT targets, enabled by Support
floating-point numbers and
Support non-finite numbers in the
Code Generation > Interface pane

16-11

16

16-12

Optimizations for Generated Code

17
Defensive Programming
• “Optimize Code for Floating-Point to Integer Conversions” on page 17-2
• “Disable Nonfinite Checks or Inlining for Math Functions” on page 17-4

17

Defensive Programming

Optimize Code for Floating-Point to Integer Conversions
In this section...
“Remove Code That Wraps Out-of-Range Values” on page 17-2
“Remove Code That Maps NaN to Integer Zero” on page 17-3

Remove Code That Wraps Out-of-Range Values
Selecting the Remove code from floating-point to integer conversions
that wraps out-of-range values check box in the Integer and fixed-point
section of the Optimization pane causes the code generator to remove code
that produces the same results as simulation when out-of-range conversions
occur. This action reduces the size and increases the speed of generated code
at the cost of potentially producing results that do not match simulation in
the case of out-of-range values. For more information, see “Optimization
Pane: General”.
The code generated for a conversion when you select the check box follows:
cg_in_0_20_0[i1] = (int32_T)((rtb_Switch[i1] + 9.0) / 0.09375);

The code generated for a conversion when you clear the check box follows:
_fixptlowering0 = (rtb_Switch[i1] + 9.0) / 0.09375;
_fixptlowering1 = fmod(_fixptlowering0 >= 0.0 ? floor(_fixptlowering0) :
ceil(_fixptlowering0), 4.2949672960000000E+009);
if(_fixptlowering1 < -2.1474836480000000E+009) {
_fixptlowering1 += 4.2949672960000000E+009;
} else if(_fixptlowering1 >= 2.1474836480000000E+009) {
_fixptlowering1 -= 4.2949672960000000E+009;
}
cg_in_0_20_0[i1] = (int32_T)_fixptlowering1;

The code generator applies the fmod function to handle out-of-range
conversion results.

17-2

Optimize Code for Floating-Point to Integer Conversions

Remove Code That Maps NaN to Integer Zero
Selecting the Remove code from floating-point to integer conversions
with saturation that maps NaN to zero check box in the Integer and
fixed-point section of the Optimization pane causes the code generator to
remove code that produces the same results as simulation when mapping
from NaN to integer zero occurs. This action reduces the size and increases
the speed of generated code at the cost of producing results that do not match
simulation in the case of NaN values. For more information, see “Optimization
Pane: General”.
The code generated for a conversion when you select the check box follows:
if (tmp < 2.147483648E+09) {
if (tmp >= -2.147483648E+09) {
tmp_0 = (int32_T)tmp;
} else {
tmp_0 = MIN_int32_T;
}
} else {
tmp_0 = MAX_int32_T;
}

The code generated for a conversion when you clear the check box follows:
if (tmp < 2.147483648E+09) {
if (tmp >= -2.147483648E+09) {
tmp_0 = (int32_T)tmp;
} else {
tmp_0 = MIN_int32_T;
}
} else if (tmp >= 2.147483648E+09) {
tmp_0 = MAX_int32_T;
} else {
tmp_0 = 0;
}

17-3

17

Defensive Programming

Disable Nonfinite Checks or Inlining for Math Functions
When Simulink Coder software generates code for math functions,
• If the model option Support non-finite numbers is selected, nonfinite
number checking is generated uniformly for math functions, without the
ability to specify that nonfinite number checking should be generated for
some functions, but not for others.
• By default, inlining is applied uniformly for math functions, without the
ability to specify that inlining should be generated for some functions,
while invocations should be generated for others.
You can use code replacement library (CRL) customization entries to:
• Selectively disable nonfinite checks for math functions. This can improve
the execution speed of the generated code.
• Selectively disable inlining of math functions. This can increase code
readability and decrease code size.
The functions for which these customizations are supported include the
following:
• Floating-point only: atan2, ceil, copysign, fix, floor, hypot, log, log10,
round, sincos, and sqrt
• Floating-point and integer: abs, max, min, mod, rem, saturate, and sign
The general workflow for disabling nonfinite number checking and/or inlining
is as follows:
1 If you can disable nonfinite number checking for a particular math

function, or if you want to disable inlining for a particular math function
and instead generate a function invocation, you can copy the following
MATLAB function code into a MATLAB file with an .m file name extension,
for example, crl_table_customization.m.
function hTable = crl_table_customization
% Create an instance of the Code Replacement Library table for controlling

17-4

Disable Nonfinite Checks or Inlining for Math Functions

% function intrinsic inlining and nonfinite support
hTable = RTW.TflTable;
% Inline - true (if function needs to be inline)
%

false (if function should not be inlined)

% SNF (support nonfinite) - ENABLE (if non-finite checking should be performed)
%

DISABLE (if non-finite checking should NOT be performed)

%

UNSPECIFIED (Default behavior)

% registerCustomizationEntry(hTable, ...
%

Priority, numInputs, key, inType, outType, Inline, SNF);

registerCustomizationEntry(hTable, ...
100, 2, 'atan2', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'atan2', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'sincos', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'sincos', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'int32',

'int32',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'int16',

'int16',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'int8',

'int8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'integer','integer',true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'uint32', 'uint32', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'uint16', 'uint16', true, 'UNSPECIFIED');

17-5

17

Defensive Programming

registerCustomizationEntry(hTable, ...
100, 1, 'abs', 'uint8',

'uint8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'hypot', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'hypot', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'log', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'log', 'single', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'log10', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'log10', 'single', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'min', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'min', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'min', 'int32',

'int32',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'min', 'int16',

'int16',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'min', 'int8',

'int8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'min', 'uint32', 'uint32', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'min', 'uint16', 'uint16', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'min', 'uint8',

'uint8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'min', 'integer','integer',true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'max', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...

17-6

Disable Nonfinite Checks or Inlining for Math Functions

100, 2, 'max', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'max', 'int32',

'int32',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'max', 'int16',

'int16',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'max', 'int8',

'int8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'max', 'uint32', 'uint32', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'max', 'uint16', 'uint16', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'max', 'uint8',

'uint8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'max', 'integer','integer',true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'int32',

'int32',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'int16',

'int16',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'int8',

'int8',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'uint32', 'uint32', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'uint16', 'uint16', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'mod', 'uint8',

'uint8',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'int32',

'int32',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...

17-7

17

Defensive Programming

100, 2, 'rem', 'int16',

'int16',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'int8',

'int8',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'uint32', 'uint32', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'uint16', 'uint16', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 2, 'rem', 'uint8',

'uint8',

false, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'round', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'round', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'int32',

'int32',

true, 'UNSPECIFIED');

'int16',

true, 'UNSPECIFIED');

'int8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'int16',
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'int8',
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'uint32', 'uint32', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'uint16', 'uint16', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'uint8',

'uint8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 3, 'saturate', 'integer','integer',true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'double', 'double',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'single', 'single',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'int32',

17-8

'integer', true, 'UNSPECIFIED');

Disable Nonfinite Checks or Inlining for Math Functions

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'int16',

'integer', true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'int8',

'integer', true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'uint32', 'uint32',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'uint16', 'uint16',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'uint8',

'uint8',

true, 'UNSPECIFIED');

registerCustomizationEntry(hTable, ...
100, 1, 'sign', 'integer','integer', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'sqrt', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'sqrt', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'ceil', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'ceil', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'floor', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'floor', 'single', 'single', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'fix', 'double', 'double', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'fix', 'single', 'single', false, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'copysign', 'double', 'double', true, 'UNSPECIFIED');
registerCustomizationEntry(hTable, ...
100, 1, 'copysign', 'single', 'single', true, 'UNSPECIFIED');

17-9

17

Defensive Programming

2 To reduce the size of the file, you can delete the

registerCustomizationEntry lines for functions for which the default
nonfinite number checking and inlining behavior is acceptable.
3 For each remaining entry,

• Set the Inline argument to true if the function should be inlined or
false if it should not be inlined.
• Set the SNF argument to ENABLE if nonfinite checking should be
generated, DISABLE if nonfinite checking should not be generated, or
UNSPECIFIED to accept the default behavior based on the model option
settings.
Save the file.
4 Optionally, perform a quick check of the syntactic validity of the

customization table entries by invoking the table definition file at the
MATLAB command line (>> tbl = crl_table_customization). Fix
syntax errors that are flagged.
5 Optionally, view the customization table entries in the Code Replacement

Viewer (>> RTW.viewTfl(crl_table_customization)). For more
information about viewing CRL tables, see “Selecting and Viewing Code
Replacement Libraries” on page 9-61.
6 To register these changes and make them appear in the Code replacement

library drop-down list located on the Code Generation > Interface
pane of the Configuration Parameters dialog box, first copy the following
MATLAB function code into an instance of the file sl_customization.m.
Note For the RTW.TflRegistry instantiation shown below, specify the
argument 'RTW' if a GRT target is selected for your model, otherwise
omit the argument.

function sl_customization(cm)
% sl_customization function to register a code replacement library (CRL)
% Register the CRL defined in local function locCrlRegFcn
cm.registerTargetInfo(@locCrlRegFcn);

17-10

Disable Nonfinite Checks or Inlining for Math Functions

end % End of SL_CUSTOMIZATION

% Local function to define a CRL containing crl_table_customization
function thisCrl = locCrlRegFcn
% Instantiate a CRL registry entry - specify 'RTW' for GRT
thisCrl = RTW.TflRegistry('RTW');
% Define the CRL properties
thisCrl.Name = 'CRL Customization Example';
thisCrl.Description = 'Example

of CRL Customization';

thisCrl.TableList = {'crl_table_customization'};
thisCrl.BaseTfl = 'C89/C90 (ANSI)';
thisCrl.TargetHWDeviceType = {'*'};
end % End of LOCCRLREGFCN

You can edit the Name field to determine what CRL name will appear in
the Code replacement library drop-down list. Also, the file name in the
TableList field must match the name of the file you created in step 1.
To register your changes, with both of the MATLAB files you created
present in the MATLAB path, enter the following command in the
MATLAB Command Window:
sl_refresh_customizations
7 Create or open a model that will generate function code corresponding to

one of the math functions for which you specified a change in nonfinite
number checking or inlining behavior.
8 Open the Configuration Parameters dialog box, go to the Code

Generation > Interface pane, and use the Code replacement library
drop-down list to select the CRL entry you registered in step 6, for example,
CRL Customization Example.
9 Generate code for the model and examine the generated code to verify that

the math functions are generated as expected.

17-11

17

17-12

Defensive Programming

18
Data Copy Reduction
• “Optimizing Generated Code” on page 18-2
• “Generate Code Without Buffer Optimization” on page 18-4
• “Generate Code With Buffer Optimization” on page 18-9
• “Minimize Computations and Storage for Intermediate Results” on page
18-11
• “Declare Signals as Local Function Data” on page 18-17
• “Inline Invariant Signals” on page 18-18

18

Data Copy Reduction

Optimizing Generated Code
In this section...
“About Optimizing Generated Code” on page 18-2
“Setting Up the Model” on page 18-2

About Optimizing Generated Code
This section shows how to configure optimizations and generate code for a
model. It shows the generated code before and after the optimizations are
applied.
Note You can view the code generated from this example using the
MATLAB editor or by generating an HTML code generation report. For more
information, see “Generate a Code Generation Report” on page 11-5.
The example model used, example, is shown below.

Setting Up the Model
First, create the model from Simulink library blocks, and set up basic
Simulink and Simulink Coder parameters as follows:
1 Create a folder, example_codegen, and make it your working folder:

!mkdir example_codegen
cd example_codegen
2 Create a new model and save it as example.
3 Add Sine Wave, Gain, and Out1 blocks to your model and connect them as

shown in the preceding diagram. Label the signals as shown.

18-2

Optimizing Generated Code

4 Open Model Explorer by selecting Model Explorer from the model’s

View menu.
5 In the Model Hierarchy pane, click the symbol preceding the model name

to reveal its components.
6 Click Configuration (Active) in the left pane.
7 Select Solver in the center pane. The Solver pane appears at the right.
8 In the Solver Options pane:
a Select Fixed-step in the Type field.
b Select discrete (no continuous states) in the Solver field.
c Specify 0.1 in the Fixed-step size field. (Otherwise, the Simulink

Coder code generator posts a warning and supplies a default value when
you generate code.)
9 Click Apply.
10 Click Data Import/Export in the center pane and make sure all check

boxes in the right pane are cleared. Click Apply if you made any changes.
11 Select Code Generation in the center pane. Under Target Selection in

the right pane, select the default generic real-time (GRT) target grt.tlc.
12 Select Generate code only at the bottom of the right pane. This option

causes the Simulink Coder software to generate code and a make file,
then stop at that point, rather than proceeding to invoke make to compile
and link the code. Note that the label on the Build button changes to
Generate code.
13 Click Apply.
14 Save the model.

18-3

18

Data Copy Reduction

Generate Code Without Buffer Optimization
With buffer optimizations Simulink Coder software generates code that
reduces memory consumption and execution time. In this example, you
disable the buffer optimizations to see what the nonoptimized generated code
looks like:
1 Select Optimization in the center pane and click the Signals and

Parameters tab in the right pane. The Signals and Parameters pane
appears at the right. Clear the Signal storage reuse option, as shown
below. Change other attributes to match the figure.
Note Clearing the Signal storage reuse option disables the following
options:
• Enable local block outputs
• Reuse block outputs
• Eliminate superfluous local variables (expression folding)
• Minimize data copies between local and global variables

2 Click Apply.
3 Select Code Generation in the center pane and click the Report tab on

the right pane. The Report pane appears at the right.

18-4

Generate Code Without Buffer Optimization

4 Select the Create code generation report and Open report

automatically check boxes. Selecting these check boxes makes the code
generation report display after the build process completes.
5 Click Apply.
6 Select the General tab in the right pane and select Generate code only.
7 Click Generate code.

Because you selected the Generate code only option, the Simulink Coder
build process does not invoke your make utility. The code generation
process ends with this message:
### Successful completion of build procedure
for model: example
8 The generated code is in the build folder, example_grt_rtw. The file

example_grt_rtw/example.c contains the output computation for the
model. You can view this file in the code generation report by clicking
the example.c link in the left pane.
9 In example.c, find the function example_output near the top of the file.

The generated C code consists of procedures that implement the algorithms
defined by your Simulink block diagram. The execution engine calls
the procedures in succession as time moves forward. The modules that
implement the execution engine and other capabilities are referred to
collectively as the run-time interface modules. See the Simulink Coder
User’s Guide for a complete discussion of how the Simulink Coder
software interfaces and executes application, system-dependent, and
system-independent modules, in each of the two styles of generated code.

18-5

18

Data Copy Reduction

In code generated for example, the generated example_output function
implements the actual algorithm for multiplying a sine wave by a gain.
The example_output function computes the model’s block outputs. The
run-time interface must call example_output at every time step. With
buffer optimizations turned off, example_output assigns unique buffers
to each block output. These buffers (rtB.sin_out, rtB.gain_out) are
members of a global block I/O data structure, called in this code example_B
and declared as follows:
/* Block signals (auto storage) */
BlockIO_example example_B;

The data type BlockIO_example is defined in example.h as follows:
/* Block signals (auto storage) */
extern BlockIO_example example_B;

The output code accesses fields of this global structure, as shown below:
/* Model output function */
static void example_output(int_T tid)
{
/* Sin: '/Sine Wave' */
example_B.sin_out = sin(example_P.SineWave_Freq * example_M->Timing.t[0] +
example_P.SineWave_Phase) * example_P.SineWave_Amp + example_P.SineWave_Bias;
/* Gain: '/Gain' */
example_B.gain_out = example_P.Gain_Gain * example_B.sin_out;
/* Outport: '/Out1' */
example_Y.Out1 = example_B.gain_out;
/* tid is required for a uniform function interface.
* Argument tid is not used in the function. */
UNUSED_PARAMETER(tid);
}

18-6

Generate Code Without Buffer Optimization

10 In GRT targets such as this, the function example_output is called

by a wrapper function, MdlOutputs. In example.c, find the function
MdlOutputs near the end. It looks like this:
void MdlOutputs(int_T tid)
{
example_output(tid);
}

Note In previous releases, MdlOutputs was the actual output function for
code generated by all GRT-configured models. It is now implemented as a
wrapper function to provide greater compatibility among different target
configurations.

18-7

18

18-8

Data Copy Reduction

Generate Code With Buffer Optimization

Generate Code With Buffer Optimization
With buffer optimizations, Simulink Coder software generates code that
reduces memory consumption and execution time. In this example, you turn
buffer optimizations on and observe how they improve the code. Enable signal
buffer optimizations and regenerate the code as follows:
1 Change your current working folder to example_codegen if you have not

already done so.
2 In Model Explorer, select Optimization in the center pane and click

the Signals and Parameters tab on the right pane. The Signals and
Parameters pane appears at the right. Select the Signal storage reuse
option.
3 Note that the following parameters become enabled in the Code

generation section:
• Enable local block outputs
• Reuse block outputs
• Eliminate superfluous local variables (expression folding)
• Minimize data copies between local and global variables
Make sure that Enable local block outputs, Reuse block outputs,
and Minimize data copies between local and global variables are
selected, and that Eliminate superfluous local variables (expression
folding) is cleared, as shown below.

18-9

18

Data Copy Reduction

You will observe the effects of expression folding later in this example. Not
performing expression folding allows you to see the effects of the buffer
optimizations.
4 Click Apply to apply the new settings.
5 Select Code Generation in the center pane, and click Generate code

on the right.
As before, the Simulink Coder software generates code in the
example_grt_rtw folder. The previously generated code is overwritten.
6 View example.c and examine the example_output function.

With buffer optimizations enabled, the code in example_output reuses the
example_Y.Out1 global buffer.
/* Model output function */
static void example_output(int_T tid)
{
/* Sin: '/Sine Wave' */
example_Y.Out1 = sin(example_P.SineWave_Freq * example_M->Timing.t[0] +
example_P.SineWave_Phase) * example_P.SineWave_Amp +
example_P.SineWave_Bias;
/* Gain: '/Gain' */
example_Y.Out1 = example_P.Gain_Gain * example_Y.Out1;
/* tid is required for a uniform function interface.
* Argument tid is not used in the function. */
UNUSED_PARAMETER(tid);
}

This code is more efficient in terms of memory usage and execution speed. By
eliminating a global variable and a data copy instruction, the data section
is smaller and the code is smaller and faster. The efficiency improvement
gained by selecting Enable local block outputs, Reuse block outputs,
and Minimize data copies between local and global variables is more
significant in a large model with many signals.

18-10

Minimize Computations and Storage for Intermediate Results

Minimize Computations and Storage for Intermediate
Results
In this section...
“About Expression Folding” on page 18-11
“Expression Folding Example” on page 18-12
“Enable Expression Folding” on page 18-15

About Expression Folding
Expression folding is a code optimization technique that minimizes the
computation of intermediate results at block outputs and the storage of such
results in temporary buffers or variables. Eliminate superfluous local
variables (expression folding) is used to enable expression folding. When
expression folding is on, the Simulink Coder code generator collapses, or
“folds,” block computations into a single expression, instead of generating
separate code statements and storage declarations for each block in the model.
Expression folding can dramatically improve the efficiency of generated code,
frequently achieving results that compare favorably to hand-optimized code.
In many cases, entire groups of model computations fold into a single highly
optimized line of code.
By default, expression folding is on. The Simulink Coder code generation
options are configured to use expression folding wherever possible. Most
Simulink blocks support expression folding.
You can also take advantage of expression folding in your own inlined
S-function blocks. See “Write S-Functions That Support Expression Folding”
on page 14-91 for information on how to do this.
In the code generation examples that follow, the Signal storage reuse
optimizations (Enable local block outputs, Reuse block outputs,
Eliminate superfluous local variables (expression folding) and
Minimize data copies between local and global variables) are all
turned on.

18-11

18

Data Copy Reduction

Expression Folding Example
As a simple example of how expression folding affects the code generated from
a model, consider the following model.

With expression folding on, this model generates a single-line output
computation, as shown in this model_output function.
static void exprfld_output(int_T tid)
{
/* Outport: '/Out1' incorporates:
* Gain: '/k1'
* Gain: '/k2'
* Inport: '/In1
* Inport: '/In2
* Product: '/Product'
*/
exprfld_Y.Out1 = exprfld_U.i1 * exprfld_P.k1_Gain *
(exprfld_U.i2 * exprfld_P.k2_Gain);
}

The generated comments indicate the block computations that were combined
into a single expression. The comments also document the block parameters
that appear in the expression.
With expression folding off, the same model computes temporary results for
both Gain blocks before the final output, as shown in this output function:
static void exprfld_output(int_T tid)

18-12

Minimize Computations and Storage for Intermediate Results

{
real_T rtb_S2;
/* Gain: '/k1' incorporates:
* Inport: '/In1'
*/
exprfld_Y.Out1 = exprfld_U.i1 * exprfld_P.k1_Gain
/* Gain: '/k2' incorporates:
* Inport: '/In2'
*/
rtb_S2 = exprfld_U.i2 * exprfld_P.k2_Gain;
/* Product: '/Product' */
exprfld_Y.Out1 = exprfld_Y.Out1 * rtb_S2;
}

Turn on expression folding, a code optimization technique that minimizes
the computation of intermediate results and the use of temporary buffers
or variables.
Enable expression folding and regenerate the code as follows:
1 Change your current working folder to example_codegen if you have not

already done so.
2 In Model Explorer, select Optimization in the center pane and click

the Signals and Parameters tab on the right pane. The Signals and
Parameters pane appears at the right.

18-13

18

Data Copy Reduction

3 Select the Eliminate superfluous local variables (expression folding)

option.

4 Click Apply.
5 Select Code Generation in the center pane, and click Generate code

on the right.
The Simulink Coder software generates code as before.
6 View example.c and examine the function example_output.

In the previous examples, the Gain block computation was computed in a
separate code statement and the result was stored in a temporary location
before the final output computation.
With Eliminate superfluous local variables (expression folding)
selected, there is a subtle but significant difference in the generated code:
the gain computation is incorporated (or folded) directly into the Outport
computation, eliminating the temporary location and separate code statement.
This computation is on the last line of the example_output function.
/* Model output function */
static void example_output(int_T tid)
{
/* Outport: '/Out1' incorporates:

18-14

*

Gain: '/Gain'

*

Sin: '/Sine Wave'

Minimize Computations and Storage for Intermediate Results

*/
example_Y.Out1 = (sin(example_P.SineWave_Freq * example_M->Timing.t[0] +
example_P.SineWave_Phase) * example_P.SineWave_Amp +
example_P.SineWave_Bias) * example_P.Gain_Gain;
/* tid is required for a uniform function interface.
* Argument tid is not used in the function. */
UNUSED_PARAMETER(tid);
}

In many cases, expression folding can incorporate entire model computations
into a single, highly optimized line of code. Expression folding is turned on by
default. Using this option will improve the efficiency of generated code.
For an example of expression folding in the context of a more complex model,
click rtwdemo_slexprfold , or type the following command at the MATLAB
prompt.
rtwdemo_slexprfold

Enable Expression Folding
Expression folding operates only on expressions involving local variables.
Expression folding is therefore available only when the Signal storage
reuse code generation option is on.
For a new model, default code generation options are set to use expression
folding. If you are configuring an existing model, enable expression folding as
follows:
1 Open the Configuration Parameters dialog box and select the

Optimization > Signals and Parameters pane.
2 Select the Signal storage reuse check box.
3 Select the Enable local block outputs check box.
4 Select the Reuse block outputs check box.
5 Select the Minimize data copies between local and global variables

check box.

18-15

18

Data Copy Reduction

6 Enable expression folding by selecting Eliminate superfluous local

variables (expression folding).
All expression folding related options are now selected.
7 Click Apply.

18-16

Declare Signals as Local Function Data

Declare Signals as Local Function Data
To declare block signals locally in functions instead of being declared globally
(when possible), select the Enable local block outputs configuration
parameter. This parameter is available only when you select Signal storage
reuse.
For more information on the use of the Enable local block outputs option,
see “Signals” on page 7-52.

18-17

18

Data Copy Reduction

Inline Invariant Signals
An invariant signal is a block output signal that does not change during
Simulink simulation. For example, the signal S3 in this block diagram is an
invariant signal.

For the previous model, if you select Inline invariant signals on the
Optimization > Signals and Parameters pane, the Simulink Coder code
generator inlines the invariant signal S3 in the generated code.
Note that an invariant signal is not the same as an invariant constant. In
the preceding example, the two constants (1 and 2) and the gain value of 3
are invariant constants. To inline these invariant constants, select Inline
parameters.
Note If your model contains Model blocks, Inline parameters must be
on for all referenced models. If a referenced model does not have Inline
Parameters set to on, the Simulink engine temporarily enables this option
while generating code for the referenced model, then turns it off again when
the build completes. Thus the referenced model is left in its previous state
and need not be resaved. For the top model, Inline parameters can be
either on or off.

18-18

19
Execution Speed
• “Inline Parameters” on page 19-2
• “Configure Loop Unrolling Threshold” on page 19-4
• “Optimize Code Generated for Vector Assignments” on page 19-6
• “Generate Target Optimizations Within Algorithm Code” on page 19-10

19

Execution Speed

Inline Parameters
When you select the Inline parameters configuration parameter:
• The Simulink Coder code generator uses the numerical values of model
parameters, instead of their symbolic names, in generated code.
If the value of a parameter is a workspace variable, or an expression
including one or more workspace variables, the variable or expression is
evaluated at code generation time. The hard-coded result value appears
in the generated code. An inlined parameter, because it has in effect been
transformed into a constant, is no longer tunable. That is, it is not visible
to externally written code, and its value cannot be changed at runtime.
• The Configure button becomes enabled. Clicking the Configure button
opens the Model Parameter Configuration dialog box.
The Model Parameter Configuration dialog box lets you remove individual
parameters from inlining and declare them to be tunable variables (or
global constants). When you declare a parameter tunable, the Simulink
Coder product generates a storage declaration that allows the parameter to
be interfaced to externally written code. This enables your hand-written
code to change the value of the parameter at run-time.
The Model Parameter Configuration dialog box lets you improve overall
efficiency by inlining most parameters, while at the same time retaining
the flexibility of run-time tuning for selected parameters.
See “Parameters” on page 7-10 for more information on interfacing
parameters to externally written code.
Inline parameters also instructs the Simulink engine to propagate constant
sample times. The engine computes the output signals of blocks that have
constant sample times once during model startup. This improves performance
because such blocks do not compute their outputs at every time step of the
model.
You can select the Inline invariant signals code generation option (which
also places constant values in generated code) only when Inline parameters
is on. See “Inline Invariant Signals” on page 18-18.

19-2

Inline Parameters

Referenced Models
When a top model uses referenced models or if a model is referenced by
another model:
• All referenced models must specify Inline parameters to be on
• The top model can specify Inline parameters to be on or off.
When the top model specifies Inline parameters to be on, you cannot use
the Model Parameter Configuration dialog box to tune parameters that are
passed to referenced models. To tune such parameters, you must declare
them in the referenced model’s workspace, and then pass run-time values (or
expressions) for them in argument lists specified for each Model block that
references that model. For more information, see “Using Model Arguments”.

19-3

19

Execution Speed

Configure Loop Unrolling Threshold
The Loop unrolling threshold parameter on the Optimization > Signals
and Parameters pane determines when a wide signal or parameter should
be wrapped into a for loop and when it should be generated as a separate
statement for each element of the signal. The default threshold value is 5.
For example, consider the model below:

The gain parameter of the Gain block is the vector myGainVec.

Assume that the loop unrolling threshold value is set to the default, 5.
If myGainVec is declared as
myGainVec = [1:10];

19-4

Configure Loop Unrolling Threshold

an array of 10 elements, myGainVec_P.Gain_Gain[], is declared within the
Parameters_model data structure. The size of the gain array exceeds the loop
unrolling threshold. Therefore, the code generated for the Gain block iterates
over the array in a for loop, as shown in the following code:
{
int32_T i1;
/* Gain: '/Gain' */
for(i1=0; i1<10; i1++) {
myGainVec_B.Gain_f[i1] = rtb_foo *
myGainVec_P.Gain_Gain[i1];
}
}

If myGainVec is declared as
myGainVec = [1:3];

an array of three elements, myGainVec_P.Gain_Gain[], is declared within
the Parameters data structure. The size of the gain array is below the loop
unrolling threshold. The generated code consists of inline references to each
element of the array, as in the code below.
/* Gain: '/Gain' */
myGainVec_B.Gain_f[0] = rtb_foo * myGainVec_P.Gain_Gain[0];
myGainVec_B.Gain_f[1] = rtb_foo * myGainVec_P.Gain_Gain[1];
myGainVec_B.Gain_f[2] = rtb_foo * myGainVec_P.Gain_Gain[2];

See “Explore Variable Names and Loop Rolling” for more information on
loop rolling.
Note When a model includes Stateflow charts or MATLAB Function
blocks, you can apply a set of Stateflow optimizations on the
Optimization > Stateflow pane. The settings you select for the Stateflow
options also apply to all MATLAB Function blocks in the model. This is
because the MATLAB Function blocks and Stateflow charts are built on top
of the same technology and share a code base. You do not need a Stateflow
license to use MATLAB Function blocks.

19-5

19

Execution Speed

Optimize Code Generated for Vector Assignments
In this section...
“Configure Model to Optimize Code Generated for Vector Assignments”
on page 19-6
“Optimize Code Generated for Vector Assignments Using memcpy” on page
19-7

Configure Model to Optimize Code Generated for
Vector Assignments
The Use memcpy for vector assignment option lets you optimize generated
code for vector assignments by replacing for loops with memcpy function calls.
The memcpy function can be more efficient than for-loop controlled element
assignment for large data sets. Where memcpy offers improved execution
speed, you can also use this model option to specify that the generated code
use memcpy when assigning a vector signal.
Selecting the Use memcpy for vector assignment option enables the
associated parameter Memcpy threshold (bytes), which allows you to
specify the minimum array size in bytes for which memcpy function calls
should replace for loops in the generated code. For more information, see
“Use memcpy for vector assignment” and “Memcpy threshold (bytes)”.
In considering whether to use this optimization,
• Verify that your target supports the memcpy function.
• Determine whether your model uses signal vector assignments (such as
Y=expression) to move large amounts of data, for example, using the
Selector block.
To apply this optimization,
1 Consider first generating code without this optimization and measuring its

execution, to establish a baseline for evaluating the optimized assignment.
2 Select Use memcpy for vector assignment and examine the setting of

Memcpy threshold (bytes), which by default specifies 64 bytes as the

19-6

Optimize Code Generated for Vector Assignments

minimum array size for which for loops are replaced with memcpy function
calls. Based on the array sizes used in your application’s signal vector
assignments, and any target environment considerations that might bear
on the threshold selection, accept the default or specify another array size.
3 Generate code, and measure its execution speed against your baseline or

previous iterations. Iterate on steps 2 and 3 until you achieve an optimal
result.
Note The memcpy optimization may not occur under certain conditions,
including when other optimizations have a higher precedence than the memcpy
optimization, or when the generated code is originating from Target Language
Compiler (TLC) code, such as a TLC file associated with an S-function block.

Note If you are licensed for Embedded Coder software, you can use a code
replacement library (CRL) to provide your own custom implementation of the
memcpy function to be used in generated model code. For more information,
see “Map memcpy Function to Target-Specific Implementations”.

Optimize Code Generated for Vector Assignments
Using memcpy
To examine the effect on generated vector assignment code of using the Use
memcpy for vector assignment option, perform the following steps:
1 Create a model that generates signal vector assignments. For example,
a Use In, Out, and Mux blocks to create the following model.

b Select the diagram and use Edit > Subsystem to make it a subsystem.

19-7

19

Execution Speed

c Open Model Explorer and configure the Signal Attributes for the In1,

In2, and In3 source blocks. For each, set Port dimensions to [1,100],
and set Data type to int32. Apply the changes.
d Go to the Optimization > Signals and Parameters pane of the

Configuration Parameters dialog box and clear the Use memcpy for
vector assignment option. Apply the changes and save the model. In
this example, the model is saved to the name vectorassign.
2 Go to the Code Generation > Report pane of the Configuration

Parameters dialog box and select the Create code generation report.
Then go to the Code Generation pane, select the Generate code only
option, and generate code for the model. When code generation completes,
the HTML code generation report is displayed.
3 In the HTML code generation report, click on the vectorassign.c section

and inspect the model output function. Notice that the vector assignments
are implemented using for loops.
/* Model output function */
static void vectorassign_output(void)
{
int32_T i;
/* Outport: '/Out1' incorporates:
*

Inport: '/In1'

*

Inport: '/In2'

*

Inport: '/In3'

*/
for (i = 0; i < 100; i++) {
vectorassign_Y.Out1[i] = vectorassign_U.In2[i];
}
for (i = 0; i < 100; i++) {
vectorassign_Y.Out1[i + 100] = vectorassign_U.In3[i];

19-8

Optimize Code Generated for Vector Assignments

}
for (i = 0; i < 100; i++) {
vectorassign_Y.Out1[i + 200] = vectorassign_U.In1[i];
}
/* End of Outport: '/Out1' */

4 Go to the Optimization > Signals and Parameters pane of the

Configuration Parameters dialog box and select the Use memcpy for
vector assignment option. Leave the Memcpy threshold (bytes) option
at its default setting of 64 Apply the changes and regenerate code for the
model. When code generation completes, the HTML code generation report
again is displayed.
5 In the HTML code generation report, click on the vectorassign.c section

and inspect the model output function. Notice that the vector assignments
now are implemented using memcpy function calls.
/* Model output function */
static void vectorassign_output(void)
{
int32_T i;
/* Outport: '/Out1' incorporates:
*

Inport: '/In1'

*

Inport: '/In2'

*

Inport: '/In3'

*/
memcpy(&vectorassign_Y.Out1[0], &vectorassign_U.In2[0], 100U * sizeof(int32_T));
memcpy(&vectorassign_Y.Out1[100], &vectorassign_U.In3[0], 100U * sizeof(int32_T));
memcpy(&vectorassign_Y.Out1[200], &vectorassign_U.In1[0], 100U * sizeof(int32_T));
}

19-9

19

Execution Speed

Generate Target Optimizations Within Algorithm Code
Some application components are hardware-specific and cannot simulate on
a host system. For example, consider a component that includes pragmas
and assembly code for enabling hardware instructions for saturate on add
operations or a Fast Fourier Transform (FFT) function.
The following table lists integration options to customize generated algorithm
code with target-specific optimizations.
Note Solutions marked with EC only require an Embedded Coder license.

19-10

If...

Then...

For More Information, See

You want to optimize
target performance
(speed and memory)
of model code by
replacing default
math functions
and operators with
target-specific code

EC only— Implement
function and operator
replacements by using
the code replacement
library (CRL) API,
Code Replacement
Tool, and Code
Replacement Viewer
to create, examine,
validate, and register
hardware-specific
replacement tables

• rtwdemo_crl_script

You want to control
how code generation
technology declares,
stores, and represents
signals, tunable
parameters, block
states, and data objects
in generated code

EC only—Design
(create) and apply
custom storage
classes

• “Introduction to Code Replacement
Libraries”

• rtwdemo_cscpredef
• rtwdemo_importstruct
• rtwdemo_advsc
• “Custom Storage Classes”

Generate Target Optimizations Within Algorithm Code

Note To simulate an algorithm that includes target-specific elements in a
host environment, you must create code that is equivalent to the target code
and can run in the host environment.

19-11

19

19-12

Execution Speed

20
Memory Usage
• “Minimize Memory Requirements During Code Generation” on page 20-2
• “Implement Logic Signals as Boolean Data” on page 20-3
• “Reduce Memory Requirements for Signals” on page 20-4
• “Reuse Memory Allocated for Signals” on page 20-5
• “Use Stack Space Allocation” on page 20-6

20

Memory Usage

Minimize Memory Requirements During Code Generation
When the Simulink Coder product generates code, it creates an intermediate
representation of your model (called model.rtw), which the Target Language
Compiler parses to transform block computations, parameters, signals, and
constant data into a high-level language, (for example, C). Parameters and
data are normally copied into the model.rtw file, whether they originate in
the model itself or come from variables or objects in a workspace.
Models which have large amounts of parameter and constant data (such as
lookup tables) can tax memory resources and slow down code generation
because of the need to copy their data to model.rtw. You can improve code
generation performance by limiting the size of data that is copied by using a
set_param command, described below.
Data vectors such as those for parameters, lookup tables, and constant blocks
whose sizes exceed a specified value are not copied into the model.rtw file.
In place of the data vectors, the code generator places a special reference
key in the intermediate file that enables the Target Language Compiler to
access the data directly from the Simulink software and format it directly
into the generated code. This results in maintaining only one copy of large
data vectors in memory.
You can specify the maximum number of elements that a parameter or other
data source can have for the Simulink Coder code generator to represent it
literally in the model.rtw file. Whenever this threshold size is exceeded, the
product writes a reference to the data to the model.rtw file, rather than its
values. The default threshold value is 10 elements, which you can verify with
get_param(0, 'RTWDataReferencesMinSize')

To set the threshold to a different value, type the following set_param
function in the MATLAB Command Window:
set_param(0, 'RTWDataReferencesMinSize', )

Provide an integer value for size that specifies the number of data elements
above which reference keys are to be used in place of actual data values.

20-2

Implement Logic Signals as Boolean Data

Implement Logic Signals as Boolean Data
When you select the Implement logic signals as Boolean data (vs.
double) check box, blocks that generate logic signals output Boolean signals.
When you clear this check box, blocks that generate logic signals output
double signals.
The check box is selected by default because it reduces memory requirements
(a Boolean signal typically requires one byte in memory while a double signal
requires eight bytes in memory). Clear this check box for compatibility with
models created using earlier versions of Simulink that support only double
signals. For details about this check box, see “Implement logic signals as
Boolean data (vs. double)”.

20-3

20

Memory Usage

Reduce Memory Requirements for Signals
To instruct the Simulink Coder code generator to reuse signal memory, which
can reduce memory requirements of your real-time program, select the
configuration parameter Signal storage reuse. Disabling Signal storage
reuse makes all block outputs global and unique, which in many cases
significantly increases RAM and ROM usage.
For more details on the Signal storage reuse option, see “Signals” on page
7-52.
Note Selecting Signal storage reuse also enables the Enable local block
outputs, Reuse block outputs, Eliminate superfluous local variables
(expression folding), and Minimize data copies between local and
global variables options on the Optimization > Signals and Parameters
pane. See “Declare Signals as Local Function Data” on page 18-17 and “Reuse
Memory Allocated for Signals” on page 20-5.

20-4

Reuse Memory Allocated for Signals

Reuse Memory Allocated for Signals
Two parameters provide the capability to reuse memory allocated for signals:
Reuse block output and Minimize data copies between local and
global variables.
Selecting Reuse block output directs the code generator to reuse signal
memory. When Reuse block output is cleared, signals are stored in unique
locations.
Reuse block output is enabled only when you select Signal storage reuse.
Selecting Minimize data copies between local and global variables
reuses existing global variables to store temporary results. Clearing
Minimize data copies between local and global variables writes data
for block outputs to local variables. You must select Signal storage reuse to
enable Minimize data copies between local and global variables.
See “Signals” on page 7-52 for more information (including generated code
example) on Reuse block output, Minimize data copies between local
and global variables, and other signal storage options.

20-5

20

Memory Usage

Use Stack Space Allocation
Your application might be constrained by limited memory. Controlling the
maximum allowable size for the stack is one way to modify whether data
is defined as local or global in the generated code. You can limit the use of
stack space by specifying a positive integer value for the “Maximum stack
size (bytes)” parameter, on the Optimization > Signals and Parameters
pane of the Configuration parameter dialog box. Specifying the maximum
allowable stack size provides control over the number of local and global
variables in the generated code. Specifically, lowering the maximum stack
size might generate more variables into global structures. The number of
local and global variables help determine the required amount of stack space
for execution of the generated code.
The default setting for “Maximum stack size (bytes)” is Inherit from
target. In this case, the value of the maximum stack size is the smaller
value of the following: the default value set by the Simulink Coder software
(200,000 bytes) or the value of the TLC variable MaxStackSize found in the
system target file (ert.tlc).
To specify a smaller stack size for your application, select the Specify a
value option of the Maximum stack size (bytes) parameter and enter a
positive integer value. To specify a smaller stack size at the command line,
use:
set_param(model_name, 'MaxStackSize', 65000);

Note For overall executable stack usage metrics, you might want to do a
target-specific measurement, such as using runtime (empirical) analysis or
static (code path) analysis with object code.
It is recommended that you use the Maximum stack size (bytes) parameter
to control stack space allocation instead of modifying the TLC variable,
MaxStackSize, in the system target file. However, a target author might want
to set the TLC variable, MaxStackSize, for a target. To set MaxStackSize,
use assign statements in the system target file (ert.tlc), as in the following
example.

20-6

Use Stack Space Allocation

%assign MaxStackSize = 4096

Write your %assign statements in the Configure RTW code generation
settings section of the system target file. The %assign statement is
described in “Target Language Compiler”.

20-7

20

20-8

Memory Usage

Verification

21
Simulation and Code
Comparison
• “Comparing Output Data” on page 21-2
• “Configure Signal Data for Logging” on page 21-3
• “Log Simulation Data” on page 21-5
• “Log Data from the Generated Program” on page 21-7
• “Compare Numerical Results” on page 21-9

21

Simulation and Code Comparison

Comparing Output Data
This example shows you how to verify the answers computed by code
generated from the sldemo_f14 model. It shows how to capture two sets of
output data and compare the sets. Simulating the model produces one set of
output data. Executing the generated code produces a second set of output
data.
Note To obtain a valid comparison between the outputs of the model and
the generated code , use the same Solver options and the same Step size
for both the simulation run and the build process. You must configure the
model to save simulation time.
For an example, see “Configure Signal Data for Logging” on page 21-3.

21-2

Configure Signal Data for Logging

Configure Signal Data for Logging
Configure the model for logging and recording signal data.
1 Make sure that sldemo_f14 is closed. Clear the MATLAB workspace to

eliminate the results of previous simulation runs. At the MATLAB prompt,
type:
clear

The clear operation clears variables created during previous simulations
and all workspace variables, some of which are standard variables that the
sldemo_f14 model requires.
2 Open the model by entering sldemo_f14 at the MATLAB command line.
3 In the model window, choose File > Save As, navigate to the working

folder, and save a copy of the sldemo_f14 model as myf14.
4 Set up your model to log signal data for signals: Stick, alpha,rad, and

NzPilot,g. For each signal, follow these steps.
a Right-click the signal and select Properties from the context menu.
b In the Signal Properties dialog box, select Log signal Data.
c In the Logging name section, in the drop-down list, select Custom. In

the field, enter the logging name for the corresponding signal.
Signal Name

Logging Name

Stick

Stick_input

alpha,rad

Angle_of_attack

NzPilot,g

Pilot_G_force

d Click Apply and OK.

For information on how to log signal data, see “Export Signal Data Using
Signal Logging”.
5 Select Simulation > Model Configuration Parameters to open the

Configuration Parameters dialog box.

21-3

21

Simulation and Code Comparison

6 Select the Solver pane. In the Solver options section, specify the Type

parameter as Fixed-step.
7 On the Data Import/Export pane:

• Specify the Format parameter as Structure with time.
• Select the Signal logging parameter.
• Select the Record and inspect simulation output parameter. When
you select this parameter, on the Simulink Editor window, the Record
button is now on.
8 Save the model.

Proceed to “Log Simulation Data” on page 21-5.

21-4

Log Simulation Data

Log Simulation Data
Run the simulation, log the signal data, and view the data in the Simulation
Data Inspector.
1 Run the model. When the simulation is done, the Simulation Data

Inspector opens. You can also open the Simulation Data Inspector from
the Simulink Editor toolbar. Click the Record button arrow, and select
Simulation Data Inspector.
2 Right-click Run1:

myf14. In the context menu, select Group Signals.
Specify the Group Signals settings.

myf14 expander to view the logged variables. Then click
the logsout expander and then the expanders for each logged signal.

3 Click the Run1:

4 On the right pane, on the View toolbar, click Show Details.
5 In the Layout column, click the field that displays 1x1. A plot matrix

opens. To create a view of 4 plots, select the 2x2 matrix.
6 Select Hide Details.
7 For each signal:
a Click a plot, which will then show a blue border.
b Select the check box next to a logged signal name.

21-5

21

Simulation and Code Comparison

The next task is to “Log Data from the Generated Program” on page 21-7.

21-6

Log Data from the Generated Program

Log Data from the Generated Program
Because you have modified the model, you must rebuild and run the myf14
executable to obtain a valid data file.
1 Select Simulation > Model Configuration Parameters to open the

Configuration Parameters dialog box.
2 Select the Code Generation > Interface pane.
3 Set the MAT-file variable name modifier menu to rt_. Doing so

prefixes rt_ to each variable that you selected to be logged in the first
part of this example.
4 Click Apply and OK.
5 Save the model.
6 To generate code, on the Simulink Editor toolbar, click the Build Model

button. Status messages in the MATLAB Command Window track the
build process.
7 When the build is finished, run the standalone program from MATLAB.

!myf14

The executing program writes the following messages to the MATLAB
Command Window.
** starting the model **
** created myf14.mat **
8 Load the data file myf14.mat.
load myf14

9 To view the two execution outputs, alpha,rad and NzPilot,g, import the

data into the Simulation Data Inspector:
a In the Simulation Data Inspector, select File > Import Data to open

the Data Import dialog box.

21-7

21

Simulation and Code Comparison

b Specify Import from as Base workspace. Specify Import to as New

run.
c Click Clear All to clear all of the check boxes. Select the check box for

data where the Time Series Root is rt_yout and the Block Path is
myf14/alpha,rad and myf14/NzPilot,g.
d Click OK.

The selected data is now under Run2: Imported_Data.

10 On the Inspect Signals tab, you can view this data by selecting the Plot

button for each output.
Proceed to “Compare Numerical Results” on page 21-9.

21-8

Compare Numerical Results

Compare Numerical Results
You have now obtained data from a Simulink run of the model and from a run
of the program generated from the model. In the Simulation Data Inspector,
select the Compare Signals tab. Your comparison results might differ from
these results.
To compare alpha, rad, under Run 1, in the Sig 1 column, select
Angle_of_attack. Under Run 2, in the Sig 2 column, select alpha, rad.
The Signals plot shows the data. The difference is calculated and plotted in
the Difference plot.

To compare NzPilot,g, under Run 1, in the Sig 1 column, select
Pilot_G_force. Under Run 2, in the Sig 2 column, select NzPilot,g. The
Signals plot shows the data.

21-9

21

Simulation and Code Comparison

Overall agreement is within 10-16. The means of residuals are an order of
magnitude smaller. This slight error can be caused by many factors, including:
• Different compiler optimizations
• Statement ordering
• Run-time libraries
For example, a function call such as sin(2.0) might return a slightly
different value depending on which C library you are using. Such variations
can also cause differences between your results and these results.

21-10

Customization
• Chapter 22, “Build Process Integration”
• Chapter 23, “Run-Time Data Interface Extensions”
• Chapter 24, “Custom Target Development”

22
Build Process Integration
• “Control Build Process Compiling and Linking” on page 22-2
• “Cross-Compile Code Generated on Microsoft Windows” on page 22-4
• “Control Library Location and Naming During Build” on page 22-7
• “Recompile Precompiled Libraries” on page 22-12
• “Customize Post-Code-Generation Build Processing” on page 22-13
• “Configure Generated Code with TLC” on page 22-18
• “Customize Build Process with STF_make_rtw_hook File” on page 22-21
• “Customize Build Process with sl_customization.m” on page 22-28
• “Replace the STF_rtw_info_hook Mechanism” on page 22-33
• “Customize Build to Use Shared Utility Code” on page 22-34

22

Build Process Integration

Control Build Process Compiling and Linking
After generating code for a model, the Simulink Coder build process
determines whether or not to compile and link an executable program. This
decision is governed by the following:
• Generate code only option
When you select this option, the Simulink Coder software generates code
for the model, including a makefile.
• Generate makefile option
When you clear this option, the Simulink Coder software does not generate
a makefile for the model. You must specify any post code generation
processing, including compilation and linking, as a user-defined command,
as explained in “Customize Post-Code-Generation Build Processing” on
page 22-13.
• Makefile-only target
The Microsoft Visual C++ Project Makefile versions of the grt, grt_malloc,
and Embedded Coder target configurations generate a Visual C++ project
makefile (model.mak). To build an executable, you must open model.mak in
the Visual C++ IDE and compile and link the model code.
• HOST template makefile variable
The template makefile variable HOST identifies the type of system upon
which your executable is intended to run. The variable can be set to one of
three possible values: PC, UNIX, or ANY.
By default, HOST is set to UNIX in template makefiles designed for use with
The Open Group UNIX platforms (such as grt_unix.tmf), and to PC in the
template makefiles designed for use with development systems for the
PC (such as grt_vc.tmf).
If the Simulink software is running on the same type of system as that
specified by the HOST variable, then the executable is built. Otherwise,

-

22-2

If HOST = ANY, an executable is still built. This option is useful when
you want to cross-compile a program for a system other than the one the
Simulink software is running on.

Control Build Process Compiling and Linking

-

Otherwise, processing stops after generating the model code and the
makefile; the following message is displayed on the MATLAB command
line.
### Make will not be invoked - template makefile is for a different host

• TGT_FCN_LIB template makefile variable
The template makefile variable TGT_FCN_LIB specifies compiler command
line options. The line in the makefile is TGT_FCN_LIB = |>TGT_FCN_LIB<|.
By default, the Simulink Coder software expands the |>TGT_FCN_LIB<|
token to match the setting of the Code replacement library option on
the Code Generation > Interface pane of the Configuration Parameters
dialog box. Possible values for this option include ANSI_C, C99 (ISO),
GNU99 (GNU), and C++ (ISO). You can use this token in a makefile
conditional statement to specify compiler options to be used. For example,
if you set the token to C99 (ISO), the compiler might need an additional
option set to support C99 library functions.

22-3

22

Build Process Integration

Cross-Compile Code Generated on Microsoft Windows
If you need to generate code with the Simulink Coder software on a Microsoft
Windows system but compile the generated code on a different supported
platform, you can do so by modifying your TMF and model configuration
parameters. For example, you would need to do this if you develop
applications with the MATLAB and Simulink products on a Windows system,
but you run your generated code on a Linux system.
To set up a cross-compilation development environment, do the following
(here a Linux system is the destination platform):
1 On your Windows system, copy the UNIX TMF for your target to a local

folder. This will be your working folder for initiating code generation.
For example, you might copy matlabroot/rtw/c/grt/grt_unix.tmf to
D:/work/my_grt_unix.tmf.
2 Make the following changes to your copy of the TMF:

• Add the following line near the SYS_TARGET_FILE = line:
MAKEFILE_FILESEP = /

• Search for the line 'ifeq ($(OPT_OPTS),$(DEFAULT_OPT_OPTS))' and,
for each occurrence, remove the conditional logic and retain only the
'else' code. That is, remove everything from the 'if' to the 'else',
inclusive, as well as the closing 'endif'. Only the lines from the 'else'
portion should remain. This forces the run-time libraries to build for
a Linux system.
3 Open your model and make the following changes in the Code Generation

pane of the Configuration Parameters dialog:
• Specify the name of your new TMF in the Template makefile text box
(for example, my_grt_unix.tmf).
• Select Generate code only and click Apply.
4 Generate the code.
5 If the build folder (folder from which the model was built) is not already

Linux accessible, copy it to a Linux accessible path. For example, if your

22-4

Cross-Compile Code Generated on Microsoft® Windows®

build folder for the generated code was D:\work\mymodel_grt_rtw, copy
that entire folder tree to a path such as /home/user/mymodel_grt_rtw.
6 If the MATLAB folder tree on the Windows system is Linux accessible, skip

this step. Otherwise, you must copy all the include and source folders to
a Linux accessible drive partition, for example, /home/user/myinstall.
These folders appear in the makefile after MATLAB_INCLUDES = and
ADD_INCLUDES = and can be found by searching for $(MATLAB_ROOT). Any
path that contains $(MATLAB_ROOT) must be copied. Here is an example
list (your list will vary depending on your model):
$(MATLAB_ROOT)/rtw/c/grt
$(MATLAB_ROOT)/extern/include
$(MATLAB_ROOT)/simulink/include
$(MATLAB_ROOT)/rtw/c/src
$(MATLAB_ROOT)/rtw/c/tools

Additionally, paths containing $(MATLAB_ROOT) in the build rules (lines
with %.o :) must be copied. For example, based on the build rule
%.o : $(MATLAB_ROOT)/rtw/c/src/ext_mode/tcpip/%.c

the following folder should be copied:
$(MATLAB_ROOT)/rtw/c/src/ext_mode/tcpip

Note The path hierarchy relative to the MATLAB root must be
maintained. For example, c:\MATLAB\rtw\c\tools\* would be copied to
/home/user/mlroot/rtw/c/tools/*.
For some blocksets, it is easiest to copy a higher-level folder that includes
the subfolders listed in the makefile. For example, the DSP System Toolbox
product requires the following folders to be copied:
$(MATLAB_ROOT)/toolbox/dspblks
$(MATLAB_ROOT)/toolbox/rtw/dspblks

7 Make the following changes to the generated makefile:

22-5

22

Build Process Integration

• Set both MATLAB_ROOT and ALT_MATLAB_ROOT equal to the Linux
accessible path to matlabroot (for example, home/user/myinstall).
• Set COMPUTER to the computer value for your platform, such as GLNX86.
Enter help computer in the MATLAB Command Window for a list of
computer values.
• In the ADD_INCLUDES list, change the build folder (designating the
location of the generated code on the Windows system) and parent
folders to Linux accessible include folders. For example, change
D:\work\mymodel_grt_rtw\ to /home/user/mymodel_grt_rtw.
Additionally, if matlabroot is a UNC path, such as
\\my-server\myapps\matlab, replace the hard-coded MATLAB root
with $(MATLAB_ROOT).
8 From a Linux shell, compile the code you generated on the Windows

system. You can do this by running the generated model.bat file or by
typing the make command line as it appears in the .bat file.
Note If errors occur during makefile execution, you may need to run the
dos2unix utility on the makefile (for example, dos2unix mymodel.mk).

22-6

Control Library Location and Naming During Build

Control Library Location and Naming During Build
Two configuration parameters, TargetPreCompLibLocation and
TargetLibSuffix, are available for you to use to control values placed
in Simulink Coder generated makefiles during the token expansion from
template makefiles (TMFs). You can use these parameters to
• Specify the location of precompiled libraries, such as blockset libraries or
the Simulink Coder library. Typically, a target has cross-compiled versions
of these libraries and places them in a target-specific folder.
• Control the suffix applied to library file names (for example, _target.a
or _target.lib).
Targets can set the parameters inside the system target file (STF) select
callback. For example:
function mytarget_select_callback_handler(varargin)
hDig=varargin{1};
hSrc=varargin{2};
slConfigUISetVal(hDig, hSrc,...
'TargetPreCompLibLocation', 'c:\mytarget\precomplibs');
slConfigUISetVal(hDig, hSrc, 'TargetLibSuffix',...
'_diab.library');

The TMF has corresponding expansion tokens:
|>EXPAND_LIBRARY_LOCATION<|
|>EXPAND_LIBRARY_SUFFIX<|

Alternatively, you can use a call to the set_param function. For example:
set_param(model,'TargetPreCompLibLocation',...
'c:\mytarget\precomplibs');

Note If your model contains referenced models, you can use the make option
USE_MDLREF_LIBPATHS to control whether libraries used by the referenced
models are copied to the parent model’s build folder. For more information,
see “Control the Location of Model Reference Libraries” on page 22-9.

22-7

22

Build Process Integration

Specify the Location of Precompiled Libraries
Use the TargetPreCompLibLocation configuration parameter to:
• Override the precompiled library location specified in the rtwmakecfg.m
file (see “Use rtwmakecfg.m API to Customize Generated Makefiles” on
page 14-124 for details)
• Precompile and distribute target-specific versions of product libraries (for
example, the DSP System Toolbox product)
For a precompiled library, such as a blockset library or the Simulink Coder
library, the location specified in rtwmakecfg.m is typically a location specific to
the blockset or the Simulink Coder product. It is expected that the library will
exist in this location and it is linked against during Simulink Coder builds.
However, for some applications, such as custom targets, it is preferable to
locate the precompiled libraries in a target-specific or other alternate location
rather than in the location specified in rtwmakecfg.m. For a custom target,
the library is expected to be created using the target-specific cross-compiler
and placed in the target-specific location for use during the Simulink Coder
build process. All libraries intended to be supported by the target should be
compiled and placed in the target-specific location.
You can set up the TargetPreCompLibLocation parameter in its select
callback. The path that you specify for the parameter must be a fully qualified
absolute path to the library location. Relative paths are not supported. For
example:
slConfigUISetVal(hDlg, hSrc, 'TargetPreCompLibLocation',...
'c:\mytarget\precomplibs');

Alternatively, you set the parameter with a call to the set_param function.
For example:
set_param(model,'TargetPreCompLibLocation',...
'c:\mytarget\precomplibs');

During the TMF-to-makefile conversion, the Simulink Coder build process
replaces the token |>EXPAND_LIBRARY_LOCATION<| with the specified location
in the rtwmakecfg.m file. For example, if the library name specified in the
rtwmakecfg.m file is 'rtwlib', the TMF expands from:

22-8

Control Library Location and Naming During Build

LIBS += |>EXPAND_LIBRARY_LOCATION<|\|>EXPAND_LIBRARY_NAME<|\
|>EXPAND_LIBRARY_SUFFIX<|

to:
LIBS += c:\mytarget\precomplibs\rtwlib_diab.library

By default, TargetPreCompLibLocation is an empty string and the Simulink
Coder build process uses the location specified in rtwmakecfg.m for the token
replacement.

Control the Location of Model Reference Libraries
On platforms other than the Apple Macintosh platform, when building a model
that uses referenced models, the Simulink Coder build process by default:
• Copies libraries used by the referenced models to the parent model’s build
folder
• Assigns the filenames of the libraries to MODELREF_LINK_LIBS in the
generated makefile
For example, if a model includes a referenced model sub, the Simulink
Coder build process assigns the library name sub_rtwlib.lib to
MODELREF_LINK_LIBS and copies the library file to the parent model’s
build folder. This definition is then used in the final link line, which links
the library into the final product (usually an executable). This technique
minimizes the length of the link line.
On the Macintosh platform, and optionally on other platforms, the Simulink
Coder build process:
• Does not copy libraries used by the referenced models to the parent model’s
build folder
• Assigns the relative paths and filenames of the libraries to
MODELREF_LINK_LIBS in the generated makefile
When using this technique, the Simulink Coder build process assigns a relative
path such as ../slprj/grt/sub/sub_rtwlib.lib to MODELREF_LINK_LIBS
and uses the path to gain access to the library file at link time.

22-9

22

Build Process Integration

To change to the non-default behavior on platforms other than the Macintosh
platform, enter the following command in the Make command field of the
Code Generation pane of the Configuration Parameters dialog box:
make_rtw USE_MDLREF_LIBPATHS=1

If you specify other Make command arguments, such as OPTS="-g", you can
specify the multiple arguments in any order.
To return to the default behavior, set USE_MDLREF_LIBPATHS to 0, or remove it.

Control the Suffix Applied to Library File Names
Use the TargetLibSuffix configuration parameter to control the suffix
applied to library names (for example, _target.lib or _target.a).
The specified suffix string must include a period (.). You can apply
TargetLibSuffix to the following libraries:
• Libraries on which a target depends, as specified in the rtwmakecfg.m
API. You can use TargetLibSuffix to affect the suffix of both precompiled
and non-precompiled libraries configured from the rtwmakecfg API. For
details, see “Use rtwmakecfg.m API to Customize Generated Makefiles”
on page 14-124.
In this case, a target can set the parameter in its select callback. For
example:
slConfigUISetVal(hDlg, hSrc, 'TargetLibSuffix',...
'_diab.library');

Alternatively, you can use a call to the set_param function. For example:
set_param(model,'TargetLibSuffix','_diab.library');

During the TMF-to-makefile conversion, the Simulink Coder build process
replaces the token |>EXPAND_LIBRARY_SUFFIX<| with the specified suffix.
For example, if the library name specified in the rtwmakecfg.m file is
'rtwlib', the TMF expands from:
LIBS += |>EXPAND_LIBRARY_LOCATION<|\|>EXPAND_LIBRARY_NAME<|\
|>EXPAND_LIBRARY_SUFFIX<|

22-10

Control Library Location and Naming During Build

to:
LIBS += c:\mytarget\precomplibs\rtwlib_diab.library

By default, TargetLibSuffix is set to an empty string. In
this case, the Simulink Coder build process replaces the token
|>EXPAND_LIBRARY_SUFFIX<| with an empty string.
• Shared utility library and the model libraries created with model
reference. For these cases, associated makefile variables do not require the
|>EXPAND_LIBRARY_SUFFIX<| token. Instead, the Simulink Coder build
process includes TargetLibSuffix implicitly. For example, for a top model
named topmodel with submodels named submodel1 and submodel2, the
top model’s TMF is expanded from:
SHARED_LIB
= |>SHARED_LIB<|
MODELLIB
= |>MODELLIB<|
MODELREF_LINK_LIBS = |>MODELREF_LINK_LIBS<|

to:
SHARED_LIB
= \
..\slprj\ert\_sharedutils\rtwshared_diab.library
MODELLIB
= topmodellib_diab.library
MODELREF_LINK_LIBS = \
submodel1_rtwlib_diab.library submodel2_rtwlib_diab.library

By default, the TargetLibSuffix parameter is an empty string. In this
case, the Simulink Coder build process chooses a default suffix for these
three tokens using a file extension of .lib on Windows hosts and .a on
UNIX hosts. (For model reference libraries, the default suffix additionally
includes _rtwlib.) For example, on a Windows host, the expanded makefile
values would be:
SHARED_LIB
= ..\slprj\ert\_sharedutils\rtwshared.lib
MODELLIB
= topmodellib.lib
MODELREF_LINK_LIBS = submodel1_rtwlib.lib submodel2_rtwlib.lib

22-11

22

Build Process Integration

Recompile Precompiled Libraries
You can recompile precompiled libraries included as part of the Simulink
Coder product, such as rtwlib or dsplib, by using a supplied MATLAB
function, rtw_precompile_libs. You might consider doing this if you
need to customize compiler settings for various platforms or environments.
For details on using rtw_precompile_libs, see “Precompile S-Function
Libraries” on page 14-129.

22-12

Customize Post-Code-Generation Build Processing

Customize Post-Code-Generation Build Processing
The Simulink Coder product provides a set of tools, including a build
information object, you can use to customize build processing that occurs after
code generation. You might use such customizations for target development
or the integration of third-party tools into your application development
environment. The next figure and the steps that follow show the general
workflow for setting up such customizations.

Program post code
generation command
Define post code
generation command

Generate
a makefile?

No

Suppress makefile
generation

Yes
Modify post code
generation command

Build model

No

Results
OK?
Yes
Done

1 Program the post code generation command.
2 Define the post code generation command.
3 Suppress makefile generation, if applicable..
4 Build the model.

22-13

22

Build Process Integration

5 Modify the command and rebuild the model until the build results are

acceptable.

Build Information Object
At the start of a model build, the Simulink Coder build process logs the
following build option and dependency information to a temporary build
information object:
• Compiler options
• Preprocessor identifier definitions
• Linker options
• Source files and paths
• Include files and paths
• Precompiled external libraries
You can retrieve information from and add information to this object by using
an extensive set of functions. For a list of available functions and detailed
function descriptions, see “Build Process”. “Program a Post Code Generation
Command” on page 22-14 explains how to use the functions to control post
code generation build processing.

Program a Post Code Generation Command
For certain applications, you might want to control aspects of the build
process after the code generation. For example, you might do this if you
develop your own target, or you want to apply an analysis tool to the
generated code before continuing with the build process. You can apply this
level of control to the build process by programming and then defining a post
code generation command.
A post code generation command is a MATLAB language file that typically
calls functions that get data from or add data to the model’s build information
object. You can program the command as a script or function.

22-14

Customize Post-Code-Generation Build Processing

If You Program the
Command as a...

Then the...

Script

Script can gain access to the model name and
the build information directly

Function

Function can pass the model name and the
build information as arguments

If your post code generation command calls user-defined functions, make sure
the functions are on the MATLAB path. If the Simulink Coder build process
cannot find a function you use in your command, the build process errors out.
You can then call any combination of build information functions, as listed
in “Build Process”, to customize the model’s post code generation build
processing.
The following example shows a fragment of a post code generation command
that gets the filenames and paths of the source and include files generated for
a model for analysis.
function analyzegencode(buildInfo)
% Get the names and paths of all source and include files
% generated for the model and then analyze them.
% buildInfo - build information for my model.
% Define cell array to hold data.
MyBuildInfo={};
% Get source file information.
MyBuildInfo.srcfiles=getSourceFiles(buildInfo, true, true);
MyBuildInfo.srcpaths=getSourcePaths(buildInfo, true);
% Get include (header) file information.
MyBuildInfo.incfiles=getIncludeFiles(buildInfo, true, true);
MyBuildInfo.incpaths=getIncludePaths(buildInfo, true);
% Analyze generated code.
.
.

22-15

22

Build Process Integration

.

Define a Post Code Generation Command
After you program a post code generation command, you need to inform the
Simulink Coder build process that the command exists and to add it to the
model’s build processing. You do this by defining the command with the
PostCodeGenCommand model configuration parameter. When you define a post
code generation command, the Simulink Coder build process evaluates the
command after generating and writing the model’s code to disk and before
generating a makefile.
As the following syntax lines show, the arguments that you specify when
setting the configuration parameter varies depending on whether you
program the command as a script, function, or set of functions.
Note When defining the command as a function, you can specify an arbitrary
number of input arguments. To pass the model’s name and build information
to the function, specify identifiers modelName and buildInfo as arguments.
Script
set_param(model, 'PostCodeGenCommand',...
'pcgScriptName');

Function
set_param(model, 'PostCodeGenCommand',...
'pcgFunctionName(modelName)');

Multiple Functions
pcgFunctions=...
'pcgFunction1Name(modelName);...
pcgFunction2Name(buildInfo)';
set_param(model, 'PostCodeGenCommand',...
pcgFunctions);

The following call to set_param defines PostCodGenCommand to evaluate the
function analyzegencode.

22-16

Customize Post-Code-Generation Build Processing

set_param(model, 'PostCodeGenCommand',...
'analyzegencode(buildInfo)');

Suppress Makefile Generation
The Simulink Coder product provides the ability to suppress makefile
generation during the build process. For example, you might do this to
integrate tools into the build process that are not driven by makefiles.
To instruct the Simulink Coder build process to not generate a makefile, do
one of the following:
• Clear the Generate makefile option on the Code Generation pane of
the Configuration Parameters dialog box.
• Set the value of the configuration parameter GenerateMakefile to off.
When you suppress makefile generation,
• You no longer can explicitly specify a make command or template makefile.
• You must specify your own instructions for any post code generation
processing, including compilation and linking, in a post code generation
command as explained in “Program a Post Code Generation Command” on
page 22-14 and “Define a Post Code Generation Command” on page 22-16.

22-17

22

Build Process Integration

Configure Generated Code with TLC
In this section...
“About Configuring Generated Code with TLC” on page 22-18
“Assigning Target Language Compiler Variables” on page 22-18
“Set Target Language Compiler Options” on page 22-20

About Configuring Generated Code with TLC
You can use the Target Language Compiler (TLC) to fine tune your generated
code. TLC supports extended code generation variables and options in
addition to parameters available on the Code Generation pane on the
Configuration Parameters dialog box. There are two ways to set TLC
variables and options, as described in this section.
Note You should not customize TLC files in the folder matlabroot/rtw/c/tlc
even though the capability exists to do so. Such TLC customizations might not
be applied during the code generation process and can lead to unpredictable
results.

Assigning Target Language Compiler Variables
The %assign statement lets you assign a value to a TLC variable, as in
%assign MaxStackSize = 4096

This is also known as creating a parameter name/parameter value pair.
For a description of the %assign statement see “Target Language Compiler
Directives”. You should write your %assign statements in the Configure RTW
code generation settings section of the system target file.
The following table lists the code generation variables you can set with the
%assign statement.

22-18

Configure Generated Code with TLC

Target Language Compiler Optional Variables
Variable

Description

MaxStackSize=N

When the Enable local block outputs check box is
selected, the total allocation size of local variables that
are declared by all block outputs in the model cannot
exceed MaxStackSize (in bytes). MaxStackSize can be
any positive integer. If the total size of local block output
variables exceeds this maximum, the remaining block
output variables are allocated in global, rather than local,
memory. The default value for MaxStackSize is rtInf,
that is, unlimited stack size.
Note: Local variables in the generated code from sources
other than local block outputs, such as from a Stateflow
diagram or MATLAB Function block, and stack usage
from sources such as function calls and context switching
are not included in the MaxStackSize calculation. For
overall executable stack usage metrics, do a target-specific
measurement by using run-time (empirical) analysis or
static (code path) analysis with object code.

MaxStackVariableSize=N

When the Enable local block outputs check box is
selected, this limits the size of any local block output
variable declared in the code to N bytes, where N>0. A
variable whose size exceeds MaxStackVariableSize
is allocated in global, rather than local, memory. The
default is 4096.

WarnNonSaturatedBlocks=value

Flag to control display of overflow warnings for blocks
that have saturation capability, but have it turned off
(unchecked) in their dialog. These are the options:
• 0 — No warning is displayed.
• 1 — Displays one warning for the model during code
generation
• 2 — Displays one warning that contains a list of all
offending blocks

22-19

22

Build Process Integration

Set Target Language Compiler Options
You can enter TLC options in the TLC options edit field on the Code
Generation pane of the Configuration Parameters dialog box. For
information about these options, see “Specify TLC Options” on page 15-12
and “Configure TLC”.

22-20

Customize Build Process with STF_make_rtw_hook File

Customize Build Process with STF_make_rtw_hook File
In this section...
“About the STF_make_rtw_hook File” on page 22-21
“Conventions for Using the STF_make_rtw_hook File” on page 22-21
“STF_make_rtw_hook.m Function Prototype and Arguments” on page 22-22
“Applications for STF_make_rtw_hook.m” on page 22-25
“Control Code Regeneration Using STF_make_rtw_hook.m” on page 22-26
“Use STF_make_rtw_hook.m for Your Build Procedure” on page 22-27

About the STF_make_rtw_hook File
The build process lets you supply optional hook files that are executed at
specified points in the code-generation and make process. You can use hook
files to add target-specific actions to the build process.
This section describes an important MATLAB hook, generically referred to as
STF_make_rtw_hook.m, where STF is the name of a system target file, such as
ert or mytarget. This hook file implements a function, STF_make_rtw_hook,
that dispatches to a specific action, depending on the hookMethod argument
passed in.
The build process automatically calls STF_make_rtw_hook, passing in
thehookMethod argument (as well as other arguments described below). You
need to implement only those hook methods that your build process requires.

Conventions for Using the STF_make_rtw_hook File
For the build process to call the STF_make_rtw_hook, check that the following
conditions are met:
• The STF_make_rtw_hook.m file is on the MATLAB path.
• The filename is the name of your system target file (STF), appended to
the string _make_rtw_hook.m. For example, if you were generating code
with a custom system target file mytarget.tlc, you would name your
STF_make_rtw_hook.m file to mytarget_make_rtw_hook.m. Likewise, the

22-21

22

Build Process Integration

hook function implemented within the file should follow the same naming
convention.
• The hook function implemented in the file follows the function prototype
described in the next section.

STF_make_rtw_hook.m Function Prototype and
Arguments
The function prototype for STF_make_rtw_hook is
function STF_make_rtw_hook(hookMethod, modelName, rtwRoot, templateMakefile,
buildOpts, buildArgs)

The arguments are defined as:
• hookMethod: String specifying the stage of build process from which the
STF_make_rtw_hook function is called. The flowchart below summarizes
the build process, highlighting the hook points. Valid values for hookMethod
are 'entry', 'before_tlc', 'after_tlc', 'before_make', 'after_make',
'exit', and 'error'. The STF_make_rtw_hook function dispatches to the
relevant code with a switch statement.

22-22

Customize Build Process with STF_make_rtw_hook File

Input:
modelName,buildArgs

Start build process
Simulink Coder
verification
STF ‘entry’ hook
Create build directory
STF ‘before_tlc’ hook

Input:
buildOpts,templateMakefile

Error occurs
STF ‘error’ hook

Generate code
STF ‘af ter_tlc’ hook
STF ‘before_make’ hook
Invoke post code
generation command
Make
STF ‘after_make’ hook
STF ‘exit’ hook
End build process

• modelName: String specifying the name of the model. Valid at all stages
of the build process.
• rtwRoot: Reserved.
• templateMakefile: Name of template makefile.

22-23

22

Build Process Integration

• buildOpts: A MATLAB structure containing the fields described in the list
below. Valid for the 'before_make', 'after_make', and 'exit' stages
only. The buildOpts fields include:

-

modules: Character array specifying a list of additional files that need
to be compiled.

-

codeFormat: Character array containing code format specified for the
target. (ERT-based targets must use the 'Embedded-C' code format.)

-

noninlinedSFcns: Cell array specifying list of noninlined S-functions in

the model.
compilerEnvVal: String specifying compiler environment variable value
(for example, C:\Applications\Microsoft Visual).

• buildArgs: Character array containing the argument to make_rtw. When
you invoke the build process, buildArgs is copied from the argument string
(if any) following "make_rtw" in the Make command field of the Code
Generation pane of the Configuration Parameters dialog box.

The make arguments from the Make command field in the figure above,
for example, generate the following:
% make -f untitled.mk VAR1=0 VAR2=4

22-24

Customize Build Process with STF_make_rtw_hook File

Applications for STF_make_rtw_hook.m
An enumeration of all possible uses for STF_make_rtw_hook.m is beyond the
scope of this document. However, this section provides some suggestions of
how you might apply the available hooks.
In general, you can use the 'entry' hook to initialize the build process
before any code is generated, for example to change or validate settings. One
application for the 'entry' hook is to rerun the auto-configuration script that
initially ran at target selection time to compare model parameters before and
after the script executes for validation purposes.
The other hook points, 'before_tlc', 'after_tlc', 'before_make',
'after_make', 'exit', and 'error' are useful for interfacing with external
tool chains, source control tools, and other environment tools.
For example, you could use the STF_make_rtw_hook.m file at any stage after
'entry' to obtain the path to the build folder. At the 'exit' stage, you
could then locate generated code files within the build folder and check them
into your version control system. You might use 'error' to clean up static
or global data used by the hook function when an error occurs during code
generation or the build process.
Note that the build process temporarily changes the MATLAB working
folder to the build folder for stages 'before_make', 'after_make', 'exit',
and 'error'. Your STF_make_rtw_hook.m file should not make incorrect
assumptions about the location of the build folder. You can obtain the
path to the build folder anytime after the 'entry' stage. In the following
code example, the build folder path is returned as a string to the variable
buildDirPath.
makertwObj = get_param(gcs, 'MakeRTWSettingsObject');
buildDirPath = getfield(makertwObj, 'BuildDirectory');

22-25

22

Build Process Integration

Control Code Regeneration Using
STF_make_rtw_hook.m
When you rebuild a model, by default, the build process performs checks
to determine whether changes to the model or relevant settings require
regeneration of the top model code. (For details on the criteria, see “Control
Regeneration of Top Model Code” on page 15-27.) If the checks determine that
top model code generation is required, the build process fully regenerates and
compiles the model code. If the checks indicate that the top model generated
code is current with respect to the model, and no model settings require full
regeneration, the build process omits regeneration of the top model code.
Regardless of whether the top model code is regenerated, the build process
subsequently calls all build process hooks, including STF_make_rtw_hook
functions and the post code generation command. The following
mechanisms allow you to perform actions related to code regeneration in
the STF_make_rtw_hook functions:
• To force code regeneration, use the following function call from the 'entry'
hook:
rtw.targetNeedsCodeGen('set', true);

• In all hooks from 'before_tlc' through 'exit', the buildOpts structure
passed to the hook has a Boolean field codeWasUpToDate, which is set to
true if model code was up to date and code was not regenerated, or false if
code was not up to date and code was regenerated. You can customize hook
actions based on the value of this field. For example:
...
case `before_tlc'
if buildOpts.codeWasUpToDate
%Perform hook actions for up to date model
else
%Perform hook actions for full code generation
end
...

22-26

Customize Build Process with STF_make_rtw_hook File

Use STF_make_rtw_hook.m for Your Build Procedure
To create a custom STF_make_rtw_hook hook file for your build procedure,
copy and edit the example ert_make_rtw_hook.m file (located in the
matlabroot/toolbox/rtw/targets/ecoder folder) as follows:
1 Copy ert_make_rtw_hook.m to a folder in the MATLAB path, and rename

it in accordance with the naming conventions described in “Conventions for
Using the STF_make_rtw_hook File” on page 22-21. For example, to use it
with the GRT target grt.tlc, rename it to grt_make_rtw_hook.m.
2 Rename the ert_make_rtw_hook function within the file to match the

filename.
3 Implement the hooks that you require by adding code to case statements

within the switch hookMethod statement.

22-27

22

Build Process Integration

Customize Build Process with sl_customization.m
In this section...
“About sl_customization.m” on page 22-28
“Register Build Process Hook Functions Using sl_customization.m” on
page 22-30
“Variables Available for sl_customization.m Hook Functions” on page 22-31
“Example Build Process Customization Using sl_customization.m” on page
22-31

About sl_customization.m
The Simulink customization file sl_customization.m is a mechanism
that allows you to use MATLAB to customize the standard Simulink user
interface. The Simulink software reads the sl_customization.m file, if
present on the MATLAB path, when it starts and the customizations specified
in the file are applied to the Simulink session. For more information on the
sl_customization.m customization file, see “Registering Customizations”.
The sl_customization.m file can be used to register installation-specific
hook functions to be invoked during the Simulink Coder build process. The
hook functions that you register through sl_customization.m complement
System Target File (STF) hooks (described in “Customize Build Process
with STF_make_rtw_hook File” on page 22-21) and post-code generation
commands (described in “Customize Post-Code-Generation Build Processing”
on page 22-13).
The following figure shows the relationship between installation-level hooks
and the other available mechanisms for customizing the build process.

22-28

Customize Build Process with sl_customization.m

Start build process
Simulink Coder verification

Entry

STF 'entry' hook
Installation 'entry' hook

Before TLC

STF 'before_tlc' hook

Installation 'before_tlc' hook

After TLC

STF 'after_tlc' hook

Installation 'after_tlc' hook

Before Make

STF 'before_make' hook

Installation 'before_make' hook

After Make

STF 'after_make' hook

Post code
generation
command

Installation 'after_make' hook

Exit

STF 'exit' hook
Installation 'exit' hook

End build process

22-29

22

Build Process Integration

Register Build Process Hook Functions Using
sl_customization.m
To register installation-level hook functions that will be invoked during
the Simulink Coder build process, you create a MATLAB function called
sl_customization.m and include it on the MATLAB path of the Simulink
installation that you want to customize. The sl_customization function
accepts one argument: a handle to a customization manager object. For
example,
function sl_customization(cm)

As a starting point for your customizations, the sl_customization function
must first get the default (factory) customizations, using the following
assignment statement:
hObj = cm.RTWBuildCustomizer;

You then invoke methods to register your customizations. The customization
manager object includes the following method for registering Simulink Coder
build process hook customizations:
• addUserHook(hObj, hookType, hook)
Registers the MATLAB hook script or function specified by hook for
the build process stage represented by hookType. The valid values for
hookType are 'entry', 'before_tlc', 'after_tlc', 'before_make',
'after_make', and 'exit'.
Your instance of the sl_customization function should use this method to
register installation-specific hook functions.
The Simulink software reads the sl_customization.m file when it starts. If
you subsequently change the file, you must restart the Simulink session or
enter the following command at the MATLAB command line to effect the
changes:
sl_refresh_customizations

22-30

Customize Build Process with sl_customization.m

Variables Available for sl_customization.m Hook
Functions
The following variables are available for sl_customization.m hook functions
to use:
• modelName — The name of the Simulink model (valid for all stages)
• dependencyObject — An object containing the dependencies of the
generated code (valid only for the 'after_make' stage)
A hook script can directly access the valid variables. A hook function can pass
the valid variables as arguments to the function. For example:
hObj.addUserHook('after_make', 'afterMakeFunction(modelName,dependencyObject);');

Example Build Process Customization Using
sl_customization.m
The sl_customization.m file shown in Example 1: sl_customization.m for
Simulink® Coder™ Build Process Customizations on page 22-31 uses the
addUserHook method to specify installation-specific build process hooks to be
invoked at the 'entry' and 'after_tlc' stages of the Simulink Coder build.
For the hook function source code, see Example 2: CustomRTWEntryHook.m
on page 22-32 and Example 3: CustomRTWPostProcessHook.m on page 22-32.
Example 1: sl_customization.m for Simulink Coder Build Process
Customizations
function sl_customization(cm)
% Register user customizations
% Get default (factory) customizations
hObj = cm.RTWBuildCustomizer;
% Register build process hooks
hObj.addUserHook('entry', 'CustomRTWEntryHook(modelName);');
hObj.addUserHook('after_tlc', 'CustomRTWPostProcessHook(modelName);');
end

22-31

22

Build Process Integration

Example 2: CustomRTWEntryHook.m
function [str, status] = CustomRTWEntryHook(modelName)
str =sprintf('Custom entry hook for model ''%s.''',modelName);
disp(str)
status =1;

Example 3: CustomRTWPostProcessHook.m
function [str, status] = CustomRTWPostProcessHook(modelName)
str =sprintf('Custom post process hook for model ''%s.''',modelName);
disp(str)
status =1;

If you include the above three files on the MATLAB path of the Simulink
installation that you want to customize, the coded hook function messages
will appear in the displayed output for Simulink Coder builds. For example, if
you open the ERT-based model rtwdemo_udt, open the Code Generation
pane of the Configuration Parameters dialog box, and click the Build button
to initiate a Simulink Coder build, the following messages are displayed:
>> rtwdemo_udt

### Starting build procedure for model: rtwdemo_udt
Custom entry hook for model 'rtwdemo_udt.'
Custom post process hook for model 'rtwdemo_udt.'
### Successful completion of build procedure for model: rtwdemo_udt
>>

22-32

Replace the STF_rtw_info_hook Mechanism

Replace the STF_rtw_info_hook Mechanism
Prior to MATLAB Release 14, custom targets supplied target-specific
information with a hook file (referred to as STF_rtw_info_hook.m).
The STF_rtw_info_hook specified properties such as word sizes for
integer data types (for example, char, short, int, and long), and C
implementation-specific properties of the custom target.
The STF_rtw_info_hook mechanism has been replaced by the Hardware
Implementation pane of the Configuration Parameters dialog box. Using
this dialog box, you can specify all properties that were formerly specified in
your STF_rtw_info_hook file.
For backward compatibility, existing STF_rtw_info_hook files are available.
However, you should convert your target and models to use of the Hardware
Implementation pane. See “Target” on page 9-9 .

22-33

22

Build Process Integration

Customize Build to Use Shared Utility Code
The shared utility folders (slprj/target/_sharedutils) typically store
generated utility code that is common to a top model and the models it
references. You can also force the build process to use a shared utilities folder
for a standalone model. See “Logging” on page 15-105 for details.
If you want your target to support compilation of code generated in the shared
utilities folder, you must modify your template makefile (TMF). The shared
utilities folder is required to support model reference builds. See “Support
Model Referencing” on page 24-101 to learn about additional updates for
supporting model reference builds.
The exact syntax of the changes can vary due to differences in the make utility
and compiler/archive tools used by your target. The examples below are based
on the Free Software Foundation’s GNU make utility. You can find the
following updated TMF examples for GNU and Microsoft Visual C++ make
utilities in the GRT and ERT target folders:
• GRT: matlabroot/rtw/c/grt/

-

grt_lcc.tmf
grt_vc.tmf
grt_unix.tmf

• ERT: matlabroot/rtw/c/ert/

-

ert_lcc.tmf
ert_vc.tmf
ert_unix.tmf

Use the GRT or ERT examples as a guide to the location, within the TMF, of
the changes and additions described below.
Note The ERT-based TMFs contain extra code to handle generation of ERT
S-functions and model reference simulation targets. Your target does not
need to handle these cases.

22-34

Customize Build to Use Shared Utility Code

Modify Template Makefiles to Support Shared
Utilities
Make the following changes to your TMF to support the shared utilities folder:
1 Add the following make variables and tokens to be expanded when the

makefile is generated:
SHARED_SRC
SHARED_SRC_DIR
SHARED_BIN_DIR
SHARED_LIB

=
=
=
=

|>SHARED_SRC<|
|>SHARED_SRC_DIR<|
|>SHARED_BIN_DIR<|
|>SHARED_LIB<|

SHARED_SRC specifies the shared utilities folder location and the source files
in it. A typical expansion in a makefile is
SHARED_SRC

= ../slprj/ert/_sharedutils/*.c

SHARED_LIB specifies the library file built from the shared source files, as

in the following expansion.
SHARED_LIB

= ../slprj/ert/_sharedutils/rtwshared.lib

SHARED_SRC_DIR and SHARED_BIN_DIR allow specification of separate
folders for shared source files and the library compiled from the source files.
In the current release, all TMFs use the same path, as in the following
expansions.
SHARED_SRC_DIR
SHARED_BIN_DIR

= ../slprj/ert/_sharedutils
= ../slprj/ert/_sharedutils

2 Set the SHARED_INCLUDES variable according to whether shared utilities

are in use. Then append it to the overall INCLUDES variable.
SHARED_INCLUDES =
ifneq ($(SHARED_SRC_DIR),)
SHARED_INCLUDES = -I$(SHARED_SRC_DIR)
endif
INCLUDES = -I. $(MATLAB_INCLUDES) $(ADD_INCLUDES) \
$(USER_INCLUDES) $(SHARED_INCLUDES)

22-35

22

Build Process Integration

3 Update the SHARED_SRC variable to list all shared files explicitly.

SHARED_SRC := $(wildcard $(SHARED_SRC))
4 Create a SHARED_OBJS variable based on SHARED_SRC.

SHARED_OBJS = $(addsuffix .o, $(basename $(SHARED_SRC)))
5 Create an OPTS (options) variable for compilation of shared utilities.

SHARED_OUTPUT_OPTS = -o $@
6 Provide a rule to compile the shared utility source files.

$(SHARED_OBJS) : $(SHARED_BIN_DIR)/%.o : $(SHARED_SRC_DIR)/%.c
$(CC) -c $(CFLAGS) $(SHARED_OUTPUT_OPTS) $<
7 Provide a rule to create a library of the shared utilities. The following

example is based on The Open Group UNIX platforms.
$(SHARED_LIB) : $(SHARED_OBJS)
@echo "### Creating $@ "
ar r $@ $(SHARED_OBJS)
@echo "### Created $@ "
8 Add SHARED_LIB to the rule that creates the final executable.

$(PROGRAM) : $(OBJS) $(LIBS) $(SHARED_LIB)
$(LD) $(LDFLAGS) -o $@ $(LINK_OBJS) $(LIBS) $(SHARED_LIB)\
$(SYSLIBS)
@echo "### Created executable: $(MODEL)"
9 Remove any explicit reference to rt_nonfinite.c or rt_nonfinite.cpp

from your TMF. For example, change
ADD_SRCS = $(RTWLOG) rt_nonfinite.c

to
ADD_SRCS = $(RTWLOG)

22-36

23
Run-Time Data Interface
Extensions
• “Customize an ASAP2 File” on page 23-2
• “Create a Transport Layer for External Communication” on page 23-14

23

Run-Time Data Interface Extensions

Customize an ASAP2 File
In this section...
“About ASAP2 File Customization” on page 23-2
“ASAP2 File Structure on the MATLAB Path” on page 23-2
“Customize the Contents of the ASAP2 File” on page 23-3
“ASAP2 Templates” on page 23-4
“Use GROUP and SUBGROUP Hierarchies to Organize Signals and
Parameters” on page 23-6
“Customize Computation Method Names” on page 23-12
“Suppress Computation Methods for FIX_AXIS” on page 23-13

About ASAP2 File Customization
The Embedded Coder product provides a number of Target Language
Compiler (TLC) files to enable you to customize the ASAP2 file generated
from a Simulink model.

ASAP2 File Structure on the MATLAB Path
The ASAP2 related files are organized within the folders identified below:
• TLC files for generating ASAP2 file
The matlabroot/rtw/c/tlc/mw folder contains TLC files that generate
ASAP2 files, asamlib.tlc, asap2lib.tlc, asap2main.tlc, and
asap2grouplib.tlc. These files are included by the selected System
target file. (See “Targets Supporting ASAP2” on page 15-175.)
• ASAP2 target files
The matlabroot/toolbox/rtw/targets/asap2/asap2 folder contains the
ASAP2 system target file and other control files.
• Customizable TLC files

23-2

Customize an ASAP2 File

The matlabroot/toolbox/rtw/targets/asap2/asap2/user folder
contains files that you can modify to customize the content of your ASAP2
files.
• ASAP2 templates
The matlabroot/toolbox/rtw/targets/asap2/asap2/user/templates
folder contains templates that define each type of CHARACTERISTIC in the
ASAP2 file.

Customize the Contents of the ASAP2 File
The ASAP2 related TLC files enable you to customize the appearance of
the ASAP2 file generated from a Simulink model. Most customization
is done by modifying or adding to the files contained in the
matlabroot/toolbox/rtw/targets/asap2/asap2/user folder. This section
refers to this folder as the asap2/user folder.
The user-customizable files provided are divided into two groups:
• The static files define the parts of the ASAP2 file that are related to
the environment in which the generated code is used. They describe
information specific to the user or project. The static files are not model
dependent.
• The dynamic files define the parts of the ASAP2 file that are generated
based on the structure of the source model.
The procedure for customizing the ASAP2 file is as follows:
1 Make a copy of the asap2/user folder before making any modifications.
2 Remove the old asap2/user folder from the MATLAB path, or add the new

asap2/user folder to the MATLAB path above the old folder. This ensures
that the MATLAB session uses the ASAP2 setup file, asap2setup.tlc
(new for Release 14).
asap2setup.tlc specifies the folders and files to include in the TLC path
during the ASAP2 file generation process. Modify asap2setup.tlc to
control the folders and folders included in the TLC path.
3 Modify the static parts of the ASAP2 file. These include

23-3

23

Run-Time Data Interface Extensions

• Project and header symbols, which are specified in asap2setup.tlc
• Static sections of the file, such as file header and tail, A2ML, MOD_COMMON,
and so on These are specified in asap2userlib.tlc.
• Specify the appearance of the dynamic contents of the ASAP2 file by
modifying the existing ASAP2 templates or by defining new ASAP2
templates. Sections of the ASAP2 file affected include
RECORD_LAYOUT: modify parts of the ASAP2 template files.
CHARACTERISTIC: modify parts of the ASAP2 template files. For more
information on modifying the appearance of CHARACTERISTIC records,

see “ASAP2 Templates” on page 23-4.
• MEASUREMENT: These are specified in asap2userlib.tlc.
• COMPU_METHOD: These are specified in asap2userlib.tlc.

ASAP2 Templates
The appearance of CHARACTERISTIC records in the ASAP2 file is controlled
using a different template for each type of CHARACTERISTIC. The asap2/user
folder contains template definition files for scalars, 1-D Lookup Table blocks
and 2-D Lookup Table blocks. You can modify these template definition files,
or you can create additional templates as required.
The procedure for creating a new ASAP2 template is as follows:
1 Create a template definition file. See “Create Template Definition Files”

on page 23-4.
2 Include the template definition file in the TLC path. The path is specified

in the ASAP2 setup file, asap2setup.tlc.

Create Template Definition Files
This section describes the components that make up an ASAP2 template
definition file. This description is in the form of code examples from
asap2lookup1d.tlc, the template definition file for the Lookup1D template.
This template corresponds to the Lookup1D parameter group.

23-4

Customize an ASAP2 File

Note When creating a new template, use the corresponding parameter group
name in place of Lookup1D in the code shown.

Template Registration Function
The input argument is the name of the parameter group associated with
this template:
%

RECORD_LAYOUT Name Definition Function
Record layout names (aliases) can be arbitrarily specified for each data type.
This function is used by the other components of this file.
%function ASAP2UserFcnRecordLayoutAlias_Lookup1D(dtId) void
%switch dtId
%case tSS_UINT8
%return "Lookup1D_UBYTE"
...
%endswitch
%endfunction

Function to Write RECORD_LAYOUT Definitions
This function writes RECORD_LAYOUT definitions associated with this template.
The function is called by the built-in functions involved in the ASAP2 file
generation process. The function name must be defined as shown, with the
template name after the underscore:
%function ASAP2UserFcnWriteRecordLayout_Lookup1D() Output
/begin RECORD_LAYOUT
%
...
/end
RECORD_LAYOUT
%endfunction

23-5

23

Run-Time Data Interface Extensions

Function to Write the CHARACTERISTIC
This function writes the CHARACTERISTIC associated with this template.
The function is called by the built-in functions involved in the ASAP2 file
generation process. The function name must be defined as shown, with the
template name after the underscore.
The input argument to this function is a pointer to a parameter group record.
The example shown is for a Lookup1D parameter group that has two members.
The references to the associated x and y data records are obtained from the
parameter group record as shown.
This function calls a number of built-in functions to obtain the required
information. For example, LibASAP2GetSymbol returns the symbol (name)
for the specified data record:
%function ASAP2UserFcnWriteCharacteristic_Lookup1D(paramGroup)
Output
%assign xParam = paramGroup.Member[0].Reference
%assign yParam = paramGroup.Member[1].Reference
%assign dtId = LibASAP2GetDataTypeId(xParam)
/begin CHARACTERISTIC
/* Name */
%
/* Long identifier */
"%"
...
/end CHARACTERISTIC
%endfunction

Use GROUP and SUBGROUP Hierarchies to Organize
Signals and Parameters
• “Signal and Parameter Grouping Overview” on page 23-7
• “TLC Functions for Defining and Adding Groups” on page 23-7
• “ASAP2 Simple Grouping” on page 23-9
• “ASAP2 Graphical Grouping” on page 23-10

23-6

Customize an ASAP2 File

Signal and Parameter Grouping Overview
The Simulink Coder product provides TLC functions that allow you to
organize signals and parameters in the generated ASAP2 file into groups
and subgroups, using the GROUP and SUBGROUP keywords in the ASAP2
standard. Grouping can be done using criteria such as the following:
• Graphical location of the signal or parameter in the model
• Functionality (I/O or local)
• Custom criteria
By default, the build process generates ASAP2 parameter and signal
descriptions as a flat list. To generate ASAP2 GROUPs and SUBGROUPs,
do the following:
1 Use the TLC customization functions that define and add groups.
2 Generate code for your model. The code generator automatically generates

the defined groups into the ASAP2 file, using the GROUP and SUBGROUP
keywords.

TLC Functions for Defining and Adding Groups
• “Create Groups” on page 23-7
• “Populate Groups” on page 23-8
• “Group by Graphical Hierarchy” on page 23-8
Create Groups. The software provides the following TLC
functions for creating an ASAP2 group and setting its description
and annotation. These functions are defined in the file
matlabroot/rtw/c/tlc/mw/asap2grouplib.tlc and can be called
at any point during the ASAP2 customization process.

23-7

23

Run-Time Data Interface Extensions

Function

Description

LibASAP2CreateGroup(groupName,
groupLongIdentifier)

Creates a group with the specified groupName
and returns the created group. If the group
already exists, returns the existing group.

LibASAP2SetGroupIsRoot(group)

Sets the specified group as a ROOT.

LibASAP2SetGroupAnnotation(group,
annotation)

Sets the annotation for the specified group. If
annotation already exists, overwrites it.

Populate Groups. The software provides the following
TLC functions for adding subgroups, characteristics, and
measurements to groups. These functions are defined in the file
matlabroot/rtw/c/tlc/mw/asap2grouplib.tlc and can be called at any
point during the ASAP2 customization process.
Function

Description

LibASAP2AddSubGroupToGroup(group,
subGroup)

Adds the specified subGroup as a SUB_GROUP
of the specified group.

LibASAP2AddCharacteristicToGroup(group,
characteristicName)

Adds the specified characteristicName as
a REF_CHARACTERISTIC of the specified
group.

LibASAP2AddMeasurementToGroup(group,
measurementName)

Adds the specified measurementName as a
REF_MEASUREMENT of the specified group.

Group by Graphical Hierarchy. The software provides the following TLC
functions for creating groups based on the graphical hierarchy of signals,
states, and parameters in the model. These functions are defined in the file
matlabroot/rtw/c/tlc/mw/asap2grouplib.tlc and can be called at any
point during the ASAP2 customization process.

23-8

Customize an ASAP2 File

Function

Description

LibASAP2CreateGraphicalGroups()

Creates groups and subgroups. A group is
created for each graphical subsystem in the
model. The graphical hierarchy is reflected in
the SUB_GROUPs.

LibASAP2AddCharacteristicToGraphical
Groups(param)

Adds a CHARACTERISTIC to one or more
groups reflecting the locations of the specified
parameter in the model.

LibASAP2AddMeasurementToGraphical
Group(signal)

Adds a MEASUREMENT to a group and
its subgroups reflecting the location of the
specified signal or state in the model.

ASAP2 Simple Grouping
Consider the following model, in which subsystem S1 contains 3 signals and
uses 2 parameters:

Suppose that you want to do the following:
• Create A ROOT group for the model.
• Organize all signals in the model in a group called Signals, which is a
subgroup of ROOT.
• Organize all parameters in the model in a group called Parameters, which
is a subgroup of ROOT.
To create this simple grouping, you perform the following steps:

23-9

23

Run-Time Data Interface Extensions

1 In your copy of asap2setup.tlc, use the TLC functions to create the root

group and subgroups. For example:
%% Create a root GROUP
%assign ASAP2RootGroup = LibASAP2CreateGroup("%", ...
"%")
%
%% -------------------%% Create a group for model signals
%assign ASAP2SigGroup = LibASAP2CreateGroup("Signals", ...
"Measurements in %")
%
%% -------------------------------%% Create a group for model parameters
%assign ASAP2ParGroup = LibASAP2CreateGroup("Parameters", ...
"Characteristics in %")
%

2 In the template function for MEASUREMENTs,

ASAP2UserFcnWriteMeasurementfile, add each signal to ASAP2SigGroup.

For example:
%

3 In the template function for CHARACTERISTICs,

ASAP2UserFcnWriteCharacteristic_Scalar, add each parameter to
ASAP2ParGroup. For example:
%

In the generated ASAP2 file, parameters and signals are separated into
groups called Parameters and Signals, under the model root.

ASAP2 Graphical Grouping
Consider the following model, in which subsystem S1 contains 3 signals and
uses 2 parameters, and also contains another subsystem S2:

23-10

Customize an ASAP2 File

Suppose that you want to do the following:
• Create a ROOT group for the model and create a subgroup for each
graphical subsystem in the model.
• Add each signal and state to the group for the subsystem that refers to it.
• Add each parameter to the groups for the subsystems that refer to it. (A
parameter can be referred to in multiple subsystems and added to multiple
groups.)
To create this graphical grouping, you perform the following steps:
1 In your copy of asap2setup.tlc, use the TLC functions to create the groups

according to the graphical hierarchy. For example:
%

3 In the template function for CHARACTERISTICs,

ASAP2UserFcnWriteCharacteristic_Scalar, add each parameter to its

graphical groups. For example:
%

23-11

23

Run-Time Data Interface Extensions

In the generated ASAP2 file, the group ordering reflects the graphical
hierarchy of the model, root > S1 > S2.

Customize Computation Method Names
In generated ASAP2 files, computation methods translate the electronic
control unit (ECU) internal representation of measurement and calibration
quantities into a physical model oriented representation. Simulink Coder
software provides the ability to customize the names of computation methods.
You can provide names that are more intuitive, enhancing ASAP2 file
readability, or names that meet organizational requirements.
To customize computation method names, use the MATLAB
function getCompuMethodName, which is defined in
matlabroot/toolbox/rtw/targets/asap2/asap2/user/getCompuMethodName.m.

The getCompuMethodName function constructs a computation method name.
The function prototype is
cmName = getCompuMethodName(dataTypeName, cmUnits)

where dataTypeName is the name of the data type associated with the
computation method, cmUnits is the units as specified in the DocUnits
property of a Simulink.Parameter or Simulink.Signal object (for example,
rpm or m/s), and cmName returns the constructed computation method name.
The default constructed name returned by the function has the format
_

where
•  is a local prefix, CM_, defined in

matlabroot/toolbox/rtw/targets/asap2/asap2/user/getCompuMethodName.m.

•  and  are the arguments you specified to the
getCompuMethodName function.
Additionally, in the generated ASAP2 file, the constructed name is
prefixed with , a model prefix defined in
matlabroot/toolbox/rtw/targets/asap2/asap2/user/asap2setup.tlc.

23-12

Customize an ASAP2 File

For example, if you call the getCompuMethodName function with the
dataTypeName argument 'int16' and the cmUnits argument 'm/s', and
generate an ASAP2 file for a model named myModel, the computation method
name would appear in the generated file as follows:
/begin COMPU_METHOD
/* Name of CompuMethod */ myModel_CM_int16_m_s
/* Units */ "m/s"
...
/end COMPU_METHOD

Suppress Computation Methods for FIX_AXIS
Versions 1.51 and later of the ASAP2 specification state that for certain
cases of lookup table axis descriptions (integer data type and no doc units), a
computation method is not required and the Conversion Method parameter
must be set to the value NO_COMPU_METHOD. You can control whether or not
computation methods are suppressed when not required using the Target
Language Compiler (TLC) option ASAP2GenNoCompuMethod. This TLC option
is disabled by default. If you enable the option, ASAP2 file generation does
not generate computation methods for lookup table axis descriptions when not
required, and instead generates the value NO_COMPU_METHOD. For example:
/begin CHARACTERISTIC
/* Name
*/
lu1d_fix_axisTable_data
...
/begin AXIS_DESCR
...
/* Conversion Method
NO_COMPU_METHOD
...
/end CHARACTERISTIC

*/

The ASAP2GenNoCompuMethod option is defined in
matlabroot/toolbox/rtw/targets/asap2/asap2/user/asap2setup.tlc.

23-13

23

Run-Time Data Interface Extensions

Create a Transport Layer for External Communication
In this section...
“About Creating a Transport Layer for External Communication” on page
23-14
“Design of External Mode” on page 23-14
“External Mode Communications Overview” on page 23-17
“External Mode Source Files” on page 23-19
“Implement a Custom Transport Layer” on page 23-23

About Creating a Transport Layer for External
Communication
This section helps you to connect your custom target by using External mode
using your own low-level communications layer. The topics include:
• An overview of the design and operation of External mode
• A description of External mode source files
• Guidelines for modifying the External mode source files and building an
executable to handle the tasks of the default ext_comm MEX-file
This section assumes that you are familiar with the execution of Simulink
Coder programs, and with the basic operation of External mode.

Design of External Mode
External mode communication between the Simulink engine and a target
system is based on a client/server architecture. The client (the Simulink
engine) transmits messages requesting the server (target) to accept parameter
changes or to upload signal data. The server responds by executing the
request.
A low-level transport layer handles physical transmission of messages. Both
the Simulink engine and the model code are independent of this layer. Both
the transport layer and code directly interfacing to the transport layer are

23-14

Create a Transport Layer for External Communication

isolated in separate modules that format, transmit, and receive messages
and data packets.
This design makes it possible for different targets to use different transport
layers. The GRT, GRT malloc, ERT, and RSim targets support host/target
communication by using TCP/IP and RS-232 (serial) communication. The
RTWin target supports shared memory communication. The Wind River
Systems Tornado target supports TCP/IP only.
The Simulink Coder product provides full source code for both the client and
server-side External mode modules, as used by the GRT, GRT malloc, ERT,
Rapid Simulation, and Tornado targets, and the Real-Time Windows Target
and xPC Target products. The main client-side module is ext_comm.c. The
main server-side module is ext_svr.c.
These two modules call the specified transport layer through the following
source files.
Built-In Transport Layer Implementations
Client or
Protocol Server?

Source Files

TCP/IP

• matlabroot/rtw/ext_mode/common/rtiostream_interface.c

Client
(host)

• matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c

Server
(target)

• matlabroot/rtw/c/src/ext_mode/common/rtiostream_interface.c
• matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c

Serial

Client
(host)
Server
(target)

• matlabroot/rtw/ext_mode/serial/ext_serial_transport.c
• matlabroot/rtw/c/src/rtiostream/rtiostreamserial/rtiostream_serial.c
• matlabroot/rtw/c/src/ext_mode/serial/ext_svr_serial_transport.c
• matlabroot/rtw/c/src/rtiostream/rtiostreamserial/rtiostream_serial.c
For serial communication, the modules ext_serial_transport.c
and rtiostream_serial.c implement the client-side transport
functions and the modules ext_svr_serial_transport.c and

23-15

23

Run-Time Data Interface Extensions

rtiostream_serial.c implement the corresponding server-side functions.
For TCP/IP communication, the modules rtiostream_interface.c and
rtiostream_tcpip.c implement both client-side and server-side functions.
You can edit copies of these files (but do not modify the originals). You can
support External mode using your own low-level communications layer by
creating similar files using the following templates:

• Client (host) side:
matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c

(TCP/IP) or
matlabroot/rtw/c/src/rtiostream/rtiostreamserial/rtiostream_serial.c

(serial)
• Server (target) side:
matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c

(TCP/IP) or
matlabroot/rtw/c/src/rtiostream/rtiostreamserial/rtiostream_serial.c

(serial)
The file rtiostream_interface.c is an interface between the External mode
protocol and an rtiostream communications channel. For more details on
implementing an rtiostream communications channel, see “Communications
rtiostream API” in the Embedded Coder documentation. Implement your
rtiostream communications channel by using the documented interface to
avoid having to make changes to the file rtiostream_interface.c or any
other External mode related files.
Note Do not modify working source files. Use the templates provided in the
/custom or /rtiostream folder as starting points, guided by the comments
within them.
You need only provide code that implements low-level communications. You
need not be concerned with issues such as data conversions between host and
target, or with the formatting of messages. The Simulink Coder software
handles these functions.
On the client (Simulink engine) side, communications are handled by
ext_comm (for TCP/IP) and ext_serial_win32_comm (for serial) MEX-files.

23-16

Create a Transport Layer for External Communication

On the server (target) side, External mode modules are linked into the target
executable. This takes place automatically if the External mode code
generation option is selected at code generation time, based on the External
mode transport option selected in the target code generation options dialog
box. These modules, called from the main program and the model execution
engine, are independent of the generated model code.
The general procedure for implementing your own client-side low-level
transport protocol is as follows:
1 Edit the template rtiostream_tcpip.c to replace low-level communication

calls with your own communication calls.
2 Generate a MEX-file executable for your custom transport.
3 Register your new transport layer with the Simulink software, so that

the transport can be selected for a model using the Interface pane of the
Configuration Parameters dialog box.
For more details, see “Create a Custom Client (Host) Transport Protocol” on
page 23-24.
The general procedure for implementing your own server-side low-level
transport protocol is as follows:
1 Edit the template rtiostream_tcpip.c to replace low-level communication

calls with your own communication calls. Typically this involves writing or
integrating device drivers for your target hardware.
2 Modify template makefiles to support the new transport.

For more details, see “Create a Custom Server (Target) Transport Protocol”
on page 23-28.

External Mode Communications Overview
This section gives a high-level overview of how a Simulink Coder generated
program communicates with Simulink External mode. This description is
based on the TCP/IP version of External mode that ships with the Simulink
Coder product.

23-17

23

Run-Time Data Interface Extensions

For communication to take place,
• The server (target) program must have been built with the conditional
EXT_MODE defined. EXT_MODE is defined in the model.mk file if the External
mode code generation option was selected at code generation time.
• Both the server program and the Simulink software must be executing.
This does not mean that the model code in the server system must be
executing. The server can be waiting for the Simulink engine to issue a
command to start model execution.
The client and server communicate by using bidirectional sockets carrying
packets. Packets consist either of messages (commands, parameter downloads,
and responses) or data (signal uploads).
If the target program was invoked with the -w command-line option, the
program enters a wait state until it receives a message from the host.
Otherwise, the program begins execution of the model. While the target
program is in a wait state, the Simulink engine can download parameters to
the target and configure data uploading.
When the user chooses the Connect to Target option from the Simulation
menu, the host initiates a handshake by sending an EXT_CONNECT message.
The server responds with information about itself. This information includes
• Checksums. The host uses model checksums to determine that the target
code is an exact representation of the current Simulink model.
• Data format information. The host uses this information when formatting
data to be downloaded, or interpreting data that has been uploaded.
At this point, host and server are connected. The server is either executing
the model or in the wait state. (In the latter case, the user can begin model
execution by selecting Start Real-Time Code from the Simulation menu.)
During model execution, the message server runs as a background task. This
task receives and processes messages such as parameter downloads.
Data uploading comprises both foreground execution and background
servicing of the signal packets. As the target computes model outputs, it also
copies signal values into data upload buffers. This occurs as part of the task

23-18

Create a Transport Layer for External Communication

associated with each task identifier (tid). Therefore, data collection occurs
in the foreground. Transmission of the collected data, however, occurs as
a background task. The background task sends the data in the collection
buffers to the Simulink engine by using data packets.
The host initiates most exchanges as messages. The target usually sends
a response confirming that it has received and processed the message.
Examples of messages and commands are
• Connection message / connection response
• Start target simulation / start response
• Parameter download / parameter download response
• Arm trigger for data uploading / arm trigger response
• Terminate target simulation / target shutdown response
Model execution terminates when the model reaches its final time, when the
host sends a terminate command, or when a Stop Simulation block terminates
execution. On termination, the server informs the host that model execution
has stopped, and shuts down its socket. The host also shuts down its socket,
and exits External mode.

External Mode Source Files
• “Client (Host) MEX-file Interface Source Files” on page 23-19
• “Server (Target) Source Files” on page 23-21
• “Other Files in the Server Folder” on page 23-23

Client (Host) MEX-file Interface Source Files
The source files for the MEX-file interface component are located in the folder
matlabroot/rtw/ext_mode, except as noted:
• common/ext_comm.c
This file is the core of External mode communication. It acts as a
relay station between the target and the Simulink engine. ext_comm.c
communicates to the Simulink engine by using a shared data structure,

23-19

23

Run-Time Data Interface Extensions

ExternalSim. It communicates to the target by using calls to the transport

layer.
Tasks carried out by ext_comm.c include establishment of a connection
with the target, downloading of parameters, and termination of the
connection with the target.
• common/rtiostream_interface.c
This file is an interface between the External mode protocol and an
rtiostream communications channel. For more details on implementing
an rtiostream communications channel, see “Communications rtiostream
API” in the Embedded Coder documentation. Implement your rtiostream
communications channel using the documented interface to avoid having
to change the file rtiostream_interface.c or any other External mode
related files.
• matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c
This file implements required TCP/IP transport layer functions. The
version of rtiostream_tcpip.c shipped with the Simulink Coder software
uses TCP/IP functions including recv(), send(), and socket().
• matlabroot/rtw/c/src/rtiostream/rtiostreamtserial/rtiostream_serial.c
This file implements required serial transport layer functions. The version
of rtiostream_serial.c shipped with the Simulink Coder software uses
serial functions including ReadFile(), WriteFile(), and CreateFile().
• serial/ext_serial_transport.c
This file implements required serial transport layer functions.
ext_serial_transport.c includes ext_serial_utils.c, which is located
in matlabroot/rtw/c/src/ext_mode/serial and contains functions
common to client and server sides.
• common/ext_main.c
This file is a MEX-file wrapper for External mode. ext_main.c interfaces
to the Simulink engine by using the standard mexFunction call. (See the
mexFunction reference page and “Application Programming Interfaces
to MATLAB” for more information.) ext_main.c contains a function
dispatcher, esGetAction, that sends requests from the Simulink engine
to ext_comm.c.
• common/ext_convert.c and ext_convert.h

23-20

Create a Transport Layer for External Communication

This file contains functions used for converting data from host to target
formats (and vice versa). Functions include byte-swapping (big to littleendian), conversion from non-IEEE floats to IEEE doubles, and other
conversions. These functions are called both by ext_comm.c and directly by
the Simulink engine (by using function pointers).
Note You do not need to customize ext_convert to implement a custom
transport layer. However, you mightwant to customize ext_convert for
the intended target. For example, if the target represents the float data
type in Texas Instruments format, ext_convert must be modified to
perform a Texas Instruments to IEEE conversion.

• common/extsim.h
This file defines the ExternalSim data structure and access macros. This
structure is used for communication between the Simulink engine and
ext_comm.c.
• common/extutil.h
This file contains only conditionals for compilation of the assert macro.
• common/ext_transport.h
This file defines functions that must be implemented by the transport layer.

Server (Target) Source Files
These files are part of the run-time interface and are linked into the model.exe
executable. They are located within matlabroot/rtw/c/src/ext_mode/
except as noted.
• common/ext_svr.c
ext_svr.c is analogous to ext_comm.c on the host, but generally is
responsible for more tasks. It acts as a relay station between the host and
the generated code. Like ext_comm.c, ext_svr.c carries out tasks such
as establishing and terminating connection with the host. ext_svr.c also
contains the background task functions that either write downloaded
parameters to the target model, or extract data from the target data buffers
and send it back to the host.

23-21

23

Run-Time Data Interface Extensions

• common/rtiostream_interface.c
This file is an interface between the External mode protocol and an
rtiostream communications channel. For more details on implementing
an rtiostream communications channel, see “Communications rtiostream
API” in the Embedded Coder documentation. Implement your rtiostream
communications channel by using the documented interface to avoid
having to change the file rtiostream_interface.c or any other External
mode related files.
• matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c
This file implements required TCP/IP transport layer functions. The
version of rtiostream_tcpip.c shipped with the Simulink Coder software
uses TCP/IP functions including recv(), send(), and socket().
• matlabroot/rtw/c/src/rtiostream/rtiostreamtserial/rtiostream_serial.c
This file implements required serial transport layer functions. The version
of rtiostream_serial.c shipped with the software uses serial functions
including ReadFile(), WriteFile(), and CreateFile().
• matlabroot/rtw/c/src/rtiostream.h
This file defines the rtIOStream* functions implemented in
rtiostream_tcpip.c.
• serial/ext_svr_serial_transport.c
This file implements required serial transport layer functions.
ext_svr_serial_transport.c includes serial/ext_serial_utils.c,
which contains functions common to client and server sides.
• common/updown.c
updown.c handles the details of interacting with the target model.
During parameter downloads, updown.c does the work of installing the
new parameters into the model’s parameter vector. For data uploading,
updown.c contains the functions that extract data from the model’s blockio
vector and write the data to the upload buffers. updown.c provides services
both to ext_svr.c and to the model code (for example, grt_main.c). It
contains code that is called by using the background tasks of ext_svr.c as
well as code that is called as part of the higher priority model execution.

• matlabroot/rtw/c/src/dt_info.h (included by generated model build
file model.h)

23-22

Create a Transport Layer for External Communication

These files contain data type transition information that allows access to
multi-data type structures across different computer architectures. This
information is used in data conversions between host and target formats.
• common/updown_util.h
This file contains only conditionals for compilation of the assert macro.
• common/ext_svr_transport.h
This file defines the Ext* functions that must be implemented by the
server (target) transport layer.

Other Files in the Server Folder
• common/ext_share.h
Contains message code definitions and other definitions required by both
the host and target modules.
• serial/ext_serial_utils.c
Contains functions and data structures for communication, MEX link,
and generated code required by both the host and target modules of the
transport layer for serial protocols.
• The serial transport implementation includes the additional files

-

serial/ext_serial_pkt.c and ext_serial_pkt.h
serial/ext_serial_port.h

Implement a Custom Transport Layer
• “Requirements for Custom Transport Layers” on page 23-24
• “Create a Custom Client (Host) Transport Protocol” on page 23-24
• “Register a Custom Client (Host) Transport Protocol” on page 23-27
• “Create a Custom Server (Target) Transport Protocol” on page 23-28

23-23

23

Run-Time Data Interface Extensions

Requirements for Custom Transport Layers
• By default, ext_svr.c and updown.c use malloc to allocate buffers in
target memory for messages, data collection, and other purposes, although
there is also an option to preallocate static memory. If your target uses
another memory allocation scheme, you must modify these modules.
• The target is assumed to support both int32_T and uint32_T data types.

Create a Custom Client (Host) Transport Protocol
To implement the client (host) side of your low-level transport protocol,
1 Edit the template file

matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c

to replace low-level communication calls with your own
communication calls.
a Copy and rename the file to rtiostream_name.c (replacing name with a

name meaningful to you).
b Replace the functions rtIOStreamOpen, rtIOStreamClose,

rtIOStreamSend, and rtIOStreamRecv with functions (of the
same name) that call your low-level communication primitives.
These functions are called from other External mode modules via
rtiostream_interface.c. For more information, see “Communications
rtiostream API” in the Embedded Coder documentation.
c Build your rtiostream implementation into a shared library that

exports the rtIOStreamOpen, rtIOStreamClose, rtIOStreamRecv and
rtIOStreamSend functions.
2 Build the customized MEX-file executable using the MATLAB mex

function. See the table MATLAB® Commands to Rebuild ext_comm and
ext_serial_win32 MEX-Files on page 23-25 for examples of mex invocations.
Do not replace the existing ext_comm MEX-file if you want to preserve its
existing function. Instead, use the -output option to name the resulting
executable (for example, mex -output ext_myrtiostream_comm ...
builds ext_myrtiostream_comm.mexext, on Windows platforms).
3 Register your new client transport layer with the Simulink software, so

that the transport can be selected for a model using the Interface pane

23-24

Create a Transport Layer for External Communication

of the Configuration Parameters dialog box. For details, see “Register a
Custom Client (Host) Transport Protocol” on page 23-27.
The following table lists the commands for building the standard ext_comm
module on PC and UNIX platforms, and for building the standard
ext_serial_win32 model on a PC platform.
MATLAB Commands to Rebuild ext_comm and ext_serial_win32 MEX-Files
Platform

Commands

PC, TCP/IP
>> cd (matlabroot)
>> mex rtw\ext_mode\common\ext_comm.c ...
rtw\ext_mode\common\ext_convert.c ...
rtw\ext_mode\common\rtiostream_interface.c ...
-Irtw\c\src -Irtw\c\src\rtiostream\utils ...
-Irtw\c\src\ext_mode\common ...
-Irtw\ext_mode\common ...
-Irtw\ext_mode\common\include ...
-lmwrtiostreamutils ...
-DEXTMODE_TCPIP_TRANSPORT ...
-DSL_EXT_DLL -output toolbox\rtw\rtw\ext_comm

Note The rtiostream_interface.c function defines
RTIOSTREAM_SHARED_LIB as libmwrtiostreamtcpip and
dynamically loads the MathWorks TCP/IP rtiostream shared library.
Modify this file if you need to load a different rtiostream shared library.
UNIX, TCP/IP

Use the PC commands but change -DSL_EXT_DLL to -DSL_EXT_SO, and replace
back slashes with forward slashes.

Mac, TCP/IP

Use the PC commands but change -DSL_EXT_DLL to --DSL_EXT_DYLIB, and
replace back slashes with forward slashes.

23-25

23

Run-Time Data Interface Extensions

MATLAB Commands to Rebuild ext_comm and ext_serial_win32 MEX-Files (Continued)
Platform

Commands

PC, serial
>> cd (matlabroot)
mex rtw\ext_mode\common\ext_comm.c ...
rtw\ext_mode\common\ext_convert.c ...
rtw\ext_mode\serial\ext_serial_transport.c ...
rtw\ext_mode\serial\ext_serial_pkt.c ...
rtw\ext_mode\serial\rtiostream_serial_interface.c ...
-Irtw\c\src -Irtw\c\src\rtiostream\utils ...
-Irtw\c\src\ext_mode\common ...
-Irtw\c\src\ext_mode\serial -Irtw\ext_mode\common ...
-Irtw\ext_mode\common\include ...
-lmwrtiostreamutils -DSL_EXT_DLL ...
-output toolbox\rtw\rtw\ext_serial_win32_comm

Note The rtiostream_interface.c function defines
RTIOSTREAM_SHARED_LIB as libmwrtiostreamserial and
dynamically loads the MathWorks serial rtiostream shared library. Modify
this file if you need to load a different rtiostream shared library.
UNIX, serial

Use the PC commands but change -DSL_EXT_DLL to -DSL_EXT_SO, and replace
back slashes with forward slashes.

Mac, serial

Use the PC commands but change -DSL_EXT_DLL to --DSL_EXT_DYLIB, and
replace back slashes with forward slashes.

Note mex requires a compiler supported by the MATLAB API. See the mex
reference page and “Application Programming Interfaces to MATLAB” for
more information about the mex function.

23-26

Create a Transport Layer for External Communication

Register a Custom Client (Host) Transport Protocol
To register a custom client transport protocol with the Simulink software,
you must add an entry of the following form to an sl_customization.m file
on the MATLAB path:
function sl_customization(cm)
cm.ExtModeTransports.add('stf.tlc', 'transport', 'mexfile', 'Level1');
% -- end of sl_customization

where
• stf.tlc is the name of the system target file for which the transport will
be registered (for example, 'grt.tlc')
• transport is the transport name to display in the Transport layer menu
on the Interface pane of the Configuration Parameters dialog box (for
example, 'mytcpip')
• mexfile is the name of the transport’s associated external interface
MEX-file (for example, 'ext_mytcpip_comm')
You can specify multiple targets and/or transports with additional
cm.ExtModeTransports.add lines, for example:
function sl_customization(cm)
cm.ExtModeTransports.add('grt.tlc', 'mytcpip', 'ext_mytcpip_comm', 'Level1');
cm.ExtModeTransports.add('ert.tlc', 'mytcpip', 'ext_mytcpip_comm', 'Level1');
% -- end of sl_customization

If you place the sl_customization.m file containing the transport registration
information on the MATLAB path, your custom client transport protocol
will be registered with each subsequent Simulink session. The name of the
transport will appear in the Transport layer menu on the Interface pane of
the Configuration Parameters dialog box. When you select the transport for
your model, the name of the associated external interface MEX-file will appear
in the noneditable MEX-file name field, as shown in the following figure.

23-27

23

Run-Time Data Interface Extensions

Create a Custom Server (Target) Transport Protocol
The rtIOStream* function prototypes in
matlabroot/rtw/c/src/rtiostream.h define the calling interface for both
the server (target) and client (host) side transport layer functions.
• The TCP/IP implementations are in

matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c.

• The serial implementations are in

matlabroot/rtw/c/src/rtiostream/rtiostreamserial/rtiostream_serial.c.

Note The Ext* function prototypes in
matlabroot/rtw/c/src/ext_mode/common/ext_svr_transport.h

are implemented in
matlabroot/rtw/c/src/ext_mode/common/rtiostream_interface.c or
matlabroot/rtw/c/src/ext_mode/serial/rtiostream_serial_interface.c.
In most cases you will not need to modify rtiostream_interface.c
or rtiostream_serial_interface.c for your custom TCP/IP or

serial transport layer.

23-28

Create a Transport Layer for External Communication

To implement the server (target) side of your low-level TCP/IP or serial
transport protocol,
1 Edit the template

matlabroot/rtw/c/src/rtiostream/rtiostreamtcpip/rtiostream_tcpip.c

or
matlabroot/rtw/c/src/rtiostream/rtiostreamserial/rtiostream_serial.c

to replace low-level communication calls with your own
communication calls.
a Copy and rename the file to rtiostream_name.c (replacing name with a

name meaningful to you).
b Replace the functions rtIOStreamOpen, rtIOStreamClose,

rtIOStreamSend,and rtIOStreamRecv with functions (of the same name)

that call your low-level communication drivers.
You must implement all the functions defined in rtiostream.h, and
your implementations must conform to the prototypes defined in that
file. Refer to the original rtiostream_tcpip.c or rtiostream_serial.c
for guidance.
2 Modify template makefiles to support the new transport. If you

are writing your own template makefile, make sure that the
EXT_MODE code generation option is defined. The generated makefile
will then link rtiostream_name.c, rtiostream_interface.c or
rtiostream_serial_interface.c, and other server code into your
executable.

23-29

23

23-30

Run-Time Data Interface Extensions

24
Custom Target
Development
• “About Embedded Target Development” on page 24-2
• “Sample Custom Targets” on page 24-9
• “Target Development Mechanics” on page 24-11
• “Customize System Target Files” on page 24-36
• “Customize Template Makefiles” on page 24-75
• “Support Optional Features” on page 24-100
• “Interface to Development Tools” on page 24-123
• “Device Drivers and Target Preferences” on page 24-135

24

Custom Target Development

About Embedded Target Development
In this section...
“Custom Targets” on page 24-2
“Types of Targets” on page 24-2
“Recommended Features for Embedded Targets” on page 24-5

Custom Targets
The targets bundled with the Simulink Coder product are suitable for many
different applications and development environments. Third-party targets
provide additional versatility. However, you might want to implement a
custom target for any of the following reasons:
• To enable end users to generate executable production code for a specific
CPU or development board, using a specific development environment
(compiler/linker/debugger).
• To support I/O devices on the target hardware by incorporating custom
device driver blocks into your models.
• To configure the build process for a special compiler (such as a
cross-compiler for an embedded microcontroller or DSP board) or
development/debugging environment.
The Simulink Coder product provides a point of departure for the creation of
custom embedded targets, for the basic purposes above. This manual covers
the tasks and techniques you need to implement a custom embedded target.

Types of Targets
• “Introduction” on page 24-3
• “Rapid Prototyping Targets” on page 24-3
• “Turnkey Production Targets” on page 24-4
• “Verifying Targets With SIL and PIL Testing” on page 24-4
• “HIL Simulation Targets” on page 24-4

24-2

About Embedded Target Development

Introduction
The following sections describe several types of targets intended for different
use cases. There is a progression of capabilities from the first (baseline or
rapid prototyping) to second (turnkey production) target types; you may
want to implement an initial rapid prototyping target and a following,
more full-featured turnkey version of a target. You might want to use
software-in-the-loop (SIL) or processor-in-the-loop (PIL) testing at any
stage to verify your embedded target. The target types are not mutually
exclusive. An embedded target can support more than one of these use cases,
or additional uses not outlined here.
The discussion of target types is followed by “Recommended Features for
Embedded Targets” on page 24-5, which contains a suggested list of target
features and general guidelines for embedded target development.

Rapid Prototyping Targets
A rapid prototyping target or baseline target offers a starting point for
targeting a production processor. A rapid prototyping target integrates
Simulink Coder software with one or more popular cross-development
environments (compiler/linker/debugger tool chains). A rapid prototyping
target provides a starting point from which you can customize the target
for application needs.
Target files provided for this type of target should be readable, easy to
understand, and fully commented and documented. Specific attention should
be paid to the interface to the intended cross-development environment.
This interface should be implemented using the preferred approach for
that particular development system. For example, some development
environments use traditional make utilities, while others are based on
project-file builds that can be automated under control of the Simulink Coder
software.
When you use a rapid prototyping target, you need to include your own device
driver and legacy code and modify linker memory maps to suit your needs.
You should be familiar with the targeted development system.

24-3

24

Custom Target Development

Turnkey Production Targets
A turnkey production target also targets a production processor, but includes
the capability to create target executables that interact immediately with the
external world. In general, ease of use is more important than simplicity or
readability of the target files, because it is assumed that you do not want
or need to modify these files.
Desirable features for a turnkey production target include
• Significant I/O driver support provided out of the box
• Easy downloading of generated standalone executables with third-party
debuggers
• User-controlled placement of an executable in FLASH or RAM memory
• Support for target visibility and tuning

Verifying Targets With SIL and PIL Testing
You can use software-in-the-loop (SIL) or processor-in-the-loop (PIL) to verify
your generated code and validate the target compiler/processor environment.
You can use SIL and PIL simulation mode to verify automatically generated
code by comparing the results with a normal mode simulation. With SIL, you
can easily verify the behavior of production-intent source code on your host
computer; however, it is generally not possible to verify exactly the same code
that will subsequently be compiled for your target hardware because the code
must be compiled for your host platform (i.e. a different compiler and different
processor architecture than the target). With PIL simulation, you can verify
exactly the same code that you intend to deploy in production, and you can
run the code either on real target hardware or on an instruction set simulator.
For examples describing how to run processor-in-the-loop testing to verify a
custom target, see “Sample Custom Targets” on page 24-9.
For more information on SIL and PIL, see “About SIL and PIL Simulations”.

HIL Simulation Targets
A specialized use case is the generation of executables intended for use in
Hardware-In-the-Loop (HIL) simulations. In a HIL simulation, parts of a pure

24-4

About Embedded Target Development

simulation are gradually replaced with hardware components as components
are refined and fabricated. HIL simulation offers an efficient design process
that eliminates costly iterations of part fabrication.

Recommended Features for Embedded Targets
• “Basic Target Features” on page 24-5
• “Integration with Target Development Environments” on page 24-6
• “Observing Execution of Target Code” on page 24-6
• “Deployment and Hardware Issues” on page 24-7

Basic Target Features
• You can base targets on the Simulink Coder generic real-time (GRT) target
or the Embedded Real-Time (ERT) target that is included in the Embedded
Coder product.
If your target is based on the ERT target, it should use that target’s
Embedded-C code format, and should inherit the options defined in the
ERT target’s system target file. By following these recommendations, your
target has all the production code generation capabilities of the ERT target.
See “Customize System Target Files” on page 24-36 for further details on
the inheritance mechanism, setting the code format, and other details.
• The most fundamental requirement for an embedded target is that it
generate a real-time executable from a model or subsystem. Typically, an
embedded target generates a timer interrupt-based, bareboard executable
(although targets can be developed for an operating system environment
as well).
Your target should support the Simulink Coder concepts of single-tasking
and multitasking solver modes for model execution. Tasking support
comes almost “for free” with the ERT target, but you should thoroughly
understand how it works before implementing an ERT-based target.
Implementation of timer interrupt-based execution is documented in
“Scheduling” on page 1-4 and “Time-Based Scheduling”.

24-5

24

Custom Target Development

• You should generate the target executable’s main program module, rather
than using a static main module (such as the static ert_main.c module
provided with the Embedded Coder product). A generated main.c or
.cpp can be made much more readable and more efficient, since it omits
preprocessor checks and other extra code.
See “Standalone Programs (No Operating System)” for information on
generated and static main program modules.
• Follow the guidelines in “Folder and File Naming Conventions” on page
24-11.

Integration with Target Development Environments
• Most cross-development systems run under a Microsoft Windows PC host.
Your target should support the Windows XP operating system as the host
environment.
Some cross-development systems support one or more versions of The Open
Group UNIX platforms, allowing for UNIX host support as well.
• Your embedded target must support at least one embedded development
environment. The interface to a development environment can take one of
several forms. The most common approach is to use a template makefile
to generate standard makefiles with the make utility provided with your
development environment. “Customize Template Makefiles” on page 24-75
describes the structure of template makefiles.
Another approach with IDE-based tools is project file creation and/or
Microsoft Windows Component Object Model (COM) automation.
It is important to consider the license requirements and restrictions of the
development environment vendor. You may need to modify files provided
by the vendor and ship them as part of the embedded target.
See “Interface to Development Tools” on page 24-123 for further
information.

Observing Execution of Target Code
• Your target should support a mechanism you can use to observe the target
code as it runs in real time (outside of a debugger).

24-6

About Embedded Target Development

You can use the rtiostream API to implement a communication channel
to enable exchange of data between different processes. See the Web
page example here “Creating a Communications Channel for Target
Connectivity”. This rtiostream communication channel is required to
enable processor-in-the-loop (PIL) on a new target. See “Communications
rtiostream API” in the Embedded Coder documentation.
One industry-standard approach is to use the CAN bus, with an ASAP2
file and CAN Calibration Protocol (CCP). There are several host-based
graphical front-end tools available that connect to a CCP-enabled target
and provide data viewing and parameter tuning. Supporting these tools
requires implementation of CAN hardware drivers and CCP protocol for
the target, as well as ASAP2 file generation. Your target can leverage the
ASAP2 support provided with the Embedded Coder product.
Another option is to support Simulink External mode over a serial
interface (RS-232). See the “Host/Target Communication” on page 15-50
for information on using the External mode API.

Deployment and Hardware Issues
• Device driver support is an important issue in the design of an embedded
target. Device drivers are Simulink blocks that support either hardware
I/O capabilities of the target CPU, or I/O features of the development board.
If you are developing a rapid prototyping target, consider providing
minimal driver support, on the assumption that end users develop their
own drivers. If you are developing a turnkey production target, you should
provide full driver support.
See “Integrate Device Drivers” on page 24-135.
• Automatic download of generated code to the target hardware makes a
target easier to use. Typically a debugger utility is used; if the chosen
debugger supports command script files, this can be straightforward to
implement. “STF_make_rtw_hook.m” on page 24-23 describes a mechanism
to execute code from the build process. You can use this mechanism to
make system() calls to invoke utilities such as a debugger. You can invoke
other simple downloading utilities in a similar fashion.

24-7

24

Custom Target Development

If your development system supports COM automation, you can control the
download process by that mechanism. Using COM automation is discussed
in “Interface to Development Tools” on page 24-123.
• Executables that are mapped to RAM memory are typical. You can provide
optional support for FLASH or RAM placement of the executable by using
your target’s code generation options. To support this capability, you might
need multiple linker command files, multiple debugger scripts, and possibly
multiple makefiles or project files. Also include the ability to automatically
switch between these files, depending on the RAM/FLASH option value.
• Select a popular, widely available evaluation or prototype board for your
target processor. Consider enclosed and ruggedized versions of the target
board. Also consider board level support for the various on-chip I/O
capabilities of the target CPU, and the availability of development systems
that support the selected board.

24-8

Sample Custom Targets

Sample Custom Targets
There are technical solutions on the MathWorks Web site that you can use
as a starting point to create your own target solution. The solutions provide
guides to the following tasks for creating custom targets:
• Methods of embedding code onto a custom processor
• Creating a system target file
• Customizing the makefile and main file
• Adding compiler, chip, and board specific information
• Integrating legacy code and device drivers
• Creating blocks and libraries
• Implementing processor-in-the-loop (PIL) testing.
1 Start by downloading the technical solution on this web page:

Solution 1-BHU00D — An example guide to developing an embedded target
This solution provides example files and a guide to developing a custom
embedded target. The guide is divided into two parts, one on creating a
generic custom target and another on creating a target for the Freescale™
S12X processor using the Cosmic Compiler.
Read the example guide along with this document to understand the tasks
for developing embedded targets.
2 For more detailed example files for specific processors, see:

• Solution ID 1-9RXFT3 — An example Freescale S12X target using the
Cosmic Compiler
• Solution ID 1-BHT815 — An example Freescale S12X target using the
CodeWarrior® Compiler
These example kits contain example models, code generation files, and
instruction guides on generating and testing code for the processor.
The Cosmic example illustrates the use of the target connectivity API
for processor-in-the-loop (PIL) testing. The CodeWarrior example does

24-9

24

Custom Target Development

not have PIL but shows CAN Calibration Protocol (CCP) and Simulink
External mode.
The intent of the example kits is to provide working examples that
you can use as a base to create your own target solution. The
intent is not to provide a full featured and maintained Embedded
Target product like those provided by MathWorks or third-party
products, as listed on the supported hardware Web page:
http://www.mathworks.com/products/embedded-coder/supportedio.html.
3 You can watch videos showing overviews of both the example kits at the

following links:
• www.mathworks.com/products/demos/rtwembedded/S12X_final_generic/
• www.mathworks.com/products/demos/rtwembedded/STR9_final_multi/
For another example target for the ARM9 (STR9) processor, see Solution
ID 1-BBT4ID — An example ARM®9 (STR9) target using the GNU ARM
Compiler and Hitex STR9-comStick.
If you have questions on specific targets, please email
mytarget@mathworks.com.
The example kits and this document describe Embedded Coder features such
as customized ert system target files and processor-in-the-loop testing, but
you can study the examples as a starting point for use with Simulink Coder
targets.

24-10

Target Development Mechanics

Target Development Mechanics
In this section...
“Folder and File Naming Conventions” on page 24-11
“Components of a Custom Target” on page 24-12
“Key Folders Under Target Root (mytarget)” on page 24-17
“Key Files in Target Folder (mytarget/mytarget)” on page 24-20
“Additional Files for Externally Developed Targets” on page 24-28
“Target Development and the Build Process” on page 24-29

Folder and File Naming Conventions
You can use a single folder for your custom target files, or if desired you
can use subfolders, for example containing files associated with specific
development environments or tools.
For a custom target implementation, the recommended folder and file naming
conventions are
• Use only lowercase in all folder names, filenames, and extensions.
• Do not embed spaces in folder names. Spaces in folder names cause errors
with many third-party development environments.
• Include desired folders in the MATLAB path
• Do not place your custom target folder anywhere in the MATLAB folder
tree (that is, in or under the matlabroot folder). If you place your folder
under matlabroot you risk losing your work if you install a new MATLAB
version (or reinstall the current version).
The following sections explain how to organize your target folders and files
and add them to the your MATLAB path. They also provide high-level
descriptions of the files.
In this document, mytarget is a placeholder name that represents folders
and files that use the target’s name. The names dev_tool1, dev_tool2, and
so on represent subfolders containing files associated with development

24-11

24

Custom Target Development

environments or tools. This document describes an example structure where
the folder mytarget contains subfolders for mytarget, blocks, dev_tool1,
dev_tool2. The top level folder mytarget is the target root folder.

Components of a Custom Target
• “Overview” on page 24-12
• “Code Components” on page 24-13
• “Control Files” on page 24-15

Overview
The components of a custom target are files located in a hierarchy of folders.
The top-level folder in this structure is called the target root folder. The
target root folder and its contents are named, organized, and located on the
MATLAB path according to conventions described in “Folder and File Naming
Conventions” on page 24-11.
The components of a custom target include
• Code components: C source code that supervises and supports execution of
generated model code.
• Control files:

-

A system target file (STF) to control the code generation process.

-

Hook files: Optional TLC and .m files that can be invoked at well-defined
stages of the build process. Hook files let you customize the build process
and communicate information between various phases of the process.

File(s) to control the building of an executable from the generated code.
In a traditional make-based environment, a template makefile (TMF)
generates a makefile for this purpose. Another approach is to generate
project files in support of a modern integrated development environment
(IDE) such as the Freescale Semiconductor CodeWarrior IDE.

• Target preferences files: These files define a target preferences class
associated with your target. Your target preference class lets you create
data objects that define and store properties associated with your target.

24-12

Target Development Mechanics

For example, you may want to store a user-defined path to a cross-compiler
that is invoked by the build process.
• Other target files: Files that let you integrate your target into the MATLAB
environment. For example, you can provide an info.xml file to make your
target block libraries, examples, and target preferences available from
a MATLAB session.
The next sections introduce key concepts and terminology you need to know
to develop each component. References to more detailed information sources
are provided.

Code Components
A Simulink Coder program containing code generated from a Simulink model
consists of a number of code modules and data structures. These fall into
two categories.
Application Components. Application components are those which are
specific to a particular model; they implement the functions represented by
the blocks in the model. Application components are not specific to the target.
Application components include
• Modules generated from the model
• User-written blocks (S-functions)
• Parameters of the model that are visible, and can be interfaced to, external
code
Execution Support Files. A number of code modules and data structures,
referred to collectively as the execution support files, are responsible for
managing and supporting the execution of the generated program. The
execution support files modules are not automatically generated. Depending
on the requirements of your target, you must implement certain parts of the
execution support files. Execution Support Files on page 24-14 summarizes
the execution support files.

24-13

24

Custom Target Development

Execution Support Files

You Provide...

The Simulink Coder Software
Provides...

Customized main program

Generic main program

Timer interrupt handler to run
model

Execution engine and integration solver
(called by timer interrupt handler)

Other interrupt handlers

Example interrupt handlers
(Asynchronous Interrupt blocks)

Device drivers

Example device drivers

Data logging, parameter tuning,
signal monitoring, and External
mode support

Data logging, parameter tuning, signal
monitoring, and External mode APIs

User-Written Execution Support Files. The Simulink Coder software
provides most of the execution support files. Depending on the requirements
of your target, you must implement some or all of the following elements:
• A timer interrupt service routine (ISR). The timer runs at the program’s
base sample rate. The timer ISR is responsible for operations that
must be completed within a single clock period, such as computing the
current output sample. The timer ISR usually calls the Simulink Coder
rt_OneStep function.
If you are targeting a real-time operating system (RTOS), your generated
code usually executes under control of the timing and task management
mechanisms provided by the RTOS. In this case, you may not have to
implement a timer ISR.
• The main program. Your main program initializes the blocks in the model,
installs the timer ISR, and executes a background task or loop. The timer
periodically interrupts the main loop. If the main program is designed to
run for a finite amount of time, it is also responsible for cleanup operations
— such as memory deallocation and masking the timer interrupt — before
terminating the program.

24-14

Target Development Mechanics

If you are targeting a real-time operating system (RTOS), your main
program most likely spawns tasks (corresponding to the sample rates used
in the model) whose execution is timed and controlled by the RTOS.
Your main program typically is based on the Embedded Coder main
program, ert_main.c. “Standalone Programs (No Operating System)”
details the structure of the Embedded Coder execution support files and the
execution of Embedded Coder code, and provides guidelines for customizing
ert_main.c.
• Device drivers. Drivers communicate with I/O devices on your target
hardware. In production code, device drivers are normally implemented as
inlined S-functions.
• Other interrupt handlers. If your models need to support asynchronous
events, such as hardware generated interrupts and asynchronous read and
write operations, you must supply interrupt handlers. The Simulink Coder
Interrupt Templates library provides examples.
• Data logging, parameter tuning, signal monitoring, and External mode
support. It is atypical to implement rapid prototyping features such as
External mode support in an embedded target. However, it is possible to
support these features by using standard Simulink Coder APIs. See “Data
Exchange” on page 15-50 for details.

Control Files
The code generation and build process is directed by a number of TLC and
MATLAB files collectively called control files. This section introduces and
summarizes the main control files.
Top-Level Control File (make_rtw). The build process is initiated when
you click Build (or type Ctrl+B). At this point, Simulink Coder build process
parses the Make command field of the Code Generation pane of the
Configuration Parameters dialog box, expecting to find the name of a top-level
MATLAB file command that controls the build process (as well as optional
arguments to that command). The default top-level control file for the build
process is make_rtw.m.
Normally, target developers do not need detailed knowledge of how
make_rtw works. (The details for target developers are described in “Target

Development and the Build Process” on page 24-29.) You should not customize

24-15

24

Custom Target Development

make_rtw.m. The make_rtw.m file contains all the logic required to execute
your target-specific control files, including a number of hook points for
execution of your custom code.
make_rtw does the following:

• Passes optional arguments in to the build process
• Performs any required preprocessing before code generation
• Executes the STF to perform code generation (and optional HTML report
generation)
• Processes the TMF to generate a makefile
• Invokes a make utility to execute the makefile and build an executable
• Performs any required post-processing (such as generating calibration data
files or downloading the generated executable to the target)
System Target File (STF). The Target Language Compiler (TLC) generates
target-specific C or C++ code from an intermediate description of your
Simulink block diagram (model.rtw). The Target Language Compiler reads
model.rtw and executes a program consisting of several target files (.tlc
files.) The STF, at the top level of this program, controls the code generation
process. The output of this process is a number of source files, which are fed
to your development system’s make utility.
You need to create a customized STF to set code generation parameters for
your target. You should copy, rename, and modify the standard ERT system
target file (matlabroot/rtw/c/ert/ert.tlc).
The detailed structure of the STF is described in “Customize System Target
Files” on page 24-36.
Template Makefile (TMF). A TMF provides information about your model
and your development system. The build process uses this information to
create a makefile (.mk file) that builds an executable program.
Some targets implement more than one TMF, in order to support multiple
development environments (for example, two or more cross-compilers)

24-16

Target Development Mechanics

or multiple modes of code generation (for example, generating a binary
executable vs. generating a project file for your compiler).
The Embedded Coder software provides a large number of TMFs suitable
for different types of host-based development systems. These TMFs are
located in matlabroot/rtw/c/ert. The standard TMFs are described in the
“Template Makefiles and Make Options” on page 9-38 section of the Simulink
Coder documentation.
The detailed structure of the TMF is described in “Customize Template
Makefiles” on page 24-75.
Hook Files. Simulink Coder build process allows you to supply optional hook
files that are executed at specified points in the code generation and make
process. You can use hook files to add target-specific actions to the build
process.
The hook files must follow well-defined naming and location requirements.
“Folder and File Naming Conventions” on page 24-11 describes these
requirements.

Key Folders Under Target Root (mytarget)
• “Target Root Folder (mytarget)” on page 24-17
• “Target Folder (mytarget/mytarget)” on page 24-18
• “Target Block Folder (mytarget/blocks)” on page 24-18
• “Development Tools Folder (mytarget/dev_tool1, mytarget/dev_tool2)” on
page 24-20
• “Target Preferences Folder (mytarget/mytarget/@mytarget)” on page 24-20
• “Target Source Code Folder (mytarget/src)” on page 24-20

Target Root Folder (mytarget)
This folder contains the key subfolders for the target (see “Folder and File
Naming Conventions” on page 24-11). You can also locate miscellaneous
files (such as a readme file) in the target root folder. The following sections
describe required and optional subfolders and their contents.

24-17

24

Custom Target Development

Target Folder (mytarget/mytarget)
This folder contains files that are central to the target, such as the system
target file (STF) and template makefile (TMF). “Key Files in Target Folder
(mytarget/mytarget)” on page 24-20 summarizes the files that should be
stored in mytarget/mytarget, and provides pointers to detailed information
about these files.
Note mytarget/mytarget should be on the MATLAB path.

Target Block Folder (mytarget/blocks)
If your target includes device drivers or other blocks, locate the block
implementation files in this folder. mytarget/blocks contains
• Compiled block MEX-files
• Source code for the blocks
• TLC inlining files for the blocks
• Library models for the blocks (if you provide your blocks in one or more
libraries)
Note mytarget/blocks should be on the MATLAB path.
You can also store example models and any supporting files in
mytarget/blocks. Alternatively, you can create a mytarget/mytargetdemos
folder, which should also be on the MATLAB path.
To display your blocks in the standard Simulink Library Browser and/or
integrate your example models into the MATLAB session environment , you
can create the files described below and store them in mytarget/blocks.
mytarget/blocks/slblocks.m. This file allows a group of blocks to be
integrated into the Simulink Library and Simulink Library Browser.

24-18

Target Development Mechanics

Example slblocks.m File
function blkStruct = slblocks
% Information for "Blocksets and Toolboxes" subsystem
blkStruct.Name = sprintf('Embedded Target\n for MYTARGET');
blkStruct.OpenFcn = 'mytargetlib';
blkStruct.MaskDisplay = 'disp(''MYTARGET'')';
% Information for Simulink Library Browser
Browser(1).Library = 'mytargetlib';
Browser(1).Name

= 'Embedded Target for MYTARGET';

Browser(1).IsFlat

= 1;% Is this library "flat" (i.e. no subsystems)?

blkStruct.Browser = Browser;

mytarget/blocks/demos.xml. This file provides information about
the components, organization, and location of example models. MATLAB
software uses this information to place the example in the MATLAB session
environment.
Example demos.xml File


Embedded Target for MYTARGET
simulink
$toolbox/matlab/icons/boardicon.gif
mytarget_overview.html




mytarget_overview.html
mytarget_model




24-19

24

Custom Target Development

Development Tools Folder (mytarget/dev_tool1,
mytarget/dev_tool2)
These folders contain files associated with specific development environments
or tools (dev_tool1, dev_tool2, etc.). Normally, your target supports at least
one such development environment and invokes its compiler, linker, and
other utilities during the build process. mytarget/dev_tool1 includes linker
command files, startup code, hook functions, and any other files required to
support this process.
For each development environment, you should provide a separate folder.
You should use the target preferences mechanism to store information about
a user’s choice of development environment or tool, paths to the installed
development tools, and so on. Using target preferences data in this way,
lets your build process code select a development environment and invoke a
compiler and other utilities for your target platform. See the code excerpt in
“mytarget_default_tmf.m Example Code” on page 24-89 for an example of how
to use target preferences data for this purpose.

Target Preferences Folder (mytarget/mytarget/@mytarget)
If you create a target preferences class to store information about user
preferences, you should store data class definition files and other files that
support your target-specific preferences in mytarget/mytarget/@mytarget.
The Simulink Data Class Designer creates the @mytarget folder automatically
within the parent folder.

Target Source Code Folder (mytarget/src)
This folder is optional. If the complexity of your target requires it, you can
use mytarget/src to store any common source code and configuration code
(such as boot and startup code).

Key Files in Target Folder (mytarget/mytarget)
• “Introduction” on page 24-21
• “mytarget.tlc” on page 24-21
• “mytarget.tmf” on page 24-22

24-20

Target Development Mechanics

• “mytarget_default_tmf.m” on page 24-22
• “mytarget_settings.tlc” on page 24-22
• “mytarget_genfiles.tlc” on page 24-22
• “mytarget_main.c” on page 24-23
• “STF_make_rtw_hook.m” on page 24-23
• “STF_wrap_make_cmd_hook.m” on page 24-23
• “STF_rtw_info_hook.m (obsolete)” on page 24-26
• “info.xml” on page 24-27
• “mytarget_overview.html” on page 24-28

Introduction
The target folder mytarget/mytarget contains key files in your target
implementation. These include the system target file, template makefile,
main program module, and optional M and TLC hook files that let you add
target-specific actions to the build process. The following sections describe the
key target folder files.

mytarget.tlc
mytarget.tlc is the system target file (STF). Functions of the STF include

• Making the target visible in the System Target File Browser
• Definition of code generation options for the target (inherited and
target-specific)
• Providing an entry point for the top-level control of the TLC code generation
process
You should base your STF on ert.tlc, the STF provided by the Embedded
Coder software.
“Customize System Target Files” on page 24-36 gives detailed information
on the structure of the STF, and also gives instructions on how to customize
an STF to

24-21

24

Custom Target Development

• Display your target in the System Target File Browser
• Add your own target options to the Configuration Parameters dialog box
• Tailor the code generation and build process to the requirements of your
target

mytarget.tmf
mytarget.tmf is the template makefile for building an executable for your

target.
For basic information on the structure and operation of template makefiles,
see “Customize Template Makefiles” on page 24-75.
If your target development environment requires automation of a modern
integrated development environment (IDE) rather than use of a traditional
make utility, see “Interface to Development Tools” on page 24-123.
You might create multiple template makefiles to support different
development environments. See “Supporting Multiple Development
Environments” on page 24-60 and “mytarget_default_tmf.m Example Code”
on page 24-89 for information.

mytarget_default_tmf.m
This file is optional. You can implement a mytarget_default_tmf.m file to
select a template makefile, based on user preferences. See “Setting Up a
Template Makefile” on page 24-88.

mytarget_settings.tlc
This file is optional. Its purpose is to centralize global settings in the code
generation environment. See “Using mytarget_settings.tlc” on page 24-55 for
details.

mytarget_genfiles.tlc
This file is optional. mytarget_genfiles.tlc is useful as a central file
from which to invoke any target-specific TLC files that generate additional
files as part of your target build process. For example, your target may
create sub-makefiles or project files for a development environment, or

24-22

Target Development Mechanics

command scripts for a debugger to do automatic downloads. See “Using
mytarget_genfiles.tlc” on page 24-58 for details.

mytarget_main.c
A main program module is required for your target. To provide a main
module, you can either
• Modify the ert_main.c module provided by the Embedded Coder software
• Generate mytarget_main.c or .cpp during the build process
“Standalone Programs (No Operating System)” contains a detailed description
of the operation of ert_main.c. The section also contains guidelines for
generating and modifying a main program module.

STF_make_rtw_hook.m
STF_make_rtw_hook.m is an optional hook file that you can use to invoke
target-specific functions or executables at specified points in the build process.
STF_make_rtw_hook.m implements a function that dispatches to a specific
action depending on the method argument that is passed into it.

“Customize Build Process with STF_make_rtw_hook File” on page 22-21
describes the operation of the STF_make_rtw_hook.m hook file in detail.

STF_wrap_make_cmd_hook.m
Use this file to override the default Simulink Coder behavior for selecting the
compiler tool to be used in the build process.
By default, the Simulink Coder build process is based on makefiles. On PC
hosts, the build process creates model.bat, an MS-DOS batch file. model.bat
sets up the environment variables for the compiler, linker, and other utilities,
and invokes a make utility. The batch file, model.bat, obtains the required
environment variable settings from the MAKECMD field in the template
makefile. The standard Simulink Coder template makefiles support only
standard compilers that build executables on the host system.
When developing an embedded target, you often need to override these
defaults. Typically, you need to support one or more target-specific

24-23

24

Custom Target Development

cross-development systems, rather than supporting compilers for the host
system. The STF_wrap_make_cmd_hook mechanism provides a way to set up
an environment specific to an embedded development tool.
Note that the naming convention for this file is not based on the target name.
It is based on the concatenation of the system target filename, STF, with the
string '_wrap_make_cmd_hook'.
Stub makefiles. Many modern cross-development systems, such as the
Freescale Semiconductor CodeWarrior development environment, are based
on project files rather than makefiles. If the interface to the embedded
development system is not makefile based, one recommended approach is to
create a stub makefile. When the build process invokes the stub makefile,
no action takes place.
STF_wrap_make_cmd_hook Mechanism. A recommended approach to
supporting non-host-based development systems is to provide a hook file that
is called instead of the default host-based compiler selection.
To do this, create a STF_wrap_make_cmd_hook.m file. If this file exists, the
build process calls it instead of the default compiler selection process. Check
that:
• The file is on the MATLAB path.
• The filename is the name of your STF, prepended to the string
'__wrap_make_cmd_hook.m'.
• The hook function implemented in the file follows the function prototype
shown in the code example below.
A typical approach would be to write a STF_wrap_make_cmd_hook.m file
that creates a MS-DOS batch file (model.bat). The batch file first sets up
environment variables for the embedded target development system. Then,
it invokes the embedded target’s make utility on the generated makefile.
The STF_wrap_make_cmd_hook function should return a system command
that invokes model.bat.
This approach is shown in “Example STF_wrap_make_cmd_hook Function”
on page 24-26.

24-24

Target Development Mechanics

Alternatively, any MS-DOS batch file can be created by
STF_wrap_make_cmd_hook, and the function can return any
command; it is not limited to model.bat. Like the exit case of the
STF_make_rtw_hook mechanism, this provides the flexibility to invoke other
utilities or applications.
On a PC host, the build process checks the standard output (STDOUT) for a
build success string. By default, the string is
"### Created"

You can change this specifying a different BUILD_SUCCESS variable in the
template makefile.

24-25

24

Custom Target Development

Example STF_wrap_make_cmd_hook Function.
function makeCmdOut = stfname_wrap_make_cmd_hook(args)
makeCmd
= args.makeCmd;
modelName
= args.modelName;
verbose
= args.verbose;
% args.compilerEnvVal not used
cmdFile = ['.\',modelName, '.bat'];
cmdFileFid = fopen(cmdFile,'wt');
if ~verbose
fprintf(cmdFileFid, '@echo off\n');
end
try
prefs = RTW.TargetPrefs.load('mytarget.prefs');
catch exception
rethrow(exception);
end
fprintf(cmdFileFid, '@set TOOL_VAR1=%s\n', prefs.ImpPath);
fprintf(cmdFileFid, '@set TOOL_VAR2=x86-win32\n');
toolRoot = fullfile(prefs.ImpPath,'host','tool','4.4b');
fprintf(cmdFileFid, '@set TOOL_VAR3=%s\n', toolRoot);
path = getenv('Path');
path1 = fullfile(prefs.ImpPath,'host','license;');
if ~isempty(strfind(path,path1)) path1 = ''; end
fprintf(cmdFileFid, '@set Path=%s%s%s\n', path1, path);
fullMakeCmd = fullfile(prefs.ImpPath,'host','tool',...
'bin', makeCmd);
fprintf(cmdFileFid, '%s\n', fullMakeCmd);
fclose(cmdFileFid);
makeCmdOut = cmdFile;

STF_rtw_info_hook.m (obsolete)
Prior to Release 14, custom targets supplied target-specific information with
a hook file (referred to as STF_rtw_info_hook.m). The STF_rtw_info_hook
specified properties such as word sizes for integer data types (for example,

24-26

Target Development Mechanics

char, short, int, and long), and C implementation-specific properties of

the custom target.
The STF_rtw_info_hook mechanism has been replaced by the Hardware
Implementation pane of the Configuration Parameters dialog box. Using
this dialog box, you can specify all properties that were formerly specified in
your STF_rtw_info_hook file.
For backward compatibility, existing STF_rtw_info_hook files are still
available. However, you should convert your target and models to use the
Hardware Implementation pane. See “Hardware Targets” on page 9-9.

info.xml
This file provides information to MATLAB software that specifies where to
display the target toolbox in the MATLAB session environment.
Example info.xml File. This example shows you how to set up access to a
target’s example page and target preferences GUI from the MATLAB session
environment.

13
Embedded Target for MYTARGET
simulink
$toolbox/simulink/simulink/simulinkicon.gif



demo simulink 'Embedded Target for MYTARGET'
$toolbox/matlab/icons/demoicon.gif



mytargetTargetPrefs =
RTW.TargetPrefs.load('mytarget.prefs');

24-27

24

Custom Target Development

gui(mytargetTargetPrefs); 
$toolbox/simulink/simulink/simulinkicon.gif




mytarget_overview.html
By convention, this file serves as home page for the target examples.
The  field in demos.xml should point to
mytarget_overview.html (see “mytarget/blocks/demos.xml” on
page 24-19).
Example mytarget_overview.html File.

Embedded Target for MYTARGET

Embedded Target for MYTARGET Example Model

This example provides a simple model that allows you to generate an executable for a supported target board. You can then download and run the executable and set breakpoints to study and monitor the execution behavior.

Additional Files for Externally Developed Targets • “Introduction” on page 24-28 • “mytarget/mytarget/mytarget_setup.m” on page 24-29 • “mytarget/mytarget/doc” on page 24-29 Introduction If you are developing an embedded target that is not installed into the MATLAB tree, you should provide a target setup script and target 24-28 Target Development Mechanics documentation within mytarget/mytarget, for the convenience of your users. The following sections describe the required materials and where to place them. mytarget/mytarget/mytarget_setup.m This file script adds paths for your target to the MATLAB path. Your documentation should instruct users to run the script when installing the target. You should include a call to the MATLAB function savepath in your mytarget_setup.m script. This function saves the added paths, so users need to run mytarget_setup.m only once. The following code is an example mytarget_setup.m file. function mytarget_setup() curpath = pwd; tgtpath = curpath(1:end-length('\mytarget')); addpath(fullfile(tgtpath, 'mytarget')); addpath(fullfile(tgtpath, 'dev_tool1')); addpath(fullfile(tgtpath, 'blocks')); addpath(fullfile(tgtpath, 'mytargetdemos')); savepath; disp('MYTARGET Target Path Setup Complete.'); mytarget/mytarget/doc You should put all documentation related to your target in the folder mytarget/mytarget/doc. Target Development and the Build Process • “About the Build Process” on page 24-30 • “Build Process Phases and Information Passing” on page 24-30 • “Additional Information Passing Techniques” on page 24-32 24-29 24 Custom Target Development About the Build Process To develop an embedded target, you need a thorough understanding of the Simulink Coder build process. Your embedded target uses the build process and may require you to modify or customize the process. A general overview of code generation and the build process is given in “Source Code Generation” and “Program Builds”. This section supplements that overview with a description of the build process as customized by the Embedded Coder software. The emphasis is on points in the process where customization hooks are available and on passing information between different phases of the process. This section concludes with “Additional Information Passing Techniques” on page 24-32, describing assorted tips and tricks for passing information during the build process. Build Process Phases and Information Passing It is important to understand where (and when) the build process obtains required information. Sources of information include • The model.rtw file, which provides information about the generating model. All information in model.rtw is available to target TLC files. • The Simulink Coder related panes of the Configuration Parameters dialog box. Options (both general and target-specific) are provided through check boxes, menus, and edit fields. You can associate options with TLC variables and makefile tokens in the rtwoptions data structure. • The target preferences data. Target preferences provide persistent information about the target, such as the location of your development tools. • The template makefile (TMF), which generates the model-specific makefile. • Environment variables on the host computer. Environment variables provide additional information about installed development tools. • Other target-specific files such as target-related TLC files, linker command files, or project files. 24-30 Target Development Mechanics It is also important to understand the several phases of the build process and how to pass information between the phases. The build process comprises several high-level phases: • Execution of the top-level file (slbuild.m or rtwbuild.m) to sequence through the build process for a target • Conversion of the model into the TLC input file (model.rtw) • Generation of the target code by the TLC compiler • Compilation of the generated code with make or other utilities • Transmission of the final generated executable to the target hardware with a debugger or download utility It is helpful to think of each phase of the process as a different “environment” that maintains its own data. These environments include • MATLAB code execution environment (MATLAB) • Simulink • Target Language Compiler execution environment • makefile • Development environments such as and IDE or debugger In each environment, you might get information from the various sources mentioned above. For example, during the TLC phase, execute MATLAB file might execute to obtain information from the MATLAB environment. Also, a given phase may generate information for a subsequent phase. See “Key Files in Target Folder (mytarget/mytarget)” on page 24-20 for details on the available MATLAB file and TLC hooks for information passing, with code examples. 24-31 24 Custom Target Development Additional Information Passing Techniques This section describes a number of useful techniques for passing information among different phases of the build process. tlcvariable Field in rtwoptions Structure. Options on the Simulink Coder related panes of the Configuration Parameters dialog box can be associated with a TLC variable, and specified in the tlcvariable field of the option’s entry in the rtwoptions structure. The variable value is passed on the command line when TLC is invoked. This provides a way to make Simulink Coder options and their values available in the TLC phase. See “System Target File Structure” on page 24-37 for further information. makevariable Field in rtwoptions Structure. Similarly, Simulink Coder options can be associated with a template makefile token, specified in the makevariable field of the option’s entry in the rtwoptions structure. If a token of the same name as the makevariable name exists in the TMF, the token is updated with the option value when the final makefile is created. If the token does not exist in the TMF, the makevariable is passed in on the command line when make is invoked. Thus, in either case, the makevariable is available to the makefile. See “System Target File Structure” on page 24-37 for further information. Accessing Host Environment Variables. You can access host shell environment variables at the MATLAB command line by entering the getenv command. For example: getenv ('MSDEVDIR') ans = D:\Applications\Microsoft Visual Studio\Common\MSDev98 To access the same information from TLC, use the FEVAL directive to invoke getenv. %assign eVar = FEVAL("getenv", ""). 24-32 Target Development Mechanics Supplying Development Environment Information to Your Template Makefile. An embedded target must tie the build process to target-specific development tools installed on a host computer. For the make process to run these tools, the TMF must be able to determine the name of the tools, the path to the compiler, linker, and other utilities, and possibly the host operating system environment variable settings. This section describes two techniques for supplying this information. The simpler, more traditional approach is to require the end user to modify the target TMF. The user enters path information (such as the location of a compiler executable), and possibly host operating system environment variables, as make variables. This allows the TMF to be tailored to specific needs. This approach is not satisfactory in an environment where the MATLAB installation is on a network and multiple users share read-only TMFs. Another possible drawback to this approach is that the tool information is only available during the makefile processing phase of the build process. A second approach is to use the target preferences feature together with the STF_wrap_make_cmd_hook mechanism (see “STF_wrap_make_cmd_hook Mechanism” on page 24-24). In this approach, compiler and other tool path information is stored as preferences data, which is obtained by the STF_wrap_make_cmd_hook.m file. This allows tool path information to be saved separately for each user. Another advantage to the second approach is that target preferences data is available to all phases of the build process, including the TLC phase. This information may be required to support features such as RAM/ROM profiling. Using MATLAB Application Data. Application data provides a way for applications to save and retrieve data stored with the GUI. This technique enables you to create what is essentially a user-defined property for an object, and use this property to store data for use in the build process. If you are unfamiliar with this technique, see the “Application Data” section of the MATLAB documentation of creating graphical user interfaces. The following code examples illustrates the use of application data to pass information to TLC. 24-33 24 Custom Target Development This file, tlc2appdata.m, stores the data passed in as application data under the name passed in (appDataName). function k = tlc2appdata(appDataName, data) disp([mfilename,': ',appDataName,' ', data]); setappdata(0,appDataName,data); k = 0; % TLC expects a return value for FEVAL. The following sample TLC file uses the FEVAL directive to invoke tlc2appdata.m to store arbitrary application data, under the name z80. %% test.tlc %% %assign myApp = "z80" %assign myData = "314159" %assign dummy = FEVAL("tlc2appdata",myApp,myData) To test this technique: 1 Create the tlc2appdata.m file as shown. Check that tlc2appdata.m is stored in a folder on the MATLAB path. 2 Create the TLC file as shown. Save it as test.tlc. 3 Enter the following command at the MATLAB prompt to execute the TLC file: tlc test.tlc 4 Get the application data at the MATLAB prompt: k = getappdata(0,'z80') The function returns the value 314159. 24-34 Target Development Mechanics 5 Enter the following command. who Note that application data is not stored in the MATLAB workspace. Also observe that the z80 data is not visible. Using application data in this way has the advantage that it does not clutter the MATLAB workspace. Also, it helps prevent you from accidently deleting your data, since it is not stored directly in the your workspace. A real-world use of application data might be to collect information from the model.rtw file and store it for use later in the build process. Adding Block-Specific Information to the Makefile. The rtwmakecfg mechanism provides a method for inlined S-functions such as driver blocks to add information to the makefile. This mechanism is described in “Using the rtwmakecfg.m API to Customize Generated Makefiles” on page 24-92. 24-35 24 Custom Target Development Customize System Target Files In this section... “Control Code Generation With the System Target File” on page 24-36 “System Target File Naming and Location Conventions” on page 24-37 “System Target File Structure” on page 24-37 “Define and Display Custom Target Options” on page 24-46 “Tips and Techniques for Customizing Your STF” on page 24-54 “Create a Custom Target Configuration” on page 24-61 Control Code Generation With the System Target File The system target file (STF) exerts overall control of the code generation stage of the build process. The STF also lets you control the presentation of your target to the end user. The STF provides • Definitions of variables that are fundamental to the build process, such as code format to be generated • The main entry point to the top-level TLC program that generates code • Target information for display in the System Target File Browser • A mechanism for defining target-specific code generation options (and other parameters affecting the build process) and for displaying them in the Configuration Parameters dialog box Note You can save a configuration set with custom options to a MAT-file. However, when you load the MAT-file, some custom options might not appear in the Configuration Parameters dialog box. • A mechanism for inheriting options from another target (such as the Embedded Real-Time (ERT) target) 24-36 Customize System Target Files This chapter provides information on the structure of the STF, guidelines for customizing an STF, and a basic tutorial that helps you get a skeletal STF up and running. Note that, although the STF is a Target Language Compiler (TLC) file, it contains embedded MATLAB code. Before creating or modifying an STF, you should acquire a working knowledge of TLC and of the MATLAB language. “Target Language Compiler” and “Scripts vs. Functions” describe the features and syntax of both the TLC and MATLAB languages. While reading this chapter, you may want to refer to the STFs provided with the Simulink Coder product. Most of these files are stored in the target-specific folders under matlabroot/rtw/c. Additional STFs are stored under matlabroot/toolbox/rtw/targets. System Target File Naming and Location Conventions An STF must be located in a folder on the MATLAB path for the target to be displayed in the System Target File Browser and invoked in the build process. Follow the location and naming conventions for STFs and related target files given in “Folder and File Naming Conventions” on page 24-11. System Target File Structure • “Overview” on page 24-38 • “Header Comments” on page 24-40 • “TLC Configuration Variables” on page 24-41 • “TLC Program Entry Point and Related %includes” on page 24-42 • “RTW_OPTIONS Section” on page 24-43 • “rtwgensettings Structure” on page 24-44 • “Additional Code Generation Options” on page 24-46 • “Model Reference Considerations” on page 24-46 24-37 24 Custom Target Development Overview This section is a guide to the structure and contents of an STF. The following listing shows the general structure of an STF. Note that this is not a complete code listing of an STF. The listing consists of excerpts from each of the sections that make up an STF. %%---------------------------%% Header Comments Section %%---------------------------%% SYSTLC: Example Real-Time Target %% TMF: my_target.tmf MAKE: make_rtw EXTMODE: ext_comm %% Inital comments contain directives for STF Browser. %% Documentation, date, copyright, and other info may follow. ... %selectfile NULL_FILE ... %%---------------------------%% TLC Configuration Variables Section %%---------------------------%% Assign code format, language, target type. %% %assign CodeFormat = "Embedded-C" %assign TargetType = "RT" %assign Language = "C" %% %%---------------------------%% (OPTIONAL) Import Target Settings %%---------------------------%include "mytarget_settings.tlc" %% %%---------------------------%% TLC Program Entry Point %%---------------------------%% Call entry point function. %include "codegenentry.tlc" %% %%---------------------------%% (OPTIONAL) Generate Files for Build Process %%---------------------------%include "mytarget_genfiles.tlc" 24-38 Customize System Target Files %%---------------------------%% RTW_OPTIONS Section %%---------------------------/% BEGIN_RTW_OPTIONS %% Define rtwoptions structure array. This array defines target-specific %% code generation variables, and controls how they are displayed. rtwoptions(1).prompt = 'example code generation options'; ... rtwoptions(6).prompt = 'Show eliminated blocks'; rtwoptions(6).type = 'Checkbox'; ... %----------------------------------------% % Configure RTW code generation settings % %----------------------------------------% ... %%---------------------------%% rtwgensettings Structure %%---------------------------%% Define suffix string for naming build folder here. rtwgensettings.BuildDirSuffix = '_mytarget_rtw' %% Callback compatibility declaration rtwgensettings.Version = '1'; %% (OPTIONAL) target inheritance declaration rtwgensettings.DerivedFrom = 'ert.tlc'; %% (OPTIONAL) other rtwGenSettings fields... ... END_RTW_OPTIONS %/ %%---------------------------%% targetComponentClass - MATHWORKS INTERNAL USE ONLY %% REMOVE NEXT SECTION FROM USER_DEFINED CUSTOM TARGETS %%---------------------------/% BEGIN_CONFIGSET_TARGET_COMPONENT targetComponentClass = 'Simulink.ERTTargetCC'; END_CONFIGSET_TARGET_COMPONENT %/ 24-39 24 Custom Target Development If you are creating a custom target based on an existing STF, you must remove the targetComponentClass section (bounded by the directives BEGIN_CONFIGSET_TARGET_COMPONENT and END_CONFIGSET_TARGET_COMPONENT). This section is reserved for the use of targets developed internally by MathWorks. Header Comments These lines at the head of the file are formatted as TLC comments. They provide required information to the System Target File Browser and to the build process. Note that you must place the browser comments at the head of the file, before any other comments or TLC statements. The presence of the comments enables the Simulink Coder software to detect STFs. When the System Target File Browser is opened, the Simulink Coder software scans the MATLAB path for TLC files that have formatted header comments. The comments contain the following directives: • SYSTLC: This string is a descriptor that appears in the browser. • TMF: Name of the template makefile (TMF) to use during build process. When the target is selected, this filename is displayed in the Template makefile field of the Code Generation pane of the Configuration Parameters dialog box. • MAKE: make command to use during build process. When the target is selected, this command is displayed in the Make command field of the Code Generation pane of the Configuration Parameters dialog box. • EXTMODE: Name of External mode interface file (if any) associated with your target. If your target does not support External mode, use no_ext_comm. The following header comments are from matlabroot/rtw/c/ert/ert.tlc. %% SYSTLC: Embedded Coder TMF: ert_default_tmf MAKE: make_rtw \ %% EXTMODE: ext_comm %% SYSTLC: Create Visual C/C++ Solution File for the Embedded Coder\ %% . . . 24-40 TMF: RTW.MSVCBuild MAKE: make_rtw EXTMODE: ext_comm Customize System Target Files Note Limitation: Each comment can only contain a maximum of two lines, as shown in the preceding example. Note that you can specify more than one group of directives in the header comments. Each such group is displayed as a different target configuration in the System Target File Browser. In the above example, the first two lines of code specify the default configuration of the ERT target. The next two lines specify a configuration that creates and builds a Microsoft Visual C++ Solution (.shn) file. The figure below shows how these configurations appear in the System Target File Browser. See “Create a Custom Target Configuration” on page 24-61 for an example of customized header comments. TLC Configuration Variables This section of the STF assigns global TLC variables that affect the overall code generation process. For an embedded target, in almost all cases you should simply use the global TLC variable settings used by the ERT target (ert.tlc). It is especially important that your STF select the Embedded-C code format. Verify that values are assigned to the following variables: 24-41 24 Custom Target Development • CodeFormat: The CodeFormat variable selects one of the available code formats. The Embedded-C format is used by the ERT target. Your ERT-based target should specify Embedded-C format. Embedded-C format is designed for production code, minimal memory usage, static memory allocation, and a simplified interface to generated code. For information on other code formats, see the “Targets and Code Formats” on page 9-29 chapter of the Simulink Coder documentation. • Language: The only valid value is C, which enables support for C or C++ code generation as specified by the configuration parameter TargetLang (see the TargetLang entry in “Parameter Command-Line Information Summary” in the Simulink Coder documentation for more information). • TargetType: The Simulink Coder software defines the preprocessor symbols RT and NRT to distinguish simulation code from real-time code. These symbols are used in conditional compilation. The TargetType variable determines whether RT or NRT is defined. Most targets are intended to generate real-time code. They assign TargetType as follows. %assign TargetType = "RT" Some targets, such as the model reference simulation target, accelerated simulation target, RSim target, and S-function target, generate code for use in nonreal time only. Such targets assign TargetType as follows. %assign TargetType = "NRT" TLC Program Entry Point and Related %includes The code generation process normally begins with codegenentry.tlc. The STF invokes codegenentry.tlc as follows. %include "codegenentry.tlc" Note codegenentry.tlc and the lower-level TLC files assume that CodeFormat, TargetType, and Language have been assigned. Set these variables before including codegenentry.tlc. 24-42 Customize System Target Files If you need to implement target-specific code generation features, you should include the TLC files mytarget_settings.tlc and mytarget_genfiles.tlc in your STF. These files provide a mechanism for executing custom TLC code before and after invoking codegenentry.tlc. For information on these mechanisms, see • “Using mytarget_settings.tlc” on page 24-55 for an example of custom TLC code for execution before the main code generation entry point. • “Using mytarget_genfiles.tlc” on page 24-58 for an example of custom TLC code for execution after the main code generation entry point. • “Target Development and the Build Process” on page 24-29 for general information on the build process, and for information on other build process customization hooks. Another way to customize the code generation process is to call lower-level functions (normally invoked by codegenentry.tlc) directly, and include your own TLC functions at each stage of the process. This approach should be taken with caution. See “TLC Files” for more information. The lower-level functions called by codegenentry.tlc are • genmap.tlc: maps block names to corresponding language-specific block target files. • commonsetup.tlc: sets up global variables. • commonentry.tlc: starts the process of generating code in the format specified by CodeFormat. RTW_OPTIONS Section The RTW_OPTIONS section is bounded by the directives: /% BEGIN_RTW_OPTIONS . . . END_RTW_OPTIONS %/ 24-43 24 Custom Target Development The first part of the RTW_OPTIONS section defines an array of rtwoptions structures. This structure is discussed in “Using rtwoptions to Display Custom Target Options” on page 24-47. The second part of the RTW_OPTIONS section defines rtwgensettings, a structure defining the build folder name and other settings for the code generation process. See “rtwgensettings Structure” on page 24-44 for information about rtwgensettings. rtwgensettings Structure The final part of the STF defines the rtwgensettings structure. This structure stores information that is written to the model.rtw file and used by the build process. The rtwgensettings fields of most interest to target developers are • rtwgensettings.Version: Use this property to enable rtwoptions callbacks and to use the Callback API in rtwgensettings.SelectCallback. Note To use callbacks you must set: rtwgensettings.Version = '1'; Add the statement above to the Configure RTW code generation settings section of the system target file. • rtwgensettings.DerivedFrom: This string property defines the system target file from which options are to be inherited. See “Inheriting Target Options” on page 24-53. • rtwgensettings.SelectCallback: this property specifies a SelectCallback function. You must set rtwgensettings.Version = '1'; or your callback will be ignored. SelectCallback is associated with the target rather than with any of its individual options. The SelectCallback function is triggered when the user selects a target with the System Target File browser. The SelectCallback function is useful for setting up (or disabling) configuration parameters specific to the target. 24-44 Customize System Target Files The following code installs a SelectCallback function: rtwgensettings.SelectCallback = 'my_select_callback_handler(hDlg, hSrc)'; The arguments to the SelectCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. Note If you have developed a custom target and you want it to be compatible with model referencing, you must implement a SelectCallback function to declare model reference compatibility. See “Support Model Referencing” on page 24-101. • rtwgensettings.ActivateCallback: this property specifies an ActivateCallback function. The ActivateCallback function is triggered when the active configuration set of the model changes. This could happen during model loading, and also when the user changes the active configuration set. The following code installs an ActivateCallback function: rtwgensettings.ActivateCallback = 'my_activate_callback_handler(hDlg, hSrc)'; The arguments to the ActivateCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. • rtwgensettings.PostApplyCallback: this property specifies a PostApplyCallback function. The PostApplyCallback function is triggered when the user clicks the Apply or OK button after editing options in the Configuration Parameters dialog box. The PostApplyCallback function is called after the changes have been applied to the configuration set. The following code installs an PostApplyCallback function: rtwgensettings.PostApplyCallback = 'my_postapply_callback_handler(hDlg, hSrc)'; The arguments to the PostApplyCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. • rtwgensettings.BuildDirSuffix: Most targets define a string that identifies build folders created by the target. The build process appends 24-45 24 Custom Target Development the string defined in the rtwgensettings.BuildDirSuffix field to the model name to form the name of the build folder. For example, if you define rtwgensettings.BuildDirSuffix as follows rtwgensettings.BuildDirSuffix = '_mytarget_rtw' the build folders are named model_mytarget_rtw. Additional Code Generation Options “Configure Generated Code with TLC” on page 22-18 in the Simulink Coder documentation describes additional TLC code generation variables. End users of any target can assign these variables by entering statements of the form -aVariable=val in the TLC options field of the Code Generation pane. However, the preferred approach is to assign these variables in the STF using statements of the form: %assign Variable = val For readability, we recommend that you add such assignments in the section of the STF after the comment Configure RTW code generation settings. Model Reference Considerations See “Support Model Referencing” on page 24-101 for important information on STF and other modifications you may need to make to support the Simulink Coder model referencing features. Define and Display Custom Target Options • “Using rtwoptions to Display Custom Target Options” on page 24-47 • “Example System Target File With Customized rtwoptions” on page 24-52 • “Inheriting Target Options” on page 24-53 24-46 Customize System Target Files Using rtwoptions to Display Custom Target Options You control the options to display in the Code Generation pane of the Configuration Parameters dialog box by customizing the rtwoptions structure in your system target file. The fields of the rtwoptions structure define variables and associated user interface elements to be displayed in the Configuration Parameters dialog box. Using the rtwoptions structure array, you can define target-specific options displayed in the dialog box and organize options into categories. You can also write callback functions to specify how these options are processed. When the Code Generation pane opens, the rtwoptions structure array is scanned and the listed options are displayed. Each option is represented by an assigned user interface element (check box, edit field, menu, or push button), which displays the current option value. The user interface elements can be in an enabled or disabled (grayed-out) state. If an option is enabled, the user can change the option value. You can also use the rtwoptions structure array to define special NonUI elements that cause callback functions to be executed, but that are not displayed in the Code Generation pane. See “NonUI Elements” on page 24-52 for details. The elements of the rtwoptions structure array are organized into groups. Each group of items begins with a header element of type Category. The default field of a Category header must contain a count of the remaining elements in the category. The Category header is followed by options to be displayed on the Code Generation pane. The header in each category is followed by one or more option definition elements. Each category of target options corresponds to options listed under Code Generation in the Configuration Parameters dialog box. The table rtwoptions Structure Fields Summary on page 24-50 summarizes the fields of the rtwoptions structure. 24-47 24 Custom Target Development Note You can save a configuration set with custom options to a MAT-file. However, when you load the MAT-file, some custom options might not appear in the Configuration Parameters dialog box. Example rtwoptions Structure. The following example is excerpted from matlabroot/rtw/c/rtwsfcn/rtwsfcn.tlc, the STF for the S-function target. The code defines an rtwoptions structure array of three elements. The default field of the first (header) element is set to 4, indicating the number of elements that follow the header. 24-48 Customize System Target Files rtwoptions(1).prompt = 'S-Function Target'; rtwoptions(1).type = 'Category'; rtwoptions(1).enable = 'on'; rtwoptions(1).default = 4; rtwoptions(1).popupstrings = ''; rtwoptions(1).tlcvariable = ''; rtwoptions(1).tooltip = ''; % number of items under this category % excluding this one. rtwoptions(1).callback = ''; rtwoptions(1).makevariable = ''; rtwoptions(2).prompt = 'Create new model'; rtwoptions(2).type = 'Checkbox'; rtwoptions(2).default = 'on'; rtwoptions(2).tlcvariable = 'CreateModel'; rtwoptions(2).makevariable = 'CREATEMODEL'; rtwoptions(2).tooltip = ... ['Create a new model containing the generated S-Function block inside it']; rtwoptions(3).prompt = 'Use value for tunable parameters'; rtwoptions(3).type = 'Checkbox'; rtwoptions(3).default = 'off'; rtwoptions(3).tlcvariable = 'UseParamValues'; rtwoptions(3).makevariable = 'USEPARAMVALUES'; rtwoptions(3).tooltip = ... ['Use value for variable instead of variable name in generated block mask edit fields']; % Override the default setting for model name prefixing because % the generated S-function is typically used in multiple models. rtwoptions(4).default = 'on'; rtwoptions(4).tlcvariable = 'PrefixModelToSubsysFcnNames'; rtwoptions(5).prompt = 'Include custom source code'; rtwoptions(5).type = 'Checkbox'; rtwoptions(5).default = 'off'; rtwoptions(5).tlcvariable = 'AlwaysIncludeCustomSrc'; rtwoptions(5).tooltip = ... ['Always include provided custom source code in the generated code']; 24-49 24 Custom Target Development The first element adds the S-Function Target pane under Code Generation in the Configuration Parameters dialog box. The options defined in rtwoptions(2), rtwoptions(3), and rtwoptions(5) display. If you want to define a large number of options, you can define multiple Category groups within a single system target file. Note the rtwoptions structure and callbacks are written in MATLAB code, although they are embedded in a TLC file. To verify the syntax of your rtwoptions structure definitions and code, you can execute the commands at the MATLAB prompt by copying and pasting them to the MATLAB Command Window. For further examples of target-specific rtwoptions definitions, see “Example System Target File With Customized rtwoptions” on page 24-52. rtwoptions Structure Fields Summary on page 24-50 lists the fields of the rtwoptions structure. rtwoptions Structure Fields Summary Field Name Description callback For examples of callback usage, see “Example System Target File With Customized rtwoptions” on page 24-52. closecallback (obsolete) Do not use closecallback. Use rtwgensettings.PostApplyCallback instead (see “rtwgensettings Structure” on page 24-44). closecallback is ignored. For examples of callback usage, see “Example System Target File With Customized rtwoptions” on page 24-52. 24-50 default Default value of the option (empty if the type is Pushbutton). enable Must be 'on' or 'off'. If 'on', the option is displayed as an enabled item; otherwise, as a disabled item. Customize System Target Files rtwoptions Structure Fields Summary (Continued) Field Name Description makevariable Template makefile token (if any) associated with the option. The makevariable is expanded during processing of the template makefile. See “Template Makefile Tokens” on page 24-76. modelReferenceParameterCheck Specifies whether the option must have the same value in a referenced model and its parent model. If this field is unspecified or has the value 'on' the option values must be same. If the field is specified and has the value 'off' the option values can differ. See “Controlling Configuration Option Value Agreement” on page 24-107. NonUI Element that is not displayed, but is used to invoke a close or open callback. See “NonUI Elements” on page 24-52. opencallback (obsolete) Do not use opencallback. Use rtwgensettings.SelectCallback instead (see “rtwgensettings Structure” on page 24-44). For examples of callback usage, see “Example System Target File With Customized rtwoptions” on page 24-52. popupstrings If type is Popup, popupstrings defines the items in the menu. Items are delimited by the "|" (vertical bar) character. The following example defines the items of the MAT-file variable name modifier menu used by the GRT target. 'rt_|_rt|none' prompt Label for the option. tlcvariable Name of TLC variable associated with the option. tooltip Help string displayed when mouse is over the item. type Type of element: Checkbox, Edit, NonUI, Popup, Pushbutton, or Category. 24-51 24 Custom Target Development NonUI Elements. Elements of the rtwoptions array that have type NonUI exist solely to invoke callbacks. A NonUI element is not displayed in the Configuration Parameters dialog box. You can use a NonUI element if you want to execute a callback that is not associated with any user interface element, when the dialog box opens or closes. Only the opencallback and closecallback fields of a NonUI element have significance. See the next section, “Example System Target File With Customized rtwoptions” on page 24-52 for an example. Example System Target File With Customized rtwoptions A working system target file, with MATLAB file callback functions, has been provided as an example of how to use the rtwoptions structure to display and process custom options on the Code Generation pane. The examples are compatible with the callback API. The example target files are in the folder: matlabroot/toolbox/rtw/rtwdemos/rtwoptions_demo The example target files include: • usertarget.tlc: The example system target file. This file illustrates how to define custom menus, check boxes, and edit fields. The file also illustrates the use of callbacks. • usertargetcallback.m: A MATLAB file callback invoked by a menu. Refer to the example files while reading this section. The example system target file, usertarget.tlc: illunstrates the use of rtwoptions to display the following custom target options: • The Execution Mode menu. • The Log Execution Time check box. • The Real-Time Interrupt Source menu. The menu executes a callback defined in an external file, usertargetcallback.m. The TLC variable associated with the menu is passed in to the callback, which displays the menu’s current value. • The edit field Signal Logging Buffer Size in Doubles. 24-52 Customize System Target Files Try studying the example code while interacting with the example target options in the Configuration Parameters dialog box. To interact with the example target file, 1 Make matlabroot/toolbox/rtw/rtwdemos/rtwoptions_demo your working folder. 2 Open any model of your choice. 3 Open the Configuration Parameters dialog box or Model Explorer and select the Code Generation pane. 4 Click Browse. The System Target File Browser opens. Select usertarget.tlc. Then click OK. 5 Observe that the Code Generation pane contains a custom sub-tab: userPreferred target options (I). 6 As you interact with the options in this category and open and close the Configuration Parameters dialog box, observe the messages displayed in the MATLAB Command Window. These messages are printed from code in the STF, or from callbacks invoked from the STF. Inheriting Target Options ert.tlc provides a basic set of Embedded Coder code generation options. If your target is based on ert.tlc, your STF should normally inherit the options defined in ERT. Use the string property rtwgensettings.DerivedFrom in the rtwgensettings structure to define the system target file from which options are to be inherited. You should convert your custom target to use this mechanism as follows. Set the rtwgensettings.DerivedFrom property as in the following example: rtwgensettings.DerivedFrom = 'stf.tlc'; where stf is the name of the system target file from which options are to be inherited. For example: rtwgensettings.DerivedFrom = 'ert.tlc'; 24-53 24 Custom Target Development When the Configuration Parameters dialog box executes this line of code, it includes the options from stf.tlc automatically. If stf.tlc is a MathWorks internal system target file that has been converted to a new layout, the dialog box displays the inherited options using the new layout. Handling Unsupported Options. If your target does not support all options inherited from ert.tlc, you should detect unsupported option settings and display a warning or error message. In some cases, if a user has selected an option your target does not support, you may need to abort the build process. For example, if your target does not support the Generate an example main program option, the build process should not be allowed to proceed if that option is selected. We recommend that you handle these options in mytarget_settings.tlc. See the example in “Using mytarget_settings.tlc” on page 24-55. Even though your target may not support all inherited ERT options, it is required that the ERT options are retained in the Code Generation pane of the Configuration Parameters dialog box. Do not simply remove unsupported options from the rtwoptions structure in the STF. Options must be in the dialog box to be scanned by the Simulink Coder software when it performs optimizations. For example, you may want to prevent users from turning off the Single output/update function option. It may seem reasonable to remove this option from the dialog box and simply assign the TLC variable CombineOutputUpdateFcns to on. However, if the option is not included in the dialog box, the Simulink Coder software assumes that output and update functions are not to be combined. Less efficient code is generated as a result. Tips and Techniques for Customizing Your STF • “Introduction” on page 24-55 • “Required and Recommended %includes” on page 24-55 • “Handling Aliases for Target Option Values” on page 24-58 • “Supporting Multiple Development Environments” on page 24-60 24-54 Customize System Target Files Introduction The following sections include information on techniques for customizing your STF, including • How to invoke custom TLC code from your STF • Approaches to supporting multiple development environments with single or multiple STFs Required and Recommended %includes If you need to implement target-specific code generation features, we recommend that your STF include the TLC files mytarget_settings.tlc and mytarget_genfiles.tlc. mytarget_settings.tlc provides a mechanism for executing custom TLC code before the main code generation entry point. See “Using mytarget_settings.tlc” on page 24-55. Once your STF has set up any required TLC environment, you must include codegenentry.tlc to start the standard code generation process. mytarget_genfiles.tlc provides a mechanism for executing custom TLC code after the main code generation entry point. See “Using mytarget_genfiles.tlc” on page 24-58. Using mytarget_settings.tlc. This file is optional. Its purpose is to centralize global settings in the code generation environment. Use mytarget_settings.tlc to • Define required TLC paths with %addincludepath directives. You may need to do this if you create target-specific TLC function libraries. • Create records that store target-specific path information and preference settings in the CompiledModel general record. This provides a clean mechanism for passing this information into the TLC code generation environment. • Check user settings for code generation options. If incorrect or unsupported option settings are found, issue an error or warning and consider aborting the build process.. 24-55 24 Custom Target Development mytarget_settings.tlc Example Code In the TLC code example below, the structure Settings is added to the CompiledModel record. The Settings structure is loaded from the stored target preferences. The Settings structure stores target preferences data fields Implementation and ImpPath. After Settings is added to the CompiledModel record, the example code handles inherited options. In this example, the target is assumed to have inherited options from the ERT target. The code examines the settings of inherited ERT code generation options. If the user has selected unsupported options, warning or error messages are displayed. In some cases, selecting an unsupported option causes the build process to terminate. Conditional code at the end of the function allows display of the Implementation and ImpPath fields in the MATLAB Command Window. %selectfile NULL_FILE %% Read user preferences for the target and add to CompiledModel %assign prefs = FEVAL("RTW.TargetPrefs.load","mytarget.prefs","structure") %addtorecord CompiledModel Settings prefs %% Check for unsupported Embedded Coder options and error/warn %if SuppressErrorStatus == 0 %assign SuppressErrorStatus = 1 %assign msg = "Suppressing Error Status as it is not used by this target." %warning % %endif %if GenerateSampleERTMain == 1 %assign msg = "Generating an example main is not supported as the proper main function is inherently generated. Unselect the \"Generate an example main program\" checkbox under ERT code generation options." %exit % %endif %if GenerateErtSFunction == 1 %assign msg = "Generating a Simulink S-Function is not supported. Unselect the \"Create SIL block\" checkbox under ERT code generation options." %exit % 24-56 Customize System Target Files %endif %if ExtMode == 1 %assign msg = "External mode is not currently supported. Unselect the \"External mode\" checkbox under ERT code generation options." %exit % %endif %if MatFileLogging == 1 %assign msg = "MAT-file logging is not currently supported. Unselect the \"MAT-file logging\" checkbox under ERT code generation options." %exit % %endif %if MultiInstanceERTCode == 1 %assign msg = "Generate reuseable code is not currently supported. Unselect the \"Generate reuseable code\" checkbox under ERT code generation options." %exit % %endif %if CodeReplacementLibrary == "ISO_C" %assign msg = "Code replacement libraries other than ANSI-C are not currently supported. Select ANSI-C for the \"Code replacement library\" option under ERT code generation options." %exit % %endif %% To display added TLC settings for debugging purposes, set EchoConfigSettings to 1. %assign EchoConfigSettings = 0 %if EchoConfigSettings %selectfile STDOUT ############################################################### IMPLEMENTATION is: % IMPLEMENTATION path is: % 24-57 24 Custom Target Development ############################################################### %selectfile NULL_FILE %endif Using mytarget_genfiles.tlc. mytarget_genfiles.tlc (optional) is useful as a central file from which to invoke any target-specific TLC files that generate additional files as part of your target build process. For example, your target may create sub-makefiles or project files for a development environment, or command scripts for a debugger to do automatic downloads. The build process can then invoke these generated files either directly from the make process, or after the executable is created. This is done with the STF_make_rtw_hook.m mechanism, as described in “Customize Build Process with STF_make_rtw_hook File” on page 22-21. The following TLC code shows an example mytarget_genfiles.tlc file. %selectfile NULL_FILE %assign ModelName = CompiledModel.Name %% Create Debugger script %assign model_script_file = "%.cfg" %assign script_file = "debugger_script_template.tlc" %if RTWVerbose %selectfile STDOUT ### Creating % %selectfile NULL_FILE %endif %include "%" %openfile bld_file = "%" % %closefile bld_file Handling Aliases for Target Option Values This section describes utility functions that can be used to detect and resolve alias values or legacy values when testing user-specified values for the 24-58 Customize System Target Files target device type (ProdHWDeviceType) and the code replacement library (CodeReplacementLibrary). RTW.isHWDeviceTypeEq. To test if two target device type strings represent the same hardware device, invoke the following function: result = RTW.isHWDeviceTypeEq(type1, type2) where type1 and type2 are strings containing target device type values or aliases. The RTW.isHWDeviceTypeEq function returns true if type1 and type2 are strings representing the same hardware device. For example, the following call returns true: RTW.isHWDeviceTypeEq('Specified', 'Generic->Custom') For a description of the target device type option ProdHWDeviceType, see the command-line information for the Hardware Implementation pane parameters “Device vendor” and “Device type” in the Simulink reference documentation. RTW.resolveHWDeviceType. To return the device type value for a hardware device, given a value that might be an alias or legacy value, invoke the following function: result = RTW.resolveHWDeviceType(type) where type is a string containing a target device type value or alias. The RTW.resolveHWDeviceType function returns the device type value of the device. For example, the following calls both return 'Generic->Custom': RTW.resolveHWDeviceType('Specified') RTW.resolveHWDeviceType('Generic->Custom') For a description of the target device type option ProdHWDeviceType, see the command-line information for the Hardware Implementation pane parameters “Device vendor” and “Device type” in the Simulink reference documentation. 24-59 24 Custom Target Development RTW.isTflEq. To test if two code replacement library (CRL) strings represent the same CRL, invoke the following function: result = RTW.isTflEq(name1, name2) where name1 and name2 are strings containing CRL values or aliases. The RTW.isTflEq function returns true if name1 and name2 are strings representing the same CRL. For example, the following call returns true: RTW.isTflEq('ANSI_C', 'C89/C90 (ANSI)') For a description of the CRL parameter CodeReplacementLibrary, see the command-line information for the Code Generation > Interface pane parameter “Code replacement library” in the Simulink Coder reference documentation. RTW.resolveTflName. To return the CRL value for a code replacement library, given a value that might be an alias or legacy value, invoke the following function: result = RTW.resolveTflName(name) where name is a string containing a CRL value or alias. The RTW.resolveTflName function returns the CRL value of the referenced CRL. For example, the following calls both return 'C89/C90 (ANSI)': RTW.resolveTflName('ANSI_C') RTW.resolveTflName('C89/C90 (ANSI)') For a description of the CRL parameter CodeReplacementLibrary, see the command-line information for the Code Generation > Interface pane parameter “Code replacement library” in the Simulink Coder reference documentation. Supporting Multiple Development Environments Your target may require support for multiple development environments (for example, two or more cross-compilers) or multiple modes of code generation (for example, generating a binary executable vs. generating a project file for your compiler). 24-60 Customize System Target Files One approach to this requirement is to implement multiple STFs; each STF invokes a template makefile for the development environment. This amounts to providing two separate targets. Another approach is to use a single STF that specifies multiple configurations in its comment header. The code within the STF then checks the target preferences to determine which template makefile to invoke. See “mytarget_default_tmf.m Example Code” on page 24-89 for an example of how to check target preferences for this information. One drawback of using a single STF in this way is that the rtwoptions need conditional sections if the target options are not the same for all of the configurations the STF supports. The following example (from a hypothetical example target) defines an rtwoptions menu element differently, depending on the whether or not the MATLAB software is running on a PC (Microsoft Windows platform). This is determined by calling the MATLAB function ispc. On the PC, the menu displays a choice of USB or serial ports to be used in communicating with a target device. Otherwise, the menu displays a choice of UNIX13 logical devices. if ispc rtwoptions(rtwoption_index).default = 'USB'; rtwoptions(rtwoption_index).popupstrings = 'USB|COM1|COM2|COM3|COM4'; else rtwoptions(rtwoption_index).default = '/dev/ttyS0'; rtwoptions(rtwoption_index).popupstrings = '/dev/ttyS0|/dev/ttyS1|/dev/ttyS2|/dev/ttyS3'; end Create a Custom Target Configuration • “Introduction” on page 24-62 • “my_ert_target Overview” on page 24-62 • “Creating Target Folders” on page 24-64 • “Create ERT-Based STF” on page 24-65 13. UNIX® is a registered trademark of The Open Group in the United States and other countries. 24-61 24 Custom Target Development • “Create ERT-Based TMF” on page 24-71 • “Create Test Model and S-Function” on page 24-71 • “Verify Target Operation” on page 24-73 Introduction This tutorial can supplement the example target guides described in “Sample Custom Targets” on page 24-9. For an introduction and example files to examine, try the example targets first. The purpose of this tutorial is to guide you through the process of creating an ERT-based target, my_ert_target. This exercise illustrates several tasks that are usually required when creating a custom target: • Setting up target folders and modifying the MATLAB path. • Making modifications to a standard STF and TMF such that the custom target is visible in the System Target File Browser, inherits ERT options, displays target-specific options, and generates code with the default host-based compiler. • Testing the build process with the custom target, using a simple model that incorporates an inlined S-function. During this exercise you implement an operational, but skeletal, ERT-based target. This target may be useful as a starting point in a complete implementation of a custom embedded target. my_ert_target Overview In the following sections you create a skeletal target, my_ert_target. The target inherits and supports the standard options of the ERT target, and displays additional target-specific options in the Configuration Parameters dialog box (see Target-Specific Options for my_ert_target on page 24-63). 24-62 Customize System Target Files Target-Specific Options for my_ert_target my_ert_target supports a makefile-based build, generating code and executables that run on the host system. my_ert_target uses the LCC compiler on a Microsoft Windows platform. This compiler was chosen because it is readily available and is distributed with the Simulink Coder product. If you use a different compiler, you can set up LCC temporarily as your default compiler by typing the MATLAB command mex -setup Follow the prompts and select LCC. 24-63 24 Custom Target Development Note On UNIX14 systems, verify that you have a C compiler installed. You can then do this exercise, substituting UNIX folder syntax. You can test my_ert_target with any model that is compatible with the ERT target. (See “Target” in the Embedded Coder documentation.) Generated programs operate identically to ERT generated programs. However, to simplify the testing of your target, we recommend testing with targetmodel, a very simple fixed-step model (see “Create Test Model and S-Function” on page 24-71). The S-Function block in targetmodel uses the source code from the timestwo example, and generates fully inlined code. See “S-Function Examples”, “Inlining S-Functions”, and “S-Function Inlining” for further discussion of the timestwo example S-function. Creating Target Folders In this section, you create folders to store the target files and add them to the MATLAB path, following the recommended conventions (see “Folder and File Naming Conventions” on page 24-11). You also create a folder to store the test model, S-function, and generated code. This example assumes that your target and model folders are located within the folder c:/work. Note that your target and model folders should not be located anywhere in the MATLAB folder tree (that is, in or under the matlabroot folder). To create the folders and make them accessible, 1 Create a target root folder, my_ert_target. To do this from the MATLAB Command Window on a Windows platform, enter: cd c:/work mkdir my_ert_target 2 Within the target root folder, create a subfolder to store your target files. 14. UNIX® is a registered trademark of The Open Group in the United States and other countries. 24-64 Customize System Target Files mkdir my_ert_target/my_ert_target 3 Add these folders to your MATLAB path. addpath c:/work/my_ert_target addpath c:/work/my_ert_target/my_ert_target 4 Create a folder, my_targetmodel, to store the test model, S-function, and generated code. mkdir my_targetmodel Create ERT-Based STF In this section, you create an STF for your target by copying and modifying the standard STF for the ERT target. Then you validate the STF by viewing the new target in the System Target File Browser and the Configuration Parameters dialog box. Editing the STF. To edit the STF, 1 Change your working folder to the folder you created in “Creating Target Folders” on page 24-64. cd c:/work/my_ert_target/my_ert_target 2 Place a copy of matlabroot/rtw/c/ert/ert.tlc in c:/work/my_ert_target/my_ert_target and rename it to my_ert_target.tlc. The file ert.tlc is the STF for the ERT target. 3 Open my_ert_target.tlc in a text editor of your choice. 4 Generally, the first step in customizing an STF is to replace the header comment lines with directives that make your STF visible in the System Target File Browser and define the associated TMF (that you create shortly), make command, and External mode interface file (if any). See “Header Comments” on page 24-40 for a detailed explanation of these directives. Replace the header comments in my_ert_target.tlc with the following header comments. 24-65 24 Custom Target Development %% SYSTLC: My ERT-based Target TMF: my_ert_target_lcc.tmf MAKE: make_rtw \ %% EXTMODE: no_ext_comm 5 The file my_ert_target.tlc inherits the standard ERT options, using the mechanism described in “Inheriting Target Options” on page 24-53. Therefore, the existing rtwoptions structure definition is superfluous. Edit the RTW_OPTIONS section such that it includes only the following code. /% BEGIN_RTW_OPTIONS %----------------------------------------% % Configure RTW code generation settings % %----------------------------------------% rtwgensettings.BuildDirSuffix = '_ert_rtw'; END_RTW_OPTIONS %/ 6 Delete the code after the end of the RTW_OPTIONS section, which is delimited by the directives BEGIN_CONFIGSET_TARGET_COMPONENT and END_CONFIGSET_TARGET_COMPONENT. This code is for use only by internal MathWorks developers. 7 Modify the build folder suffix in the rtwgenSettings structure in accordance with the conventions described in “rtwgensettings Structure” on page 24-44. To set the suffix to a string for the _my_ert_target custom target, change the line rtwgensettings.BuildDirSuffix = '_ert_rtw' to rtwgensettings.BuildDirSuffix = '_my_ert_target_rtw' 8 Modify the rtwgenSettings structure to inherit options from the ERT target and declare Release 14 or later compatibility as described in “rtwgensettings Structure” on page 24-44. Add the following code to the rtwgenSettings definition: 24-66 Customize System Target Files rtwgensettings.DerivedFrom = 'ert.tlc'; rtwgensettings.Version = '1'; 9 Add an rtwoptions structure that defines a target-specific options category with three check boxes just after the BEGIN_RTW_OPTIONS directive. The following code shows the complete RTW_OPTIONS section, including the rtwgenSettings changes made in previous steps. /% BEGIN_RTW_OPTIONS rtwoptions(1).prompt = 'My Target Options'; rtwoptions(1).type = 'Category'; rtwoptions(1).enable = 'on'; rtwoptions(1).default = 3; % number of items under this category % excluding this one. rtwoptions(1).popupstrings = ''; rtwoptions(1).tlcvariable = ''; rtwoptions(1).tooltip = ''; rtwoptions(1).callback = ''; rtwoptions(1).makevariable = ''; rtwoptions(2).prompt = 'Demo option 1'; rtwoptions(2).type = 'Checkbox'; rtwoptions(2).default = 'off'; rtwoptions(2).tlcvariable = 'DummyOpt1'; rtwoptions(2).makevariable = ''; rtwoptions(2).tooltip = ['Demo option1 (non-functional)']; rtwoptions(2).callback = ''; rtwoptions(3).prompt = 'Demo option 2'; rtwoptions(3).type = 'Checkbox'; rtwoptions(3).default = 'off'; rtwoptions(3).tlcvariable = 'DummyOpt2'; rtwoptions(3).makevariable = ''; rtwoptions(3).tooltip = ['Demo option2 (non-functional)']; rtwoptions(3).callback = ''; rtwoptions(4).prompt = 'Demo option 3'; rtwoptions(4).type = 'Checkbox'; 24-67 24 Custom Target Development rtwoptions(4).default = 'off'; rtwoptions(4).tlcvariable = 'DummyOpt3'; rtwoptions(4).makevariable = ''; rtwoptions(4).tooltip = ['Demo option3 (non-functional)']; rtwoptions(4).callback = ''; %----------------------------------------% % Configure RTW code generation settings % %----------------------------------------% rtwgensettings.BuildDirSuffix = '_my_ert_target_rtw'; rtwgensettings.DerivedFrom = 'ert.tlc'; rtwgensettings.Version = '1'; END_RTW_OPTIONS %/ 10 Save your changes to my_ert_target.tlc and close the file. Viewing the STF. At this point, you can verify that the target inherits and displays ERT options as follows: 1 Create a new model. 2 Open the Model Explorer or the Configuration Parameters dialog box. 3 Select the Code Generation pane. 4 Click Browse to open the System Target File Browser. 5 In the Browser, scroll through the list of targets to find the new target, my_ert_target.tlc. (This step assumes that your MATLAB path contains c:/work/my_ert_target/my_ert_target, as previously set in “Creating Target Folders” on page 24-64.) 6 Select My ERT-based Target as shown below, and click OK. 24-68 Customize System Target Files 7 The Code Generation pane now shows that the model is configured for the my_ert_target.tlc target. The System target file, Make command, and Template makefile fields should appear as follows: 8 Select the My Target Options pane and observe that the target displays the three check box options defined in the rtwoptions structure, as shown in the following figure. 24-69 24 Custom Target Development 9 Select the Code Generation pane and reopen the System Target File Browser. 10 Select the Embedded Coder target (ert.tlc) and observe that the target displays the standard ERT options. 11 Close the model. You do not need to save it. At this point, the STF for the skeletal target is complete. Note, however, that the STF header comments reference a TMF, my_ert_target_lcc.tmf. You are not able to invoke the build process for your target until the TMF file is in place. In the next section, you create my_ert_target_lcc.tmf. 24-70 Customize System Target Files Create ERT-Based TMF In this section, you create a TMF for your target by copying and modifying the standard ERT TMF for the LCC compiler: 1 Check that your working folder is still set to the target file folder you created previously in “Creating Target Folders” on page 24-64. c:/work/my_ert_target/my_ert_target 2 Place a copy of matlabroot/rtw/c/ert/ert_lcc.tmf in c:/work/my_ert_target/my_ert_target and rename it to my_ert_target_lcc.tmf. The file ert_lcc.tmf is the ERT compiler-specific template makefile for the LCC compiler. 3 Open my_ert_target_lcc.tmf in a text editor of your choice. 4 Change the SYS_TARGET_FILE parameter so that the file reference for your .tlc file is generated in the make file. Change the line SYS_TARGET_FILE = any to SYS_TARGET_FILE = my_ert_target.tlc 5 Save changes to my_ert_target_lcc.tmf and close the file. Your target can now generate code and build a host-based executable. In the next sections, you create a test model and test the build process using my_ert_target. Create Test Model and S-Function In this section, you build a simple test model for later use in code generation: 1 Set your working folder to c:/work/my_targetmodel. cd c:/work/my_targetmodel For the remainder of this tutorial, my_targetmodel is assumed to be the working folder. Your target writes the output files of the code generation process into a build folder within the working folder. When inlined code is 24-71 24 Custom Target Development generated for the timestwo S-function, the build process looks for the TLC implementation of the S-function in the working folder. 2 Copy the following C and TLC files for the timestwo S-function to your working folder: • matlabroot/toolbox/simulink/simdemos/simfeatures/src/timestwo.c • matlabroot/toolbox/simulink/simdemos/simfeatures/tlc_c/timestwo.tlc 3 Build the timestwo MEX-file in c:/work/my_targetmodel. mex timestwo.c 4 Create the following model, using an S-Function block from the Simulink User-Defined Functions library. Save the model in your working folder as targetmodel. 5 Double-click the S-Function block to open the Block Parameters dialog box. Enter the S-function name timestwo. Click OK. The block is now bound to the timestwo MEX-file. 6 Open Model Explorer or the Configuration Parameters dialog box and select the Solver pane. 7 Set the solver Type to fixed-step and click Apply. 8 Save the model. 9 Open the scope and run a simulation. Verify that the timestwo S-function multiplies its input by 2.0. Keep the targetmodel model open for use in the next section, in which you generate code using the test model. 24-72 Customize System Target Files Verify Target Operation In this section you configure targetmodel for the my_ert_target custom target, and use the target to generate code and build an executable: 1 Open the Configuration Parameters dialog box and select the Code Generation pane. 2 Click Browse to open the System Target File Browser. 3 In the Browser, select My ERT-based Target and click OK. 4 The Configuration Parameters dialog box now displays the Code Generation pane for my_ert_target. 5 Select the Code Generation > Report pane and select the Create code generation report option. 6 Click Apply and save the model. The model is configured for my_ert_target. 7 Build the model. If the build succeeds, the MATLAB Command Window displays the message below. ### Created executable: ../targetmodel.exe ### Successful completion of build procedure for model: targetmodel Your working folder contains the targetmodel.exe file and the build folder, targetmodel_my_ert_target_rtw, which contains generated code and other files. The working folder also contains an slprj folder, used internally by the build process. The code generator also creates and displays a code generation report. 8 To view the generated model code, go to the code generation report window. In the Contents pane, click the targetmodel.c link. 24-73 24 Custom Target Development 9 In targetmodel.c, locate the model step function, targetmodel_step. Observe the following code. /* S-Function Block: /S-Function */ /* Multiply input by two */ targetmodel_B.SFunction = targetmodel_B.SineWave * 2.0; The presence of this code confirms that the my_ert_target custom target has generated an inlined output computation for the S-Function block in the model. 24-74 Customize Template Makefiles Customize Template Makefiles In this section... “Template Makefiles and Tokens” on page 24-75 “Invoke the make Utility” on page 24-82 “Structure of the Template Makefile” on page 24-83 “Customize and Create Template Makefiles” on page 24-87 Template Makefiles and Tokens • “Prerequisites” on page 24-75 • “Template Makefile Role In Makefile Creation” on page 24-75 • “Template Makefile Tokens” on page 24-76 Prerequisites To configure or customize a template makefile (TMF), you should be familiar with how the make command works and how it processes makefiles. You should also understand makefile build rules. For information on these topics, refer to the documentation provided with the make utility you use. Template Makefile Role In Makefile Creation TMFs are made up of statements containing tokens. The Simulink Coder build process expands tokens and creates a makefile, model.mk. TMFs are designed to generate makefiles for specific compilers on specific platforms. The generated model.mk file is tailored to compile and link code generated from your model, using commands specific to your development system. Creation of model.mk 24-75 24 Custom Target Development Template Makefile Tokens The make_rtw command (or a different command provided with some targets) directs the process of generating model.mk. The make_rtw command processes the TMF specified on the Code Generation pane of the Configuration Parameters dialog box. make_rtw copies the TMF, line by line, expanding each token encountered. Template Makefile Tokens Expanded by make_rtw on page 24-76 lists the tokens and their expansions. These tokens are used in several ways by the expanded makefile: • To control the conditional behavior in the makefile. The conditionals are used to control the source file lists, library names, target to be built, and other build-related information. • To provide the macro definitions for compiling the files, for example, -DINTEGER_CODE=1. Template Makefile Tokens Expanded by make_rtw Token Expansion General purpose 24-76 |>ALT_MATLAB_BIN<| Alternate full pathname for the MATLAB executable; value is different than value for MATLAB_BIN token when the full pathname contains spaces. |>ALT_MATLAB_ROOT<| Alternate full pathname for the MATLAB installation; value is different than value for MATLAB_ROOT token when the full pathname contains spaces. |>BUILDARGS<| Options passed to make_rtw. This token is provided so that the contents of your model.mk file changes when you change the build arguments, thus forcing an update of all modules when your build options change. |>COMBINE_OUTPUT_UPDATE_FCNS<| True (1) when Single output/update function is selected, otherwise False (0). Used for the macro definition -DONESTEPFCN=1. Customize Template Makefiles Template Makefile Tokens Expanded by make_rtw (Continued) Token Expansion |>COMPUTER<| Computer type. See the MATLAB computer command. |>EXPAND_LIBRARY_LOCATION<| Location of precompiled library file. The TargetPreCompLibLocation configuration parameter can override this setting. For examples, see “Control Library Location and Naming During Build” on page 22-7. |>EXPAND_LIBRARY_NAME<| Library name. For examples, see “Control Library Location and Naming During Build” on page 22-7 and “Modify the Template Makefile” on page 14-127. |>EXPAND_LIBRARY_SUFFIX<| Library suffix. The TargetLibSuffix configuration parameter can override this setting. For examples, see “Control Library Location and Naming During Build” on page 22-7. |>EXT_MODE<| True (1) to enable generation of External mode support code, otherwise False (0). |>EXTMODE_TRANSPORT<| Index of transport mechanism (for example, tcpip, serial) for External mode. |>EXTMODE_STATIC<| True (1) if static memory allocation is selected for External mode. False (0) if dynamic memory allocation is selected. |>EXTMODE_STATIC_SIZE<| Size of static memory allocation buffer (if any) for External mode. |>GENERATE_ERT_S_FUNCTION<| True (1) when Create SIL block is selected, otherwise False (0). Used for control of the makefile target of the build. |>INCLUDE_MDL_TERMINATE_FCN<| True (1) when Terminate function required is selected, otherwise False (0). Used for the macro definition -DTERMFCN==1. 24-77 24 Custom Target Development Template Makefile Tokens Expanded by make_rtw (Continued) Token Expansion |>INTEGER_CODE<| True (1) when Support floating-point numbers is not selected, otherwise False (0). INTEGER_CODE is a required macro definition when compiling the source code and is used when selecting precompiled libraries to link against. |>MAKEFILE_NAME<| model.mk — The name of the makefile that was created from the TMF. 24-78 |>MAT_FILE<| True (1) when MAT-file logging is selected, otherwise False (0). MAT_FILE is a required macro definition when compiling the source code and also is used to include logging code in the build process. |>MATLAB_BIN<| Location of the MATLAB executable. |>MATLAB_ROOT<| Path to where MATLAB is installed. |>MEM_ALLOC<| Either RT_MALLOC or RT_STATIC. Indicates how memory is to be allocated. |>MEXEXT<| MEX-file extension. See the MATLAB mexext command. |>MODEL_MODULES<| Any additional generated source modules. For example, you can split a large model into two files, model.c and model1.c. In this case, this token expands to model1.c. |>MODEL_MODULES_OBJ<| Object filenames (.obj) corresponding to any additional generated source modules. |>MODEL_NAME<| Name of the Simulink block diagram currently being built. |>MULTITASKING<| True (1) if solver mode is multitasking, otherwise False (0). |>NCSTATES<| Number of continuous states. |>NUMST<| Number of sample times in the model. Customize Template Makefiles Template Makefile Tokens Expanded by make_rtw (Continued) Token Expansion |>PORTABLE_WORDSIZES<| True (1) when Enable portable word sizes is selected, otherwise False (0). |>RELEASE_VERSION<| The MATLAB release version. |>S_FUNCTIONS<| List of noninlined S-function sources. |>S_FUNCTIONS_LIB<| List of S-function libraries available for linking. |>S_FUNCTIONS_OBJ<| Object (.obj) file list corresponding to noninlined S-function sources. |>SOLVER<| Solver source filename, for example, ode3.c. |>SOLVER_OBJ<| Solver object (.obj) filename, for example, ode3.obj. |>TARGET_LANG_EXT<| c when the Simulink Coder Language selection is C, cpp when the Language selection is C++. Used in the makefile to control the extension on generated source files. |>TGT_FCN_LIB<| Specifies compiler command line options. The line in the makefile is TGT_FCN_LIB = |>TGT_FCN_LIB<|. By default, the Simulink Coder build process expands the |>TGT_FCN_LIB<| token to match the setting of the Code replacement library parameter on the Code Generation > Interface pane of the Configuration Parameters dialog box. Possible values for this option include ANSI_C, C99 (ISO), GNU99 (GNU), and C++ (ISO). You can use this token in a makefile conditional statement to specify compiler options to be used. For example, if you set the token to C99 (ISO), the compiler might need an additional option set to support C99 library functions. |>TID01EQ<| True (1) if sampling rates of the continuous task and the first discrete task are equal, otherwise False (0). 24-79 24 Custom Target Development Template Makefile Tokens Expanded by make_rtw (Continued) Token Expansion S-function and build information support Note For examples of the tokens in this section, see “Modify the Template Makefile” on page 14-127. |>START_EXPAND_INCLUDES<| |>EXPAND_DIR_NAME<| |>END_EXPAND_INCLUDES<| List of folder names to add to the include path. Additionally, the ADD_INCLUDES macro must be added to the INCLUDES line. |>START_EXPAND_LIBRARIES<| |>EXPAND_LIBRARY_NAME<| |>END_EXPAND_LIBRARIES<| List of library names. |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<| |>END_EXPAND_MODULES<| Library module names within |>START_EXPAND_RULES<| |>EXPAND_DIR_NAME<| |>END_EXPAND_RULES<| Makefile rules. |>START_PRECOMP_LIBRARIES<| |>EXPAND_LIBRARY_NAME<| |>END_PRECOMP_LIBRARIES<| List of precompiled library names. |>START_EXPAND_LIBRARIES<| and |>START_PRECOMP_LIBRARIES<| library lists. Model reference support Note For examples of the tokens in this section, see “Providing Model Referencing Support in the TMF” on page 24-104. 24-80 |>MASTER_ANCHOR_DIR<| For parallel builds, current work folder (pwd) at the time the build started. |>MODELLIB<| Name of the library file generated for the current model. |>MODELREFS<| List of models referenced by the top model. Customize Template Makefiles Template Makefile Tokens Expanded by make_rtw (Continued) Token Expansion |>MODELREF_LINK_LIBS<| List of referenced model libraries against which the top model links. |>MODELREF_LINK_RSPFILE_NAME<| Name of a response file against which the top model links. This token is valid only for build environments that support linker response files. For an example of its use, see matlabroot/rtw/c/grt/grt_vc.tmf. |>MODELREF_TARGET_TYPE<| Type of target being built. Possible values are • NONE: Standalone model or top model referencing other models • RTW: Model reference Simulink Coder target build • SIM: Model reference simulation target build |>RELATIVE_PATH_TO_ANCHOR<| Relative path, from the location of the generated makefile, to the MATLAB working folder. |>START_DIR<| Current work folder (pwd) at the time the build started. This token is required for parallel builds. |>START_MDLREFINC_EXPAND_INCLUDES<| |>MODELREF_INC_PATH<| |>END_MDLREFINC_EXPAND_INCLUDES<| List of include paths for models referenced by the top model. |>SHARED_BIN_DIR<| Folder for the library file built from the shared source files. |>SHARED_LIB<| Library file built from the shared source files, including the path to the library folder. |>SHARED_SRC<| Shared source files specification, including the path to the shared utilities folder. |>SHARED_SRC_DIR<| Folder for shared source files. These tokens are expanded by substitution of parameter values known to the build process. For example, if the source model contains blocks with two different sample times, the TMF statement NUMST = |>NUMST<| 24-81 24 Custom Target Development expands to the following in model.mk. NUMST = 2 In addition to the above, make_rtw expands tokens from other sources: • Target-specific tokens defined in the target options of the Configuration Parameters dialog box • Structures in the rtwoptions section of the system target file. Any structures in the rtwoptions structure array that contain the field makevariable are expanded. The following example is extracted from matlabroot/rtw/c/grt/grt.tlc. The section starting with BEGIN_RTW_OPTIONS contains MATLAB code that sets up rtwoptions. The following directive causes the |>EXT_MODE<| token to be expanded to 1 (on) or 0 (off), depending on how you set the External mode options. rtwoptions(2).makevariable = 'EXT_MODE' Invoke the make Utility • “make Command” on page 24-82 • “make Utility Versions” on page 24-83 make Command After creating model.mk from your TMF, the Simulink Coder build process invokes a make command. To invoke make, the build process issues this command. makecommand -f model.mk makecommand is defined by the MAKECMD macro in your target’s TMF (see “Structure of the Template Makefile” on page 24-83). You can specify additional options to make in the Make command field of the Code Generation pane. (See the sections “Specify a Make Command” on page 15-13 and “Template Makefiles and Make Options” on page 9-38 in the Simulink Coder documentation.) 24-82 Customize Template Makefiles For example, specifying OPT_OPTS=-O2 in the Make command field causes make_rtw to generate the following make command. makecommand -f model.mk OPT_OPTS=-O2 A comment at the top of the TMF specifies the available make command options. If these options do not provide you with enough flexibility, you can configure your own TMF. make Utility Versions The make utility lets you control nearly every aspect of building your real-time program. There are several different versions of make available. The Simulink Coder software provides the Free Software Foundation GNU make for both UNIX15 and PC platforms in platform-specific subfolders under matlabroot/bin It is possible to use other versions of make with the Simulink Coder software, although GNU Make is recommended. To be compatible with the Simulink Coder software, verify that your version of make supports the following command format. makecommand -f model.mk Structure of the Template Makefile A TMF has multiple sections, including the following: • Abstract — Describes what the makefile targets. Here is a representative abstract from the GRT TMFs in matlabroot/rtw/c/grt: # File : grt_lcc.tmf # # Abstract: # Template makefile for building a PC-based stand-alone generic real-time # version of Simulink model using generated C code and LCC compiler # Version 2.4. # 15. UNIX® is a registered trademark of The Open Group in the United States and other countries. 24-83 24 Custom Target Development # This makefile attempts to conform to the guidelines specified in the # IEEE Std 1003.2-1992 (POSIX) standard. It is designed to be used # with GNU Make (gmake) which is located in matlabroot/bin/win32. # # Note that this template is automatically customized by the build # procedure to create ".mk" # # The following defines can be used to modify the behavior of the # build: # OPT_OPTS - Optimization options. Default is none. To enable # OPTS - User specific compile options. # USER_SRCS - Additional user sources, such as files needed by USER_INCLUDES - Additional include paths # debugging specify as OPT_OPTS=-g4. # S-functions. # # (i.e. USER_INCLUDES="-Iwhere-ever -Iwhere-ever2") # (For Lcc, have a '/'as file seperator before the # file name instead of a '\' . # i.e., d:\work\proj1/myfile.c - reqd for 'gmake') # # This template makefile is designed to be used with a system target # file that contains 'rtwgensettings.BuildDirSuffix'. See grt.tlc. • Macros read by make_rtw section — Defines macros that tell make_rtw how to process the TMF. Here is a representative Macros read by make_rtw section from the GRT TMFs in matlabroot/rtw/c/grt: #------------------------ Macros read by make_rtw -----------------------------# # The following macros are read by the build procedure: # # MAKECMD - This is the command used to invoke the make utility # HOST - What platform this template makefile is targeted for # BUILD - Invoke make from the build procedure (yes/no)? # SYS_TARGET_FILE - Name of system target file. # 24-84 (i.e. PC or UNIX) MAKECMD = "%MATLAB%\bin\win32\gmake" SHELL = cmd HOST = PC Customize Template Makefiles BUILD = yes SYS_TARGET_FILE = grt.tlc BUILD_SUCCESS = *** Created COMPILER_TOOL_CHAIN = lcc MAKEFILE_FILESEP = / The macros in this section might include: - MAKECMD — Specifies the command used to invoke the make utility. For example, if MAKECMD = mymake, then the make command invoked is mymake -f model.mk - HOST — Specifies the platform targeted by this TMF. This can be PC, UNIX, computer_name (see the MATLAB computer command), or ANY. - BUILD — Instructs make_rtw whether or not it should invoke make from the Simulink Coder build procedure. Specify yes or no. - SYS_TARGET_FILE — Specifies the name of the system target file or the value any. This is used for consistency checking by make_rtw to verify the system target file specified in the Target selection panel of the Code Generation pane of the Configuration Parameters dialog box. If you specify any, you can use the TMF with any system target file. - BUILD_SUCCESS — Optional macro that specifies the build success string to be displayed for make completion on the PC. For example, BUILD_SUCCESS = ### Successful creation of The BUILD_SUCCESS macro, if used, replaces the standard build success string found in the TMFs distributed with the bundled Simulink Coder targets (such as GRT): @echo ### Created executable $(MODEL).exe Your TMF must include either the standard build success string, or use the BUILD_SUCCESS macro. For an example of the use of BUILD_SUCCESS, see matlabroot/rtw/c/grt/grt_lcc.tmf or the code example above this list of macros. - BUILD_ERROR — Optional macro that specifies the build error message to be displayed when an error is encountered during the make procedure. For example, 24-85 24 Custom Target Development BUILD_ERROR = ['Error while building ', modelName] - VERBOSE_BUILD_OFF_TREATMENT = PRINT_OUTPUT_ALWAYS — Optional macro to include if you want the makefile output to be displayed always (regardless of the setting of the Verbose build option in the Code Generation > Debug pane). - COMPILER_TOOL_CHAIN — For builds on Windows systems, specifies which compiler setup file (located in matlabroot/toolbox/rtw/rtw) to use: • lcc • vc selects setup_for_lcc.m selects setup_for_visual.m • vcx64 • watc selects setup_for_visual_x64.m selects setup_for_watcom.m • default selects setup_for_default.m For builds on UNIX systems, specify unix. Any other value is flagged as unknown and make_rtw uses setup_for_default.m. - DOWNLOAD — An optional macro that you can specify as yes or no. If specified as yes (and BUILD=yes), then make is invoked a second time with the download target. make -f model.mk download - DOWNLOAD_SUCCESS — An optional macro that you can use to specify the download success string to be used when looking for a completed download. For example, DOWNLOAD_SUCCESS = ### Downloaded - DOWNLOAD_ERROR — An optional macro that you can use to specify the download error message to be displayed when an error is encountered during the download. For example, DOWNLOAD_ERROR = ['Error while downloading ', modelName] • Tokens expanded by make_rtw section — Defines the tokens that make_rtw expands. Here is a brief excerpt from a representative 24-86 Customize Template Makefiles Tokens expanded by make_rtw section from the GRT TMFs in matlabroot/rtw/c/grt: #---------------------- Tokens expanded by make_rtw ---------------------------# # The following tokens, when wrapped with "|>" and "<|" are expanded by the # build procedure. # # MODEL_NAME - Name of the Simulink block diagram # MODEL_MODULES - Any additional generated source modules # MAKEFILE_NAME - Name of makefile created from template makefile .mk # MATLAB_ROOT - Path to where MATLAB is installed. ... MODEL = |>MODEL_NAME<| MODULES = |>MODEL_MODULES<| MAKEFILE = |>MAKEFILE_NAME<| MATLAB_ROOT = |>MATLAB_ROOT<| ... For more information about TMF tokens, see Template Makefile Tokens Expanded by make_rtw on page 24-76. • Subsequent sections vary based on compiler, host, and target. Some common sections include Model and reference models, External mode, Tool Specifications or Tool Definitions, Include Path, C Flags, Additional Libraries, and Source Files. • Rules section — Contains the make rules used in building an executable from the generated source code. The build rules are typically specific to your version of make. The Rules section might be followed by related sections such as Dependencies. Customize and Create Template Makefiles • “Introduction” on page 24-88 • “Setting Up a Template Makefile” on page 24-88 • “Using Macros and Pattern Matching Expressions in a Template Makefile” on page 24-90 24-87 24 Custom Target Development • “Using the rtwmakecfg.m API to Customize Generated Makefiles” on page 24-92 • “Supporting Continuous Time in Custom Targets” on page 24-98 • “Model Reference Considerations” on page 24-99 • “Generating Make Commands for Nondefault Compilers” on page 24-99 Introduction This section describes the mechanics of setting up a custom template makefile (TMF) and incorporating it into the build process. It also discusses techniques for modifying a TMF and MATLAB file mechanisms associated with the TMF. Before creating a custom TMF, you should read “Folder and File Naming Conventions” on page 24-11 to understand the folder structure and MATLAB path requirements for custom targets. Setting Up a Template Makefile To customize or create a new TMF, you should copy an existing GRT or ERT TMF from one of the following locations: matlabroot/rtw/c/grt matlabroot/rtw/c/ert Place the copy in the same folder as the associated system target file (STF). Usually, this is the mytarget/mytarget folder within the target folder structure. Then, rename your TMF (for example, mytarget.tmf) and modify it. To allow the build process to locate and select your TMF, you must provide information in the STF file header (see “System Target File Structure” on page 24-37). For a target that implements a single TMF, the standard way to specify the TMF to be used in the build process is to use the TMF directive of the STF file header. TMF: mytarget.tmf If your target must support multiple development environments, you can specify a MATLABfile script that selects the TMF, based on user preferences. To do this, you must 24-88 Customize Template Makefiles • Create the script in your mytarget/mytarget folder. The naming convention for this file is mytarget_default_tmf.m. • Specify this file in the TMF directive of the STF file header. TMF: mytarget_default_tmf The build process then invokes your mytarget_default_tmf.m file, which then selects theTMF, based on target preference settings. “mytarget_default_tmf.m Example Code” on page 24-89 illustrates this technique. Another useful technique is to store a path to the user’s installed development environment in your target preferences. You can then locate the template makefiles under the tool folder. This allows several tool-specific template makefiles files to be located under the specific tool folder. mytarget_default_tmf.m Example Code. The code example below implements a function, mytarget_default_tmf. The function loads target preferences into a structure from preferences data stored on disk. The code verifies that the target preferences information is consistent with the STF name, and extracts the associated TMF name. The TMF name is returned as the string tmf. function [tmf,envVal] = mytarget_default_tmf try prefs = RTW.TargetPrefs.load('mytarget.prefs','structure'); catch exception rethrow(exception); end % Get the desired MYTARGET implementation and check that it is supported if ~isfield(prefs, 'Implementation') error('MYTARGET preferences not set correctly, update Target Preferences.'); end imp = deblank(lower(prefs.Implementation)); stfname = deblank(lower(get_param(bdroot, 'RTWSystemTargetFile'))); if ~strncmp(imp, stfname, length(stfname) - length('.tlc')) msg = ['System Target filename: ', stfname, ' does not match Implementation specified in Target Preferences: ', imp]; error(msg); 24-89 24 Custom Target Development end % Return the desired template make file. tmf = [imp, '.tmf']; % This argument is unused envVal = ''; Using Macros and Pattern Matching Expressions in a Template Makefile This section shows, through an example, how to use macros and file-pattern-matching expressions in a TMF to generate commands in the model.mk file. The make utility processes the model.mk makefile and generates a set of commands based upon dependency rules defined in model.mk. After make generates the set of commands for building or rebuilding test, make executes them. For example, to build a program called test, make must link the object files. However, if the object files don’t exist or are out of date, make must compile the source code. Thus there is a dependency between source and object files. Each version of make differs slightly in its features and how rules are defined. For example, consider a program called test that gets created from two sources, file1.c and file2.c. Using most versions of make, the dependency rules would be test: file1.o file2.o cc -o test file1.o file2.o file1.o: file1.c cc -c file1.c file2.o: file2.c cc -c file2.c 24-90 Customize Template Makefiles In this example, a UNIX16 environment is assumed. In a PC environment the file extensions and compile and link commands are different. In processing the first rule test: file1.o file2.o make sees that to build test, it needs to build file1.o and file2.o. To build file1.o, make processes the rule file1.o: file1.c If file1.o doesn’t exist, or if file1.o is older than file1.c, make compiles file1.c. The format of Simulink Coder TMFs follows the above example. Our TMFs use additional features of make such as macros and file-pattern-matching expressions. In most versions of make, a macro is defined with MACRO_NAME = value References to macros are made with $(MACRO_NAME). When make sees this form of expression, it substitutes value for $(MACRO_NAME). You can use pattern matching expressions to make the dependency rules more general. For example, using GNU17 Make, you could replace the two “file1.o: file1.c” and “file2.o: file2.c” rules with the single rule %.o : %.c cc -c $< Note that $< in the previous example is a special macro that equates to the dependency file (that is, file1.c or file2.c). Thus, using macros and the "%" pattern matching character, the previous example can be reduced to SRCS = file1.c file2.c OBJS = $(SRCS:.c=.o) 16. UNIX® is a registered trademark of The Open Group in the United States and other countries. 17. GNU® is a registered trademark of the Free Software Foundation. 24-91 24 Custom Target Development test: $(OBJS) cc -o $@ $(OBJS) %.o : %.c cc -c $< Note that the $@ macro above is another special macro that equates to the name of the current dependency target, in this case test. This example generates the list of objects (OBJS) from the list of sources (SRCS) by using the string substitution feature for macro expansion. It replaces the source file extension (for example, .c) with the object file extension (.o). This example also generalized the build rule for the program, test, to use the special "$@" macro. Using the rtwmakecfg.m API to Customize Generated Makefiles • “Overview” on page 24-92 • “Creating the rtwmakecfg.m Function” on page 24-93 • “Modifying the Template Makefile” on page 24-96 Overview. Simulink Coder TMFs provide tokens that let you add the following items to generated makefiles: • Source folders • Include folders • Run-time library names • Run-time module objects S-functions can add this information to the makefile by using an rtwmakecfg.m file function. This function is particularly useful when building a model that contains one or more of your S-Function blocks, such as device driver blocks. To add information pertaining to an S-function to the makefile, 24-92 Customize Template Makefiles 1 Create the function rtwmakecfg in a file rtwmakecfg.m. The Simulink Coder software associates this file with your S-function based on its folder location. “Creating the rtwmakecfg.m Function” on page 24-93 discusses the requirements for the rtwmakecfg function and the data it should return. 2 Modify your target’s TMF such that it supports macro expansion for the information returned by rtwmakecfg functions. “Modifying the Template Makefile” on page 24-96 discusses the required modifications. After the TLC phase of the build process, when generating a makefile from the TMF, the Simulink Coder build process searches for an rtwmakecfg.m file in the folder that contains the S-function component. If it finds the file, the build process calls the rtwmakecfg function. Creating the rtwmakecfg.m Function. Create the rtwmakecfg.m file in the same folder as your S-function component (a MEX-file with a platform-dependent extension, such as .mexw32 on 32-bit Microsoft Windows platforms). The function must return a structured array that contains the following fields: Field Description makeInfo.includePath A cell array that specifies additional include folder names, organized as a row vector. The Simulink Coder build process expands the folder names into include instructions in the generated makefile. makeInfo.sourcePath A cell array that specifies additional source folder names, organized as a row vector. The Simulink Coder build process expands the folder names into make rules in the generated makefile. makeInfo.sources A cell array that specifies additional source filenames (C or C++), organized as a row vector. The Simulink Coder build process expands the filenames into make variables that contain the source files. You should specify only filenames (with extension). Specify path information with the sourcePath field. 24-93 24 24-94 Custom Target Development Field Description makeInfo.linkLibsObjs A cell array that specifies additional, fully qualified paths to object or library files against which Simulink Coder generated code should link. The Simulink Coder build process does not compile the specified objects and libraries. However, it includes them when linking the final executable. This can be useful for incorporating libraries that you do not want the Simulink Coder build process to recompile or for which the source files are not available. You might also use this element to incorporate source files from languages other than C and C++. This is possible if you first create a C compatible object file or library outside of the Simulink Coder build process. makeInfo.precompile A Boolean flag that indicates whether the libraries specified in the rtwmakecfg.m file exist in a specified location (precompile==1) or if the libraries need to be created in the build folder during the Simulink Coder build process (precompile==0). makeInfo.library A structure array that specifies additional run-time libraries and module objects, organized as a row vector. The Simulink Coder build process expands the information into make rules in the generated makefile. See the next table for a list of the library fields. Customize Template Makefiles The makeInfo.library field consists of the following elements: Element Description makeInfo.library(n).Name A character array that specifies the name of the library (without an extension). makeInfo.library(n).Location A character array that specifies the folder in which the library is located when precompiled. See the description of makeInfo.precompile in the preceding table for more information. A target can use the TargetPreCompLibLocation parameter to override this value. See “Specify the Location of Precompiled Libraries” on page 22-8 in the Simulink Coder documentation for details. makeInfo.library(n).Modules A cell array that specifies the C or C++ source file base names (without an extension) that comprise the library. Do not include the file extension. The makefile appends the object extension. Note The makeInfo.library field must fully specify each library and how to build it. The modules list in the makeInfo.library(n).Modules element cannot be empty. If you need to specify a link-only library, use the makeInfo.linkLibsObjs field instead. Example: disp(['Running rtwmakecfg from folder: ',pwd]); makeInfo.includePath = { fullfile(pwd, 'somedir2') }; makeInfo.sourcePath = {fullfile(pwd, 'somedir2'), fullfile(pwd, 'somedir3')}; makeInfo.sources = { 'src1.c', 'src2.cpp'}; makeInfo.linkLibsObjs = { fullfile(pwd, 'somedir3', 'src3.object'),... fullfile(pwd, 'somedir4', 'mylib.library')}; makeInfo.precompile = 1; makeInfo.library(1).Name = 'myprecompiledlib'; makeInfo.library(1).Location = fullfile(pwd,'somdir2','lib'); makeInfo.library(1).Modules = {'srcfile1' 'srcfile2' 'srcfile3' }; 24-95 24 Custom Target Development Note If a path that you specify in the rtwmakecfg.m API contains spaces, the Simulink Coder software does not automatically convert the path to its non-space equivalent. If the build environments you intend to support do not support spaces in paths, refer to “Enabling the Simulink® Coder™ Software to Build When Path Names Contain Spaces” on page 9-44 in the Simulink Coder documentation. Modifying the Template Makefile. To expand the information generated by an rtwmakecfg function, you can modify the following sections of your target’s TMF: • Include Path • C Flags and/or Additional Libraries • Rules The TMF code examples below may not apply to your make utility. For additional examples, see the GRT or ERT TMFs located in matlabroot/rtw/c/grt/*.tmf or matlabroot/rtw/c/ert/*.tmf. Example — Adding Folder Names to the Makefile Include Path The following TMF code example adds folder names to the include path in the generated makefile: ADD_INCLUDES = \ |>START_EXPAND_INCLUDES<| -I|>EXPAND_DIR_NAME<| \ |>END_EXPAND_INCLUDES<| Additionally, the ADD_INCLUDES macro must be added to the INCLUDES line, as shown below. INCLUDES = -I. -I.. $(MATLAB_INCLUDES) $(ADD_INCLUDES) $(USER_INCLUDES) Example — Adding Library Names to the Makefile The following TMF code example adds library names to the generated makefile. 24-96 Customize Template Makefiles LIBS = |>START_PRECOMP_LIBRARIES<| LIBS += |>EXPAND_LIBRARY_NAME<|.a |>END_PRECOMP_LIBRARIES<| |>START_EXPAND_LIBRARIES<| LIBS += |>EXPAND_LIBRARY_NAME<|.a |>END_EXPAND_LIBRARIES<| For more information on how to use configuration parameters to control library names and location during the build process, see “Control Library Location and Naming During Build” on page 22-7 in the Simulink Coder documentation. Example — Adding Rules to the Makefile The following TMF code example adds rules to the generated makefile. |>START_EXPAND_RULES<| $(BLD)/%.o: |>EXPAND_DIR_NAME<|/%.c $(SRC)/$(MAKEFILE) rtw_proj.tmw @$(BLANK) @echo ### "|>EXPAND_DIR_NAME<|\$*.c" $(CC) $(CFLAGS) $(APP_CFLAGS) -o $(BLD)$(DIRCHAR)$*.o \ |>EXPAND_DIR_NAME<|$(DIRCHAR)$*.c > $(BLD)$(DIRCHAR)$*.lst |>END_EXPAND_RULES<| |>START_EXPAND_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \ |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<|.o \ |>END_EXPAND_MODULES<| |>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw $(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o) @$(BLANK) @echo ### Creating $@ $(AR) -r $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o) |>END_EXPAND_LIBRARIES<| |>START_PRECOMP_LIBRARIES<|MODULES_|>EXPAND_LIBRARY_NAME<| = \ |>START_EXPAND_MODULES<| |>EXPAND_MODULE_NAME<|.o \ |>END_EXPAND_MODULES<| |>EXPAND_LIBRARY_NAME<|.a : $(MAKEFILE) rtw_proj.tmw 24-97 24 Custom Target Development $(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o) @$(BLANK) @echo ### Creating $@ $(AR) -r $@ $(MODULES_|>EXPAND_LIBRARY_NAME<|:%.o=$(BLD)/%.o) |>END_PRECOMP_LIBRARIES<| Supporting Continuous Time in Custom Targets If you want your custom ERT-based target to support continuous time, you must update your template makefile (TMF) and the static main program module (for example, mytarget_main.c) for your target. Template Makefile Modifications. Add the NCSTATES token expansion after the NUMST token expansion, as follows: NUMST = |>NUMST<| NCSTATES = |>NCSTATES<| In addition, add NCSTATES to the CPP_REQ_DEFINES macro, as in the following example: CPP_REQ_DEFINES = -DMODEL=$(MODEL) -DNUMST=$(NUMST) -DNCSTATES=$(NCSTATES) \ -DMAT_FILE=$(MAT_FILE) -DINTEGER_CODE=$(INTEGER_CODE) \ -DONESTEPFCN=$(ONESTEPFCN) -DTERMFCN=$(TERMFCN) \ -DHAVESTDIO -DMULTI_INSTANCE_CODE=$(MULTI_INSTANCE_CODE) \ Modifications to Main Program Module. The main program module defines a static main function that manages task scheduling for all supported tasking modes of single- and multiple-rate models. NUMST (the number of sample times in the model) determines whether the main function calls multirate or single-rate code. However, when a model uses continuous time, do not rely on NUMST directly. When the model has continuous time and the flag TID01EQ is true, both continuous time and the fastest discrete time are treated as one rate in generated code. The code associated with the fastest discrete rate is guarded by a major time step check. When the model has only two rates, and TID01EQ is true, the generated code has a single-rate call interface. 24-98 Customize Template Makefiles To support models that have continuous time, update the static main module to take TID01EQ into account, as follows: 1 Before NUMST is referenced in the file, add the following code: #if defined(TID01EQ) && TID01EQ == 1 && NCSTATES == 0 #define DISC_NUMST (NUMST - 1) #else #define DISC_NUMST NUMST #endif 2 Replace all instances of NUMST in the file by DISC_NUMST. Model Reference Considerations See “Support Model Referencing” on page 24-101 for important information on TMF modifications you may need to make to support the Simulink Coder model referencing features. Note If you are using a TMF without the variables SHARED_SRC or MODELREFS, the file might have been used with a previous release of Simulink software. If you want your TMF to support model referencing, add either variable SHARED_SRC or MODELREFS to the make file. Generating Make Commands for Nondefault Compilers Custom targets might need a target-specific hook file to generate a make command when you use a nondefault compiler. Use this file to override the default behavior for selecting the compiler tool for the build process. See “STF_wrap_make_cmd_hook.m” on page 24-23 for further details. 24-99 24 Custom Target Development Support Optional Features In this section... “Overview” on page 24-100 “Support Model Referencing” on page 24-101 “Support Compiler Optimization Level Control” on page 24-115 “Support firstTime Argument Control” on page 24-117 “Support C Function Prototype Control” on page 24-119 “Support C++ Encapsulation Interface Control” on page 24-121 Overview This chapter describes how to configure a custom embedded target to support any of the following optional features: 24-100 Optional Feature Target Configuration Parameters Building a model that includes referenced models ModelReferenceCompliant ParMdlRefBuildCompliant (parallel build support) Controlling the compiler optimization level for building generated code CompOptLevelCompliant Controlling inclusion of the firstTime argument in the model_initialize function generated for a Simulink model. ERTFirstTimeCompliant (ERT only) Controlling the C function prototypes of initialize and step functions that are generated for a Simulink model ModelStepFunctionPrototypeControlCompliant (ERT only) Generating and configuring C++ encapsulation interfaces to model code CPPClassGenCompliant (ERT only) Support Optional Features The required configuration changes are modifications to your system target file (STF), and in some cases also modifications to your template makefile (TMF) or your custom static main program. The API for STF callbacks provides a function SelectCallback for use in STFs. SelectCallback is associated with the target rather than with any of its individual options. If you implement a SelectCallback function for a target, it is triggered whenever the user selects the target in the System Target File Browser. Additionally, the API provides the functions slConfigUIGetVal, slConfigUISetEnabled, and slConfigUISetVal for controlling custom target configuration options from a user-written SelectCallback function. (For function descriptions and examples, see the function reference pages.) The general requirements for supporting one of the optional features include: • To support model referencing or compiler optimization level control, the target must be derived from the GRT or the ERT target. To support firstTime argument control, C function prototype control, or C++ encapsulation interface control, the target must be derived from the ERT target. • The system target file (STF) must declare feature compliance by including one of the target configuration parameters listed above in a SelectCallback function call. • Additional changes such as TMF modifications or static main program modifications may be required, depending on the feature. See the detailed steps in the subsections for individual features. Support Model Referencing • “Overview” on page 24-102 • “Declaring Model Referencing Compliance” on page 24-103 • “Providing Model Referencing Support in the TMF” on page 24-104 • “Controlling Configuration Option Value Agreement” on page 24-107 • “Supporting the Shared Utilities Folder” on page 24-108 24-101 24 Custom Target Development • “Verifying Worker Configuration for Parallel Builds of Model Reference Hierarchies (Optional)” on page 24-112 • “Preventing Resource Conflicts (Optional)” on page 24-114 Overview This section describes how to configure a custom embedded target to support model referencing. Without the described modifications, you will not be able to use the custom target when building a model that includes referenced models. If you do not intend to use referenced models with your target, you can skip this section. If you later find that you need to use referenced models, you can upgrade your target then. The requirements for supporting model referencing are as follows: • The target must be derived from the GRT target or the ERT target. • The system target file (STF) must declare model reference compliance, as described in “Declaring Model Referencing Compliance” on page 24-103. • The template makefile (TMF) must define some entities that support model referencing, as described in “Providing Model Referencing Support in the TMF” on page 24-104. • The TMF must support using the Shared Utilities folder, as described in “Supporting the Shared Utilities Folder” on page 24-108. Optionally, you can provide additional capabilities that support model referencing: • You can configure a target to support parallel builds for large model reference hierarchies (see “Reduce Build Time for Referenced Models” on page 15-28 in the Simulink Coder documentation). To do this, you must modify the STF and TMF for parallel builds as described in “Declaring Model Referencing Compliance” on page 24-103 and “Providing Model Referencing Support in the TMF” on page 24-104. • If your target supports parallel builds for large model reference hierarchies, you can additionally set up automatic verification of MATLAB Distributed Computing Server (MDCS) workers, as described in “Verifying Worker Configuration for Parallel Builds of Model Reference Hierarchies (Optional)” on page 24-112. 24-102 Support Optional Features • You can modify hook files to handle referenced models differently than top models to prevent resource conflicts, as described in “Preventing Resource Conflicts (Optional)” on page 24-114. See “Overview of Model Referencing” for information about model referencing in Simulink models, and “Generate Code for Referenced Models” on page 3-4 for information about model referencing in Simulink Coder generated code. Declaring Model Referencing Compliance To declare model reference compliance for your target, you must implement a callback function that sets the ModelReferenceCompliant flag, and then install the callback function in the SelectCallback field of the rtwgensettings structure in your STF. The callback function is triggered whenever the user selects the target in the System Target File Browser. For example, the following STF code installs a SelectCallback function named custom_select_callback_handler: rtwgensettings.SelectCallback = 'custom_select_callback_handler(hDlg, hSrc)'; The arguments to the SelectCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. These handles are restricted to use in STF callback functions. They should be passed in without alteration. Your callback function should set the ModelReferenceCompliant flag as follows: slConfigUISetVal(hDlg, hSrc, 'ModelReferenceCompliant', 'on'); slConfigUISetEnabled(hDlg, hSrc, 'ModelReferenceCompliant', false); If you might use the target to build models containing large model reference hierarchies, consider configuring the target to support parallel builds, as discussed in “Reduce Build Time for Referenced Models” on page 15-28 in the Simulink Coder documentation. To configure a target for parallel builds, your callback function must also set the ParMdlRefBuildCompliant flag as follows: slConfigUISetVal(hDlg, hSrc, 'ParMdlRefBuildCompliant', 'on'); slConfigUISetEnabled(hDlg, hSrc, 'ParMdlRefBuildCompliant', false); 24-103 24 Custom Target Development For more information about the STF callback API, see the slConfigUIGetVal, slConfigUISetEnabled, and slConfigUISetVal function reference pages. Providing Model Referencing Support in the TMF Do the following to configure the template makefile (TMF) to support model referencing: 1 Add the following make variables and tokens to be expanded when the makefile is generated: MODELREFS = |>MODELREFS<| MODELLIB = |>MODELLIB<| MODELREF_LINK_LIBS = |>MODELREF_LINK_LIBS<| MODELREF_LINK_RSPFILE = |>MODELREF_LINK_RSPFILE_NAME<| MODELREF_INC_PATH = |>START_MDLREFINC_EXPAND_INCLUDES<|\ -I|>MODELREF_INC_PATH<| |>END_MDLREFINC_EXPAND_INCLUDES<| RELATIVE_PATH_TO_ANCHOR = |>RELATIVE_PATH_TO_ANCHOR<| MODELREF_TARGET_TYPE = |>MODELREF_TARGET_TYPE<| The following code excerpt shows how makefile tokens are expanded for a referenced model. MODELREFS = MODELLIB = engine3200cc_rtwlib.a MODELREF_LINK_LIBS = MODELREF_LINK_RSPFILE = MODELREF_INC_PATH = RELATIVE_PATH_TO_ANCHOR = ../../.. MODELREF_TARGET_TYPE = RTW The following code excerpt shows how makefile tokens are expanded for the top model that references the referenced model. MODELREFS = engine3200cc transmission MODELLIB = archlib.a MODELREF_LINK_LIBS = engine3200cc_rtwlib.a transmission_rtwlib.a MODELREF_LINK_RSPFILE MODELREF_INC_PATH 24-104 = = -I../slprj/ert/engine3200cc -I../slprj/ert/transmission RELATIVE_PATH_TO_ANCHOR = .. MODELREF_TARGET_TYPE = NONE Support Optional Features Token Expands to MODELREFS for the top model List of referenced model names. MODELLIB Name of the library generated for the model. MODELREF_LINK_LIBS token for List of referenced model libraries that the top model links against. the top model MODELREF_LINK_RSPFILE token for the top model Name of a response file that the top model links against. This token is valid only for build environments that support linker response files. For an example of its use, see matlabroot/rtw/c/grt/grt_vc.tmf. MODELREF_INC_PATH token for Include path to the referenced models. the top model RELATIVE_PATH_TO_ANCHOR Relative path, from the location of the generated makefile, to the MATLAB working folder. MODELREF_TARGET_TYPE Signifies the type of target being built. Possible values are • NONE: Standalone model or top model referencing other models • RTW: Model reference Simulink Coder target build • SIM: Model reference simulation target build If you are configuring your target to support parallel builds, as discussed in “Reduce Build Time for Referenced Models” on page 15-28 in the Simulink Coder documentation, you must also add the following token definitions to your TMF: START_DIR = |>START_DIR<| MASTER_ANCHOR_DIR = |>MASTER_ANCHOR_DIR<| 24-105 24 Custom Target Development Token Expands to START_DIR Current work folder (pwd) at the time the build started. MASTER_ANCHOR_DIR Current work folder (pwd) at the time the build started. 2 Add RELATIVE_PATH_TO_ANCHOR and MODELREF_INC_PATH include paths to the overall INCLUDES variable. INCLUDES = -I. -I$(RELATIVE_PATH_TO_ANCHOR) $(MATLAB_INCLUDES) $(ADD_INCLUDES) \ $(USER_INCLUDES) $(MODELREF_INC_PATH) $(SHARED_INCLUDES) 3 Change the SRCS variable in your TMF so that it initially lists only common modules. Additional modules are then appended conditionally, as described in the next step. For example, change SRCS = $(MODEL).c $(MODULES) ert_main.c $(ADD_SRCS) $(EXT_SRC) to SRCS = $(MODULES) $(S_FUNCTIONS) 4 Create variables to define the final target of the makefile. You can remove any variables that may have existed for defining the final target. For example, remove PROGRAM = ../$(MODEL) and replace it with ifeq ($(MODELREF_TARGET_TYPE), NONE) # Top model for RTW PRODUCT = $(RELATIVE_PATH_TO_ANCHOR)/$(MODEL) BIN_SETTING = $(LD) $(LDFLAGS) -o $(PRODUCT) $(SYSLIBS) BUILD_PRODUCT_TYPE = "executable" # ERT based targets SRCS += $(MODEL).c ert_main.c $(EXT_SRC) # GRT based targets # SRCS 24-106 += $(MODEL).c grt_main.c rt_sim.c $(EXT_SRC) $(SOLVER) Support Optional Features else # sub-model for RTW PRODUCT = $(MODELLIB) BUILD_PRODUCT_TYPE = "library" endif 5 Create rules for the final target of the makefile (replace any existing final target rule). For example: ifeq ($(MODELREF_TARGET_TYPE),NONE) # Top model for RTW $(PRODUCT) : $(OBJS) $(SHARED_LIB) $(LIBS) $(MODELREF_LINK_LIBS) $(BIN_SETTING) $(LINK_OBJS) $(MODELREF_LINK_LIBS) $(SHARED_LIB) $(LIBS) @echo "### Created $(BUILD_PRODUCT_TYPE): $@" else # sub-model for RTW $(PRODUCT) : $(OBJS) $(SHARED_LIB) $(LIBS) @rm -f $(MODELLIB) $(ar) ruvs $(MODELLIB) $(LINK_OBJS) @echo "### Created $(MODELLIB)" @echo "### Created $(BUILD_PRODUCT_TYPE): $@" endif 6 Create a rule to allow submodels to compile files that reside in the MATLAB working folder (pwd). %.o : $(RELATIVE_PATH_TO_ANCHOR)/%.c $(CC) -c $(CFLAGS) $< Note If you are using a TMF without the variables SHARED_SRC or MODELREFS, the file might have been used with a previous release of Simulink software. If you want your TMF to support model referencing, add either variable SHARED_SRC or MODELREFS to the make file. Controlling Configuration Option Value Agreement By default, the value of any configuration option defined in the system target file for a TLC-based custom target must be the same in any referenced 24-107 24 Custom Target Development model and its parent model. To relax this requirement, include the modelReferenceParameterCheck field in the rtwoptions structure element that defines the configuration option, and set the value of the field to 'off'. For example: rtwoptions(2).prompt = 'My Custom Parameter'; rtwoptions(2).type = 'Checkbox'; rtwoptions(2).default = 'on'; rtwoptions(2).modelReferenceParameterCheck rtwoptions(2).tlcvariable = 'on'; = 'mytlcvariable'; ... The configuration option My Custom Parameter can differ in a referenced model and its parent model. See “Customize System Target Files” on page 24-36 for information about TLC-based system target files, and rtwoptions Structure Fields Summary on page 24-50 for a list of all rtwoptions fields. Supporting the Shared Utilities Folder • “Overview” on page 24-108 • “Implementing Shared Utilities Folder Support” on page 24-110 Overview. The makefile used by the Simulink Coder build process must support compiling and creating libraries, and so on, from the locations in which the code is generated. Therefore, you need to update your makefile and the model reference build process to support the shared utilities location. The Shared code placement options have the following requirements: • Auto - Standalone model build — All files go to the build folder; no makefile updates. - Referenced model or top model build — Use shared utilities folder; makefile requires full model reference support. • Shared location - 24-108 Standalone model build — Use shared utilities folder; makefile requires shared location support. Support Optional Features - Referenced model or top model build — Use shared utilities folder; makefile requires full model reference support. The shared utilities folder (slprj/target/_sharedutils) typically stores generated utility code that is common between a top model and the models it references. You can also force the build process to use a shared utilities folder for a standalone model. See “Project Folder Structure for Model Reference Targets” on page 3-16 in the Simulink Coder documentation for details. If you want your target to support compilation of code generated in the shared utilities folder, several updates to your template makefile (TMF) are required. Support for Model Reference builds requires the shared utilities folder. See the preceding sections of this chapter to learn about additional updates for supporting Model Reference builds. The exact syntax of the changes can vary due to differences in the make utility and compiler/archiver tools used by your target. The examples below are based on the GNU18 make utility. You can find the following updated TMF examples for GNU and Microsoft Visual C++ make utilities in the GRT and ERT target folders: • GRT: matlabroot/rtw/c/grt/ - grt_lcc.tmf grt_vc.tmf grt_unix.tmf • ERT: matlabroot/rtw/c/ert/ - ert_lcc.tmf ert_vc.tmf ert_unix.tmf Use the GRT or ERT examples as a guide to the location, within the TMF, of the changes and additions described below. 18. GNU® is a registered trademark of the Free Software Foundation. 24-109 24 Custom Target Development Note The ERT-based TMFs contain extra code to handle generation of ERT S-functions and Model Reference simulation targets. Your target does not need to handle these cases. Implementing Shared Utilities Folder Support. Make the following changes to your TMF to support the shared utilities folder: 1 Add the following make variables and tokens to be expanded when the makefile is generated: SHARED_SRC SHARED_SRC_DIR SHARED_BIN_DIR SHARED_LIB = = = = |>SHARED_SRC<| |>SHARED_SRC_DIR<| |>SHARED_BIN_DIR<| |>SHARED_LIB<| SHARED_SRC specifies the shared utilities folder location and the source files in it. A typical expansion in a makefile is SHARED_SRC = ../slprj/ert/_sharedutils/*.c SHARED_LIB specifies the library file built from the shared source files, as in the following expansion. SHARED_LIB = ../slprj/ert/_sharedutils/rtwshared.lib SHARED_SRC_DIR and SHARED_BIN_DIR allow specification of separate folders for shared source files and the library compiled from the source files. In the current release, all TMFs use the same path, as in the following expansions. SHARED_SRC_DIR SHARED_BIN_DIR = ../slprj/ert/_sharedutils = ../slprj/ert/_sharedutils 2 Set the SHARED_INCLUDES variable according to whether shared utilities are in use. Then append it to the overall INCLUDES variable. SHARED_INCLUDES = ifneq ($(SHARED_SRC_DIR),) SHARED_INCLUDES = -I$(SHARED_SRC_DIR) endif 24-110 Support Optional Features INCLUDES = -I. $(MATLAB_INCLUDES) $(ADD_INCLUDES) \ $(USER_INCLUDES) $(SHARED_INCLUDES) 3 Update the SHARED_SRC variable to list all shared files explicitly. SHARED_SRC := $(wildcard $(SHARED_SRC)) 4 Create a SHARED_OBJS variable based on SHARED_SRC. SHARED_OBJS = $(addsuffix .o, $(basename $(SHARED_SRC))) 5 Create an OPTS (options) variable for compilation of shared utilities. SHARED_OUTPUT_OPTS = -o $@ 6 Provide a rule to compile the shared utility source files. $(SHARED_OBJS) : $(SHARED_BIN_DIR)/%.o : $(SHARED_SRC_DIR)/%.c $(CC) -c $(CFLAGS) $(SHARED_OUTPUT_OPTS) $< 7 Provide a rule to create a library of the shared utilities. The following example is based on UNIX19. $(SHARED_LIB) : $(SHARED_OBJS) @echo "### Creating $@ " ar r $@ $(SHARED_OBJS) @echo "### Created $@ " 19. UNIX® is a registered trademark of The Open Group in the United States and other countries. 24-111 24 Custom Target Development Note Depending on your make utility, you may be able to combine Steps 6 and 7 into one rule. For example, gmake (used with ert_unix.tmf) uses: $(SHARED_LIB) : $(SHARED_SRC) @echo "### Creating $@ " cd $(SHARED_BIN_DIR); $(CC) -c $(CFLAGS) $(GCC_WALL_FLAG_MAX) $(notdir $?) ar ruvs $@ $(SHARED_OBJS) @echo "### $@ Created " See this and other examples in the files ert_vc.tmf, ert_lcc.tmf, and ert_unix.tmf located at matlabroot/rtw/c/ert. 8 Add SHARED_LIB to the rule that creates the final executable. $(PROGRAM) : $(OBJS) $(LIBS) $(SHARED_LIB) $(LD) $(LDFLAGS) -o $@ $(LINK_OBJS) $(LIBS) $(SHARED_LIB) $(SYSLIBS) @echo "### Created executable: $(MODEL)" 9 Remove any explicit reference to rt_nonfinite.c from your TMF. For example, change ADD_SRCS = $(RTWLOG) rt_nonfinite.c to ADD_SRCS = $(RTWLOG) Note If your target interfaces to a development environment that is not makefile based, you must make equivalent changes to provide information to your target compilation environment. Verifying Worker Configuration for Parallel Builds of Model Reference Hierarchies (Optional) If your target supports parallel builds for large model reference hierarchies, you can additionally set up automatic verification of MATLAB Distributed Computing Server (MDCS) workers. This addresses the possibility that 24-112 Support Optional Features parallel workers might have different configurations, some of which might not be compatible with a specific target build. For example, the required compiler might not be installed on a worker system. Simulink Coder provides a programming interface that you can use to automatically check the configuration of parallel workers. If parallel workers are not set up as expected, take action, such as reverting to sequential builds or throwing an error. To set up automatic verification of MDCS workers, you must define a parallel configuration check function named STF_par_cfg_chk, where STF designates your system target file name. For example, the parallel configuration check function for ert.tlc is ert_par_cfg_chk. The general syntax for the function is: function varargout = STF_par_cfg_chk(action, varargin) The number of output and input arguments vary according to the action specified, and according to the types of information you choose to coordinate between the client and the workers. The function should support the following general sequence of parallel configuration setup calls, differentiated by the first argument passed in: Call Syntax Called on: Action cfg = STF_par_cfg_chk ('getPreferredCfg'); MDCS client Return a structure representing the preferred configuration for MDCS workers. [tf, cfg] = STF_par_cfg_chk ('getWorkerCfg', cfg); MDCS workers Each worker is passed the MDCS client’s preferred configuration. Return true if the worker can support the preferred configuration; otherwise return false along with a structure representing a configuration the worker can support. Information returned by each worker is added to a cell array of configurations. 24-113 24 Custom Target Development Call Syntax Called on: Action [tf, cfg] = STF_par_cfg_chk ('getCommonCfg', cfgs); MDCS client The client is passed the cell array of worker configurations. If a usable common configuration exists, return true, and return the common configuration to set for all systems. If a common configuration cannot be established, return false or take some action, such as reverting to sequential builds or throwing an error. tf = STF_par_cfg_chk ('setCommonCfg', cfg); MDCS workers and client Each system is passed the common configuration to use. Set up the common configuration and, if successful, return true. If any errors or issues occur, return false or take some action, such as reverting to sequential builds or throwing an error. STF_par_cfg_chk ('clearCfg'); MDCS workers and client Clean up after completion of the parallel build. The parallel configuration check functions for MathWorks provided targets are implemented as wrapper functions that call a function named parallelMdlRefHostConfigCheckFcn. For example, see the ERT parallel configuration check function in the file matlabroot/toolbox/rtw/rtw/ert_par_cfg_chk.m, and the function it calls in the file matlabroot/toolbox/simulink/simulink/+Simulink/parallelMdlRefHostConfigCheckFcn.m. The parallelMdlRefHostConfigCheckFcn function tries to establish a common compiler across the MDCS client and workers. For more information about parallel builds, see “Reduce Build Time for Referenced Models” on page 15-28 in the Simulink Coder documentation. Preventing Resource Conflicts (Optional) Hook files are optional .m and TLC files that are invoked at well-defined stages of the build process. Hook files let you customize the build process and communicate information between various phases of the process. 24-114 Support Optional Features If you are adapting your custom target for code generation compatibility with model reference features, consider adding checks to your hook files for handling referenced models differently than top models to prevent resource conflicts. For example, consider adding the following check to your STF_make_rtw_hook.m file: % Check if this is a referenced model mdlRefTargetType = get_param(codeGenModelName,`ModelReferenceTargetType'); isNotModelRefTarget = strcmp(mdlRefTargetType, `NONE'); % NONE, SIM, or RTW if isNotModelRefTarget % code that is specific to the top model else % code that is specific to the referenced model end You may need to do a similar check in your TLC code. %if !IsModelReferenceTarget() %% code that is specific to the top model %else %% code that is specific to the referenced model %endif Support Compiler Optimization Level Control • “Overview” on page 24-115 • “Declaring Compiler Optimization Level Control Compliance” on page 24-116 • “Providing Compiler Optimization Level Control Support in the Target Makefile” on page 24-117 Overview This chapter describes how to configure a custom embedded target to support compiler optimization level control. Without the described modifications, you will not be able to use the Compiler optimization level parameter on the Code Generation pane of the Configuration Parameters dialog box to control the compiler optimization level for building generated code. (For 24-115 24 Custom Target Development more information about compiler optimization level control, see “Compiler optimization level” in the Simulink Coder reference documentation.) The requirements for supporting compiler optimization level control are as follows: • The target must be derived from the GRT target or the ERT target. • The system target file (STF) must declare compiler optimization level control compliance, as described in “Declaring Compiler Optimization Level Control Compliance” on page 24-116. • The target makefile must honor the setting for Compiler optimization level, as described in “Providing Compiler Optimization Level Control Support in the Target Makefile” on page 24-117. Declaring Compiler Optimization Level Control Compliance To declare compiler optimization level control compliance for your target, you must implement a callback function that sets the CompOptLevelCompliant flag, and then install the callback function in the SelectCallback field of the rtwgensettings structure in your STF. The callback function is triggered whenever the user selects the target in the System Target File Browser. For example, the following STF code installs a SelectCallback function named custom_select_callback_handler: rtwgensettings.SelectCallback = 'custom_select_callback_handler(hDlg, hSrc)'; The arguments to the SelectCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. These handles are restricted to use in STF callback functions. They should be passed in without alteration. Your callback function should set the CompOptLevelCompliant flag as follows: slConfigUISetVal(hDlg, hSrc, 'CompOptLevelCompliant', 'on'); slConfigUISetEnabled(hDlg, hSrc, 'CompOptLevelCompliant', false); For more information about the STF callback API, see the slConfigUIGetVal, slConfigUISetEnabled, and slConfigUISetVal function reference pages. 24-116 Support Optional Features When the CompOptLevelCompliant target configuration parameter is set to on, the Compiler optimization level parameter is displayed in the Code Generation pane of the Configuration Parameters dialog box for your model. Providing Compiler Optimization Level Control Support in the Target Makefile As part of supporting compiler optimization level control for your target, you must modify the target makefile to honor the setting for Compiler optimization level. Use a GRT or ERT target provided by MathWorks as a model for making the modifications. Support firstTime Argument Control • “Overview” on page 24-117 • “Declaring firstTime Argument Control Compliance” on page 24-118 • “Providing firstTime Argument Control Support in the Custom Static Main Program” on page 24-119 Overview This chapter describes how to configure a custom embedded target to support firstTime argument control. Without the described modifications, you will not be able to use the IncludeERTFirstTime model configuration parameter to control inclusion of the firstTime argument in the model_initialize function generated for your model. (For more information about firstTime argument control, see model_initialize in the Embedded Coder reference documentation.) The requirements for supporting firstTime argument control are as follows: • The target must be derived from the ERT target. • The system target file (STF) must declare firstTime argument control compliance, as described in “Declaring firstTime Argument Control Compliance” on page 24-118. • If your target uses a custom static main program, the main program must handle the inclusion and suppression of the firstTime argument for 24-117 24 Custom Target Development a given model, as described in “Providing firstTime Argument Control Support in the Custom Static Main Program” on page 24-119. Declaring firstTime Argument Control Compliance To declare firstTime argument control compliance for your target, you must implement a callback function that sets the ERTFirstTimeCompliant flag, and then install the callback function in the SelectCallback field of the rtwgensettings structure in your STF. The callback function is triggered whenever the user selects the target in the System Target File Browser. For example, the following STF code installs a SelectCallback function named custom_select_callback_handler: rtwgensettings.SelectCallback = 'custom_select_callback_handler(hDlg, hSrc)'; The arguments to the SelectCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. These handles are restricted to use in STF callback functions. They should be passed in without alteration. Your callback function should set the ERTFirstTimeCompliant flag as follows: slConfigUISetVal(hDlg, hSrc, 'ERTFirstTimeCompliant', 'on'); slConfigUISetEnabled(hDlg, hSrc, 'ERTFirstTimeCompliant', false); For more information about the STF callback API, see the slConfigUIGetVal, slConfigUISetEnabled, and slConfigUISetVal function reference pages. When the ERTFirstTimeCompliant target configuration parameter is set to on, you can use the IncludeERTFirstTime model configuration parameter to control inclusion of the firstTime argument in the model_initialize function generated for your model. Note If the ERTFirstTimeCompliant parameter is set to off for your selected target, you cannot control inclusion of the firstTime argument in the model_initialize function. If you attempt to include or suppress the firstTime argument using the IncludeERTFirstTime model configuration parameter, Embedded Coder software ignores the request, and your generated model_initialize function will not reflect the requested change. 24-118 Support Optional Features Providing firstTime Argument Control Support in the Custom Static Main Program If your target uses a custom static main program, you must update the static main program to handle the inclusion and suppression of the firstTime argument for a given model. One way to do this is to 1 Check that the target TLC file assigns 1 to AutoBuildProcedure when using a static main program. For example, %assign AutoBuildProcedure = !GenerateSampleERTMain 2 In the generated header file autobuild.h, the macro INCLUDE_FIRST_TIME_ARG will be set to 0 if the IncludeERTFirstTime parameter is set to off or 1 if the parameter is set to on. 3 Inside the static main program, do #include autobuild.h and then conditionally compile declarations and calls to the model_initialize function, based on the value of the INCLUDE_FIRST_TIME_ARG macro. Support C Function Prototype Control • “Overview” on page 24-119 • “Declaring C Function Prototype Control Compliance” on page 24-120 • “Providing C Function Prototype Control Support in the Custom Static Main Program” on page 24-121 Overview This chapter describes how to configure a custom embedded target to support C function prototype control. Without the described modifications, you will not be able to use the Configure Model Functions button on the Interface pane of the Configuration Parameters dialog box to control the function prototypes of initialize and step functions that are generated for your model. (For more information about C function prototype control, see “Function Prototype Control” in the Embedded Coder documentation.) The requirements for supporting C function prototype control are as follows: • The target must be derived from the ERT target. 24-119 24 Custom Target Development • The system target file (STF) must declare C function prototype control compliance, as described in “Declaring C Function Prototype Control Compliance” on page 24-120. • If your target uses a custom static main program, and if a nondefault function prototype control configuration is associated with a model, the static main program must call the function prototype controlled initialize and step functions, as described in “Providing C Function Prototype Control Support in the Custom Static Main Program” on page 24-121. Declaring C Function Prototype Control Compliance To declare C function prototype control compliance for your target, you must implement a callback function that sets the ModelStepFunctionPrototypeControlCompliant flag, and then install the callback function in the SelectCallback field of the rtwgensettings structure in your STF. The callback function is triggered whenever the user selects the target in the System Target File Browser. For example, the following STF code installs a SelectCallback function named custom_select_callback_handler: rtwgensettings.SelectCallback = 'custom_select_callback_handler(hDlg, hSrc)'; The arguments to the SelectCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. These handles are restricted to use in STF callback functions. They should be passed in without alteration. Your callback function should set the ModelStepFunctionPrototypeControlCompliant flag as follows: slConfigUISetVal(hDlg, hSrc, 'ModelStepFunctionPrototypeControlCompliant', 'on'); slConfigUISetEnabled(hDlg, hSrc, 'ModelStepFunctionPrototypeControlCompliant', false); For more information about the STF callback API, see the slConfigUIGetVal, slConfigUISetEnabled, and slConfigUISetVal function reference pages. When the ModelStepFunctionPrototypeControlCompliant target configuration parameter is set to on, you can use the Configure Model Functions button on the Interface pane of the Configuration Parameters dialog box to control the function prototypes of initialize and step functions that are generated for your model. 24-120 Support Optional Features Providing C Function Prototype Control Support in the Custom Static Main Program If your target uses a custom static main program, and if a nondefault function prototype control configuration is associated with a model, you must update the static main program to call the function prototype controlled initialize and step functions. You can do this in either of the following ways: 1 Manually adapt your static main program to declare model data and call the function prototype controlled initialize and step functions. 2 Generate your main program using Generate an example main program on the Templates pane of the Configuration Parameters dialog box. The generated main program declares model data and calls the function prototype controlled initialize and step function. Support C++ Encapsulation Interface Control • “Overview” on page 24-121 • “Declaring C++ Encapsulation Interface Control Compliance” on page 24-122 Overview This chapter describes how to configure a custom embedded target to support C++ encapsulation interface control. Without the described modifications, you will not be able to use the C++ (Encapsulated) language option and the Configure C++ Encapsulation Interface button on the Interface pane of the Configuration Parameters dialog box to generate and configure C++ encapsulation interfaces to model code. (For more information about C++ encapsulation interface control, see “C++ Encapsulation Interface Control” in the Embedded Coder documentation.) The requirements for supporting C++ encapsulation interface control are as follows: • The target must be derived from the ERT target. • The system target file (STF) must declare C++ encapsulation interface control compliance, as described in “Declaring C++ Encapsulation Interface Control Compliance” on page 24-122. 24-121 24 Custom Target Development Declaring C++ Encapsulation Interface Control Compliance To declare C++ encapsulation interface control compliance for your target, you must implement a callback function that sets the CPPClassGenCompliant flag, and then install the callback function in the SelectCallback field of the rtwgensettings structure in your STF. The callback function is triggered whenever the user selects the target in the System Target File Browser. For example, the following STF code installs a SelectCallback function named custom_select_callback_handler: rtwgensettings.SelectCallback = 'custom_select_callback_handler(hDlg, hSrc)'; The arguments to the SelectCallback function (hDlg, hSrc) are handles to private data used by the callback API functions. These handles are restricted to use in STF callback functions. They should be passed in without alteration. Your callback function should set the CPPClassGenCompliant flag as follows: slConfigUISetVal(hDlg, hSrc, 'CPPClassGenCompliant', 'on'); slConfigUISetEnabled(hDlg, hSrc, 'CPPClassGenCompliant', false); For more information about the STF callback API, see the slConfigUIGetVal, slConfigUISetEnabled, and slConfigUISetVal function reference pages. When the CPPClassGenCompliant target configuration parameter is set to on, you can use the C++ (Encapsulated) language option and the Configure C++ Encapsulation Interface button on the Interface pane of the Configuration Parameters dialog box to generate and configure C++ encapsulation interfaces to model code. Note Selecting the C++ (Encapsulated) language value for your model turns on the model option Generate an example main program. With this option on, code generation generates an example main program, ert_main.cpp. The generated example main program declares model data and calls the C++ encapsulation interface configured model step method, and illustrates how the generated code can be deployed. 24-122 Interface to Development Tools Interface to Development Tools In this section... “About Interfacing to Development Tools” on page 24-123 “Makefile Approach” on page 24-124 “Interface to an Integrated Development Environment” on page 24-124 About Interfacing to Development Tools Unless you are developing a target purely for code generation purposes, you will want your embedded target to support a complete build process. A full post-code generation build process includes • Compilation of generated code • Linking of compiled code and runtime libraries into an executable program module (or some intermediate representation of the executable code, such as S-Rec format) • Downloading the executable to target hardware with a debugger or other utility • Initiating execution of the downloaded program Supporting a complete build process is inherently a complex task, because it involves interfacing to cross-development tools and utilities that are external to the Simulink Coder software. If your development tools can be controlled with traditional makefiles and a make utility such as gmake, it may be relatively simple for you to adapt existing target files (such as the ert.tlc and ert.tmf files provided by the Embedded Coder software) to your requirements. This approach is discussed in “Makefile Approach” on page 24-124. Automating your build process through a modern integrated development environment (IDE) presents a different set of challenges. Each IDE has its own way of representing the set of source files and libraries for a project and for specifying build arguments. Interfacing to an IDE may require generation of specialized file formats required by the IDE (for example, project files) 24-123 24 Custom Target Development and, and also may require the use of inter-application communication (IAC) techniques to run the IDE. One such approach to build automation is discussed in “Interface to an Integrated Development Environment” on page 24-124. Makefile Approach A template makefile provides information about your model and your development system. The build process uses this information to create a makefile (.mk file) to build an executable program. The Embedded Coder product provides a number of template makefiles suitable for host-based compilers such as LCC (ert_lcc.tmf) and Microsoft Visual C++ (ert_vc.tmf). Adapting one of the existing template makefiles to your cross-compiler’s make utility may require little more than copying and renaming the template makefile in accordance with the conventions of your project. If you need to make more extensive modifications, you need to understand template makefiles in detail. For a detailed description of the structure of template makefiles and of the tokens used in template makefiles, see “Customize Template Makefiles” on page 24-75. The following sections of this document supplement the basic template makefile information in the Simulink Coder documentation: • “Supporting Multiple Development Environments” on page 24-60 • “Supplying Development Environment Information to Your Template Makefile” on page 24-33 • “mytarget_default_tmf.m” on page 24-22 Interface to an Integrated Development Environment • “Introduction” on page 24-125 • “Generating a CPP_REQ_DEFINES Header File” on page 24-125 • “Interfacing to the Freescale CodeWarrior IDE” on page 24-126 24-124 Interface to Development Tools Introduction This section describes techniques that have been used to integrate embedded targets with integrated development environment (IDEs), including • How to generate a header file containing directives to define variables (and their values) required by a non-makefile based build. • Some problems and solutions specific to interfacing embedded targets with the Freescale Semiconductor CodeWarrior IDE. The examples provided should help you to deal with similar interfacing problems with your particular IDE. Generating a CPP_REQ_DEFINES Header File In Simulink Coder template makefiles, the token CPP_REQ_DEFINES is expanded and replaced with a list of parameter settings entered with various dialog boxes. This variable often contains information such as MODEL (name of generating model), NUMST (number of sample times in the model), MT (model is multitasking or not), and numerous other parameters (see “Template Makefiles and Tokens” on page 24-75). The Simulink Coder makefile mechanism handles the CPP_REQ_DEFINES token automatically. If your target requires use of a project file, rather than the traditional makefile approach, you can generate a header file containing directives to define these variables and provide their values. The following TLC file, gen_rtw_req_defines.tlc, provides an example. The code generates a C header file, cpp_req_defines.h. The information required to generate each#define directive is derived either from information in the model.rtw file (e.g., CompiledModel.NumSynchronousSampleTimes), or from make variables from the rtwoptions structure (e.g., PurelyIntegerCode). %% File: gen_rtw_req_defines_h.tlc %openfile CPP_DEFINES = "cpp_req_defines.h" #ifndef _CPP_REQ_DEFINES_ #define _CPP_REQ_DEFINES_ #define MODEL % #define ERT 1 #define NUMST % #define TID01EQ % %% 24-125 24 Custom Target Development %if CompiledModel.FixedStepOpts.SolverMode == "MultiTasking" #define MT 1 #define MULTITASKING 1 %else #define MT 0 #define MULTITASKING 0 %endif %% #define MAT_FILE 0 #define INTEGER_CODE % #define ONESTEPFCN % #define TERMFCN % %% #define MULTI_INSTANCE_CODE 0 #define HAVESTDIO 0 #endif %closefile CPP_DEFINES Interfacing to the Freescale CodeWarrior IDE Interfacing an embedded target’s build process to the CodeWarrior IDE requires that two problems must be dealt with: • The build process must generate a CodeWarrior compatible project file. This problem, and a solution, is discussed in “XML Project Import” on page 24-126. The solution described is applicable to any ASCII project file format. • During code generation, the target must automate a CodeWarrior session that opens a project file and builds an executable. This task is described in “Build Process Automation” on page 24-131. The solution described is applicable to any IDE that can be controlled with Microsoft Component Object Model (COM) automation. XML Project Import. This section illustrates how to use the Target Language Compiler (TLC) to generate an eXtensible Markup Language (XML) file, suitable for import into the CodeWarrior IDE, that contains information about the source code generated by an embedded target. 24-126 Interface to Development Tools The choice of XML format is dictated by the fact that the CodeWarrior IDE supports project export and import with XML files. As of this writing, native CodeWarrior project files are in a proprietary binary format. Note that if your target needs to support some other compiler’s project file format, you can apply the techniques shown here to virtually any ASCII file format (see “Generating a CPP_REQ_DEFINES Header File” on page 24-125). To illustrate the basic concept, consider a hypothetical XML file exported from a CodeWarrior stationery project. The following is a partial listing: ... <\settings> foo.c<\name> <\file> ... foobar.c<\name> <\file> foo.c<\name> <\fileref> ... foobar.c<\name> <\fileref> <\target> 24-127 24 Custom Target Development Insert this XML code into an %openfile/%closefile block within a TLC file, test.tlc, as shown below. %% test.tlc %% This code will generate a file model_project.xml, %% where model is the generating model name specified in %% the CompiledModel.Name field of the model.rtw file. %openfile XMLFileContents = %_project.xml ... <\settings> %.c<\name> <\file> ... foobar.c<\name> <\file> %.c<\name> <\fileref> ... foobar.c<\name> <\fileref> <\target> %closefile XMLFileContents %selectfile NULL_FILE Note the use of the TLC token CompiledModel.Name. The token is resolved and the resulting filename is included in the output stream. You can specify other information, such as paths and libraries, in the output stream by specifying other tokens defined in model.rtw. For example, System.Name may be defined as /Susbsystem1. Now suppose that test.tlc is invoked during a target’s build process, where the generating model is mymodel. This should be done after the codegenentry statement. For example, test.tlc could be included directly in the system target file: %include "codegenentry.tlc" %include "test.tlc" 24-128 Interface to Development Tools Alternatively, the %include "test.tlc" directive could be inserted into the mytarget_genfiles.tlc hook file, if present. TLC tokens such as %.c<\name> are expanded, with the CompiledModel record in the mymodel.rtw file, as in mymodel.c<\name> test.tlc generates an XML file, file model_project.xml, from any model. model_project.xml contains references to generated code files. model_project.xml can be imported into the CodeWarrior IDE as a project. The following flowchart summarizes this process. 24-129 24 Custom Target Development proj.mcp: CodeWarrior project binary stationery file Code Warrior (manual): Export to XML. proj.xml: XML project file Text editor (manual): Add TLC tokens to generate references to model files, MATLAB and other paths, and other settings. Embed the XML code marked with tokens in openfile/closefile block. Save as proj_gen.tlc. proj_gen.tlc:TLC file for generating XML file TLC: During code generation, expand TLC tokens and generate XML project file, model_project.xml. model_project.xml: Generated XML project file with generated file references and target-specific information Code Warrior (manual or with script): Import from XML. model_project.mcp: CodeWarrior project binary file Code Warrior (manual or with script): Build project as indicated in "Build Process Automation". 24-130 Interface to Development Tools Note This process has drawbacks. First, manually editing an XML file exported from a CodeWarrior stationery project can be a laborious task, involving modification of a few dozen lines embedded within several thousand lines of XML code. Second, if you make changes to the CodeWarrior project after importing the generated XML file, the XML file must be exported and manually edited once again. Build Process Automation. An application that supports COM automation can control any other application that includes a COM interface. Using MATLAB COM automation functions, a MATLAB file can command a COM-compatible development system to execute tasks required by the build process. The MATLAB COM automation functions described in this section are documented in “COM Objects”. For information about automation commands supported by the CodeWarrior IDE, see your CodeWarrior documentation. COM automation is used by some embedded targets to automate the CodeWarrior IDE to execute tasks such as: • Opening a new CodeWarrior session • Configure a project • Loading a CodeWarrior project file • Removing object code from the project • Building or rebuilding the project • Debug an application COM technology automates certain repetitive tasks and allows the user to interact directly with the external application. For example, when the end user of the embedded targets capability initiates a build, the target quickly invokes CodeWarrior actions and leaves a project built and ready to run with the IDE. 24-131 24 Custom Target Development Example COM Automation Functions The functions below use the MATLAB actxserver command to invoke COM functions for controlling the CodeWarrior IDE from a MATLAB file: • CreateCWComObject: Create a COM connection to the CodeWarrior IDE. • OpenCW: Open the CodeWarrior IDE without opening a project. • OpenMCP: Open the CodeWarrior project file (.mcp file) specified by the input argument. • BuildCW: Open the specified .mcp file, remove object code, and build project. These functions are examples; they do not constitute a full implementation of a COM automation interface. If your target creates the project file during code generation, the top-level BuildCW function should be called after the code generation process is completed. Normally BuildCW would be called from the exit method of your STF_make_rtw_hook.m file (see “STF_make_rtw_hook.m” on page 24-23). In the code examples, the variable in_qualifiedMCP is assumed to store a fully qualified path to a CodeWarrior project file (for example, path, filename, and extension). For example: in_qualifiedMCP = 'd:\work\myproject.mcp'; In actual practice, your code is responsible for determining the conventions used for the project filename and location. One simple convention would be to default to a project file model.mcp, located in your target’s build folder. Another approach would be to let the user specify the location of project files with the target preferences. %====================================================================== % Function: CreateCWComObject % Abstract: Creates the COM connection to CodeWarrior % function ICodeWarriorApp = CreateCWComObject vprint([mfilename ': creating CW com object']); try ICodeWarriorApp = actxserver('CodeWarrior.CodeWarriorApp'); catch 24-132 Interface to Development Tools error(['Error creating COM connection to ' ComObj ... '. Verify that CodeWarrior is installed. Verify COM access to CodeWarrior outside of MATLAB.']); end return; %====================================================================== % Function: OpenCW % Abstract: Opens CodeWarrior without opening a project. Returns the % handle ICodeWarriorApp. % function ICodeWarriorApp = OpenCW() ICodeWarriorApp = CreateCWComObject; CloseAll; OpenMCP(in_qualifiedMCP); %===================================================================== % Function: OpenMCP % Abstract: open an MCP project file % function OpenMCP(in_qualifiedMCP) % Argument checking. This method requires valid project file. if ~exist(in_qualifiedMCP) error([mfilename ': Missing or empty project file argument']); end if isempty(in_qualifiedMCP) error([mfilename ': Missing or empty project file argument']); end ICodeWarriorApp = CreateCWComObject; vprint([mfilename ': Importing']); try ICodeWarriorProject = ... invoke(ICodeWarriorApp.Application,... 'OpenProject', in_qualifiedMCP,... 1,0,0); catch error(['Error using COM connection to import project. ' ... ' Verify that CodeWarrior is installed. Verify COM access to 24-133 24 Custom Target Development CodeWarrior outside of MATLAB.']); end %===================================================================== % Function: BuildCW % Abstract: Opens CodeWarrior. % Opens the specified CodeWarrior project. % Deletes objects. % Builds. % function ICodeWarriorApp = BuildCW(in_qualifiedMCP) % ICodeWarriorApp = BuildCW; ICodeWarriorApp = CreateCWComObject; CloseAll; OpenMCP(in_qualifiedMCP); try invoke(ICodeWarriorApp.DefaultProject,'RemoveObjectCode', 0, 1); catch error(['Error using COM connection to remove objects of current project. ' ... 'Verify that CodeWarrior is installed. Verify COM access to CodeWarrior outside of MATLAB.']); end try invoke(ICodeWarriorApp.DefaultProject,'BuildAndWaitToComplete'); catch error(['Error using COM connection to build current project. ' ... 'Verify that CodeWarrior is installed. Verify COM access to CodeWarrior outside of MATLAB.']); end 24-134 Device Drivers and Target Preferences Device Drivers and Target Preferences In this section... “Integrate Device Drivers” on page 24-135 “Use Target Preferences” on page 24-135 Integrate Device Drivers Device drivers that communicate with target hardware are essential to many real-time development projects. You can integrate existing C (or C++) device driver functions into Simulink models by using the Legacy Code Tool. When you use the Simulink Coder product to generate code from a model, the Legacy Code Tool can insert a call to your C function into the generated code. For details, see “Integrate External Code Using Legacy Code Tool” on page 14-28 and “Example of Integrating Existing C Functions into Simulink Models with the Legacy Code Tool”. Embedded Coder target support provides the Target Block Builder Tool for integrating custom device driver code with the algorithmic code generated by code generation software. If you have the Embedded Coder product, see the Texas Instruments C6000 example “Custom Device Driver Integration via Target Block Builder Tool”. Use Target Preferences You may want to associate certain types of data with the target. For example, an embedded target might offer a choice of several supported development systems (cross-compilers, debuggers, and so on). To invoke a specific development tool during the build process, the target needs information such as the user’s choice of development tool, and the location on the host system where the user has installed the compiler and debugger executables. Other data associated with a target might specify host/target communications parameters, such as the communications port and baud rate to be used. Target developers need to define and store the properties they want to associate with their target. End users need a simple mechanism to set target property values. 24-135 24 Custom Target Development To define preferences to associate with your target, see the following function pages: • addpref • getpref • setpref 24-136 Desktop IDEs and Desktop Targets 25 Project and Build Configurations for Desktop Targets • “Model Setup” on page 25-2 • “IDE Projects” on page 25-16 • “Makefiles for Software Build Tool Chains” on page 25-19 25 Project and Build Configurations for Desktop Targets Model Setup In this section... “Block Selection” on page 25-2 “Target Preferences” on page 25-3 “Configuration Parameters” on page 25-7 “Model Reference” on page 25-14 Block Selection You can create models for targeting the same way you create other Simulink models—by combining standard blocks and C-MEX S-functions. You can use blocks from the following sources: • The Desktop Targets library (desktoptargetslib) in the Simulink Coder product. • Blocks from the System Toolboxes products • Custom blocks Avoid using blocks that do not generate code, including the following blocks. Block Name/Category 25-2 Library Description Scope Simulink, DSP System Toolbox software Provides oscilloscope view of your output. Do not use the Save data to workspace option on the Data history pane in the Scope Parameters dialog box. To Workspace Simulink Return data to your MATLAB workspace. From Workspace Simulink Send data to your model from your MATLAB workspace. Model Setup Block Name/Category Library Description Spectrum Scope DSP System Toolbox Compute and display the short-time FFT of a signal. It has internal buffering that can slow your process without adding value. Triggered to Workspace DSP System Toolbox Send data to your MATLAB workspace. Signal To Workspace DSP System Toolbox Send a signal to your MATLAB workspace. Signal From Workspace DSP System Toolbox Get a signal from your MATLAB workspace. Triggered Signal From Workspace DSP System Toolbox Get a signal from your MATLAB workspace. To Wave device DSP System Toolbox Send data to a .wav device. From Wave device DSP System Toolbox Get data from a .wav device. Target Preferences This topic contains the following subtopics: • “Supported IDEs” on page 25-3 • “What is a Target Preferences Block?” on page 25-4 • “Adding a Target Preferences Block to Your Model” on page 25-4 • “Creating a Library of Customized Target Preferences Blocks” on page 25-6 Supported IDEs This “Target Preferences” on page 25-3 section applies to Eclipse™ IDE. 25-3 25 Project and Build Configurations for Desktop Targets What is a Target Preferences Block? If you are preparing to generate code for a target processor, add a Target Preferences block to the model. You can use the Target Preferences block to specify information such as the processor, board, hardware settings, operating system, memory map, and code generation features. Simulink Coder, Embedded Coder, and Simulink products use this information to generate code from your model. For detailed information about the Target Preference block parameters and options, consult the Target Preferences block reference topic. Key Points • To generate code, the model must contain a Target Preferences block. • Use one Target Preferences block per model. Exceptions to this rule are noted in the documentation for specific features, such as “Model Block PIL” on page 26-3. • Changing Target Preferences block settings can change tabs, panes, parameters, and options visible when you open the block. • Adding a Target Preferences block to a model changes the values of some Configuration Parameters. If you need to preserve the Configuration Parameters of a specific model, make a backup copy of the model before adding a Target Preferences block to it. Adding a Target Preferences Block to Your Model To generate code, with few exceptions, your model must contain only one Target Preferences block. • When you are generating code for a model, place the Target Preferences block at the top level of your model. • When you are generating code for a subsystem in your model, place the Target Preferences block at the subsystem level of your model. To add a Target Preferences block to your model: 25-4 Model Setup 1 Open the Simulink library browser. 2 Copy the Target Preferences block from the Simulink Coder > Desktop Targets library to your model 3 The software displays the Initialize Configuration Parameters dialog box. For example. Set the following parameters, and click Yes: • IDE/Tool Chain • Board • Processor When you click Yes, the software automatically sets the model Configuration Parameters for the IDE/Tool Chain, Board, and Processor you selected. You have completed the process of adding a Target Preferences block to your model. If you click No, the software leaves the values of the Configuration Parameters unchanged. The model cannot simulate or generate valid code unless you configure the Configuration Parameters with the right values. Setting these values manually can be difficult. 25-5 25 Project and Build Configurations for Desktop Targets Note The following actions update some of the model Configuration Parameters with new values: • Adding a Target Preferences block to your model and clicking Yes in the Initialize Configuration Parameters dialog box. • Opening the Target Preferences block in your model and selecting a new IDE/Tool Chain. • Opening the Target Preferences block in your model and applying changes to the Board and Processor parameters. Note The Initialize Configuration Parameters dialog box uses your previous selections for IDE/Tool Chain, Board, and Processor as default values the next time you copy a Target Preference block to a model. Creating a Library of Customized Target Preferences Blocks If you work regularly with a variety of IDEs, tool chains, boards and processors, you can save time by creating a library of customized Target Preferences blocks. Later, you reuse these preconfigured Target Preferences blocks instead repeating the customization process on a new Target Preferences block. To create a library of customized Target Preferences blocks: 1 In Simulink, select File > New > Library. This action creates a new untitled library. 2 Save the library to a folder included in your MATLAB search paths. Note Click File > Set Path to see a list of MATLAB search paths and add new ones. 3 Copy or drag configured Target Preferences blocks from your models to the library. 25-6 Model Setup 4 Edit the label of each block to describe that block’s configuration. 5 After the new blocks are added and labeled, save the library. To copy a Target Preferences block from your library to a model, type the library name in the MATLAB Command Window. When the library appears, copy the block to your model. Configuration Parameters • “What are Configuration Parameters?” on page 25-7 • “Setting Model Configuration Parameters” on page 25-7 What are Configuration Parameters? To see the model Configuration Parameters, open the Configuration Parameters dialog box. You can do this in the model editor by selecting Simulation > Model Configuration Parameters, or by pressing Ctrl+E on your keyboard. The Configuration Parameters dialog box specifies the values for a model’s active configuration set. These parameters determine the type of solver used, the import and export settings, and other values that determine how the model runs. To set the Configuration Parameters to the right values for you to generate code from your model, add a Target Preferences block to your model. This action initializes the model Configuration Parameters to the right default values for you to generate code. You can then use the Configuration Parameters dialog box to make further modifications to the values. Setting Model Configuration Parameters To apply the right default values in Configuration Parameters, add a Target Preferences block to your model and select the Initialize Configuration Parameters, as described in “Adding a Target Preferences Block to Your Model” on page 25-4. You can generate buildable code using these default values. 25-7 25 Project and Build Configurations for Desktop Targets To make further changes, select Simulation > Model Configuration Parameters in the Model Editor, or press Ctrl+E. This action opens the Configuration Parameters dialog box. The following subsections provide a quick overview of the panes and parameters with which you are most likely to interact. Code Generation Pane. When you set System target file to idelink_ert.tlc or idelink_grt.tlc, the dialog box adds an IDE Link pane to the list of panes under Code Generation. 25-8 Model Setup Setting the System target file to idelink_ert.tlc requires an Embedded Coder license. Leave Language set to C. The idelink_ert.tlc and idelink_grt.tlc system target files do not support C++ code generation. For more information, see “Code Generation Pane: General” IDE Link Pane Parameters. The IDE Link entry provides options in these areas: • Run-Time — Set options for run-time operations, like the build action • Vendor Tool Chain — Set compiler, linker, and system stack size options 25-9 25 Project and Build Configurations for Desktop Targets • Code Generation — Configure your code generation requirements • Link Automation — Export an IDE handle object, such as IDE_Obj, to your MATLAB workspace • Diagnostics — Determine how the code generation process responds when you use source code replacement in the Custom Code pane. For more information, see Code Generation Pane: IDE Link. Build format Select Project to create an IDE project, or select Makefile to create a makefile build script. Build action Your selection for Build action determines what happens when you click Build or press Ctrl+B. Your selection tells Simulink Coder software when to stop the code generation and build process. To run your model on the processor, select Build_and_execute. This selection is the default build action. The actions are cumulative—each action performs an additional step relative to the preceding action on the list. If you set Build format to Project, select one of the following options: • Create_project — Directs Simulink Coder software to start the IDE and populate a new project with the files from the build process. This option offers a convenient way to build projects in the IDE. • Archive_library — Directs Simulink Coder software to create an archive library for this model. Use this option when you plan to use the model in a model reference application. Model reference requires that you archive your the IDE projects for models that you use in model referencing. • Build — Builds the executable file, but does not download the file to the target processor. 25-10 Model Setup • Build_and_execute — Directs Simulink Coder software to build, download, and run your generated code as an executable on your target processor. • Create_processor_in_the_loop_project — Directs code generation process to create PIL algorithm object code as part of the project build. This option requires an Embedded Coder license. If you set Build format to Makefile, select one of the following options: • Create_makefile — Creates a makefile. • Archive_library — Creates a makefile and the generated output will be an archive library. • Build — Creates a makefile and an executable. • Build_and_execute — Creates a makefile and an executable. Then it evaluates the execute instruction in the current configuration. Overrun notification To enable the overrun indicator, choose one of three ways for the target to respond to an overrun condition in your model: • None — Ignore overruns encountered while running the model. • Print_message — When the target encounters an overrun condition, it prints a message to the standard output device, stdout. • Call_custom_function — Respond to overrun conditions by calling the custom function you identify in Function name. Function name When you select Call_custom_function from the Overrun notification list, you enable this option. Enter the name of the function the target should use to notify you that an overrun condition occurred. The function must exist in your code on the target processor. 25-11 25 Project and Build Configurations for Desktop Targets Configuration The Configuration parameter defines sets of build options that apply to all of the files generated from your model. The Release and Debug option apply build settings that are defined by your compiler. For more information, refer to your compiler documentation. Custom has the same default values as Release, but: • Leaves Compiler options string empty. Compiler options string To determine the degree of optimization provided by the optimizing compiler, enter the optimization level to apply to files in your project. For details about the compiler options, refer to your IDE documentation. When you create new projects, the coder product does not set any optimization flags. Linker options string To specify the options provided by the linker during link time, you enter the linker options as a string. For details about the linker options, refer to your IDE documentation. When you create new projects, the coder product does not set any linker options. System stack size (MAUs) Enter the amount of memory that is available for allocating stack data, measured in minimum addressable units (MAU). Block output buffers are placed on the stack until the stack memory is fully allocated. After that, the output buffers go in global memory. An MAU is typically 1 byte, but its size can vary by target processor. This parameter is used in all targets to allocate the stack size for the generated application. For example, with embedded processors that are not running an operating system, this parameter determines the total stack space 25-12 Model Setup that can be used for the application. For such as Linux or WindowsVxWorks operating systems, this value specifies the stack space allocated per thread. This parameter also affects the “Maximum stack size (bytes)” parameter, located in the Optimization > Signals and Parameters pane. Link Automation When you build a model for a target, the coder product automatically creates or uses an existing IDE handle object (named IDE_Obj, by default) to connect to your IDE. Although IDE_Obj is a handle for a specific instance of the IDE, it also contains information about the IDE instance to which it refers, such as the target the IDE accesses. In this pane, the Export IDE link handle to base workspace option lets you instruct the coder product to export the object to your MATLAB workspace, giving it the name you assign in IDE link handle name. You can also use the IDE handle object to interact with the IDE using IDE Automation Interface commands. Maximum time allowed to build project (s) Specifies how long the software waits for the IDE to build the software. Maximum time allowed to complete IDE operation (s) Specifies how long the software waits for IDE functions, such as read or write, to return completion messages. If you do not specify a timeout, the default value is 10 seconds. Export IDE link handle to base workspace Directs the software to export the IDE_Obj object to your MATLAB workspace. 25-13 25 Project and Build Configurations for Desktop Targets IDE link handle name Specifies the name of the IDE_Obj object that the build process creates. Source file replacement Selects the diagnostic action to take if the software detects conflicts when you replace source code with custom code. The diagnostic message responds to both source file replacement in the Configuration Parameters under Code Generation > IDE link parameters and under Code Generation > Custom Code. The following settings define the messages you see and how the code generation process responds: • none — Does not generate warnings or errors when it finds conflicts. • warning — Displays a warning. warn is the default value. • error — Terminates the build process and displays an error message that identifies which file has the problem and suggests how to resolve it. The build operation continues if you select warning and the software detects custom code replacement problems. You see warning messages as the build progresses. Select error the first time you build your project after you specify custom code to use. The error messages can help you diagnose problems with your custom code replacement files. Use none when the replacement process works and you do not want to see multiple messages during your build. Model Reference The idelink_ert.tlc and idelink_grt.tlc system target files provide support for generating code from models that use Model Reference. A referenced model will generate an archive library. To enable Model Reference builds: 1 Open your referenced model. 25-14 Model Setup 2 Select Simulation > Model Configuration Parameters from the model menus. 3 From the list of panes under Code Generation, choose IDE Link. 4 In the right pane, under Run-Time, select Archive_library from the Build action list. If your top-model uses a reference model that does not have the Build action set to Archive_library, the build process automatically changes the Build action to Archive_library and issues a warning about the change. Target Preferences Blocks in Reference Models Include a configured Target Preferences block in each referenced model and the top-model . Configure all of the Target Preferences blocks for the same processor so that the software tool chain and build process is consistent across the model hierarchy. 25-15 25 Project and Build Configurations for Desktop Targets IDE Projects In this section... “Support for Third Party Products” on page 25-16 “Third Party Product Setup” on page 25-16 “Code Generation and Build” on page 25-16 “Automation of IDE Tasks and Processes” on page 25-17 Support for Third Party Products For more information about Simulink Coder support for Eclipse IDE, see http://www.mathworks.com/products/simulink-coder/eclipse-adaptor.html Third Party Product Setup Install your third party IDE or software build tool chain according to the vendor’s instructions. If you are using one of the following IDEs, perform the additional steps described here: Eclipse IDE Complete the instructions in “Installing Third-Party Software for Eclipse” on page 27-2 and in “Configuring Your MathWorks Software to Work with Eclipse” on page 27-10. Code Generation and Build Building Your Model In your model, click Build Model . The software performs the actions you selected for Build action in the model Configuration Parameters, under Code Generation > IDE Link. 25-16 IDE Projects IDE Project Generator Features The IDE Project Generator component provides or supports the following features for developing IDE projects and generating code: • Automatically create IDE projects for your generated code during the code generation process. • Customize code generation using options in the model Configuration Parameters and the Target Preferences block. • Configure the automatic project build process. • Automatically download and run your generated projects on your target processor. IDE Handle Objects IDE Project Generator automatically creates and uses an IDE handle object to communicate with your IDE and target processor. To create the IDE handle object for Eclipse IDE, IDE Project Generator uses the eclipseide constructor function. For a command line example, see the eclipseide reference page. Automation of IDE Tasks and Processes The IDE Automation Interface component provides a powerful API for automating IDE tasks via MATLAB scripts. For example, with IDE Automation Interface, your script can automatically: • Automate project creation, including adding source files, include paths, and preprocessor defines • Configure batch building of projects • Launch a debugging session Examples of IDE Automation Interface for Specific IDEs To help you become familiar with IDE Automation Interface, you can use the “IDE Automation Interface Tutorial” example for Eclipse IDE. The example shows you how to: 25-17 25 Project and Build Configurations for Desktop Targets 1 Configure and create an IDE handle object. 2 Create and query objects in an IDE. 3 Use MATLAB software to load files into your IDE. 4 Work with your IDE project from MATLAB software. 5 Close connections you the IDE. 25-18 Makefiles for Software Build Tool Chains Makefiles for Software Build Tool Chains In this section... “What is the XMakefile Feature” on page 25-19 “Using Makefiles to Generate and Build Software” on page 25-21 “Making an XMakefile Configuration Operational” on page 25-24 “Working with Microsoft® Visual Studio®” on page 25-24 “Creating a New XMakefile Configuration” on page 25-25 “XMakefile User Configuration Dialog Box” on page 25-31 What is the XMakefile Feature • “Overview” on page 25-19 • “Supported Tool Chains in Simulink® Coder™” on page 25-20 • “Available XMakefile Configurations” on page 25-20 • “Feature Support” on page 25-20 Overview You can use makefiles instead of IDE projects during the automated software build process. This approach is described in “Using Makefiles to Generate and Build Software” on page 25-21. The XMakefile feature lets you choose the configuration of a specific software build tool chain to use during the automated build process. The configuration contains paths and settings for your make utility, compiler, linker, archiver, pre-build, post-build, and execute tools. You can choose one built-in configuration described in and “Available XMakefile Configurations” on page 25-20. You can also create a new configuration for a new tool chain, as described in “Creating a New XMakefile Configuration” on page 25-25. 25-19 25 Project and Build Configurations for Desktop Targets Your requirements for specific features may determine whether you choose makefiles or IDE projects. See “Feature Support” on page 25-20. Supported Tool Chains in Simulink Coder Simulink Coder includes support for the following IDEs and tool chains. Tool Chain Processor Family/Target Operating System Host Operating System GNU development tools Linux Linux MinGW development tools Windows Windows Microsoft Visual Studio Windows Windows Embedded Coder includes support for other IDEs and tool chains. See Supported Tool Chains in Embedded Coder. Available XMakefile Configurations The following list describes the configurations in the XMakefile dialog box that this product supports: • gcc_target: GNU Compiler Collection & Host Operating System or Embedded Operating System • mingw_host: Minimalist GNU for Windows & Host Operating System • msvs_host: Microsoft Visual Studio & Host Operating System For more information about supported versions of third-party software, see “Support for Third Party Products” on page 25-16 Feature Support With makefiles, you cannot use features that rely on direct communications between your MathWorks software and third-party IDEs. You cannot use the following features with makefiles: 25-20 Makefiles for Software Build Tool Chains • IDE Project Generation • IDE Automation Interface • IDE debugger communications during Processor-in-the-loop (PIL) simulation Using Makefiles to Generate and Build Software In addition to this chapter, see the Makefile Generator Tutorial example for more information about using makefiles to generate code. Configuring Your Model to Use Makefiles Update your model Configuration Parameters to use a makefile instead of an IDE when you build software from the model: 1 Add a Target Preferences block to your model and configure it for your target processor. For more information, see “Target Preferences” on page 25-3. 2 In your Simulink Editor, select Simulation > Model Configuration Parameters or press Ctrl+e. 3 Under the Code Generationtab, select IDE Link. 4 Set Build format to Makefile. For more information, see Build format on page 10. 5 Set Build action to Build_and_execute. For more information, see Build action on page 10. Choosing an XMakefile Configuration Configure how to generate makefiles: 1 Enter xmakefilesetup on the MATLAB Command Window. The software opens an XMakefile User Configuration dialog box. 25-21 25 Project and Build Configurations for Desktop Targets 2 Leave Template set to gmake. 3 For Configuration, select gcc_target or msvs_host to match the compiler toolchain you are using — gcc or Microsoft Visual Studio, respectively. Click Apply. Note Changing some elements of the XMakefile dialog box disables other elements until you apply the changes. Click Apply or OK after changing any of the following: • Template • Configurations • User Templates • User Configurations • Tool Directories 25-22 Makefiles for Software Build Tool Chains Note With the XMakefile User Configuration dialog, if you have a Simulink Coder license but no Embedded Coder license, the only valid settings for Configuration are gcc_target, mingw_host, or msvs_host. The other configurations, though visible, are only supported by the Embedded Coder product. Note If you set Configuration to msvs_host, restart MATLAB as described in “Working with Microsoft® Visual Studio®” on page 25-24 before building your model software. Things to consider while setting Configuration: • Selecting Display operational configurations only hides configurations that contain incomplete or invalid information. For a configuration to be operational, the vendor tool chain must be installed, and the configuration must have the valid paths for each component of the vendor tool chain. For more information, see “Making an XMakefile Configuration Operational” on page 25-24. • To display all of the configurations, including non-operational configurations, clear Display operational configurations only. • The list of configurations can include non-editable configurations defined in the software and editable configurations defined by you. • To create a new editable configuration, use the New button. • For more information, see “XMakefile User Configuration Dialog Box” on page 25-31. Building Your Model In your model, click Build Model . This action creates a makefile and performs the other actions you specified in Build action. 25-23 25 Project and Build Configurations for Desktop Targets By default, this process outputs files in the / folder. For example, in model_name/CustomMW. Making an XMakefile Configuration Operational When the XMakefile utility starts, it checks each configuration file to verify that the specified paths for the vendor tool chain are valid. If the paths are not valid, the configuration is non-operational. Typically, the cause of this problem is a difference between the path in the configuration and the actual path of the vendor toolchain. To make a configuration operational: 1 Clear Display operational configurations only to display non-operational configurations. 2 Select the non-operational configuration from the Configuration options. 3 When you click Apply, a new dialog box prompts you for the folder path of any missing resources the configuration requires. Use mapped network drives instead of UNC paths to specify directory locations. Using UNC paths with compilers that do not support them causes build errors. Working with Microsoft Visual Studio If you set Configuration to msvs_host, restart MATLAB from a Visual Studio® command prompt before building your model software with makefiles. The vsvars32.bat file associated with the Visual Studio command prompt configures the Visual Studio environment. Starting MATLAB from this command prompt results in a session that can generate makefiles from the msvs_host configuration. To restart MATLAB from a Visual Studio command prompt: 1 Open a Visual Studio command prompt: a Select your MSVS product from the Windows Start > Programs menu. 25-24 Makefiles for Software Build Tool Chains b In Visual Studio Tools, select the Visual Studio Command Prompt. For example: 2 Enter matlab at the Visual Studio Command Prompt. 3 In MATLAB, open and build your model. If you do not restart MATLAB from Microsoft Visual Studio command prompt, building your model software generates an error whose ending is similar to the following text: The build failed with the following message: "C:/Program Files/Microsoft Visual Studio... 3792 Abort C:/Program Files/Microsoft Visual Studio 8/VC/bin/cl gmake: *** [MW_csl.obj] Error 134 A related article is available on the Microsoft Web site at: http://msdn.microsoft.com/en-us/library/1700bbwd.aspx Creating a New XMakefile Configuration • “Overview” on page 25-25 • “Create a Configuration” on page 25-26 • “Modify the Configuration” on page 25-27 • “Test the Configuration” on page 25-30 Overview This example shows you how to add support for a software development toolchain to the XMakefile utility. This example uses the Intel Compiler and Eclipse IDE, which provides an open framework and allows for otherwise unsupported toolchains. 25-25 25 Project and Build Configurations for Desktop Targets Note To specify directory locations, use mapped network drives instead of UNC paths. UNC paths cause build errors with compilers that do not support them. Create a Configuration When you click New, the new configuration inherits values and behavior from the current configuration. To create a configuration for the Intel Compiler, clone a configuration from any of these configurations: msvs_host, mingw_host and gcc_target. Note The linker used by the Intel Compiler uses the Microsoft Visual Studio tool chain and therefore the execution environment must have access to these tools (vcvars.bat). For more information, see “Working with Microsoft® Visual Studio®” on page 25-24. Open the XMakefile User Configuration UI by typing xmakefilesetup at the MATLAB prompt. This action displays the following dialog box. Select an existing configuration, such as msvs_host, mingw_host, montavista_arm or gcc_target. Click the New button. 25-26 Makefiles for Software Build Tool Chains A pop-up dialog prompts you for the name of the new configuration. Enter intel_compiler and click OK. The dialog box displays a new configuration called intel_compiler, based on the previous configuration. Modify the Configuration Adjust the compiler, linker, and archiver settings of the newly created configuration. This example assumes the location of the Intel compiler is C:\Program Files\Intel\Compiler\. Make Utility. You do not need to make any changes. This configuration uses the gmake tool that ships with MATLAB. 25-27 25 Project and Build Configurations for Desktop Targets Compiler. For Compiler, enter the location of icl.exe in the Intel installation. Linker. For Linker, enter the location of the linker executable, xilink.exe. For Arguments, add the /LIBPATH path to the Intel libraries. 25-28 Makefiles for Software Build Tool Chains Archiver. For Archiver, enter the location of the archiver, xilib.exe. Confirm that File extensions for library files includes .lib. Other tabs. For this example, ignore the remaining tabs. In other circumstances, you can use them to configure additional build actions. In a later step of this example, you will configure the software to automatically build and run the generated code. 25-29 25 Project and Build Configurations for Desktop Targets Test the Configuration Open the “sumdiff” model by entering sumdiff on the MATLAB prompt. Use a Target Preferences block to configure the model for use with the Eclipse IDE. In the Simulink Library Browser, search for “Target Preferences”. Drag and drop the Target Preferences block from the search results to the summdiff model. 25-30 Makefiles for Software Build Tool Chains Configure the Target Preferences block as follows: set IDE/Tool Chain to Eclipse, set Board to Custom, and set Processor to Intel x86/Pentium. Open the Target Preferences block and set Operating System to None or select Windows. Click OK. Open the Configuration Parameters for the summdiff model by pressing Ctrl+E. Set Build format to Makefile and Build action to Build_and_execute. Save the model to a temporary location, such as C:\Temp\IntelTest\. Set that location as a Current Folder by typing cd C:\temp\IntelTest\ at the MATLAB prompt. Build the model by pressing Ctrl+B. The MATLAB Command Window displays something like: ### TLC code generation complete. ### Creating HTML report file sumdiff_codegen_rpt.html ### Creating project: c:\temp\IntelTest\sumdiff_eclipseide\sumdiff.mk ### Project creation done. ### Building project... ### Build done. ### Downloading program: c:\temp\IntelTest\sumdiff_eclipseide\sumdiff ### Download done. A command window comes up showing the running model. Terminate the generated executable by pressing Ctrl+C. XMakefile User Configuration Dialog Box • “Active” on page 25-32 • “Make Utility” on page 25-34 • “Compiler” on page 25-34 • “Linker” on page 25-35 • “Archiver” on page 25-35 25-31 25 Project and Build Configurations for Desktop Targets • “Pre-build” on page 25-36 • “Post-build” on page 25-36 • “Execute” on page 25-37 • “Tool Directories” on page 25-37 Active Template. Select the template that matches your toolchain and processor. The template defines the syntax rules for writing the contents of the makefile or buildfile. The default template is gmake, which works with the GNU make utility. To add templates to this parameter, save them as .mkt files to the location specified by the User Templates parameter. For more information, see “User Templates” on page 25-33. Configuration. Select the configuration that best describes your toolchain and target processor. You cannot edit or delete the configurations provided by MathWorks. You can, however, edit and delete the configurations that you create. Use the New button to create an editable copy of the currently selected configuration. 25-32 Makefiles for Software Build Tool Chains Use the Delete button to delete a configuration you created. Note You cannot edit or delete the configurations provided by MathWorks. Note Use mapped network drives instead of UNC paths to specify directory locations. Using UNC paths with compilers that do not support them causes build errors. Display operational configurations only. When you open the XMakefile User Configuration dialog box, the software verifies that each configuration provided by MathWorks contains valid paths to the executable files it uses. If all of the paths are valid, the configuration is operational. If any of the paths are not valid, the configuration is not operational. This setting only affects configurations provided by MathWorks, not configurations you create. To display valid configurations, select Display operational configurations only. To display all of the configurations, including non-operational configurations, clear Display operational configurations only. For more information, see “Making an XMakefile Configuration Operational” on page 25-24. User Templates. Set the path of the folder to which you can add template files. Saving templates files with the .mkt extension to this folder adds them to the Templates options. User Configurations. Set the location of configuration files you create with the New button. 25-33 25 Project and Build Configurations for Desktop Targets Make Utility Make utility. Set the path and filename of the make utility executable. Arguments. Define the command-line arguments to pass to the make utility. For more information, consult the third-party documentation for your make utility. Optional include. Set the path and file name of an optional makefile to include. Compiler Compiler. Set the path and file name of the compiler executable. Arguments. Define the command-line arguments to pass to the compiler. For more information, consult the third-party documentation for your compiler. Source. Define the file name extension for the source files. Use commas to separate multiple file extensions. Header. Define the file name extension for the header files. Use commas to separate multiple file extensions. Object. Define the file name extension for the object files. 25-34 Makefiles for Software Build Tool Chains Linker Linker. Set the path and file name of the linker executable. Arguments. Define the command-line arguments to pass to the linker. For more information, consult the third-party documentation for your linker. File extensions for library files. Define the file name extension for the file library files. Use commas to separate multiple file extensions. Generated output file extension. Define the file name extension for the generated libraries or executables. Archiver Archiver. Set the path and file name of the archiver executable. Arguments. Define the command-line arguments to pass to the archiver. For more information, consult the third-party documentation for your archiver. Generated output file extension. Define the file name extension for the generated libraries. 25-35 25 Project and Build Configurations for Desktop Targets Pre-build Enable Prebuild Step. Select this check box to define a prebuild tool that runs before the compiler. Prebuild tool. Set the path and file name of the prebuild tool executable. Arguments. Define the command-line arguments to pass to the prebuild tool. For more information, consult the third-party documentation for your prebuild tool. Post-build Enable Postbuild Step. Select this check box to define a postbuild tool that runs after the compiler or linker. Postbuild tool. Set the path and file name of the postbuild tool executable. Arguments. Define the command-line arguments to pass to the postbuild tool. For more information, consult the third-party documentation for your postbuild tool. 25-36 Makefiles for Software Build Tool Chains Execute Use Default Execute Tool. Select this check box to use the generated derivative as the execute tool when the build process is complete. Uncheck it to specify a different tool. The default value, echo, simply displays a message that the build process is complete. Note On the Linux operating system, multirate multitasking executables require root privileges to schedule POSIX threads with real-time priority. If you are using makefiles to build multirate multitasking executables on your Linux development system, you cannot use Execute tool to run the executable. Instead, use the Linux command, sudo, to run the executable. Execute tool. Set the path and file name of the execute tool executable or built-in command. Arguments. Define the command-line arguments to pass to the execute tool. For more information, consult the third-party documentation for your execute tool. Tool Directories 25-37 25 Project and Build Configurations for Desktop Targets Installation. Use the Tool Directories tab to change the toolchain path of an operational configuration. For example, if you installed two versions of a vendor build tool in separate folders, you can use the Installation path to change which one the configuration uses. 25-38 26 Verification Code Generated for Desktop Targets Verify and profile generated code executing on processors 26 Verification Code Generated for Desktop Targets Processor-in-the-Loop (PIL) Simulation In this section... “Overview” on page 26-2 “PIL Approaches” on page 26-3 “Communications” on page 26-8 “Running Your PIL Application to Perform Simulation and Verification” on page 26-11 “Definitions” on page 26-11 “PIL Issues and Limitations” on page 26-12 Overview Processor-in-the-loop (PIL) requires an Embedded Coder license. Verification consists broadly of running generated code on a processor and verifying that the code does what you intend. Embedded Coder provides processor-in-the-loop (PIL) simulation to meet this need. PIL compares the numeric output of your model under simulation with the numeric output of your model running as an executable on a target processor. With PIL, you run your generated code on a target processor or instruction set simulator. To verify your generated code, you compare the output of model simulation modes, such as Normal or Accelerator, with the output of the generated code running on the processor. You can switch between simulation and PIL modes. This flexibility allows you to verify the generated code by executing the model as compiled code in the target environment. You can model and test your embedded software component in Simulink and then reuse your regression test suites across simulation and compiled object code. This process avoids the time-consuming process of leaving the Simulink software environment to run tests again on object code compiled for the production hardware. Embedded Coder supports the following PIL approaches: • Model block PIL 26-2 Processor-in-the-Loop (PIL) Simulation • Top-model PIL • PIL block When you use makefiles with PIL, use the “model block PIL” approach. With makefiles, the other two approaches, “top-model PIL” and “PIL block”, and are not supported. Processor-in-the-loop (PIL) builds and uses a MEX function to run the PIL simulation block. Before using PIL, set up a compiler for MATLAB to build the MEX files. Run the command |mex -setup| to select a compiler configuration. For more information, read “Build MEX-Files” PIL Approaches Model Block PIL Use model block PIL to: • Verify code generated for referenced models (model reference code interface). • Provide a test harness model (or a system model) to generate test vector or stimulus inputs. • Switch a model block between normal, SIL, or PIL simulation modes. To perform a model block PIL simulation, start with a top-model that contains a model block. The top-model serves as a test harness, providing inputs and outputs for the model block. The model block references the model you plan to run on a target processor. During PIL simulation, the referenced model runs on the target processor. For more information about using the model block, see Model Variants and “Model Reference”. By default, your MathWorks software uses the IDE debugger for PIL communications with the target processor. To achieve faster communications, consider using one alternatives presented in “Communications” on page 26-8. To use model block PIL: 26-3 26 Verification Code Generated for Desktop Targets 1 Right-click the Model block, and select ModelReference Parameters. 2 When the software displays the Function Block Parameters: Model dialog box, set Simulation mode to Processor-in-the-loop (PIL) and click OK. 3 Open the model block. 4 Add a Target Preferences block to either model, and configure it for the target processor. 5 Copy the Target Preferences block from one model to the other. The top-model and the model block now contain identical Target Preference blocks. 6 In the referenced model (model block) Configuration Parameters (Ctrl+E), under Code Generation > IDE Link, set Build action set to Archive_library. This action avoids a warning when you start the simulation. 7 Save the changes to both models. 8 In the top-model menu bar, select Simulation > Run. This action builds the referenced model in the model block, downloads it to your target processor, and runs the PIL simulation. Note In the top-model Configuration Parameters (Ctrl+E), under Code Generation > IDE Link, leave Build action set to Build_and_execute. Do not change Build action to Create_Processor_In_the_Loop_Project. Top-Model PIL Use top-model PIL to: • Verify code generated for a top-model (standalone code interface). • Load test vectors or stimulus inputs from the MATLAB workspace. • Switch the entire model between normal and SIL or PIL simulation modes. 26-4 Processor-in-the-Loop (PIL) Simulation Setting Model Configuration Parameters to Generate the PIL Application. Configure your model to generate the PIL executable from your model: 1 Add a Target Preferences block in to your model. The Target Preferences block is located in the Simulink library browser under Simulink Coder > Desktop Targets. 2 Open the Target Preferences block and select your processor from the list of processors. 3 From the model toolstrip, select Simulation > Model Configuration Parameters. 4 In Configuration Parameters, select Code Generation. 5 Set System Target File to idelink_ert.tlc. 6 From the list of panes under Code Generation, choose IDE Link. 7 Set Build format to Project. 8 Set Build action to Create_processor_in_the_loop_project. 9 Click OK to close the Configuration Parameters dialog box. For more information, see “Code Generation Pane: IDE Link”. Running the Top-Model PIL Application. To create a PIL block, perform the following steps: 1 In the model toolstrip, set the Simulation mode to Processor-in-the-loop. 26-5 26 Verification Code Generated for Desktop Targets 2 In the model toolstrip, click Run . A new Simulink Editor opens with the new PIL model block in it. The third-party IDE compiles and links the PIL executable file. Follow the progress of the build process in the MATLAB command window. PIL Block Use the PIL block to: • Verify code generated for a top-model (standalone code interface) or subsystem (right-click build standalone code interface). • Represent a component running in SIL or PIL mode. The test harness model or a system model provides test vector or stimulus inputs. Preparing Your Model to Generate a PIL Block. Start with a model that contains the algorithm blocks you want to verify on the processor as compiled object code. To create a PIL application and PIL block from your algorithm subsystem, follow these steps: 1 Identify the algorithm blocks to cosimulate. 2 Convert those blocks into an unmasked subsystem in your model. For information about how to convert your process to a subsystem, refer to Creating Subsystems in Using Simulink or in the online Help system. 3 Open the newly created subsystem and copy a Target Preferences block to it. The Target Preferences block is located in the Simulink library browser under Simulink Coder > Desktop Targets. Open the Target Preferences block and select your processor from the list of processors. 26-6 Processor-in-the-Loop (PIL) Simulation Setting Model Configuration Parameters to Generate the PIL Application. After you create your subsystem, set the Configuration Parameters for your model to enable the model to generate a PIL block. Configure your model to enable it to generate PIL algorithm code and a PIL block from your subsystem: 1 From the model menu bar, select Simulation > Model Configuration Parameters. This action opens the Configuration Parameters dialog box. 2 In the Configuration Parameters dialog box, select Code Generation. 3 Set System Target File to idelink_ert.tlc. 4 From the list of panes under Code Generation, choose IDE Link. 5 Set Build format to Project. 6 Set Build action to Create_processor_in_the_loop_project. 7 Click OK to close the Configuration Parameters dialog box. For more information, see “Code Generation Pane: IDE Link”. Creating the PIL Block from a Subsystem. To create a PIL block, perform the following steps: 1 Right-click the masked subsystem in your model and select C/C++ Code > Build This Subsystem from the context menu. A new Simulink Editor opens and the new PIL block appears in it. The third-party IDE compiles and links the PIL executable file. This step builds the PIL algorithm object code and a PIL block that corresponds to the subsystem, with the same inputs and outputs. Follow the progress of the build process in the MATLAB command window. 2 Copy the new PIL block from the new model to your model. To simulate the subsystem processes concurrently, place it parallel to your masked subsystem. Otherwise, replace the subsystem with the PIL block. 26-7 26 Verification Code Generated for Desktop Targets To see a PIL block in a parallel masked subsystem, search the product help for Getting Started with Application Development and select the example that matches your IDE. Note Models can have multiple PIL blocks for different subsystems. They cannot have more than one PIL block for the same subsystem. Including multiple PIL blocks for the same subsystem causes errors and inaccurate results. Communications • “TCP/IP” on page 26-9 • “IDE Debugger” on page 26-10 Chose one of the following communication methods for transferring code and data during PIL simulations: Method Speed Comments IDE Debugger Slow TCP/IP Fast • Supports PIL communications with an executable running an embedded target processor. • Supports PIL communications with • Supports the largest number of an executable running on a Linux or targets. Windows host. • Requires a physical connection • Supports embedded targets running between host and target processor. Linux, TI DSP/BIOS, and Wind River • VxWorks. Only works with builds from IDE projects. Does not work with builds • Requires network connection between from makefiles. host and target processor. • Works with builds from IDE projects and from makefiles. Serial Communication Interface (SCI) 26-8 Fast • Supports PIL communications with an executable running an embedded target processor. Processor-in-the-Loop (PIL) Simulation Method Speed Comments • Supports only TI C28035 and C28335 microcontrollers. • Requires an SCI connection between host and target processor. • Works with builds from IDE projects and from makefiles. TCP/IP You can use TCP/IP for PIL communications with a hardware target running: • Linux • Microsoft Windows Using TCP/IP for PIL communications is typically faster than using a debugger, particularly for large data sets, such as with video and audio applications. You can use TCP/IP with the following PIL approaches: • Top-model PIL • Model block PIL TCP/IP does not work with the Subsystem PIL approach. To enable and configure TCP/IP with PIL: 1 Set up a PIL simulation according to the PIL approach you have chosen. 2 In the MATLAB Command Window, use setpref to specify the IP address of the PIL server (servername). If you are running the PIL server on a remote target, specify the IP address of the target processor. For example: setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','servername','144.212.109.114'); 26-9 26 Verification Code Generated for Desktop Targets If you are running PIL server locally, on your host Windows or Linux system, enter 'localhost' instead of an IP address: setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','servername','localhost'); 3 Specify the TCP/IP port number to use for PIL data communication. Use one of the free ports in your system. For example: setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','portnum', 17025); 4 Enable PIL communications over TCP/IP: setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','enabletcpip', true); To disable PIL communications over TCP/IP, change the value to false. This action automatically enables PIL communications over an IDE debugger, if an IDE is available. 5 Open the Target Preferences block in your model, then set the Operating System parameter to an operating system. Note You cannot use TCP/IP for PIL when the value of Operating System is None. 6 Regenerate the code or PIL block. To disable PIL communications over TCP/IP, enter: setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','enabletcpip', false); IDE Debugger To enable PIL communications over an IDE debugger, disable PIL communications over TCP/IP and SCI by entering the following commands: setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','enabletcpip',false); setpref('MathWorks_Embedded_IDE_Link_PIL_Preferences','enableserial',false); Then regenerate the code or PIL block. 26-10 Processor-in-the-Loop (PIL) Simulation Using IDE debugger for PIL communication only works when you build your code from IDE projects. Using IDE debugger for PIL communication does not work with builds from makefiles. Running Your PIL Application to Perform Simulation and Verification After you add your PIL block to your model, click Simulation > Run or press Ctrl+T to run the PIL simulation and view the results. Definitions PIL Algorithm The algorithmic code, which corresponds to a subsystem or portion of a model, to test during the PIL simulation. The PIL algorithm is in compiled object form to enable verification at the object level. PIL Application The executable application that runs on the processor platform. Your coder product creates a PIL application by augmenting your algorithmic code with the PIL execution framework. The PIL execution framework code compiles as part of your embedded application. The PIL execution framework code includes the string.h header file so that the PIL application can use the memcpy function. The PIL application uses memcpy to exchange data between the Simulink model and the simulation processor. PIL Block When you build a subsystem from a model for PIL, the process creates a PIL block optimized for PIL simulation. When you run the simulation, the PIL block acts as the interface between the model and the PIL application running on the processor. The PIL block inherits the signal names and shape from the source subsystem in your model. Inheritance is convenient for copying the PIL block into the model to replace the original subsystem for simulation. 26-11 26 Verification Code Generated for Desktop Targets PIL Issues and Limitations Consider the following issues when you work with PIL blocks. Constraints When using PIL in your models, keep the following constraints in mind: • Models can have multiple PIL blocks for different subsystems. They cannot have more than one PIL block for the same subsystem. Including multiple PIL blocks for the same subsystem causes errors and inaccurate results. • A model can contain a single model block running PIL mode. • A model can contain a subsystem PIL block or a model block in PIL mode, but not both. Generic PIL Issues Refer to PIL Feature Support and Limitations for general information about using the PIL block with embedded link products. Simulink Coder grt.tlc-Based Targets Not Supported PIL does not support grt.tlc system target files. To use PIL, set System target file in the Configuration Parameters > Code Generation pane to idelink_ert.tlc. 26-12 27 Working with Eclipse IDE • “Installing Third-Party Software for Eclipse” on page 27-2 • “Configuring Your MathWorks Software to Work with Eclipse” on page 27-10 • “Troubleshooting with Eclipse IDE” on page 27-14 Note To use the coder product with Eclipse IDE, complete the steps in “Installing Third-Party Software for Eclipse” on page 27-2 and “Configuring Your MathWorks Software to Work with Eclipse” on page 27-10 27 Working with Eclipse™ IDE Installing Third-Party Software for Eclipse In this section... “Tested Software Versions” on page 27-2 “Installing Sun Java Runtime Environment (JRE)” on page 27-3 “Installing Eclipse IDE for C/C++ Developers” on page 27-5 “Verifying the GNU Tool Chain on Linux Host” on page 27-6 “Installing the GNU Tool Chain on Windows” on page 27-7 Tested Software Versions MathWorks has tested the coder product with the specific software versions listed in the following tables. 27-2 Required for all platforms Tested Versions Sun™ Java™ Runtime Environment (JRE) JRE 6.0 (Java 1.6.x) Eclipse IDE for C/C++ Developers package, which includes the CDT feature Ganymede (Eclipse 3.4) CDT (If CDT is installed separately from Eclipse IDE for C/C++ Developers package, match CDT version with Eclipse version.) CDT 5.0 Linux: Additional Software Required Tested Versions GNU GCC (compiler) GCC 4.4 GNU as (assembler — part of the GNU binutils package) as 2.18 Installing Third-Party Software for Eclipse™ Linux: Additional Software Required Tested Versions GNU ar (archiver — part of the GNU binutils package) ar 2.18 GNU GDB (debugger) GDB 6.8.x GNU make make 3.81 Windows: Additional Software Required Tested Versions MinGW 5.1.x GDB GDB 6.3.x MSYS 1.0.11 You can try untested versions and combinations of third-party software at your own risk. For the most current information about using the coder product software with Eclipse IDE, see: www.mathworks.com/products/simulink-coder/eclipse-adaptor.html Installing Sun Java Runtime Environment (JRE) To install the JRE, complete the following steps: 1 At your Windows or Linux command prompt, enter: java -version If Java is present, the command line responds with the version information, as this example shows. 2 If Java is missing or the version is lower than 1.6.x, download and install JRE 6.0 from http://www.java.com. 27-3 27 Working with Eclipse™ IDE 3 Get the path of the Java JRE by entering which java on the command line. 4 Set the PATH system variable in your operating system. For example, in Windows 7: a Press the Windows key and search for “System environment variables” and open “Edit the system environment variables”. b In System Properties, to go Advanced and click Environment Variables. c In the System variables, locate and select “Path”. d Click the Edit button and add the path of the Java JRE to the Variable value. For example , add C:\Program Files\Java\jre6\bin; to the Variable value. e Click OK to save your changes. For example, with Linux: a Open a startup file, such as ~/ .cshrc. b Add the path of the Java JRE to the PATH variable. For example, on a 64-bit Linux host computer, if you are using csh or tcsh, enter: setenv PATH $PATH:/local/MATLAB/R2011b/sys/java/jre/glnxa64/jre/bin For example, on a 64-bit Linux host computer, if you are using sh, ksh, or bash, enter: PATH=$PATH:/local/MATLAB/R2011b/sys/java/jre/glnxa64/jre/bin ; export PATH c Save your changes and close the file. For more information, see http://www.java.com/en/download/help/path.xml. 5 Verify that Java is working by entering java -version again or by visiting http://www.java.com/en/download/help/testvm.xml. 27-4 Installing Third-Party Software for Eclipse™ Installing Eclipse IDE for C/C++ Developers Note The following instructions are based on Eclipse 3.4 (Ganymede). More recent versions of the Eclipse IDE can have different appearances, menus, or software package names. The Eclipse IDE for C/C++ Developers package includes the Eclipse IDE and the C/C++ Development Tools (CDT). To install Eclipse IDE for C/C++ Developers package, complete the following steps: 1 Download the Ganymede SR2 zip file for Eclipse IDE for C/C++ Developers, from http://www.eclipse.org/downloads/packages/release/ganymede/sr2. 2 Extract the Eclipse files to a permanent location, such as C:\eclipse\ and create a desktop shortcut to eclipse.exe. 3 Start Eclipse, and select Help > Software Updates. 4 Look under the Installed Software tab, and verify that Eclipse has the following three CDT software packages. • Eclipse C/C++ Development Platform • Eclipse C/C++ Development Tools • Mylin Bridge: C/C++ Development If you have a previous Eclipse installation that does not include CDT, complete the following steps: 1 In Eclipse, select Help > Software Updates. 2 Click the Available Software tab. 3 Click Ganymede Update Site. 4 Select C and C++ Development, and click Install. 5 When the installation process completes, click the Installed Software tab, and verify that you have CDT. 27-5 27 Working with Eclipse™ IDE Verifying the GNU Tool Chain on Linux Host Most Linux distributions include the following GNU C/C++ development tools. Eclipse and CDT require these tools to compile code, build projects, and debug applications: • Assembler (as) • Archiver (ar) • compiler and linker (gcc) • debugger (gdb) • build utility (make) Verify that the GNU tools are present and set the tool chain path: 1 On the Linux command line, enter: • gcc --version • gdb --version • as --version • ar --version • make --version 2 Compare the version of each tool with the following list of tested versions: • gcc 4.4 • as 2.18 • ar 2.18 • gdb 6.8.x • make 3.81 If you are using Eclipse for targeting embedded Linux, disregard the version numbers in the preceding list. To install a missing tool or to change the version of the tool, use the software installation manager that comes with your Linux distribution. 27-6 Installing Third-Party Software for Eclipse™ Alternatively, visit http://directory.fsf.org/GNU/ for more information about individual tools. Source files for the tools are available from: • binutils (includes as and ar), http://ftp.gnu.org/gnu/binutils/ • gcc, http://ftp.gnu.org/gnu/gcc/ • gdb, http://ftp.gnu.org/gnu/gdb/ • make, http://ftp.gnu.org/gnu/make/ 3 Modify the PATH environment using the right commands for your running shell. You can also modify the path environment variable in your login scripts. If you are using a Bash shell prompt, enter: PATH=my_tool_path:$PATH Where my_tool_path is the path to the GNU tool binaries. For example: PATH=/bin:$PATH If you are using a C shell prompt, enter: setenv PATH my_tool_path:$PATH Where my_tool_path is the path to the GNU tool binaries. For example: setenv PATH /bin:$PATH Installing the GNU Tool Chain on Windows Windows typically does not include GNU C/C++ development tools. Eclipse and CDT require these tools to compile code, build projects, and debug applications. Provide a GNU tool chain for Windows by installing MinGW: 1 Open http://sourceforge.net/projects/mingw/files/. 2 Download and run the latest version of the “Automated MinGW Installer". 27-7 27 Working with Eclipse™ IDE Note The earliest version of MinGW available is more recent than the tested version. 3 Start the MinGW installation wizard to perform a default installation. Perform a default installation until you reach Select Components. At that step, select MSYS Basic System. Then, complete the default installation process. Wait for the installation wizard to download, and install additional files from the Internet. Note If you alter the default installation path, C:/MinGW, do not use spaces in the new path. Set the PATH environment variable: 1 In Windows, right-click My Computer or Computer, and choose Properties. 2 Then select Advanced or Advanced system settings, and click Environment Variables. 3 Under System variables, scroll down to the Path variable. 4 Select Path, and click Edit. 5 Configure the operating system to the GNU tools when there are multiple paths: a Add the paths of the MinGW and MSYS bin folders to the beginning of the Variable value. b Use semicolons to separate the paths. For example, C:\mingw\bin;C:\mingw\msys\1.0\bin; 27-8 Installing Third-Party Software for Eclipse™ 6 To verify the GNU tools installation and path settings, enter the following commands on the Windows command line: • gcc --version • gdb --version • as --version • ar --version • make --version Each command displays the tool name and version on the command line. If you receive a message that the command is not recognized, verify that you completed the preceding installation and path configuration instructions. You can use versions of the GNU tools that are more recent than the tested versions at your own risk. 27-9 27 Working with Eclipse™ IDE Configuring Your MathWorks Software to Work with Eclipse After you install the third-party software, configure the coder product to work with Eclipse: 1 Close Eclipse IDE before you run eclipseidesetup. For more information, see “Build Errors” on page 27-15. 2 in the MATLAB Command Window, enter eclipseidesetup. The coder product opens the “IDE Link: Eclipse Adaptor Setup” dialog box, as shown here on Windows: Note On Linux, the “IDE Link: Eclipse Adaptor Setup” dialog box shows different options than on Windows 3 Update Executable with the location and file name of the Eclipse application file. For example, C:\eclipse\eclipse.exe. 27-10 Configuring Your MathWorks® Software to Work with Eclipse™ You can get this value by right-clicking a shortcut for Eclipse and looking at the properties. 4 Update Workspace with the default location where Eclipse creates and saves new project files. For example, C:\WINNT\Profiles\username\workspace. To find the current workspace, open Eclipse and select File > Switch Workspace > Other. In the future, if you change the Eclipse workspace, repeat this configuration procedure. Do not use workspace paths that contain spaces. If you have a path with spaces, recreate the workspace, and then update the path in Eclipse. 5 For Port number, enter a valid, unused, IP port number. For example, 5555. 6 For Site, identify where the coder product uploads and runs the executable file upon completing the build process. Use either of these options: • Choose local to run the executable on your Linux or Windows workstation. This option requires the Simulink Coder product. • Choose remote to download the executable to a remote target running Linux operating system over a network connection (for example, to connect to an embedded system connection to the Ethernet port on your workstation). This option requires the Embedded Coder product. You must perform additional steps to connect to a remote target running Linux. See . Note Later on, when you are working on your model, open the Target Preferences block, and set Processor to match the processor at the Site you selected. 27-11 27 Working with Eclipse™ IDE 7 To customize the Tool Chain settings, see the Custom GCC/GDB topic. 8 When you click OK or Apply, the coder product: • Verifies the locations of the Executable and Workspace in the Eclipse Adaptor Setup dialog box. • Verifies that the required third-party software is present. • Installs the coder product plug-ins in the Eclipse plugins folder. For example, in C:\Program Files\eclipse\plugins\. • Saves configuration information to the mwidelink.ini file, located in the Eclipse plugins folder. Note When Eclipse starts, it loads the coder product plug-in. The coder product plug-in loads the port number from mwidelink.ini. To resolve a port number conflict, change the port number by running eclipseidesetup again. Do not edit mwidelink.ini. 9 To verify that the configuration process is complete, create a handle object for the Eclipse IDE. Enter the following command in MATLAB IDE_Obj = eclipseide This command, starts Eclipse IDE if it is not already running, and creates a handle object. For example: Starting Eclipse(TM) IDE... ECLIPSEIDE Object: Default timeout : Eclipse folder : Eclipse workspace: Port number : Processor site : 10.00 secs C:\eclipse3.4\eclipse C:\WINNT\Profiles\rolfedh\workspace 5555 local If you are using more recent versions of the GNU tools, you can disregard command-line warnings about using untested versions. 10 In Eclipse, click the following icon to see the status of the IDE Link plug-in. 27-12 Configuring Your MathWorks® Software to Work with Eclipse™ 27-13 27 Working with Eclipse™ IDE Troubleshooting with Eclipse IDE In this section... “SIGSEGV Segmentation Fault for GDB” on page 27-14 “GDB Stops on Each Semaphore Post” on page 27-14 “Build Errors” on page 27-15 “Profiling Not Available for Intel x86/Pentium and AMD K5/K6/Athlon Processors Running Windows or Linux Operating Systems” on page 27-15 “Eclipse Message: “Can’t find a source file”” on page 27-15 “Eclipse Message: “Cannot access memory at address”” on page 27-16 “Some Versions of Eclipse CDT Do Not Catch GCC Errors” on page 27-16 SIGSEGV Segmentation Fault for GDB If you use Comodo Internet Security (CIS) software on your development system, CIS causes a SIGSEGV segmentation fault for GDB. When this fault occurs, you receive the following message: Debugger name and version: GNU gdb (GDB) 7.0 Program received signal SIGSEGV, Segmentation fault. In ntdll!RtlpWaitForCriticalSection () (C:\WINDOWS\system32\ntdll.dll) Continuing... Program received signal SIGSEGV, Segmentation fault. In ?? () (C:\WINDOWS\system32\guard32.dll) If you get this message, click OK and then click Continue. For more information, see the “Guard32.dll causes SIGSEGV segmentation fault for GDB debugger CIS 3.9.95478 x32” topic at http://forums.comodo.com/. GDB Stops on Each Semaphore Post If you use gdb to debug a target application running on Linux or Windows, gdb stops on each semaphore post. You can override this expected behavior adding the following text to .gdbinit, the GDB init file: 27-14 Troubleshooting with Eclipse™ IDE handle SIG34 nostop noprint pass handle SIG35 nostop noprint pass On Linux, .gdbinit resides on your home folder, by default. On Windows, the environment variable HOME defines the home folder. For more information about creating .gdbinit and configuring gdb, consult the GDB User Manual, available from http://www.gnu.org/software/gdb/documentation/. Build Errors If you use eclipseidesetup without closing Eclipse IDE, you may get build errors similar to the following ones: The call to idelink_ert_make_rtw_hook, during the exit hook generated the following error: Error while creating the project. The build process will terminate as a result. === Error while creating the project. === Error creating a new project. === An exception occurred while performing this operation. 0 To solve this problem, close and restart Eclipse IDE. Profiling Not Available for Intel x86/Pentium and AMD K5/K6/Athlon Processors Running Windows or Linux Operating Systems Profiling is not available for Intel x86/Pentium and AMD K5/K6/Athlon processors running Windows or Linux. Eclipse Message: “Can’t find a source file” With specific Configuration Parameters, while building and loading a target application, Eclipse IDE displays a message that it could not find a source file. This message appears even if the load action completes. Here is an example of the message: 27-15 27 Working with Eclipse™ IDE Can't find a source file at "../../sumdiff_bash_eclipseide/sumdiff_bash_main.c Locate the file or edit the source lookup path to include its location. In Configuration Parameters, on the IDE Link pane, in the Vendor Tool Chain section: If Configuration is set to Release or Custom, the coder product does not specify the -g compiler option for gcc. Therefore, the build process does not produce debugging information gdb requires. Without this information, gdb cannot map the executable to the source file, resulting in the "Can’t find a source file” message. To solve this problem, add -g to the Compiler options string for the Custom and Release configurations, or set Configuration to Debug. Eclipse Message: “Cannot access memory at address” If you use the coder product’s halt method to stop the target application, Eclipse displays a message similar to the following example: [Switching to thread 5528.0x1664] Quit (expect signal SIGINT when the program is resumed) Cannot access memory at address 0x720000 Cannot access memory at address 0x720000 This error is not related to Eclipse IDE. It is a bug with gdb/MinGW. It typically occurs when gdb tries to access an invalid or protected memory location. Some Versions of Eclipse CDT Do Not Catch GCC Errors If you set a bad compiler flag, specific versions of Eclipse CDT prior to version 7.0.2 fail to catch gcc errors that the flag is wrong. To reproduce this problem: 1 Open a project and select C/C++ Build > Tool Chain Editor. 27-16 Troubleshooting with Eclipse™ IDE 2 Set Current builder to CDT Internal Builder. 3 Select Project properties > C/C++ Build > Settings. 4 Set GCC C Compiler: Miscellaneous to -D. 5 Build the project. Notice that gcc displays the following error while the Problems tab for the Eclipse IDE project does not display any errors: : error: macro names must be identifiers 27-17 27 27-18 Working with Eclipse™ IDE 28 Working with Linux Target • “Disambiguation” on page 28-2 • “Preparing Models to Run on Linux Target” on page 28-3 • “Scheduler” on page 28-4 28 Working with Linux® Target Disambiguation This documentation uses the term “Linux” generically to refer to: • Linux running on a host computer • Linux running on an target processor If the distinction between host and target is important, the documentation will identify the hardware platform on which Linux is running. For example: • “Embedded Linux” or “Linux running on a target processor” • “Linux running on a host computer.” 28-2 Preparing Models to Run on Linux® Target Preparing Models to Run on Linux Target To build an executable that runs on Linux, perform the following steps: 1 Install and configure Eclipse IDE according to the instructions in “Working with Eclipse IDE”. 2 Locate the Target Preferences block in the Simulink Library Browser, under Simulink Coder > Desktop Targets. 3 Copy the Target Preferences block to your model. 4 In the Initialize Configuration Parameters dialog box, set the IDE to Eclipse, and select the processor for which you are generating code. 5 Set Operating System to Linux. This action creates a Linux tab for setting the Scheduling Mode and Base Rate Priority. 6 Set the Scheduling Mode to one of these options: • If you select real-time, the model uses a timer to trigger the base rate at regular periods. • If you select free-running, the model does not use a timer. Instead, the model completes each process or thread before running the next one. 7 For Linux, you can set the Base Rate Priority relative to other processes and threads. You can enter values from (the number of rates + 1) to 99. 8 In IDE Link, configure the model to build and execute: a In the model, select Simulation > Model Configuration Parameters. b Under Code Generation, select the IDE Link pane. c Set Build action to Build and execute. 9 Click Build Model on the model toolstrip. After the build completes, Embedded Coder software downloads the executable to the remote system and runs it. 28-3 28 Working with Linux® Target Scheduler In this section... “Base Rate” on page 28-4 “Running Target Applications on Multicore Processors” on page 29-4 “Running Multirate, Multitasking Executables on the Linux Desktop” on page 28-11 “Avoiding Lock-Up in Free-Running, Multirate, Multitasking Models” on page 28-12 Base Rate The base rate in the model maps to a thread and runs as fast as possible. The base rate priority selection in the OS tab allows you to set a static priority for the base rate task. By default, this rate is 40. The process running single-tasking models has Default scheduling policy when model is single-tasking or there is a single rate in the model. Static priority of the process is 0 in this case. Running Target Applications on Multicore Processors Introduction This section provides a variation of the process described in “Build and Download to a Multicore Target”. This section shows you how to: • Configure a multirate model • Generate a multithreaded application from that model So that the resulting application is enabled for concurrent multicore execution on a desktop target running Linux or Windows. 28-4 Scheduler This process uses the idelink_ert.tlc or idelink_grt.tlc system target files, which enable you to: • Use Eclipse IDE to manage projects for Linux and Windows targets (Support for this capability is only available on 32-bit host platforms) • Set thread priority using a Target Preference block Looking at a Model Before setting up your own model, consider the sldemo_concurrent_execution example model, which is referenced by “Build and Download to a Multicore Target”. The sldemo_concurrent_execution model is a useful example to look at because: • The model is partitioned using Model blocks that can potentially execute concurrently. • You can look at the Map Blocks To Tasks pane in the Concurrent Execution window to see how the tasks are configured for concurrent execution. However, you cannot run an unmodified version of the sldemo_concurrent_execution model on a desktop target running Linux or Windows. To prepare the sldemo_concurrent_execution as an example model for the “Setting Up the Model” on page 29-7 and “Deploying the Model to Your Target” on page 29-8 topics, first perform the following modifications: • Update the Plant Model Block • Update the Compensator Model Block • Verify that Models are Mapped These procedures guide you through the processes of discretizing models and matching sample times of blocks with models. 28-5 28 Working with Linux® Target Update the Plant Model Block. 1 In the sldemo_concurrent_execution model, open the “Plant” Model block: sldemo_concurrent_execution_plant 2 Discretize the Plant model. Replace the Integrator blocks, “x1” and “x2”, with equivalent discrete time blocks (such as the Discrete Time Integrator block) or use the “Model Discretizer”. 3 Prevent modeling constraints by matching the sample time of the “x1” and “x2” blocks with the model: Open the “x1” and “x2” blocks and change the Sample time parameters to 0.1. Matching the sample times to the model can also be accomplished using Rate Transition blocks. 4 Convert blocks with continuous sample times (Sample time = 0) to inherited sample times (Sample time = -1). Open the “u1”, “u2” and “x” blocks. For each one, click the Signal Attributes tab, then change Sample time to -1. 5 Save your changes to the blocks and the model. Update the Compensator Model Block. 1 In the sldemo_concurrent_execution model, open the “Compensator” Model block: sldemo_concurrent_execution_compensator 2 Discretize the Compensator model. Replace the Integrator block, “c”, with an equivalent discrete time block (such as the Discrete Time Integrator block) or use the “Model Discretizer”. 3 Prevent modeling constraints by matching the sample time of the “c” block with the top model: Open the “c” block and change the Sample time parameters to 0.1. Matching the sample times to the top model, sldemo_concurrent_execution, can also be accomplished using Rate Transition blocks. 4 Convert blocks with continuous sample times (Sample time = 0) to inherited sample times (Sample time = -1). Open the “y1”, “y2”, and “x” blocks. For each one, click the Signal Attributes tab, then change Sample time to -1. 28-6 Scheduler 5 The following parameters cannot both be enabled when you build the model. Open the Configuration Parameters (Ctrl+E) and verify that one of the following parameters is disabled (unchecked): • Minimize algebraic loop occurrences, located on the Model Referencing pane. • Single output/update function, located on the Code Generation > Interface pane 6 Save your changes to the blocks and the model. Verify that the Models are Mapped. Open and inspect the Task editor to see if the models are appropriately mapped: 1 In the Simulink model editor for sldemo_concurrent_execution, select View > Model Explorer (Ctrl + H). 2 In Model Explorer, expand the top model, sldemo_concurrent_execution. 3 Under the top model, select Configuration (Active), then click Concurrent Execution in the second column. In the third column, click the ConfigureTasks and Map Blocks to Tasks button. 4 Click Map Blocks To Tasks. The mapping of the models should conform to the guidelines provided by “Design Considerations”. The sldemo_concurrent_execution example model is ready for you to use in “Setting Up the Model” on page 29-7 and “Deploying the Model to Your Target” on page 29-8. Setting Up the Model This procedure explains how to set up a model for a multicore processor. 1 Apply the recommendations in “Design Considerations” to your multirate Simulink model. Or, refer to the sldemo_concurrent_execution example model. 2 Add a Target Preferences block to your model as described in “Target Preferences” on page 25-3 . 28-7 28 Working with Linux® Target 3 In the Target Preferences block, set Operating System to Linux or Windows. 4 If your model uses a Rate Transition block to transition between rates, then open the Rate Transition block and clear the Ensure deterministic data transfer check box so that the block uses the most recent data available. 5 Configure the model for concurrent execution: a In the Simulink model editor, select View > Model Explorer (Ctrl + H). b In Model Explorer, expand the top model. c Under the top model, right click Configuration (Active) and select Convert to Configuration for Concurrent Execution. (In the sldemo_concurrent_execution example model, this step has already been performed.) 6 For each referenced model in the model hierarchy that you want to run with concurrent execution: a Copy the Target Preferences block from the top model to the referenced model. b Repeat steps 4 through 5. 7 Select the configuration set of the model at the top of the model hierarchy. In the second column, select the Concurrent Execution node. A Concurrent Execution pane appears in the third column. (In the sldemo_concurrent_execution example model, this step has already been performed.) 8 In the Concurrent Execution pane in the third column, select the This is the top of the model hierarchy check box, and click the ConfigureTasks and Map Blocks to Tasks button. (In the sldemo_concurrent_execution example model, this step has already been performed.) 9 The Concurrent Execution configuration parameters dialog box is displayed. Click Apply. 28-8 Scheduler Deploying the Model to Your Target In your model, click the build button or enter Ctrl+B. The software performs the actions you selected for Build action in the Configuration Parameters dialog, on the Code Generation > IDE Link pane. For more information on the structure of the code, please refer to “Build and Download to a Multicore Target”. As mentioned in that section, the coder product generates all target-dependent code for thread creation, thread synchronization, interrupt service routines, and signal handlers and data transfer. For each periodic task, Simulink Coder combines the output and update methods of the blocks mapped to that task and binds these methods to a target-specific thread. Note The idelink_ert.tlc or idelink_grt.tlc system target files do not support Continuous times. Generated Code For idelink_ert.tlc or idelink_grt.tlc system target files, the generated code from a mapped model creates a thread for each task and automatically leverages the threading APIs supported by the operating system running on the target. • If the target platform is running Windows , the generated code will use Windows threads. • If the target platform is running Linux or VxWorks , the generated code will use POSIX® threads (pthreads). The following table summarizes the differences in the generated code between the target platforms. 28-9 28 Working with Linux® Target Aspect of Concurrent Execution Linux Windows Periodic triggering event POSIX timer Windows timer Aperiodic triggering event POSIX real-time signal Windows event Aperiodic trigger For blocks mapped to an aperiodic task: thread waiting for a signal For blocks mapped to an aperiodic trigger: signal action Thread waiting for an event Threads POSIX Windows Thread priority Assigned based on Target Preference Block setting Fixed Example of overrun detection Yes Yes The software checks that data transfer between concurrently executing tasks behave as described in Data Transfer Options. The software checks data transfer using the following APIs on supported targets. API Linux Implementation Windows Implementation Data protection API • pthread_mutex_init • CreateMutex • pthread_mutex_destroy• CloseHandle • pthread_mutex_lock • WaitForSingleObject • pthread_mutex_unlock • ReleaseMutex Synchronization API 28-10 • sem_init • CreateSemaphore • sem_destroy • CloseHandle • sem_wait • WaitForSingleObject • sem_post • ReleaseSemaphore Scheduler Running Multirate, Multitasking Executables on the Linux Desktop In Linux, multirate, multitasking executables require root privileges to schedule POSIX threads with real-time priority. Thus, Eclipse IDE software must have its own root privileges to run the multirate, multitasking executable with root privileges locally on your Linux development system. If all three of the following conditions are true, start Eclipse IDE with root privileges: • Your model produces a multirate, multitasking executable. • Embedded Coder uses the default Configuration Parameters which automatically run the executable. You can verify the Configuration Parameters in the Configuration Parameters dialog box, under Code Generation, select the IDE Link pane. Make sure that the Build format is Project and the Build action is Build_and_execute. • The Eclipse plug-in is using the default settings, which run the executable on the local Linux development system. (During the eclipseidesetup process, you left Site set to local.) If any of the following conditions are true, you do not need to start Eclipse IDE with root privileges: • Your model produces multirate, single-tasking executables or single rate executables. • You are performing a proccesor-in-the-loop (PIL) simulation. • You are using a Windows development platform. • You have configured Embedded Coder and Eclipse to run the executable on a remote Linux target. • You not have configured Embedded Coder and Eclipse to run the executable. 28-11 28 Working with Linux® Target Starting Eclipse IDE with root privileges 1 Install and configure Eclipse IDE according to the instructions in “Working with Eclipse IDE”. 2 If an Eclipse IDE handle object exists in the MATLAB workspace, delete the object. For example, delete IDE_Obj. 3 If Eclipse IDE is running, close it. 4 Open a command-line session, and cd to the Eclipse installation folder. For example, if you installed Eclipse in usr/bin/eclipse, enter: cd usr/bin/eclipse 5 Start Eclipse with root privileges using sudo ./. For example: sudo ./eclipse 6 At the prompt, enter the root password. 7 When Eclipse starts and prompts you for the workspace, enter the same workspace you specified during the Eclipse installation and configuration process. 8 In IDE Link, configure the model to build and execute: a In the model, select Simulation > Model Configuration Parameters. b Under Code Generation, select the IDE Link pane. c Set Build action to Build and execute. 9 Click Build Model on the model toolstrip. This action builds, loads, and runs your code on the processor. When the build process finishes, the multirate, multitasking executable automatically starts and runs with root privileges. Avoiding Lock-Up in Free-Running, Multirate, Multitasking Models This section applies when the following conditions are true: 28-12 Scheduler • The model is a multirate multitasking model • In the Target Preferences block, on the Board pane, the Operating system parameter is set to Linux • In the Target Preferences block, on the Linux pane, the Scheduling Mode parameter is set to free-running Because of the rate monotonic scheduling requirement in Linux, the scheduler runs threads with a SCHED_FIFO scheduling policy. A process scheduled with SCHED_FIFO prevents other process from running while it is ready to run. Therefore, if the model does not contain any blocking peripherals, the entire Linux system can become unresponsive while you are running the generated code. Such lock-up can even preempt the shell window from running. To avoid this lock-up, apply one of the following solutions: • Set Scheduling Mode to real_time. • Include a blocking device driver, such as a UDP block, in your model that suspends running thread while data is not available. • Raise the shell window priority above the base-rate priority so you can kill the process running with SCHED_FIFO class. 28-13 28 28-14 Working with Linux® Target 29 Working with Microsoft Windows Target • “Preparing Models to Run on Windows” on page 29-2 • “Scheduler” on page 29-3 29 Working with Microsoft® Windows® Target Preparing Models to Run on Windows To build an executable that runs on Windows , perform the following steps: 1 Install and configure Eclipse IDE according to the instructions in “Working with Eclipse IDE”. 2 Enter desktoptargetslib at the MATLAB prompt. This action opens the desktoptargetslib library. 3 Copy the Target Preferences block to your model. 4 In the Initialize Configuration Parameters dialog box, set IDE/Toolchain to Eclipse, and select the processor for which you are generating code. 5 Open the Target Preferences block in your model and set Operating System to Windows (or None). Selecting Windows creates a Windows tab, which you can use to set Scheduling Mode. 6 Set the Scheduling Mode to one of these options: • If you select real-time, the model uses a timer to trigger the base rate at regular periods. • If you select free-running, the model does not use a timer. Instead, the model completes each process or thread before running the next one. 7 In IDE Link, configure the model to build and execute: a In the model, select Simulation > Model Configuration Parameters. b Under Code Generation, select the IDE Link pane. c Set Build action to Build and execute. 8 Click Build Model on the model toolstrip. After the build completes, Embedded Coder software downloads the executable to the remote system and runs it. 29-2 Scheduler Scheduler In this section... “Selecting the Operating System and Scheduling Mode” on page 29-3 “Base Rate” on page 29-4 “Running Target Applications on Multicore Processors” on page 29-4 “Limitations” on page 29-10 Selecting the Operating System and Scheduling Mode The following table refers to the Operating System and Scheduling Mode options in the Target Preferences block. Operating System Scheduling Mode Behavior Windows free_running The model generates multithreaded, free-running code. Each rate in the model maps to a separate thread in the generated code. Multithreaded code can potentially run faster than single-threaded code. Windows real_time The model generates multithreaded, real-time code: Each rate in the Simulink model runs at the rate specified in the model. For example, a 1 s rate runs at exactly 1 s intervals. None Not applicable The model generates free-running code that runs in an infinite while loop with no timing. Does not support External mode. For more information, see “Scheduling” on page 1-4 in the Simulink Coder User’s Guide. 29-3 29 Working with Microsoft® Windows® Target Base Rate The base rate in the model maps to a thread and runs as fast as possible. In Windows target, the timer resolution is 1 ms. The base rate priority selection in the OS tab allows you to set a static priority for the base rate task. The Windows OS does not have a selection. The default base rate priority is THREAD_PRIORITY_HIGHEST (10) and the process running the generated code has NORMAL_PRIORITY_CLASS. The process running single-tasking models has Default scheduling policy when model is single-tasking or there is a single rate in the model. Static priority of the process is 0 in this case. Running Target Applications on Multicore Processors Introduction This section provides a variation of the process described in “Build and Download to a Multicore Target”. This section shows you how to: • Configure a multirate model • Generate a multithreaded application from that model So that the resulting application is enabled for concurrent multicore execution on a desktop target running Linux or Windows. This process uses the idelink_ert.tlc or idelink_grt.tlc system target files, which enable you to: • Use Eclipse IDE to manage projects for Linux and Windows targets (Support for this capability is only available on 32-bit host platforms) • Set thread priority using a Target Preference block 29-4 Scheduler Looking at a Model Before setting up your own model, consider the sldemo_concurrent_execution example model, which is referenced by “Build and Download to a Multicore Target”. The sldemo_concurrent_execution model is a useful example to look at because: • The model is partitioned using Model blocks that can potentially execute concurrently. • You can look at the Map Blocks To Tasks pane in the Concurrent Execution window to see how the tasks are configured for concurrent execution. However, you cannot run an unmodified version of the sldemo_concurrent_execution model on a desktop target running Linux or Windows. To prepare the sldemo_concurrent_execution as an example model for the “Setting Up the Model” on page 29-7 and “Deploying the Model to Your Target” on page 29-8 topics, first perform the following modifications: • Update the Plant Model Block • Update the Compensator Model Block • Verify that Models are Mapped These procedures guide you through the processes of discretizing models and matching sample times of blocks with models. Update the Plant Model Block. 1 In the sldemo_concurrent_execution model, open the “Plant” Model block: sldemo_concurrent_execution_plant 2 Discretize the Plant model. Replace the Integrator blocks, “x1” and “x2”, with equivalent discrete time blocks (such as the Discrete Time Integrator block) or use the “Model Discretizer”. 29-5 29 Working with Microsoft® Windows® Target 3 Prevent modeling constraints by matching the sample time of the “x1” and “x2” blocks with the model: Open the “x1” and “x2” blocks and change the Sample time parameters to 0.1. Matching the sample times to the model can also be accomplished using Rate Transition blocks. 4 Convert blocks with continuous sample times (Sample time = 0) to inherited sample times (Sample time = -1). Open the “u1”, “u2” and “x” blocks. For each one, click the Signal Attributes tab, then change Sample time to -1. 5 Save your changes to the blocks and the model. Update the Compensator Model Block. 1 In the sldemo_concurrent_execution model, open the “Compensator” Model block: sldemo_concurrent_execution_compensator 2 Discretize the Compensator model. Replace the Integrator block, “c”, with an equivalent discrete time block (such as the Discrete Time Integrator block) or use the “Model Discretizer”. 3 Prevent modeling constraints by matching the sample time of the “c” block with the top model: Open the “c” block and change the Sample time parameters to 0.1. Matching the sample times to the top model, sldemo_concurrent_execution, can also be accomplished using Rate Transition blocks. 4 Convert blocks with continuous sample times (Sample time = 0) to inherited sample times (Sample time = -1). Open the “y1”, “y2”, and “x” blocks. For each one, click the Signal Attributes tab, then change Sample time to -1. 5 The following parameters cannot both be enabled when you build the model. Open the Configuration Parameters (Ctrl+E) and verify that one of the following parameters is disabled (unchecked): • Minimize algebraic loop occurrences, located on the Model Referencing pane. • Single output/update function, located on the Code Generation > Interface pane 29-6 Scheduler 6 Save your changes to the blocks and the model. Verify that the Models are Mapped. Open and inspect the Task editor to see if the models are appropriately mapped: 1 In the Simulink model editor for sldemo_concurrent_execution, select View > Model Explorer (Ctrl + H). 2 In Model Explorer, expand the top model, sldemo_concurrent_execution. 3 Under the top model, select Configuration (Active), then click Concurrent Execution in the second column. In the third column, click the ConfigureTasks and Map Blocks to Tasks button. 4 Click Map Blocks To Tasks. The mapping of the models should conform to the guidelines provided by “Design Considerations”. The sldemo_concurrent_execution example model is ready for you to use in “Setting Up the Model” on page 29-7 and “Deploying the Model to Your Target” on page 29-8. Setting Up the Model This procedure explains how to set up a model for a multicore processor. 1 Apply the recommendations in “Design Considerations” to your multirate Simulink model. Or, refer to the sldemo_concurrent_execution example model. 2 Add a Target Preferences block to your model as described in “Target Preferences” on page 25-3 . 3 In the Target Preferences block, set Operating System to Linux or Windows. 4 If your model uses a Rate Transition block to transition between rates, then open the Rate Transition block and clear the Ensure deterministic data transfer check box so that the block uses the most recent data available. 5 Configure the model for concurrent execution: a In the Simulink model editor, select View > Model Explorer (Ctrl + H). 29-7 29 Working with Microsoft® Windows® Target b In Model Explorer, expand the top model. c Under the top model, right click Configuration (Active) and select Convert to Configuration for Concurrent Execution. (In the sldemo_concurrent_execution example model, this step has already been performed.) 6 For each referenced model in the model hierarchy that you want to run with concurrent execution: a Copy the Target Preferences block from the top model to the referenced model. b Repeat steps 4 through 5. 7 Select the configuration set of the model at the top of the model hierarchy. In the second column, select the Concurrent Execution node. A Concurrent Execution pane appears in the third column. (In the sldemo_concurrent_execution example model, this step has already been performed.) 8 In the Concurrent Execution pane in the third column, select the This is the top of the model hierarchy check box, and click the ConfigureTasks and Map Blocks to Tasks button. (In the sldemo_concurrent_execution example model, this step has already been performed.) 9 The Concurrent Execution configuration parameters dialog box is displayed. Click Apply. Deploying the Model to Your Target In your model, click the build button or enter Ctrl+B. The software performs the actions you selected for Build action in the Configuration Parameters dialog, on the Code Generation > IDE Link pane. For more information on the structure of the code, please refer to “Build and Download to a Multicore Target”. As mentioned in that section, the coder product generates all target-dependent code for thread creation, thread synchronization, interrupt service routines, and signal handlers and data transfer. For each periodic task, Simulink Coder combines the output and update methods of the blocks mapped to that task and binds these methods to a target-specific thread. 29-8 Scheduler Note The idelink_ert.tlc or idelink_grt.tlc system target files do not support Continuous times. Generated Code For idelink_ert.tlc or idelink_grt.tlc system target files, the generated code from a mapped model creates a thread for each task and automatically leverages the threading APIs supported by the operating system running on the target. • If the target platform is running Windows , the generated code will use Windows threads. • If the target platform is running Linux or VxWorks , the generated code will use POSIX threads (pthreads). The following table summarizes the differences in the generated code between the target platforms. Aspect of Concurrent Execution Linux Windows Periodic triggering event POSIX timer Windows timer Aperiodic triggering event POSIX real-time signal Windows event Aperiodic trigger For blocks mapped to an aperiodic task: thread waiting for a signal For blocks mapped to an aperiodic trigger: signal action Thread waiting for an event Threads POSIX Windows 29-9 29 Working with Microsoft® Windows® Target Aspect of Concurrent Execution Linux Windows Thread priority Assigned based on Target Preference Block setting Fixed Example of overrun detection Yes Yes The software checks that data transfer between concurrently executing tasks behave as described in Data Transfer Options. The software checks data transfer using the following APIs on supported targets. API Linux Implementation Windows Implementation Data protection API • pthread_mutex_init • CreateMutex • pthread_mutex_destroy• CloseHandle • pthread_mutex_lock • WaitForSingleObject • pthread_mutex_unlock • ReleaseMutex Synchronization API • sem_init • CreateSemaphore • sem_destroy • CloseHandle • sem_wait • WaitForSingleObject • sem_post • ReleaseSemaphore Limitations Profiling is not available for Intel x86/Pentium and AMD K5/K6/Athlon processors running Windows or Linux Operating Systems If you use Embedded Coder with Eclipse to build and run applications on processors running Windows or Linux: The stack profiling and real-time execution profiling is only available for ARM® processors running Linux. 29-10 Scheduler Profiling is not available for Intel x86/Pentium and AMD K5/K6/Athlon processors running Windows or Linux. 29-11 29 29-12 Working with Microsoft® Windows® Target A Examples Use this list to find examples in the documentation. A Examples Models “Single-Tasking and Multitasking Model Execution” on page 1-27 “Spawn a Wind River Systems VxWorks Task” on page 1-46 “Block Execution Order” on page 1-120 “Generate Code for Signal Objects from Command Line” on page 7-67 “Optimization Tools and Techniques” on page 16-7 “Inline Invariant Signals” on page 18-18 “Configure Loop Unrolling Threshold” on page 19-4 A-2 Timing Services Timing Services “Elapsed Timer Code Generation Example” on page 1-85 A-3 A Examples Model Reference “Generate Code for Referenced Models” on page 3-4 “Code Reuse and Model Blocks with Root Inport or Outport Blocks” on page 3-33 A-4 Data Management Data Management “Nontunable Parameter Storage” on page 7-11 “Tunable Expressions in Masked Subsystems” on page 15-129 “Signals with Auto Storage Class” on page 7-55 “Symbolic Naming Conventions for Signals” on page 7-62 “Tunable Expressions in Masked Subsystems” on page 15-129 A-5 A Examples Custom Code “Embed Custom Code Directly Into MdlStart Function” on page 14-40 A-6 S-Functions S-Functions “TLC S-Function Wrapper” on page 14-59 “Write Fully Inlined S-Functions” on page 14-64 “Multiport S-Function” on page 14-65 “S-Function RTWdata” on page 14-67 “Direct-Index Lookup Table Example” on page 14-69 A-7 A Examples Optimizations “Expression Folding for Blocks with Multiple Outputs” on page 14-103 “Optimizing Generated Code” on page 18-2 “Expression Folding Example” on page 18-12 A-8 External Mode External Mode “Set Up an External Mode Communication Channel” on page 15-51 A-9 A Examples Verification “Log Data for Analysis” on page 15-106 A-10 Interfaces Interfaces “Generate Example C API Files” on page 15-146 “Use the C API in an Application” on page 15-160 A-11 A Examples Advanced Code Generation “Example Build Process Customization Using sl_customization.m” on page 22-31 A-12 Code Generation Using Makefiles Code Generation Using Makefiles “Creating a New XMakefile Configuration” on page 25-25 A-13 A A-14 Examples Index A Index absolute time computation 1-79 addLibs field 14-132 algorithm models integrating for real-time rapid prototyping 13-2 APIs timer services 1-81 ASAP2 files customizing 23-2 data attributes required for 15-175 generating 15-182 structure of 15-187 targets supporting 15-175 asynchronous tasks timers for 1-80 atomic subsystem 2-2 automatic S-function generation 14-23 See also S-function target B block states Simulink data objects and 7-90 State Properties dialog box and 7-85 storage and interfacing 7-83 storage classes for 7-84 symbolic names for 7-87 block-based code integration with S-functions 14-120 blocks Custom Code 14-36 depending on absolute time 1-89 Model Header 14-37 Model Source 14-37 Rate Transition 1-14 blocks, Simulink support for 1-94 boards, selecting 25-17 Browse button on Code Generation pane 9-35 buffer reuse option 20-5 build folder contents of 10-29 naming convention 10-28 seeing files 15-24 15-44 sldemo_f14 example 15-25 build folder optional contents C API files 10-30 HTML report files 10-30 model.rtw 10-29 object files 10-29 project files 10-30 subsystem code modules 10-30 TLC profiler files 10-30 build format 25-10 build process COM automation of 24-131 controlling 22-7 files and folders created 10-24 interfacing to development tools integrated development environments 24-124 make utilities 24-124 messages in MATLAB Command Window 15-23 15-43 passing information in 24-32 phases of 24-30 steps in 15-38 build specification 14-131 C C API files used in 15-141 for S-functions 1-82 generating files 15-138 introduction 15-137 mapping to real-time model 15-158 using for your application 15-160 Index-1 Index C language selecting 9-71 C++ encapsulation interface control, custom target support for 24-121 C++ language selecting 9-71 checksums and S-Function target 12-45 for models 12-45 subsystem 12-45 code integrating existing 14-2 build support for 14-120 code files porting 15-33 relocating 15-33 code format choosing 9-16 embedded 9-24 real-time 9-20 real-time malloc 9-22 S-function 9-23 code generation TLC variables for 24-41 code generation example 18-2 code generation options Application lifespan (days) 16-9 Boolean logic signals 20-3 buffer reuse 20-5 See also signal storage reuse 20-5 Classic call interface 9-29 Compiler optimization level 16-6 create code generation report 11-5 Custom compiler optimization flags 16-6 expression folding 18-11 Generate makefile option 15-13 inline invariant signals 18-18 inline parameters 19-2 local block outputs 18-17 See also signal storage reuse 18-17 Index-2 loop rolling threshold 19-4 MAT-file variable name modifier 9-59 retain .rtw file 9-80 show eliminated blocks 9-72 signal storage reuse 20-4 See also local block outputs 20-4 Solver pane 1-90 TLC options 15-12 Use memcpy for vector assignment 19-6 verbose builds 9-80 Code Generation pane 9-2 Language option 9-71 opening 9-2 target configuration options Browse button 9-35 Generate makefile 15-13 make command field 15-13 system target file field 9-35 template makefile field 15-13 TLC options 15-12 Code replacement library option relationship to TGT_FCN_LIB variable 22-3 code reuse diagnostics for 2-32 code verification example 21-1 code with buffer optimization 18-10 efficiency 18-10 code with expression folding 18-13 code without buffer optimization 18-6 code, generated testing in system environment 13-5 combining models by using grt_malloc target 4-2 in Embedded Coder target 4-2 comments options 15-23 communication External mode 15-51 compilation 22-2 customizing 22-3 compiler Index configuring 15-2 Compiler optimization level control, custom target support for 24-115 compiler options specifying 22-3 compilers list of supported 15-2 MEX 15-2 optimization settings 15-10 version mismatches for 15-9 component models integrating for real-time rapid prototyping 13-2 configuration parameters Custom Code library overview 14-36 custom target components of 24-12 application 24-13 code 24-13 control files 24-15 device drivers 24-15 interrupt service routines 24-14 main program 24-14 run-time interface 24-13 purpose of 24-2 custom target configuration tutorial 24-61 TargetLibSuffix controlling suffix applied to library names with 22-10 TargetPreCompLibLocation controlling location of precompiled libraries with 22-8 Configuration Parameters dialog box Code Generation pane 9-2 Solver options pane 1-90 controller models integrating for real-time rapid prototyping 13-2 counters in triggered subsystems 1-81 time 1-80 Create code generation report 11-5 cross-development relocating files for 15-33 custcode command 14-36 custom code build support for 14-120 integrating with C MEX S-functions 14-28 integrating with generated code 14-2 Custom Code blocks 14-36 example 14-40 in subsystems 14-43 D data logging 15-106 from generated code 21-7 tutorial 15-106 via Scope blocks example 21-3 Data Store Memory blocks Simulink data objects and 7-96 data structures in generated code block I/O 8-28 block parameters 8-28 block states 8-28 external inputs 8-28 external outputs 8-28 debug options 15-21 declaration code 14-39 development environments supporting multiple 24-60 dialog boxes Block Parameters 15-53 External Mode Control Panel 15-59 External Signal and Triggering 15-60 direct-index lookup table algorithm 14-67 Index-3 Index example 14-69 discrete states initializing 7-74 documentation 11-16 dt_info.h 10-13 E Eclipse™ IDE for C/C++ Developers 27-5 elapsed time computation 1-79 elapsed time counters 1-80 in triggered subsystems 1-81 elapsed timer example 1-85 entry points, model 8-2 examples building generic real-time program 15-14 code generation 18-2 code verification 21-1 data logging 15-106 direct-index lookup table 14-69 External mode 15-51 model referencing 3-4 multiport S-function 14-65 executable running 15-24 15-43 execution code 14-39 exit code 14-39 Expression folding 18-11 in S-Functions 14-91 ext_work.h 10-13 External mode 15-50 architecture 15-88 baud rates 15-74 blocks compatible with 15-83 building executable 15-54 client-server architecture 23-14 command line options for target program 15-97 communication channel creation 23-14 Index-4 communications overview 23-17 configuration parameter options 15-64 control panel 15-59 control panel options 15-70 data archiving options 15-79 design of 23-14 download mechanism 15-87 example 15-51 ext_comm MEX-file optional arguments to (serial) 15-94 optional arguments to (TCP/IP) 15-92 rebuilding 23-25 host and target systems in 15-50 menu and toolbar items and keyboard shortcuts 15-66 model setup 15-52 parameter downloading options 15-82 parameter tuning 15-62 running executable 15-58 Signal Viewing Subsystems in 15-84 signals and triggering options 15-75 target communications options 15-73 TCP implementation 15-90 transport layer 23-17 External mode API host source files 23-19 implementing transport layer 23-23 target source files 23-21 External Target Interface dialog box MEX-file arguments 15-74 F files for inlined S-functions 14-29 generated. See generated files firstTime argument control, custom target support for 24-117 fixed-step solver 15-16 fixedpoint.h 10-13 Index float.h 10-11 folder precompiled library 14-130 folders build 15-15 used in build process 15-2 working 15-15 From File block specifying signal data file for 12-24 Function prototype control, custom target support for 24-119 functions rtw_precompile_libs 14-129 ssSetChecksumVal 12-45 G general code appearance options Maximum identifier length 9-73 Reserved names 9-73 generate optimized code 25-9 generated code compiling and linking 22-2 include path specification 10-21 profiling 15-45 testing in system environment 13-5 generated files 10-24 contents of 10-4 dependencies among 10-4 model (UNIX executable) 10-26 model file 10-24 model.bat 10-27 model.c 10-24 model_capi.c 10-28 model_capi.h 10-28 model_data.c 10-26 model_dt.h 10-27 model.exe (PC executable) 10-26 model.h 10-25 model.mk 10-26 model_private.h 10-25 model.rtw 10-24 model_targ_data_map.m 10-27 model_target_rtw 10-28 model_types.h 10-25 modelsources.txt 10-27 rt_nonfinite.c 10-27 rt_nonfinite.h 10-27 rt_sfcn_helper.c, 10-28 rt_sfcn_helper.h 10-28 rtmodel.h 10-26 rtw_proj.tmw 10-27 rtwtypes.h 10-26 subsystem.c 10-27 subsystem.h 10-28 generated S-functions tunable parameters in 12-42 generic real-time (GRT) target example 15-14 GNU® Tool Chain on Linux® 27-6 GNU® Tool Chain on Windows® 27-7 H hand-written code build support for 14-120 integrating with generated code 14-2 hardware-in-the-loop (HIL) testing verifying generated code in system environment with 13-5 header files dependencies of model.h 10-9 rtwtypes.h 10-6 hook files STF_make_rtw_hook 24-23 customizing build process with 22-21 STF_wrap_make_cmd_hook 24-23 hook interface for profiling generated code 15-45 Index-5 Index host in External mode 15-50 I include paths specifying 10-21 initial values tunable 7-82 initialization of signals and discrete states 7-74 inlined S-functions 14-64 with mdlRTW routine 14-66 Inport block latch options generated code for option 1-120 specifying signal data file for 12-27 integration, code build support for 14-120 interrupt service routine under VxWorks 1-6 interrupt service routine (ISR) 24-14 interrupt service routines 1-37 interrupts handling 1-37 intOnlyBuild field 14-132 issues, using PIL 26-12 L Language option description of 9-71 Latch input by copying inside signal option generated code for 1-120 Latch input by delaying outside signal generated code for 1-120 latches generated code for 1-120 legacy code build support for 14-120 Index-6 integrating with C MEX S-functions 14-28 integrating with generated code 14-2 Legacy Code Tool deploying S-functions generated with 14-32 generating code with 14-28 legacy_code function addressing file dependencies for code generation 14-31 LibAddToCommonIncludes function using for S-function build support 14-123 LibAddToModelSources function using for S-function build support 14-123 libraries controlling suffix applied to names of 22-10 model reference controlling the location of 22-9 precompiled controlling the location of 22-8 S-function precompiling 14-129 suffixes for 14-131 local block outputs option 18-17 M make command 24-82 make_rtw 15-13 makefile 15-39 customizations 22-7 options for 14-132 makefile commands USE_MDLREF_LIBPATHS controlling location of model reference libraries with 22-9 makeInfo.precompile rtwmakecfg field 14-130 makeOpts field 14-132 MAT-files creating 15-111 loading 21-7 math.h 10-11 Index MATLAB application data 24-33 MATLAB blocks and Stateflow optimizations 19-5 MATLAB Report Generator opening 11-18 setting report output options for 11-20 specifying models and subsystems with 11-21 mdlRTW routine writing inlined S-functions 14-65 MEX S-function wrapper definition 14-55 model (UNIX executable) 10-26 model compiling process 10-31 Model Configuration Parameters dialog box using 7-18 model entry points 8-2 model execution in real time 1-12 in Simulink 1-12 Simulink versus real-time 1-11 Model Explorer viewing code in 3-13 model file 10-24 Model Header block 14-37 Model Parameter Configuration dialog box tunable parameters and 7-10 using 15-125 model reference compatibility of top and referenced models 3-19 inherited sample time and 3-29 parameter interfacing 3-26 project folder structure and 3-16 signal interfacing 3-25 subsystem code reuse and 3-32 model reference libraries controlling location of 22-9 model referencing converting to 3-7 definition of 3-4 example 3-4 generating code 3-11 Model referencing, custom target support for 24-101 Model Source block 14-37 model.bat 10-27 model.c 10-24 model_capi.c 10-28 model_capi.h 10-28 model_data.c 10-26 model_dt.h 10-27 model.exe (PC executable) 10-26 model.h 10-25 model.mk 10-26 model_private.h 10-25 model.rtw 10-24 model_targ_data_map.m 10-27 model_target_rtw 10-28 model_types.h 10-25 models checksums for 12-45 code files for porting 15-33 relocating 15-33 integrating for real-time rapid prototyping 13-2 reference building in parallel 24-102 modelsources.txt 10-27 multiple models combining 4-1 multiport S-function example 14-65 multitasking automatic rate transition 1-20 building program for 1-10 enabling 1-10 example model 1-27 execution 1-31 inserted rate transition block HTML report 1-21 Index-7 Index model execution 1-6 operation 1-13 task identifiers in 1-7 task priorities 1-7 versus single-tasking 1-5 N noninlined S-functions 14-52 nonvirtual subsystems atomic 2-2 categories of 2-2 conditionally executed 2-2 modularity of code generated from 2-3 O operating system tasking primitives 8-12 optimization pane Stateflow and MATLAB options 19-5 optimization, processor specific 25-9 optimizations expression folding 18-13 signal storage reuse 18-9 P parallel builds 24-102 parameters interfacing 7-10 setting 15-16 storage declarations 7-10 TargetPreCompLibLocation 14-130 tunable 7-10 tuning 7-10 performance of generated code 15-45 periodic tasks timers for 1-80 persistent signals Index-8 initialization of 7-80 PIL issues 26-12 pilot G Force plot 15-110 precompiled libraries controlling location of 22-8 priority of sample rates 1-8 processor configuration options build action 25-10 overrun action 25-11 processor specific optimization 25-9 ProfileGenCode variable 15-47 ProfilerTLC variable 15-47 program architecture program execution 8-18 program timing 8-16 project documenting 11-16 project folder 10-29 working with 3-14 project generation selecting the board 25-17 prototyping, rapid integrating component models for 13-2 pseudomultitasking 1-8 R rapid prototyping integrating component models for 13-2 rapid simulation target 12-2 batch simulations (Monte Carlo) 12-19 command line options 12-21 limitations 12-33 output filename specification 12-32 parameter structure access 12-24 signal data file specification for From File block 12-24 signal data file specification for Inport block 12-27 Index rate transition block and continuous sample time 1-22 Rate Transition block 1-14 auto-insertion of 1-20 HTML report of automatically inserted 1-21 rate transitions faster to slower 1-22 slower to faster 1-24 real time executing models in 1-12 real-time malloc target 9-22 combining models with 4-2 real-time model data structure 9-24 recommended target features 24-5 reference models building in parallel 24-102 referenced models code generation incompatibilities 3-19 registration files multiple for code generation 14-31 report format 11-20 Report Generator customizing reports with 11-22 opening 11-18 setting report format for 11-20 setting report location for 11-20 setting report name for 11-20 setting report output options for 11-20 specifying models and subsystems with 11-21 report location 11-20 report name 11-20 report output options 11-20 reports generating code generation 11-16 reset value initial value as 7-82 root models Custom Code blocks in 14-37 rsim See rapid simulation target 12-2 rt_logging.h 10-13 rt_nonfinite.c 10-27 rt_nonfinite.h 10-27 rt_sfcn_helper.c 10-28 rt_sfcn_helper.h 10-28 rtm macros 9-24 rtModel 9-24 rtmodel.h 10-26 rtw_continuous.h 10-14 rtw_extmode.h 10-14 rtw_local_blk_outs 7-56 rtw_matlogging.h 10-14 rtw_precompile_libs function 14-129 rtw_proj.tmw 10-27 rtw_solver.h 10-14 RTWdata structure inlining an S-function 14-67 rtwgensettings structure 24-44 rtwlib command 14-36 rtwmakecfg field TargetPreCompLibLocation 14-130 rtwmakecfg.m creating S-functions 14-125 generating for C MEX S-functions 14-31 using for S-functions 14-124 rtwmakecfgDirs field 14-131 rtwMakecftDirs field 14-131 rtwoptions structure callbacks in 24-52 example of 24-48 fields in 24-50 overview of 24-47 rtwtypes.h 10-26 run-time interface modules 18-5 S S-Function blocks masked Index-9 Index configured to call existing external code 14-28 S-function libraries precompiling 14-129 S-function target 9-23 applications of 12-34 automatic S-function generation 14-23 generating reusable components with 12-37 tunable parameters in 12-42 S-Function target checksums and 12-45 S-functions build support for 14-120 creating rtwmakecfg.m for 14-125 deploying generated 14-32 fully inlined with mdlRTW routine 14-65 generating automatically 14-23 implicit build support for 14-121 inlined 14-64 generated with Legacy Code Tool 14-28 generating files for 14-29 modifying TMF for 14-127 noninlined 14-52 setting SFunctionModules parameter for 14-122 that work with Simulink Coder 14-46 types of 14-48 using rtwmakecfg.m for 14-124 using TLC library functions for 14-123 wrapper 14-54 sample rate transitions 1-13 faster to slower in real-time 1-23 in Simulink 1-22 slower to faster in real-time 1-25 in Simulink 1-24 sample time constraints setting for multitasking 1-6 sample time properties Index-10 setting for multitasking 1-6 selecting boards 25-17 set stack size 25-12 SFunctionModules parameter setting 14-122 signal data specifying for From File block 12-24 specifying for Inport block 12-27 signal initialization in generated code 7-80 signal objects initializing 7-74 signal properties 7-36 setting by using Signal Properties dialog box 7-36 signal storage reuse option 20-4 Signal Viewing Subsystems 15-84 signals initializing 7-74 simstruc.h 10-15 simstruc_types.h 10-15 Simulink and Simulink Coder block execution order 1-120 interactions to consider 1-117 sample time propagation 1-119 using parameter objects 7-38 using signal objects 7-65 Simulink Coder parameters interfacing 7-10 storage 7-10 tuning 7-10 third-party compilers support 15-2 Simulink data objects parameter objects 7-38 signal objects 7-65 Simulink Report Generator customizing reports with 11-22 Index opening 11-18 setting report format for 11-20 setting report location for 11-20 setting report name for 11-20 setting report output options for 11-20 specifying models and subsystems with 11-21 single-tasking 1-10 building program for 1-10 enabling 1-11 example model 1-27 execution 1-28 operation 1-13 sldemo_f14 GRT code generation example 15-14 slprj folder 10-29 ssSetChecksumVal function 12-45 stack size, set stack size 25-12 states, discrete initializing 7-74 10-11 10-11 10-12 STF_make_rtw_hook function arguments to 22-22 storage classes required for signal initialization 7-74 10-12 subsystem.c 10-27 subsystem.h 10-28 subsystems checksums for 12-45 converting to referenced models 3-7 custom code blocks in 14-43 treating as atomic units 3-6 suffixes precompiled library 14-131 Sun™ Java™ Runtime Environment 27-3 symbols options 15-22 10-15 System Derivatives function block 14-39 System Disable function block 14-39 System Enable function block 14-39 system environment testing generated code in 13-5 System Initialize function block 14-39 System Outputs function block 14-39 System Start function block 14-39 system target file 10-32 system target file (STF) customization techniques 24-54 defining target options in 24-43 header comments section 24-40 location of 24-37 naming conventions for 24-37 overview of 24-36 RTW_OPTIONS section 24-43 rtwgensettings structure 24-44 structure of 24-37 target options inheritance mechanism 24-53 TLC entry point in 24-42 TLC variables section 24-41 System Target File Browser 9-34 system target file creation tutorial 24-61 system target files selecting programmatically 9-37 System Terminate function block 14-39 System Update function block 14-39 T target how to specify 15-18 rapid simulation See rapid simulation target 12-2 real-time malloc See real-time malloc target 9-22 target file system 10-32 target files main.c 24-23 Index-11 Index naming conventions 24-11 system target file (STF) 24-21 target settings file 24-22 template makefile (TMF) 24-22 target folders blocks Folder 24-18 central folder 24-18 development tool support files in 24-20 for common source files 24-20 for target preferences classes 24-20 naming conventions 24-11 target root 24-12 target root folder 24-17 Target Language Compiler code generation variables 24-41 function library 10-31 generation of code by 10-31 TLC scripts 10-31 target options inheritance 24-53 mechanism for 24-53 target root folder 24-12 target types baseline 24-3 cosimulation 24-4 turnkey 24-4 TargetLibSuffix parameter controlling suffix applied to library names with 22-10 TargetPreCompLibLocation parameter 14-130 controlling location of precompiled libraries with 22-8 targets available configurations 9-12 selecting programmatically 9-37 task spawning 1-46 task identifier (tid) 1-7 template makefile compiler-specific 9-38 Index-12 structure of 24-75 tokens 24-76 template makefile options LCC 9-43 UNIX 9-39 Visual C++ 9-40 Watcom 9-42 template makefile variables TGT_FCN_LIB 22-3 TGT_FCN_LIB template makefile variable 22-3 time counters 1-80 in triggered subsystems 1-81 timer, elapsed example 1-85 timers 1-79 allocation of 1-80 APIs for accessing 1-81 integer 1-81 timing services 1-79 TLC API for code generation 1-84 TLC block file generating for C MEX S-functions 14-29 TLC hook function interface for profiling generated code 15-45 TLC library functions using for inlined S-functions 14-123 TMFs modifying for S-functions 14-127 tokens 24-76 tunable expressions 7-10 7-22 15-129 in masked subsystems 7-22 15-129 operators, restrictions on 7-24 15-131 tunable parameters in signal initial values 7-82 tuning parameters 15-62 tutorials creating custom target configuration 24-61 Index U Variables ProfileGenCode 15-47 ProfilerTLC 15-47 USE_MDLREF_LIBPATHS command controlling location of model reference libraries with 22-9 user code build support for 14-120 integrating with generated code 14-2 W V working folder 10-28 wrapper S-functions 14-54 VxWorks task spawning 1-46 variable-step solver 15-16 Index-13

Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.5
Linearized                      : Yes
Author                          : batserve
Create Date                     : 2012:08:04 19:56:46-04:00
Modify Date                     : 2012:08:04 19:56:46-04:00
XMP Toolkit                     : Adobe XMP Core 4.2.1-c041 52.342996, 2008/05/07-20:48:00
Creator Tool                    : PScript5.dll Version 5.2.2
Producer                        : Acrobat Distiller 9.0.0 (Windows)
Format                          : application/pdf
Title                           : Print Preview - C:\TEMP\Apdf_2541_3068\home\AppData\Local\PTC\Arbortext\Editor\.aptcache\ae1qwjtr/tf1qwcnj
Creator                         : batserve
Document ID                     : uuid:b27dd172-acc6-409a-8bb5-c37b1505e157
Instance ID                     : uuid:38039d7c-75be-4230-b920-61b8dfede82d
Page Count                      : 1365
EXIF Metadata provided by EXIF.tools

Navigation menu