User`s guide | Real-Time Workshop®

Real-Time Workshop
®
For Use with Simulink ®
Modeling
Simulation
Implementation
User’s Guide
Version 4
How to Contact The MathWorks:
508-647-7000
Phone
508-647-7001
Fax
The MathWorks, Inc.
3 Apple Hill Drive
Natick, MA 01760-2098
Mail
http://www.mathworks.com
Web
Anonymous FTP server
Newsgroup
ftp.mathworks.com
comp.soft-sys.matlab
support@mathworks.com
suggest@mathworks.com
bugs@mathworks.com
doc@mathworks.com
subscribe@mathworks.com
service@mathworks.com
info@mathworks.com
Technical support
Product enhancement suggestions
Bug reports
Documentation error reports
Subscribing user registration
Order status, license renewals, passcodes
Sales, pricing, and general information
Real-Time Workshop User’s Guide
 COPYRIGHT 1994- 2000 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
or for the federal government of the United States. By accepting delivery of the Program, the government
hereby agrees that this software qualifies as "commercial" computer software within the meaning of FAR
Part 12.212, DFARS Part 227.7202-1, DFARS Part 227.7202-3, DFARS Part 252.227-7013, and DFARS Part
252.227-7014. The terms and conditions of The MathWorks, Inc. Software License Agreement shall pertain
to the government’s use and disclosure of the Program and Documentation, and shall supersede any
conflicting contractual terms or conditions. If this license fails to meet the government’s minimum needs or
is inconsistent in any respect with federal procurement law, the government agrees to return the Program
and Documentation, unused, to MathWorks.
MATLAB, Simulink, Stateflow, Handle Graphics, and Real-Time Workshop are registered trademarks, and
Target Language Compiler is a trademark of The MathWorks, Inc.
Other product or brand names are trademarks or registered trademarks of their respective holders.
Printing History: May 1994
January 1998
January 1999
September 2000
First printing
Second printing
Third printing
Fourth printing
Version 1
Version 2.1
Version 3.11 (Release 11)
Version 4 (Release 12)
Contents
Preface
Chapter Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi
Related Products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Installing the Real-Time Workshop . . . . . . . . . . . . . . . . . . . . . xxi
Third-Party Compiler Installation on Windows . . . . . . . . . . . xxii
Supported Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiv
Compiler Optimization Settings . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Typographical Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Introduction to the Real-Time Workshop
1
Product Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-2
Getting Started: Basic Concepts and Tutorials . . . . . . . . .
Tutorial 1: Building a Generic Real-Time Program . . . . . . . .
Tutorial 2: Data Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tutorial 3: Code Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tutorial 4: A First Look at Generated Code . . . . . . . . . . . . . .
1-37
1-42
1-49
1-52
1-56
Where to Find Information in This Manual . . . . . . . . . . . . . 1-63
i
Technical Overview
2
The Rapid Prototyping Process . . . . . . . . . . . . . . . . . . . . . . . .
Key Aspects of Rapid Prototyping . . . . . . . . . . . . . . . . . . . . . . . .
Rapid Prototyping for Digital Signal Processing . . . . . . . . . . . .
Rapid Prototyping for Control Systems . . . . . . . . . . . . . . . . . . .
2-2
2-2
2-5
2-6
Open Architecture of the Real-Time Workshop . . . . . . . . . . 2-8
Automatic Program Building . . . . . . . . . . . . . . . . . . . . . . . . . . 2-12
Steps in the Build Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-13
Code Generation and the Build Process
3
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-2
Overview of the Real-Time Workshop User Interface . . . . . 3-4
Using the Real-Time Workshop Page . . . . . . . . . . . . . . . . . . . . . 3-4
Target Configuration Options . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-7
General Code Generation Options . . . . . . . . . . . . . . . . . . . . . . . 3-9
Target Specific Code Generation Options . . . . . . . . . . . . . . . . . 3-13
TLC Debugging Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-15
Real-Time Workshop Submenu . . . . . . . . . . . . . . . . . . . . . . . . . 3-16
Simulation Parameters and Code Generation . . . . . . . . . . .
Solver Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Workspace I/O Options and Data Logging . . . . . . . . . . . . . . . .
Diagnostics Page Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Advanced Options Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tracing Generated Code Back to Your
Simulink Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Other Interactions Between Simulink
and the Real-Time Workshop . . . . . . . . . . . . . . . . . . . . . . . . . .
ii
Contents
3-17
3-17
3-18
3-21
3-22
3-28
3-29
Selecting a Target Configuration . . . . . . . . . . . . . . . . . . . . . . 3-34
The System Target File Browser . . . . . . . . . . . . . . . . . . . . . . . . 3-34
Available Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-36
Nonvirtual Subsystem Code Generation . . . . . . . . . . . . . . . . 3-41
Nonvirtual Subsystem Code Generation Options . . . . . . . . . . 3-41
Modularity of Subsystem Code . . . . . . . . . . . . . . . . . . . . . . . . . 3-48
Generating Code and Executables from Subsystems . . . . . 3-49
Parameters: Storage, Interfacing, and Tuning . . . . . . . . . .
Storage of Nontunable Parameters . . . . . . . . . . . . . . . . . . . . . .
Tunable Parameter Storage . . . . . . . . . . . . . . . . . . . . . . . . . . .
Storage Classes of Tunable Parameters . . . . . . . . . . . . . . . . . .
Using the Model Parameter Configuration Dialog . . . . . . . . .
Tunable Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tunability of Linear Block Parameters . . . . . . . . . . . . . . . . . .
3-51
3-51
3-53
3-54
3-57
3-61
3-63
Signals: Storage, Optimization, and Interfacing . . . . . . . . .
Signal Storage Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Signals with Auto Storage Class . . . . . . . . . . . . . . . . . . . . . . . .
Declaring Test Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Interfacing Signals to External Code . . . . . . . . . . . . . . . . . . . .
Symbolic Naming Conventions for Signals
in Generated Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Summary of Signal Storage Class Options . . . . . . . . . . . . . . . .
C API for Parameter Tuning and Signal Monitoring . . . . . . . .
Target Language Compiler API for Parameter
Tuning and Signal Monitoring . . . . . . . . . . . . . . . . . . . . . . . . .
Parameter Tuning via MATLAB Commands . . . . . . . . . . . . . .
3-65
3-65
3-68
3-71
3-72
Simulink Data Objects and Code Generation . . . . . . . . . . .
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Parameter Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Signal Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Object Property Information in the model.rtw File . . . . . . . . .
3-79
3-79
3-79
3-81
3-85
3-88
3-74
3-76
3-77
3-77
3-77
iii
Configuring the Generated Code via TLC . . . . . . . . . . . . . . 3-93
Target Language Compiler Variables and Options . . . . . . . . . 3-93
Making an Executable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-97
Directories Used in the Build Process . . . . . . . . . . . . . . . . . . 3-98
Choosing and Configuring Your Compiler . . . . . . . . . . . . . . 3-99
Template Makefiles and Make Options . . . . . . . . . . . . . . . . 3-102
Compiler-Specific Template Makefiles . . . . . . . . . . . . . . . . . . 3-102
Template Makefile Structure . . . . . . . . . . . . . . . . . . . . . . . . . 3-106
Generated Code Formats
4
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
Choosing a Code Format for Your Application . . . . . . . . . . . 4-3
Real-Time Code Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Unsupported Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
System Target Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Template Makefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4-6
4-6
4-6
4-6
Real-Time malloc Code Format . . . . . . . . . . . . . . . . . . . . . . . . .
Unsupported Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
System Target Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Template Makefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4-8
4-8
4-8
4-8
S-Function Code Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-10
Embedded C Code Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-11
iv
Contents
External Mode
5
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-2
Tutorial: Getting Started with External Mode Using GRT . 5-4
Part 1: Setting Up the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4
Part 2: Building the Target Executable . . . . . . . . . . . . . . . . . . . 5-6
Part 3: Running the External Mode Target Program . . . . . . . 5-11
Part 4: Tuning Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-14
Using the External Mode User Interface . . . . . . . . . . . . . . .
External Mode Related Menu and Toolbar Items . . . . . . . . . .
External Mode Control Panel . . . . . . . . . . . . . . . . . . . . . . . . . .
Connection and Start/Stop Controls . . . . . . . . . . . . . . . . . . . . .
Target Interface Dialog Box . . . . . . . . . . . . . . . . . . . . . . . . . . .
External Signal & Triggering Dialog Box . . . . . . . . . . . . . . . . .
Data Archiving . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Parameter Download Options . . . . . . . . . . . . . . . . . . . . . . . . . .
5-16
5-16
5-21
5-22
5-23
5-24
5-28
5-31
External Mode Compatible Blocks and Subsystems . . . . . 5-32
Compatible Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-32
Signal Viewing Subsystems . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-32
Overview of External Mode Communications . . . . . . . . . . . 5-36
The Download Mechanism . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-36
The TCP/IP Implementation . . . . . . . . . . . . . . . . . . . . . . . . . .
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Using the TCP/IP Implementation . . . . . . . . . . . . . . . . . . . . . .
The External Interface MEX-File . . . . . . . . . . . . . . . . . . . . . . .
External Mode Compatible Targets . . . . . . . . . . . . . . . . . . . . .
Running the External Program . . . . . . . . . . . . . . . . . . . . . . . . .
Error Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Implementing an External Mode Protocol Layer . . . . . . . . . . .
5-38
5-38
5-38
5-40
5-41
5-41
5-44
5-44
Limitations of External Mode . . . . . . . . . . . . . . . . . . . . . . . . . 5-45
v
Program Architecture
6
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-2
Model Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-5
Program Timing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-13
Program Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-14
External Mode Communication . . . . . . . . . . . . . . . . . . . . . . . . 6-14
Data Logging In Singleand Multitasking Model Execution . . . . . . . . . . . . . . . . . . . . . . 6-14
Rapid Prototyping and Embedded
Model Execution Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-15
Rapid Prototyping Model Functions . . . . . . . . . . . . . . . . . . . . . 6-16
Embedded Model Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-22
Rapid Prototyping Program Framework . . . . . . . . . . . . . . .
Rapid Prototyping Program Architecture . . . . . . . . . . . . . . . . .
Rapid Prototyping System Dependent Components . . . . . . . .
Rapid Prototyping System Independent Components . . . . . . .
Rapid Prototyping Application Components . . . . . . . . . . . . . .
6-24
6-25
6-26
6-27
6-30
Embedded Program Framework . . . . . . . . . . . . . . . . . . . . . . . 6-35
Models with Multiple Sample Rates
7
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-2
Single- Versus Multitasking Environments . . . . . . . . . . . . . . 7-3
Executing Multitasking Models . . . . . . . . . . . . . . . . . . . . . . . . . 7-5
Multitasking and Pseudomultitasking . . . . . . . . . . . . . . . . . . . . 7-5
Building the Program for Multitasking Execution . . . . . . . . . . 7-8
Singletasking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-9
Building the Program for Singletasking Execution . . . . . . . . . . 7-9
Model Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-9
Simulating Models with Simulink . . . . . . . . . . . . . . . . . . . . . . 7-10
Executing Models in Real Time . . . . . . . . . . . . . . . . . . . . . . . . . 7-10
vi
Contents
Sample Rate Transitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Faster to Slower Transitions in Simulink . . . . . . . . . . . . . . . .
Faster to Slower Transitions in Real Time . . . . . . . . . . . . . . . .
Slower to Faster Transitions in Simulink . . . . . . . . . . . . . . . .
Slower to Faster Transitions in Real Time . . . . . . . . . . . . . . . .
7-12
7-13
7-14
7-16
7-17
Optimizing the Model for Code Generation
8
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2
General Modeling Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . 8-3
Block Diagram Performance Tuning . . . . . . . . . . . . . . . . . . . . 8-4
Look-Up Tables and Polynomials . . . . . . . . . . . . . . . . . . . . . . . . 8-4
Accumulators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-15
Use of Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-17
Stateflow Optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-23
Simulation Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-24
Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-26
Real-Time Workshop Embedded Coder
9
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-2
Data Structures and Code Modules . . . . . . . . . . . . . . . . . . . . . 9-4
Real-Time Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-4
Code Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-5
vii
Program Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-9
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-9
Main Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-10
rt_OneStep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-11
Model Entry Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-14
Automatic S-Function Wrapper Generation . . . . . . . . . . . . 9-17
Optimizing the Generated Code . . . . . . . . . . . . . . . . . . . . . . .
Basic Code Generation Options . . . . . . . . . . . . . . . . . . . . . . . . .
Generating Code from Subsystems . . . . . . . . . . . . . . . . . . . . . .
Generating Block Comments . . . . . . . . . . . . . . . . . . . . . . . . . . .
Generating a Code Generation Report . . . . . . . . . . . . . . . . . . .
Controlling Stack Space Allocation . . . . . . . . . . . . . . . . . . . . . .
9-20
9-20
9-22
9-22
9-23
9-25
Advanced Code Generation Options . . . . . . . . . . . . . . . . . . .
Create Simulink (S-Function) Block . . . . . . . . . . . . . . . . . . . . .
Generate HTML Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Generate ASAP2 File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9-27
9-27
9-27
9-28
Requirements and Restrictions . . . . . . . . . . . . . . . . . . . . . . . . 9-29
Unsupported Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-30
System Target File and Template Makefiles . . . . . . . . . . . . 9-31
The S-Function Target
10
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2
Intellectual Property Protection . . . . . . . . . . . . . . . . . . . . . . . . 10-3
Creating an S-Function Block from a Subsystem . . . . . . . . 10-4
Tunable Parameters in Generated S-Functions . . . . . . . . 10-10
Automated S-Function Generation . . . . . . . . . . . . . . . . . . . 10-12
viii Contents
Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-15
Unsupported Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-16
System Target File and Template Makefiles . . . . . . . . . . . 10-17
System Target File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-17
Template Makefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-17
Real-Time Workshop Rapid Simulation Target
11
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2
Building for the Rapid Simulation Target . . . . . . . . . . . . . . 11-4
Running a Rapid Simulation . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-5
Simulation Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-12
Batch and Monte Carlo Simulations . . . . . . . . . . . . . . . . . . . . 11-12
Targeting Tornado for Real-Time Applications
12
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2
Confirming Your Tornado Setup Is Operational . . . . . . . . . . . 12-2
VxWorks Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-3
Run-Time Architecture Overview . . . . . . . . . . . . . . . . . . . . . . 12-5
Parameter Tuning and Monitoring . . . . . . . . . . . . . . . . . . . . . . 12-5
Run-Time Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-8
ix
Implementation Overview . . . . . . . . . . . . . . . . . . . . . . . . . . .
Adding Device Driver Blocks . . . . . . . . . . . . . . . . . . . . . . . . . .
Configuring the Template Makefile . . . . . . . . . . . . . . . . . . . .
Tool Locations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Building the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Downloading and Running the Executable
Interactively . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12-12
12-14
12-14
12-15
12-15
12-19
Targeting DOS for Real-Time Applications
13
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-2
DOS Device Drivers Library . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-2
Implementation Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-4
System Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-5
Sample Rate Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-7
Device Driver Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Device Driver Block Library . . . . . . . . . . . . . . . . . . . . . . . . . .
Configuring Device Driver Blocks . . . . . . . . . . . . . . . . . . . . . .
Adding Device Driver Blocks to the Model . . . . . . . . . . . . . . .
13-10
13-10
13-11
13-16
Building the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-17
Running the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13-18
Custom Code Blocks
14
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2
Custom Code Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-5
Model Code Sublibrary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-5
Subsystem Code Sublibrary . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-9
x
Contents
Asynchronous Support
15
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-2
Interrupt Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-5
Asynchronous Interrupt Block . . . . . . . . . . . . . . . . . . . . . . . . . 15-5
Task Synchronization Block . . . . . . . . . . . . . . . . . . . . . . . . . . 15-12
Asynchronous Buffer Block . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-16
Rate Transition Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-18
Creating a Customized Asynchronous Library . . . . . . . . . 15-20
Real-Time Workshop Ada Coder
16
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Real-Time Workshop Ada Coder Applications . . . . . . . . . . . . .
Supported Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Supported Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Generated Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Types of Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Supported Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Restrictions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16-2
16-3
16-3
16-3
16-4
16-4
16-4
16-4
Getting Started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-6
Models with S-Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-11
Configuring the Template Makefile . . . . . . . . . . . . . . . . . . . . 16-13
Data Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-13
Generating Block Comments . . . . . . . . . . . . . . . . . . . . . . . . . . 16-14
Application Modules Required for the
Real-Time Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-14
Configuring and Interfacing Parameters and Signals . . 16-16
Model Parameter Configuration . . . . . . . . . . . . . . . . . . . . . . . 16-16
Signal Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-16
xi
Code Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-18
Analyzing Data with MATLAB . . . . . . . . . . . . . . . . . . . . . . . . 16-20
Supported Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-21
Targeting Real-Time Systems
17
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-2
Components of a Custom Target Configuration . . . . . . . . .
Code Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
User-Written Run-Time Interface Code . . . . . . . . . . . . . . . . . .
Run-Time Interface for Rapid Prototyping . . . . . . . . . . . . . . . .
Run-Time Interface for Embedded Targets . . . . . . . . . . . . . . .
Control Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17-4
17-4
17-5
17-6
17-6
17-7
Tutorial: Creating a Custom Target Configuration . . . . . . 17-9
xii
Contents
Customizing the Build Process . . . . . . . . . . . . . . . . . . . . . . .
System Target File Structure . . . . . . . . . . . . . . . . . . . . . . . . .
Adding a Custom Target to the System Target
File Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Template Makefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17-16
17-16
Creating Device Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Inlined and Noninlined Drivers . . . . . . . . . . . . . . . . . . . . . . .
Device Driver Requirements and Limitations . . . . . . . . . . . .
Parameterizing Your Driver . . . . . . . . . . . . . . . . . . . . . . . . . .
Writing a Noninlined S-Function Device Driver . . . . . . . . . .
Writing an Inlined S-Function Device Driver . . . . . . . . . . . .
Building the MEX-File and the Driver Block . . . . . . . . . . . . .
Source Code for Inlined ADC Driver . . . . . . . . . . . . . . . . . . . .
17-34
17-35
17-37
17-38
17-39
17-48
17-54
17-55
17-24
17-25
Interfacing Parameters and Signals . . . . . . . . . . . . . . . . . .
Signal Monitoring via Block Outputs . . . . . . . . . . . . . . . . . . .
Parameter Tuning via model_pt.c . . . . . . . . . . . . . . . . . . . . . .
Target Language Compiler API for
Signals and Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17-65
17-65
17-71
Creating an External Mode Communication Channel . . .
The Design of External Mode . . . . . . . . . . . . . . . . . . . . . . . . .
Overview of External Mode Communications . . . . . . . . . . . .
External Mode Source Files . . . . . . . . . . . . . . . . . . . . . . . . . . .
Guidelines for Implementing the Transport Layer . . . . . . . .
17-73
17-73
17-74
17-76
17-79
17-72
Combining Multiple Models . . . . . . . . . . . . . . . . . . . . . . . . . . 17-82
DSP Processor Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-86
Blocks That Depend on Absolute Time
A
B
Glossary
xiii
xiv Contents
Preface
Chapter Summary
. . . . . . . . . . . . . . . . . xvi
Related Products . . . . . . . . . . . . . . . . . . xviii
Installing the Real-Time Workshop . . .
Third-Party Compiler Installation on Windows
Supported Compilers . . . . . . . . . . .
Compiler Optimization Settings . . . . . .
Typographical Conventions . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
xxi
xxii
xxiv
xxv
xxv
Preface
Chapter Summary
Chapter 1, “Introduction to the Real-Time Workshop” introduces basic
concepts and terminology of the Real-Time Workshop. It also provides
information linking basic real-time development tasks to corresponding
sections of this book. The “Getting Started: Basic Concepts and Tutorials”
section in this chapter will get you working with hands-on exercises.
Chapter 2, “Technical Overview” is a quick introduction to the rapid
prototyping process, the open architecture of the Real-Time Workshop, and the
automatic program building process.
Chapter 3, “Code Generation and the Build Process” describes the automatic
program building process in detail. It discusses all code generation options
controlled by the Real-Time Workshop’s graphical user interface. Topics
include data logging, inlining and tuning parameters, interfacing parameters
and signals to your code, code generation from subsystems, and template
makefiles. The chapter also summarizes available target configurations.
Chapter 4, “Generated Code Formats” compares and contrasts targets and
their associated code formats. This include the real-time, real-time malloc,
embedded C, and S-Function code formats.
Chapter 5, “External Mode” contains information about external mode, a
simulation environment that supports on-the-fly parameter tuning, signal
monitoring, and data logging.
Chapter 6, “Program Architecture” discusses the architecture of programs
generated by the Real-Time Workshop, and the run-time interface.
Chapter 7, “Models with Multiple Sample Rates” describes how to handle
multirate systems.
Chapter 8, “Optimizing the Model for Code Generation” discusses techniques
for optimizing your generated programs.
Chapter 9, “Real-Time Workshop Embedded Coder” discusses the structure
and operation of programs generated using the Real-Time Workshop
Embedded Coder. The Real-Time Workshop Embedded Coder is designed for
generation of code for embedded systems.
Chapter 10, “The S-Function Target” explains how to generate S-Function
blocks from models and subsystems. This enables you to encapsulate models
and subsystems and protect your designs by distributing only binaries.
xvi
Chapter Summary
Chapter 11, “Real-Time Workshop Rapid Simulation Target” discusses the
rapid simulation target (RSIM), which executes your model in nonreal-time on
your host computer. You can use this feature to generate fast, stand-alone
simulations that allow batch parameter tuning and the loading of new
simulation data (signals) from a standard MATLAB MAT-file without needing
to recompile your model.
Chapter 12, “Targeting Tornado for Real-Time Applications” contains
information that is specific to developing programs that target Tornado, and
signal monitoring using StethoScope.
Chapter 13, “Targeting DOS for Real-Time Applications” contains information
on developing programs that target DOS.
Chapter 14, “Custom Code Blocks” contains information about the Real-Time
Workshop library, a collection of blocks and templates you can use to customize
code generation for your application.
Chapter 15, “Asynchronous Support” describes the Interrupt Template library,
which allow you to model synchronous/asynchronous event handling.
Chapter 16, “Real-Time Workshop Ada Coder” discusses the Real-Time
Workshop Ada Target, which generates Ada code from your models. The Ada
Coder is a separate product from the Real-Time Workshop.
Chapter 17, “Targeting Real-Time Systems” discusses information of interest
to developers who want to develop programs for custom targets. This includes
developing device driver blocks, customizing system target files and template
makefiles, combining multiple models into a single executable, and APIs for
external mode communication, signal monitoring, and parameter tuning.
Appendix A lists blocks whose use is restricted due to dependency on absolute
time.
Appendix B is a glossary that contains definitions of terminology associated
with the Real-Time Workshop and real-time development.
xvii
Preface
Related Products
The MathWorks provides several products that are especially relevant to the
kinds of tasks you can perform with the Real-Time Workshop®. They are listed
in the table below.
The Real-Time Workshop requires these products:
• MATLAB® 6.0 (Release 12)
• Simulink® 4.0 (Release 12)
• A supported compiler (See “Supported Compilers” on page xxiv and
“Third-Party Compiler Installation on Windows” on page xxii)
For more information about any of these products, see either:
• The online documentation for that product, if it is installed or if you are
reading the documentation from the CD
• The MathWorks Web site, at http://www.mathworks.com; see the “products”
section
Note The toolboxes listed below all include functions that extend MATLAB’s
capabilities. The blocksets listed below all include blocks that extend
Simulink’s capabilities.
xviii
Product
Description
Communications Toolbox
MATLAB functions for modeling the physical
layer of communications systems
Control System Toolbox
Tool for modeling, analyzing, and designing
control systems using classical and modern
techniques
Dials & Gauges Blockset
Graphical instrumentation for monitoring and
controlling signals and parameters in
Simulink models
Related Products
Product
Description
DSP Blockset
Simulink block libraries for the design,
simulation, and prototyping of digital signal
processing systems
Fixed-Point Blockset
Simulink blocks that model, simulate, and
automatically generate pure integer code for
fixed-point applications
Fuzzy Logic Toolbox
Tool to help master fuzzy logic techniques and
their application to practical control problems
Nonlinear Control
Design (NCD) Blockset
Simulink block libraries that provide a
time-domain-based optimization approach to
system design; automatically tunes
parameters based on user-defined
time-domain performance constraints
Power System Blockset
Simulink block libraries for the design,
simulation, and prototyping of electrical power
systems
Real-Time Workshop
Ada Coder
Tool that allows you to automatically generate
Ada 95 code. It produces the code directly from
Simulink models and automatically builds
programs that can be run in real time in a
variety of environments.
Real-Time Workshop
Embedded Coder
Tool that allows you to automatically generate
production-quality C code from Simulink
models. Supports software-in-the-loop
validation of generated code in Simulink.
Real-Time Windows
Target
Tool that allows you to run Simulink models
interactively and in real time on your PC
under Windows
Simulink
Interactive, graphical environment for
modeling, simulating, and prototyping
dynamic systems
xix
Preface
xx
Product
Description
Stateflow®
Tool for graphical modeling and simulation of
complex control logic
Stateflow Coder
Tool for generating highly readable, efficient C
code from Stateflow diagrams
xPC Target
Tool that supports many I/O blocks for
Simulink block diagrams. Supports
downloading code generated by Real-Time
Workshop to a second PC that runs the xPC
Target real-time kernel, for rapid prototyping
and hardware-in-the-loop testing of control
and DSP systems.
xPC Target Embedded
Option
Add-on to xPC Target to deploy the xPC Target
operating system, together with embedded
code, to external PCs
Installing the Real-Time Workshop
Installing the Real-Time Workshop
Your platform-specific MATLAB Installation Guide provides all of the
information you need to install the Real-Time Workshop.
Prior to installing the Real-Time Workshop, you must obtain a License File or
Personal License Password from The MathWorks. The License File or Personal
License Password identifies the products you are permitted to install and use.
As the installation process proceeds, it displays a dialog similar to the one
below, letting you indicate which products to install.
xxi
Preface
The Real-Time Workshop has certain product prerequisites that must be met
for proper installation and execution.
Licensed
Product
Prerequisite
Products
Additional Information
Simulink
MATLAB 6
(Release 12)
Allows installation of Simulink.
The Real-Time
Workshop
Simulink 4.0
(Release 12)
Requires Borland C, LCC, Visual C/
C++, or Watcom C compiler to create
MATLAB MEX-files on your
platform.
The Real-Time
Workshop Ada
Coder
The Real-Time
Workshop 4.0
The Real-Time
Workshop
Embedded
Coder
The Real-Time
Workshop 4.0
If you experience installation difficulties and have Web access, connect to the
MathWorks home page (http://www.mathworks.com). Look for the license
manager and installation information under the Tech Notes/FAQ link under
Tech Support Info.
Third-Party Compiler Installation on Windows
Several of the Real-Time Workshop targets create an executable that runs on
your workstation. When creating the executable, the Real-Time Workshop
must be able to access a compiler. The following sections describe how to
configure your system so that the Real-Time Workshop has access to your
compiler.
xxii
Installing the Real-Time Workshop
Borland
Make sure that your Borland environment variable is defined and correctly
points to the directory in which your Borland compiler resides. To check this,
type
set BORLAND
at the DOS prompt. The return from this includes the selected directory.
If the BORLAND environment variable is not defined, you must define it to point
to where you installed your Borland compiler. On Microsoft Windows 95 or 98,
add
set BORLAND=<path to your compiler>
to your autoexec.bat file.
On Microsoft Windows NT, in the control panel select System, go to the
Environment page, and define BORLAND to be the path to your compiler.
LCC
The freeware LCC C compiler is shipped with MATLAB, and is installed with
the product. If you want to use LCC to build programs generated by the
Real-Time Workshop, you should use the version that is currently shipped with
the product. Information about LCC is available at
http://www.cs.virginia.edu/~lcc-win32/.
Microsoft Visual C/C++
Define the environment variable MSDevDir to be
MSDevDir=<path to compiler>\SharedIDE
MSDevDir=<path to compiler>\Common\MSDev98
for Visual C/C++ 5.0
for Visual C/C++ 6.0
Watcom
Note As of this printing, the Watcom C compiler is no longer available from
the manufacturer. The Real-Time Workshop continues to ship Watcom-related
target configurations at this time. However, this policy may be subject to
change in the future.
xxiii
Preface
Make sure that your Watcom environment variable is defined and correctly
points to the directory in which your Watcom compiler resides. To check this,
type
set WATCOM
at the DOS prompt. The return from this includes the selected directory.
If the WATCOM environment variable is not defined, you must define it to point
to where you installed your Watcom compiler. On Windows 95 or 98, add
set WATCOM=<path to your compiler>
to your autoexec.bat file.
On Windows NT, in the control panel select System, go to the Environment
page, and define WATCOM to be the path to your compiler.
Out-of-Environment Error Message
If you are receiving out-of-environment space error messages, you can
right-click your mouse on the program that is causing the problem (for
example, dosprmpt or autoexec.bat) and choose Properties. From there
choose Memory. Set the Initial Environment to the maximum allowed and
click Apply. This should increase the amount of environment space available.
Supported Compilers
On Windows. As of this printing, we have tested the Real-Time Workshop with
these compilers on Windows.
Compiler
xxiv
Versions
Borland
5.3, 5.4,5.5
LCC
Use version of LCC shipped with
MATLAB.
Microsoft Visual C/C++
5.0, 6.0
Watcom
10.6, 11.0 (see “Watcom” above)
Installing the Real-Time Workshop
Typically you must make modifications to your setup when a new version of
your compiler is released. See the MathWorks home page,
http://www.mathworks.com, for up-to-date information on newer compilers.
On UNIX. On UNIX, the Real-Time Workshop build process uses the default
compiler. cc is the default on all platforms except SunOS, where gcc is the
default.
Compiler Optimization Settings
In some very rare instances, due to compiler defects, compiler optimizations
applied to Real-Time Workshop generated code may cause the executable
program to produce incorrect results, even though the code itself is correct.
The Real-Time Workshop uses the default optimization level for supported
compilers. You can usually work around problems caused by compiler
optimizations by lowering the optimization level of the compiler, or turning off
optimizations. Please refer to your compiler's documentation for information
on how to do this.
Typographical Conventions
This manual uses some or all of these conventions.
To Indicate...
This Guide Uses...
Example
Example code
Monospace font
To assign the value 5 to A,
enter
A = 5
Function names/syntax
Monospace font
The cos function finds the
cosine of each array element.
Syntax line example is
MLGetVar ML_var_name
Mathematical
expressions
Italics for variables
Standard text font for
functions, operators, and
constants
This vector represents the
polynomial
p = x2 + 2x + 3
xxv
Preface
To Indicate...
This Guide Uses...
Example
MATLAB output
Monospace font
MATLAB responds with
A =
5
xxvi
Menu names, menu items, and
controls
Boldface with an initial
Choose the File menu.
capital letter
New terms
Italics
An array is an ordered
collection of information.
String variables (from a finite
list)
Monospace italics
sysc = d2c(sysd, 'method')
1
Introduction to the
Real-Time Workshop
Product Summary
. . . . . . . . . . . . . . . . . 1-2
Getting Started: Basic Concepts and Tutorials
Tutorial 1: Building a Generic Real-Time Program .
Tutorial 2: Data Logging . . . . . . . . . . .
Tutorial 3: Code Validation . . . . . . . . . .
Tutorial 4: A First Look at Generated Code . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 1-37
. 1-42
. 1-49
. 1-52
. 1-56
Where to Find Information in This Manual . . . . . . 1-63
1
Introduction to the Real-Time Workshop
Product Summary
Real-Time Workshop generates optimized, portable, and customizable code
from Simulink models. Using integrated makefile based targeting support, it
builds programs that can help speed up your simulations, provide intellectual
property protection, or run on a wide variety of real-time rapid prototyping or
production targets. Simulink’s external mode run-time monitor works
seamlessly with real-time targets, providing an elegant signal monitoring and
parameter tuning interface. Real-Time Workshop supports continuous-time,
discrete-time and hybrid systems, including conditionally executed and atomic
systems. Real-Time Workshop accelerates your development cycle, producing
higher quality results in less time.
Real-Time Workshop is a key link in the set of system design tools provided by
The MathWorks. Conceptually, Real-Time Workshop is the final piece in the
design process.
MATLAB
and
Toolboxes
Design
and
Analysis
Real-Time
Workshop
components
Simulink,
Stateflow, and Blocksets
Modeling and simulation
Rapid simulations
External Mode
Monitoring and
parameter tuning
Simulink Code
Generator
Generates C or Ada
Make
process
Rapid Prototyping Target
Real-time test environment
Early rapid prototyping iterations
1-2
Customer defined
Monitoring and
parameter tuning
Production
Target
Final production
iteration
Product Summary
Real-Time Workshop provides a real-time development environment — a
direct path from system design to hardware implementation. You can shorten
development cycles and reduce costs with Real-Time Workshop by testing
design iterations with real-time hardware. Real-Time Workshop supports the
execution of dynamic system models on hardware by automatically converting
models to code and providing model-based debugging support. It is well suited
for accelerating simulations, rapid prototyping, turnkey solutions, and
production embedded real-time applications.
With Real-Time Workshop, you can quickly generate C code for discrete-time,
continuous-time, and hybrid systems, including systems containing triggered
and enabled subsystems. With the optional Real-Time Workshop Ada Coder,
you can generate Ada code. The optional Stateflow Coder add-on lets you
generate code for finite state machines modeled in Stateflow.
System design using the MathWorks toolset differs from one application to
another. A typical product cycle starts with modeling in Simulink, followed by
an analysis of the simulations in MATLAB. During the simulation process, you
use the rapid simulation features of Real-Time Workshop to speed up your
simulations.
After you are satisfied with the simulation results, you use Real-Time
Workshop in conjunction with a rapid prototyping target, such as xPC Target.
The rapid prototyping target is connected to your physical system. You test and
observe your system, using your Simulink model as the interface to your
physical target. After creating your model, you use Real-Time Workshop to
transform your model to C or Ada code. An extensible make process and
download procedure creates an executable for your model and places it on the
target system. Finally, using external mode, you can monitor and tune
parameters in real-time as your model executes on the target environment.
Conceptually, there are two types of targets: rapid prototyping targets and the
embedded target. Code generated for the rapid prototyping targets supports
increased monitoring and tuning capabilities. The generated embedded code
used in the embedded target is highly optimized and suitable for deployment
in production systems. You can add application-specific entry points to monitor
signals and tune parameters in the embedded code.
1-3
1
Introduction to the Real-Time Workshop
The basic components of Real-Time Workshop are:
• Simulink Code Generator: automatically generates C or Ada code from your
Simulink model.
• Make Process: The Real-Time Workshop’s user-extensible make process lets
you create your own production or rapid prototyping target.
• Simulink External Mode: External mode enables communication between
Simulink and a model executing on a real-time test environment, or in
another process on the same machine. External mode lets you perform
real-time parameter tuning and data viewing using Simulink as a front end.
• Targeting Support: Using Real-Time Workshop’s bundled targets, you can
build systems for a number of environments, including Tornado and DOS.
The generic real-time and embedded real-time targets provide a framework
for developing customized rapid prototyping or production target
environments. In addition to the bundled targets, Real-Time Windows
Target and/or xPC Target let you turn a PC of any form factor into a rapid
prototyping target, or a small to medium volume production target.
• Rapid Simulations: Using Simulink Accelerator (part of the Simulink
Performance Tools product), S-Function Target, or Rapid Simulation Target,
you can accelerate your simulations by 5 to 20 times on average. Executables
built with these targets bypass Simulink’s normal interpretive simulation
mode, which must handle all configurations of each basic modeling primitive.
The code generated by Simulink Accelerator, S-Function Target, or Rapid
Simulation Target is highly optimized to execute only the algorithms used in
your specific model. In addition, these targets apply many optimizations,
such as eliminating ones and zeros in computations for filter blocks.
Integrated Development Environment
If the Real-Time Workshop target you are using supports Simulink external
mode, you can use Simulink as the monitoring/debugging interface for the
generated code. With external mode, you can:
• Change parameters via the block dialogs, gauges, and the set_param
MATLAB command. The set_param command lets you interact
programmatically with your target.
• View target signals in Scope blocks, Display blocks, general S-Function
blocks, and via gauges.
1-4
Product Summary
These concepts are illustrated by Figure 1-1 and Figure 1-2.
You can view the
state of target data
values using display
devices.
You can change
block parameter values
on the target while your
model is executing.
You can view
target data values
using display blocks.
You can view
target signals
using scope blocks.
TCP/IP, serial, shared memory or other
communication link
Target system
Figure 1-1: Signal Viewing and Parameter Tuning in External Mode
1-5
1
Introduction to the Real-Time Workshop
Simulink
model
TCP/IP, serial, shared memory or other
communication link
Target system
Figure 1-2: Dials and Gauges Provide Front End to Target System
1-6
Product Summary
A Next-Generation Development Tool
The MathWorks toolset, including Simulink and Real-Time Workshop, is
revolutionizing the way embedded systems are designed. Simulink is a very
high level language (VHLL) — a next-generation programing language. A brief
look at the history of dynamic and embedded system design methodologies
reveals a steady progression toward higher-level design tools and processes:
• Design -> analog components: Before the introduction of microcontrollers,
design was done on paper and realized using analog components.
• Design -> hand written assembly -> early microcontrollers: In the early
microprocessor era, design was done on paper and realized by writing
assembly code and placing it on microcontrollers. Today, very low-end
applications still use assembly language, but advancements in Real-Time
Workshop and C/Ada compiler technology will soon render such techniques
obsolete.
• Design -> high-level language (HLL) -> object code -> microcontroller: The
advent of efficient HLL compilers led to the realization of paper designs in
languages such as C. HLL code, transformed to assembly language by a
compiler, was then placed on a microcontroller. In the early days of
high-level languages, programmers often inspected the machine generated
assembly code produced by compilers for correctness. Today, it is taken for
granted that the assembly code is correct.
• Design -> modeling tool -> manual HLL coding -> object code ->
microcontroller: When design tools such as Simulink appeared, designers
were able to express system designs graphically and simulate them for
correctness. While this process saved considerable time and improved
performance, designs were still translated to C code manually before being
placed on a microcontroller. This translation process was both time
consuming and error prone.
• Design -> Simulink -> Real-Time Workshop (automatic code generation) ->
object code -> microcontroller. With the addition of Real-Time Workshop,
Simulink itself becomes a very high level language (VHLL). Modeling
constructs in Simulink are the basic elements of the language. The
Real-Time Workshop then compiles models to produce C or Ada code. This
machine-generated code is produced quickly and correctly. The manual
1-7
1
Introduction to the Real-Time Workshop
process of transforming designs to code has now been eliminated, yielding
significant improvements in system design.
The Simulink code generator included within Real-Time Workshop is a
next-generation graphical block diagram compiler. Real-Time Workshop has
capabilities beyond those of a typical HLL compiler. Generated code is highly
readable and customizable. It is normally unnecessary to read the object code
produced by the HLL compiler.. You can use the Real-Time Workshop in a
wide variety of applications, improving your design process.
Key Features
The general goal of the MathWorks toolset, including Real-Time Workshop, is
to enable you to accelerate your design process while reducing cost, decreasing
time to market, and improving quality.
labor
Traditional
development:
Area under
curve indicates
the development cost.
design,
implementation,
test
start
In traditional
development practices
products often
ship before they
are completely tested,
resulting in a product
with defects.
labor
Development via
the MathWorks tools:
time
product
release
time
product
release
Traditional development practices tend to be very labor intensive. Poor tools
often lead to a proliferation of ad hoc software projects that fail to deliver
reusable code. With the MathWorks toolset, you can focus energy on design and
achieve better results in less time with fewer people.
1-8
Product Summary
Real-Time Workshop, along with other components of the MathWorks tools,
provides:
• A rapid and direct path from system design to implementation
• Seamless integration with MATLAB and Simulink
• A simple graphical user interface
• An open and extensible architecture
The following features of Real-Time Workshop enable you to reach the above
goal:
• Code generator for Simulink models
- Generates optimized, customizable code. There are several styles of
generated code, which can be classified as either embedded (production
phase) or rapid prototyping.
- Supports all Simulink features, including 8, 16, and 32 bit integers and
floating-point data types.
- Fixed-Point Blockset and Real-Time Workshop allow for scaling of integer
words ranging from 2 to 128 bits. Code generation is limited by the
implementation of char, short, int, and long in embedded C compiler
environments (usually 8, 16, and 32 bits).
- Generated code is processor independent. The generated code represents
your model exactly. A separate run-time interface is used to execute this
code. We provide several example run-time interfaces as well as
production run-time interfaces.
- Supports any single or multitasking operating system. Also supports
“bare-board” (no operating system) environments.
- The Target Language CompilerTM (TLC) allows extensive customization of
the generated code.
- Provides for custom code generation for S-functions (user-created blocks)
via TLC, enabling you to embed very efficient custom code into the model’s
generated code.
• Extensive model-based debugging support
- External mode enables you to examine what the generated code is doing
by uploading data from your target to the graphical display elements in
your model. There is no need to use a conventional C or Ada debugger to
look at your generated code.
1-9
1
Introduction to the Real-Time Workshop
- External mode also enables you to tune the generated code via your
Simulink model. When you change a parametric value of a block in your
model, the new value is passed down to the generated code, running on
your target, and the corresponding target memory location is updated.
Again, there is no need to use an embedded compiler debugger to perform
this type of operation. Your model is your debugger user interface.
• Integration with Simulink
- Code validation. You can generate code for your model and create a
standalone executable that exercises the generated code and produces a
MAT-file containing the execution results.
- Generated code contains system/block identification tags to help you
identify the block, in your source model, that generated a given line of
code. The MATLAB command hilite_system recognizes these tags and
highlights the corresponding blocks in your model.
- Support for Simulink Data Objects lets you define how your signals and
block parameters interface to the external world.
• Rapid simulations
- Real-Time Workshop supports several ways to speed up your simulations
by creating optimized, model-specific executables.
• Target support
- Turnkey solutions for rapid prototyping substantially reduce design
cycles, allowing for fast turnaround of design iterations.
- Bundled rapid prototyping example targets are provided.
- Add-on targets (Real-Time Windows Target and xPC Target) for PC based
hardware are available from The MathWorks. These targets enable you to
turn a PC with fast, high-quality, low cost hardware into a rapid
prototyping system.
- Supports a variety of third-party hardware and tools, with extensible
device driver support.
• Extensible make process
- Allows for easy integration with any embedded compiler and linker.
- Provides for easy linkage with your hand-written supervisory or
supporting code.
1-10
Product Summary
• Real-Time Workshop Embedded Coder provides:
- Customizable, portable, and readable C code that is designed to be placed
in a production embedded environment.
- More efficient code is created, because inlined S-functions are required
and continuous time states are not allowed.
- Software-in-the-loop. With Real-Time Workshop Embedded Coder, you
can generate code for your embedded application and bring it back into
Simulink for verification via simulation.
- Web-viewable code generation report describes code modules, analyzes the
generated code, and helps to identify code generation optimizations
relevant to your program.
- Annotation of the generated code using the Description block property.
- Hooks for external parameter tuning and signal monitoring are provided
enabling easy interfacing of the generated code in your real-time system.
• Real-Time Workshop Ada Coder provides:
- Customizable, readable, efficient embeddable Ada code.
- Generates more efficient code than the classic Real-Time Workshop
targets. This is possible because all S-functions must be inlined using the
Target Language Compiler.
- Hooks for external parameter tuning and signal monitoring are provided
enabling easy interfacing of the generated code in your real-time system.
- Annotation of the generated code using the Description block property.
Benefits
You can benefit by using Real-Time Workshop in the following applications.
This is not an exhaustive list, but a general survey.
• Production Embedded Real-Time Applications
Real-Time Workshop lets you generate, cross-compile, link, and download
production quality C or Ada code for real-time systems (such as controllers
or DSP applications) onto your target processor directly from Simulink. You
can customize the generated code by inserting S-functions into your model
and specifying, via the Target Language Compiler, what the generated code
should look like. Using the optimized, automatically generated code, you can
1-11
1
Introduction to the Real-Time Workshop
focus your coding efforts on specific features of your product, such as device
drivers and general device interfacing.
• Rapid Prototyping
As a rapid prototyping tool, Real-Time Workshop enables you to implement
your embedded systems designs quickly, without lengthy hand-coding and
debugging. Rapid prototyping is typically used in the software/hardware
integration and testing phases of the design cycle enabling you to:
- Conceptualize solutions graphically in a block diagram modeling
environment.
- Evaluate system performance early on - prior to laying out hardware,
coding production software, or committing to a fixed design.
- Refine your design by rapid iteration between algorithm design and
prototyping.
- Tune parameters while your real-time model runs, using Simulink
operating in external mode as a graphical front end.
You can use Real-Time Workshop to generate downloadable, targeted C code
that runs on top of a real-time operating system (RTOS). Alternatively, you
can generate code to run on the bare hardware at interrupt level, using a
simple rate monotonic scheduling executive that you create from examples
provided with the Real-Time Workshop. There are many rapid prototyping
targets provided; or you can create your own.
During rapid prototyping, the generated code is fully instrumented enabling
direct access via Simulink external mode for easy monitoring and debugging.
The generated code contains a data structure that encapsulates the details
of your model. This data structure is used in the bidirectional connection to
Simulink running in external mode. Using Simulink external mode, you can
monitor signal and tune parameters to further refine your model in rapid
iterations enabling you to achieve desired results quickly.
• Real-Time Simulation
You can create and execute code for an entire system or specified subsystems
for hardware-in-the-loop simulations. Typical applications include training
simulators, real-time model validation, and prototype testing.
• Turnkey Solutions
Bundled Real-Time Workshop targets and third-party turnkey solutions
support a variety of control and DSP applications. The target environments
1-12
Product Summary
include embedded PC, PCI, ISA, VME, and custom hardware, running
off-the-shelf real-time operating systems, DOS, or Microsoft Windows.
Target system processor architectures include Motorola MC680x0 and
PowerPC processors, Intel-80x86 and compatibles, Alpha, and Texas
Instruments DSPs. Third-party vendors are regularly adding other
architectures. For a current list of third-party turnkey solutions, see the
MATLAB Connections Web page: http://www.mathworks.com/products/
connections.
The open environment of Real-Time Workshop also lets you create your own
turnkey solution.
• Intellectual Property Protection
The S-Function Target, in addition to speeding up your simulation, allows
you to protect your intellectual property: the designs and algorithms
embodied in your models. Using the S-Function Target, you can generate
and distribute binaries from your models or subsystems. End users have
access to the interface, but not to the body, of your algorithms.
• Rapid Simulations
The MathWorks tools can be used in the design of most dynamic systems.
Generally Simulink is either used to model a high-fidelity dynamic system
(e.g., an engine) or a real-time system (such as an engine controller or a
signal processing system).
When modeling high-fidelity systems, you can use Real-Time Workshop to
accelerate the design process by speeding up your simulations. This is
achieved by using one of the following Real-Time Workshop components:
- Simulink Accelerator: Creates a dynamically linked library (MEX-file)
from code optimized and generated for your specific model configuration.
This executable is used in place of the normal interpretive mode of
simulation. Typical speed improvements range from 2 to 8 times faster
than normal simulation time. Simulink Accelerator supports both fixed
and variable step solvers. Simulink Accelerator is part of the Simulink
Performance Tools product.
- Rapid Simulation Target: Creates a stand-alone executable from code
optimized and generated for your specific model configuration. This
stand-alone executable does not need to interact with a graphics
subsystem. Typical speed improvements range from 5 to 20 times faster
than normal simulation times. The Rapid Simulation Target is ideal for
1-13
1
Introduction to the Real-Time Workshop
repetitive (batch) simulations where you are adjusting model parameters
or coefficients. Rapid Simulation Target supports only fixed-step solvers.
- S-Function Target: This target, like Simulink Accelerator, creates a
dynamically linked library (MEX-file) from a model. You can incorporate
this component into another model using the Simulink S-function block.
The MathWorks Tools and the Development Process
Figure 1-3 is a high-level view of a traditional development process without the
MathWorks toolset.
Problem/task
formulation
Requirements
specification
Unrealizable or
incorrect requirements
System level
design
System specification,
component interface
specification,
and validation plan
Unfeasible system
specification
Detailed
design
Components specifications
and component validation
Unrealizable or
incorrect design
Software and
hardware
implementation
Prototype system
and test plans
Design error found
during testing
Design validation
via testing
Production system
ready for deployment
Field failure or
manufacturing
problem
Production and
manufacturing
testing
Figure 1-3: Traditional Development Process Without MathWorks Toolset
1-14
Product Summary
In Figure 1-3, each block represents a work phase. Documents are used to
coordinate the different work phases. In this environment, it is easy to go back
one work phase, but hard to go back multiple work phases. In this
environment, design engineers (such as control system engineers or signal
processing engineers) are not usually involved in the prototyping phase until
many months after they have specified the design. This can result in poor time
to market and inferior quality.
In this environment, different tools are used in each phase. Designs are
communicated via paper. This enforces a serial, rather than an iterative,
development process. Developers must re-enter the result of the previous
phase before they can begin work on a new phase. This leads to
miscommunication and errors, resulting in lost work hours. Errors found in
later phases are very expensive and time consuming to correct. Correction
often involves going back several phases. This is difficult because of the poor
communication between the phases.
The MathWorks does not suggest or impose a development process. The
MathWorks toolset can be used to complement any development process. In the
above process, use of our tools in each phase can help eliminate paper work.
Our toolset also lends itself well to the spiral design process shown in
Figure 1-4.
1-15
1
Introduction to the Real-Time Workshop
tai
l ed
de
sig
n
System level design
De
Pr
ob
le
kf
ta s
/
m
or
la
mu
ti o
n
Done
Start
Design validation
via testing
nd
re a
a
w
Soft dware tation
har lemen
imp
Pro
manductio
test ufact n and
ing urin
g
Figure 1-4: Spiral Design Process
Using the MathWorks toolset, your model represents your understanding of
your system. This understanding is passed from phase to phase in the model,
reducing the need to go back to a previous phase. In the event that rework is
necessary in a previous phase, it is easier to transition back one or more
phases, because the same model and tools are used in all phases.
A spiral design process iterates quickly between phases, enabling engineers to
work on innovative features. The only way to do this cost effectively is to use
tools that make it easy to move from one phase to another. For example, in a
matter of minutes a control system engineer or a signal processing engineer
can validate an algorithm on a real-world rapid prototyping system. The spiral
process lends itself naturally to parallelism in the overall development process.
You can provide early working models to validation and production groups,
1-16
Product Summary
involving them in your system development process from the start. This helps
compress the overall development cycle while increasing quality.
Another advantage of the MathWorks toolset is that it enables people to work
on tasks that they are good at and enjoy doing. For example, control system
engineers specialize in design control laws, while embedded system engineers
enjoy pulling together a system consisting of hardware and low-level software.
It is possible to have very talented people perform different roles, but it is not
efficient. Embedded system engineers, for example, are rewarded by specifying
and building the hardware and creating low-level software such as device
drivers, or real-time operating systems. They do not find data entry operations,
such as the manual conversion of a set of equations to efficient code, to be
rewarding. This is where the MathWorks toolset shines. The equations are
represented as models and Real-Time Workshop converts them to highly
efficient code ready for deployment.
1-17
1
Introduction to the Real-Time Workshop
Role of the MathWorks Tools in Your Development Process
The following figure outlines where the MathWorks toolset, including
Real-Time Workshop, helps you in your development process.
Interactive design
Interactive modeling and simulation
MATLAB
and
Toolboxes
High speed simulation
Accelerator,
Simulink,
Stateflow, and Blocksets
S-Function Targets
Batc
Design
Cycle
Sy
Deployed system
Embedded Code
in Custom Target
System testing and tuning
Embedded Code
in Custom Target
Software integration
sign
valid
R ap
ation
id S
imu
Targ lation
et
m
de
Ra
v el
p
op
i
Ta d
me
rg Pr
nt
ets ot
t
(r e ot yp e st in
alg
tim ing
e)
g
in
st
te
e
it
od
un
C
e
ar
ed les
ftw edd du
So
b o
m M
E
Customer defined
monitoring and
parameter tuning
st e
h de
Embedded Code
in Custom Target
Early in the design phase, you will start with MATLAB and Simulink to help
you formulate your problems and create your initial design. Real-Time
Workshop helps with this process by enabling high-speed simulations via
Simulink Accelerator (also part of Simulink Performance Tools), and the
S-function Target for componentization and model speed-up.
After you have a functional model, you may need to tune your model’s
coefficients. This can be done quickly using Real-Time Workshop’s Rapid
1-18
Product Summary
Simulation Target for Monte-Carlo type simulations (varying coefficients over
many simulations).
After you’ve tuned your model, you can move into system development testing
by exercising your model on a rapid prototyping system such as Real-Time
Windows Target or xPC Target. With a rapid prototyping target, you connect
your model to your physical system. This lets you locate design flaws or
modeling errors quickly.
After your prototype system is created, you can use Real-Time Workshop
Embedded Coder to create embeddable code for deployment on your custom
target. The signal monitoring and parameter tuning capabilities enable you to
easily integrate the embedded code into a production environment equipped
with debugging and upgrade capabilities.
Code Formats
The Real-Time Workshop code generator transforms your model to HLL code.
Real-Time Workshop supports a variety of code formats designed for different
execution environments, or targets.
In the traditional embedded system development process, an engineer develops
an algorithm (or equations) to be implemented in an embedded system. These
algorithms are manually converted to a computer language such as C or Ada.
This translation process, usually done by an embedded system engineer, is
much like data entry.
Using Simulink to specify the algorithm (or equations), and Real-Time
Workshop to generate corresponding code, engineers can bypass this
redundant translation step. This enables embedded system engineers to focus
on the key issues involved in creating an embedded system: the hardware
configuration, device drivers, supervisory logic, and supporting logic for the
model equations. Simulink itself is the programming language that expresses
the algorithmic portion of the system.
1-19
1
Introduction to the Real-Time Workshop
The Simulink code generator provided with Real-Time Workshop is an open
“graphical compiler” supporting a variety of code formats. The relationship
between code formats and targets is shown below.
Simulink,
Stateflow, and Blocksets
Modeling and simulation
Simulink Code
Generator
S-function/Accelerator
code format
Real-time
code format
(single-instance)
Stateflow Coder
Real-Time Malloc
code format
(multi-instance)
Embedded
code format
MEX-file
Interface
Generic
Run-Time
Interface
Turnkey
Run-Time
Interface
Rapid
Simulation
Run-Time
Interface
Embedded
Run-Time
Interface
.DLL or .so
for use with
Simulink
Any
computer or
processor
VME, PCI, ISA
and other
environments
Workstation
executable
Embedded
microcontroller /
processor
Integrated
accelerated
simulations
and intellectual
property
protection
Generic workstation
Turnkey
target for model
prototyping
verification and for
targets
use as a starting point
when creating a new
rapid prototyping target
Rapid Simulation
Target
for fast
simulation and
batch processing
Figure 1-5: Relationship Between Code Formats and Targets
1-20
Embedded
targets
Product Summary
S-Function/Accelerator Code Format
This code format, used by the S-Function Target and Simulink Accelerator,
generates code that conforms to Simulink C MEX S-function API.
Real-Time Code Format
The real-time code format is ideally suited for rapid prototyping. This code
format (C only) supports increased monitoring and tuning capabilities,
enabling easy connection with external mode. Real-time code format supports
continuous-time models, discrete-time single- or multirate models, and hybrid
continuous-time and discrete-time models. Real-time code format supports
both inlined and noninlined S-functions. Memory allocation is declared
statically at compile time.
Real-Time Malloc Code Format
The real-time malloc code format is similar to the real-time code format. The
primary difference is that the real-time malloc code format declares memory
dynamically. This supports multiple instances of the same model, with each
instance including a unique data set. Multiple models can be combined into one
executable without name clashing. Multiple instances of a given model can also
be created in one executable.
Embedded Code Format
The embedded code format is designed for embedded targets. The generated
code is optimized for speed, memory usage, and simplicity. Generally, this
format is used in deeply embedded or deployed applications. There are no
dynamic memory allocation calls; all persistent memory is statically allocated.
Real-Time Workshop can generate either C or Ada code in the embedded code
format. Note Ada code requires Real-Time Workshop Ada Coder, an add-on
product.
The embedded code format provides a simplified calling interface and reduced
memory usage. This format manages model and timing data in a compact
real-time object structure. This contrasts with the other code formats, which
use a significantly larger, model-independent Simulink data structure
(SimStruct) to manage the generated code.
The embedded code format improves readability of the generated code, reduces
code size, and speeds up execution. The embedded code format supports all
discrete-time single- or multirate models.
1-21
1
Introduction to the Real-Time Workshop
Because of its optimized and specialized data structures, the embedded code
format supports only inlined S-functions.
Target Environments
The Real-Time Workshop supports many target environments. These include
ready-to-run configurations and third-party targets. You can also develop your
own custom target.
This section begins with a list of available target configurations. Following the
list, we summarize the characteristics of each target.
Available Target Configurations
Target Configurations Bundled with Real-Time Workshop. The MathWorks supplies
the following target configurations with Real-Time Workshop:
• DOS (4GW) Target (example only)
• Generic Real-Time (GRT) Target
• LE/O (Lynx Embedded OSEK) Real-Time Target (example only)
• Rapid Simulation Target
• Tornado (VxWorks) Real-Time Target
Target Configurations Bundled with Real-Time Workshop Ada Coder. The MathWorks
supplies the following target configurations with Real-Time Workshop Ada
Coder (a separate product from the Real-Time Workshop):
• Ada Real-Time Multitasking Target
• Ada Simulation Target
Target Configurations Bundled with Real-Time Workshop Embedded Coder. The
MathWorks supplies the following target configuration with Real-Time
Workshop Embedded Coder (a separate product from the Real-Time
Workshop):
• Real-Time Workshop Embedded Coder Target
Turnkey Rapid Prototyping Target Products. These self-contained solutions ( separate
products from the Real-Time Workshop) include:
• Real-Time Windows Target
1-22
Product Summary
• xPC Target
DSP Target Products. See Texas Instruments DSP Developer's Kit User’s Guide for
information on these targets:
• Texas Instruments Code Composer Studio Target
• Texas Instruments EVM67x Target
Third-Party Targets. Numerous software vendors have developed customized
targets for the Real-Time Workshop. For an up-to-date listing of third-party
targets, visit the MATLAB Connections Web page at http://
www.mathworks.com/products/connections
View Third-Party Solutions by Product Type, and then select RTW Target.
Custom Targets. Typically, to target custom hardware, you must write a harness
(main) program for your target system to execute the generated code, and I/O
device drivers to communicate with your hardware. You must also create a
system target file and a template makefile.
The Real-Time Workshop supplies generic harness programs as starting points
for custom targeting. Chapter 17, “Targeting Real-Time Systems” provides the
information you will need to develop a custom target.
Rapid Simulation Target
Rapid Simulation Target (RSIM) consists of a set of target files for
non-real-time execution on your host computer. RSIM enables you to use the
Real-Time Workshop to generate fast, stand-alone simulations. RSIM allows
batch parameter tuning and downloading of new simulation data (signals)
from a standard MATLAB MAT-file without the need to recompile the model.
The speed of the generated code also makes RSIM ideal for Monte Carlo
simulations. The RSIM target enables the generated code to read and write
data from or to standard MATLAB MAT-files. RSIM reads new signals and
parameters from MAT-files at the start of simulation.
RSIM enables you to run stand-alone, fixed-step simulations on your host
computer or on additional computers. If you need to run 100 large simulations,
you can generate the RSIM model code, compile it, and run the executables on
10 identical computers. The RSIM target allows you to change the model
parameters and the signal data, achieving significant speed improvements by
using a compiled simulation.
1-23
1
Introduction to the Real-Time Workshop
S-Function and Accelerator Targets
S-Function Target provides the ability to transform a model into a Simulink
S-function component. Such a component can then be used in a larger model.
This allows you to speed up simulations and/or reuse code. You can include
multiple instances of the same S-function in the same model, with each
instance maintaining independent data structures. You can also share
S-function components without exposing the details of the a proprietary source
model.
The Accelerator Target is similar to the S-Function Target in that an
S-function is created for a model. The Accelerator Target differs from the
S-Function Target in that the generated S-function operates in the
background. It provides for faster simulations while preserving all existing
simulation capabilities (parameter change, signal visualization, full S-function
support, etc.).
Turnkey Rapid Prototyping Targets
Real-Time Windows Target and xPC Target are add-on products to Real-Time
Workshop. Both of these targets turn an Intel 80x86/Pentium or compatible PC
into a real-time system. Both support a large selection of off-the-shelf I/O cards
(both ISA and PCI).
With turnkey target systems, all you need to do is install the MathWorks
software and a compiler, and insert the I/O cards. You can then use a PC as a
real-time system connected to external devices via the I/O cards.
Real-Time Windows Target. Real-Time Windows Target brings rapid prototyping
and hardware-in-the-loop simulation to your desktop. It is the most portable
solution available today for rapid prototyping and hardware-in-the-loop
simulation when used on a laptop outfitted with a PCMCIA I/O card.
Real-Time Windows Target is ideal since a second PC or other real-time
hardware is often unnecessary, impractical or cumbersome.
1-24
Product Summary
This picture shows the basic components of the Real-Time Windows Target.
MATLAB/Simulink
Real-Time Workshop
Real-time debugging
of your model using
Simulink external mode:
- Run-time parameter tuning
- Data uploading to scopes
- Data uploading to display blocks
- Data uploading to custom blocks
(S-functions)
- Full Dials & Gauges support
- Support for general simulation viewing
devices
Visual C/C++ or
Watcom C/C++ Compiler
Hard Real-Time Task Running
Underneath Windows
I/O Boards in PC
Modeling and simulation
Code generation
Automated build and download process
Single-box solution
10 kHz + sample rates
Support for over 100 I/O boards
(more added on request)
As a prototyping environment, Real-Time Windows Target is exceptionally
easy to use, due to tight integration with Simulink and external mode. It is
much like using Simulink itself, with the added benefit of gaining real-time
performance and connectivity to the real world through a wide selection of
supported I/O boards. You can control your real-time execution with buttons
located on the Simulink toolbar. Parameter tuning is done “on-the-fly,” by
simply editing Simulink blocks and changing parameter values. For viewing
signals, Real-Time Windows Target uses standard Simulink Scope blocks,
without any need to alter your Simulink block diagram. Signal data can also be
logged to a file or set of files for later analysis in MATLAB.
Real-Time Windows Target is often called the “one-box rapid prototyping
system,” since both Simulink and the generated code run on the same PC. A
run-time interface enables you to run generated code on the same processor
that runs Windows NT or Windows 95/98/2000. The generated code executes in
1-25
1
Introduction to the Real-Time Workshop
hard real-time, allowing Windows to execute when there are free CPU cycles.
Real-Time Windows Target supports over 100 I/O boards, including ISA, PCI,
CompactPCI, and PCMCIA. Sample rates in excess of 10 to 20 kHz can be
achieved on Pentium PCs.
In universities, Real-Time Windows Target provides a cost effective solution
since only a single computer is required. In commercial applications,
Real-Time Windows Target is often used at an engineer’s desk prior to taking
a project to an expensive dedicated real-time testing environment. Its
portability is unrivaled, allowing you to use your laptop as a real-time test bed
for applications in the field.
Figure 1-6 illustrates the use of Real-Time Windows Target in a model using
magnetic levitation to suspend a metal ball in midair. The system is controlled
by the model shown in Figure 1-7.
Electromagnet
Si mulink &
Real-Time
Workshop
Metallic ball
PMCIA I/O
Proximity sensor
Sensor and actuator
connector cable
Figure 1-6: Magnetic Levitation System
1-26
Product Summary
Metallic ball height offset
oscillation frequency and amplitude
Strip chart shows height of metallic ball
Figure 1-7: Model for Controlling Magnetic Levitation System
xPC Target. xPC Target is often referred to as a two-box solution. xPC Target
requires two PCs: a host PC to run Simulink, and a target PC to run the
generated code. The target PC runs an extremely compact real-time kernel
that uses 32-bit protected mode. Communication between the host and the
target is supported either via an Ethernet networking connection or via a serial
cable. Figure 1-8 illustrates the XPC target in a rapid prototyping
environment.
1-27
1
Introduction to the Real-Time Workshop
Since the target PC is dedicated to running the generated code, xPC Target
achieves both increased performance and increased system stability. The
target PC is required to have a PC-compatible architecture, but can have any
of several form factors, including PC motherboards, CompactPCI,PC104, and
single-board computers (SBCs).
xPC Target is also useful in limited production environments. Given the cost of
PC hardware, it may make sense to deploy xPC Target in low volume or
high-end production systems. This is achieved by using the xPC Target
Embedded Option, which is an add-on to xPC Target.
Figure 1-8: xPC Target Rapid Prototyping Environment
Rapid Prototyping Targets
There are two classes of rapid prototyping targets: those using the real-time
code format and those using the real-time malloc code format. These differ in
the way they allocate memory (statically versus dynamically). Most rapid
prototyping targets use the real-time code format.
We define two forms of rapid prototyping environments:
• Heterogeneous rapid prototyping environments use rapid prototyping
hardware (such as an Intel-80x86/Pentium or similar processor) that differs
1-28
Product Summary
from the final production hardware. For example, an Intel-80x86/Pentium or
similar processor might be used during rapid prototyping of a system that is
eventually deployed onto a fixed-point Motorola microcontroller.
• Homogeneous rapid prototyping environments are characterized by the use
of similar hardware for the rapid prototyping system and the final
production system. The main difference is that the rapid prototyping system
has extra memory and/or interfacing hardware to support increased
debugging capabilities, such as communication with external mode.
Homogeneous rapid prototyping environments eliminate uncertainty because
the rapid prototyping environment is closer to the final production system.
However, a turnkey system for your specific hardware may not exist. In this
case, you must weigh the advantages and disadvantages of using one of the
existing turnkey systems for heterogeneous rapid prototyping, versus creating
a homogeneous rapid prototyping environment.
Several rapid prototyping targets are bundled with Real-Time Workshop.
Generic Real-Time (GRT) Target. This target uses the real-time code format and
supports external mode communication. It is designed to be used as a starting
point when creating a custom rapid prototyping target, or for validating the
generated code on your workstation.
Generic Real-Time Malloc (GRTM) Target. This target is similar to the GRT target
but it uses the real-time malloc code format. This format uses the C malloc and
free routines to manage all data. With this code format, you can have multiple
instances of your model and/or multiple models in one executable.
Tornado Target. The Tornado target uses the real-time or real-time malloc code
format. A set of run-time interface files are provided to execute your models on
the Wind River System’s real-time operating system, VxWorks. The Tornado
target supports singletasking, multitasking, and hybrid continuous and
discrete-time models.
The Tornado run-time interface and device driver files can also be used as a
starting point when targeting other real-time operating system environments.
The run-time interface provides full support for external mode, enabling you to
take full advantage of the debugging capabilities for parameter tuning and
data monitoring via graphical devices.
1-29
1
Introduction to the Real-Time Workshop
DOS Target. The DOS target (provided as an example only) uses the real-time
code format to turn a PC running the DOS operating system into a real-time
system. This target includes a set of run-time interface files for executing the
generated code. This run-time interface installs interrupt service routines to
execute the generated code and handle other interrupts. While the DOS target
is running, the user does not have access to the DOS operating system. Sample
device drivers are provided.
The MathWorks recommends that you use Real-Time Windows Target or xPC
Target as alternatives to the DOS Target. The DOS target is provided only as
an example and its support will be discontinued in the future.
OSEK Targets. The OSEK target (provided as an example only) lets you use the
automotive standard open real-time operating system. The run-time interface
and OSEK configuration files that are included with this target make it easy
to port applications to a wide range of OSEK environments.
Embedded Targets
The embedded real-time target is the main component of the Real-Time
Workshop Embedded Coder. It consists of a set of run-time interface files that
drive code, generated in the embedded code format, on your workstation. This
target is ideal for memory-constrained embedded applications. Real-Time
Workshop supports generation of embedded code in both C and Ada.
In its default configuration, the embedded real-time target is designed for use
as a starting point for targeting custom embedded applications, and as a means
by which you can validate the generated code. To create a custom embedded
target, you start with the embedded real-time target run-time interface files
and edit them as needed for your application.
In the terminology of Real-Time Workshop, an embedded target is a deeply
embedded system. Note that it is possible to use a rapid prototyping target in
an embedded (production) environment. This may make more sense in your
application.
Code Generation Optimizations
The Simulink code generator included with Real-Time Workshop is packed
with optimizations to help create fast and minimal size code. The optimizations
are classified either as cross-block optimizations, or block specific
optimizations. Cross-block optimizations apply to groups of blocks or the
1-30
Product Summary
general structure of a model. Block specific optimizations are handled locally
by the object generating code for a given block. Listing each block specific
optimization here is not practical; suffice it to say that the Target Language
Compiler technology generates very tight and fast code for each block in your
model.
The following sections discuss some of the cross-block optimizations.
Multirate Support
One of the more powerful features of Simulink is its implicit support for
multirate systems. The ability to run different parts of a model at different
rates guarantees optimal use of the target processor. In addition, Simulink
enforces correctness by requiring that you create your model in a manner that
guarantees deterministic execution.
Inlining S-Function Blocks for Optimal Code
The ability to add blocks to Simulink via S-functions is enhanced by the Target
Language Compiler. You can create blocks that embed the minimal amount of
instructions into the generated code. For example, if you create a device driver
using an S-function, you can have the generated code produce one line for the
device read, as in the following code fragment.
mdlOutputs(void)
{
.
.
rtB.deviceout = READHW(); /* Macro to read hw device using
.
assembly code */
.
}
Note that the generic S-function API is suitable for any basic block-type
operation.
Loop Rolling Threshold
The code generated for blocks can contain for loops, or the loop iterations can
be “flattened out” into inline statements. For example, the general gain block
equation is
for (i = 0; i < N; i++) {
y[i] = k[i] * u[i];
}
1-31
1
Introduction to the Real-Time Workshop
If N is less than a specified roll threshold, Real-Time Workshop expands out the
for loop, otherwise Real-Time Workshop retains the for loop.
Tightly Coupled Optimal Stateflow Interface
The generated code for models that combine Simulink blocks and Stateflow
charts is tightly integrated and very efficient.
Stateflow Optimizations
The Stateflow Coder contains a large number of optimizations that produce
highly readable and very efficient generated code.
Inlining of Systems
In Simulink, a system starting at a nonvirtual subsystem boundary (e.g. an
enabled, triggered, enabled and triggered, function-call, or atomic subsystem)
can be inlined by selecting the RTW inline subsystem option from the
subsystem block properties dialog. The default action is to inline the
subsystem, unless it is a function-call subsystem with multiple callers.
Block I/O Reuse
Consider a model with a D/A converter feeding a gain block (for scaling), then
feeding a transfer function block, then feeding a A/D block. If all signals refer
to the same memory location, then less memory will be used. This is referred
to as block I/O reuse. It is a powerful optimization technique for re-using
memory locations. It reduces the number of global variables improving the
executing speed (faster execution) and reducing the size of the generated code.
Declaration of Block I/O Variables in Local Scope
If input/output signal variables are not used across function scope, then they
can be placed in local scope. This optimization technique reduces code size and
improves the execution speed (faster execution).
Inlining of Parameters
If you select the Inline parameters option, the numeric values of block
parameters that represent coefficients are embedded in the generated code. If
Inline parameters is off, block parameters that represent coefficients can be
changed while the model is executing.
1-32
Product Summary
Note that it is still possible to “tune” key parameters by using the Workspace
parameter attributes dialog.
Inlining of Invariant Signals
An invariant signal is a block output signal that does not change during
Simulink simulation. For example, the output of a sum block that is fed by two
constants cannot change. When Inline invariant signals is specified, a single
numeric value is placed in the generated code to represent the output value of
the sum block. The Inline invariant signals option is available when the
Inline parameters option is on.
Parameter Pooling
The Parameter pooling option is available when Inline parameters is
selected. If Real-Time Workshop detects identical usage of parameters (e.g. two
lookup tables with same tables), it will pool these parameters together, thereby
reducing code size.
Block Reduction Optimizations
Real-Time Workshop can detect block patterns (e.g. an accumulator
represented by a constant, sum and a delay block) and reduce these patterns to
a single operation, resulting in very efficient generated code.
Creation of Contiguous Signals to Speed Block Computations
Some block algorithms (for example a matrix multiply) can be implemented
more efficiently if the signals entering the blocks are contiguous.
Noncontiguous signals occur because of the handling of virtual blocks. For
example, the output of a Mux block is noncontiguous. When this class of block
requires a contiguous signal, Simulink will insert (if needed) a copy block
operator to make the signal contiguous. This results in better code efficiency.
Support for Noncontiguous Signals by Blocks
Noncontiguous signals occur because of the block virtualization capabilities of
Simulink. For example, the output of a Mux block is generally a noncontiguous
signal (i.e., the output signal consists of signals from multiple sources). General
blocks in Simulink support this behavior by generating very efficient code to
handle each different signal source in a noncontiguous signal.
1-33
1
Introduction to the Real-Time Workshop
Data Type Support
Simulink models support a wide range of data types. You can use double
precision values to represent real-world values and then when needed use
integers or Booleans for discrete valued signals. You can also use fixed-point
(integer scaling) capabilities to target models for fixed-point embedded
processors. The wide selection of data types in Simulink models enables you to
realize your models efficiently.
Frame Support
In signal processing, a frame of data represents time sampled sequences of an
input. Many devices have support in hardware for collecting frames of data.
With Simulink and the DSP Blockset, you can use frames and perform frame
based operations on the data. Frames are a very efficient way of handling high
frequency signal processing applications.
Matrix Support
Most blocks in Simulink support the use of matrices. This enables you to create
models that represent high levels of abstractions and produce very efficient
generated code.
Virtualization of Blocks
Nearly half of the blocks in a typical model are connection type blocks (e.g.
Virtual Subsystem, Inport, Outport, Goto, From, Data Store Memory, Selector,
Bus Selector, Mux, Demux, Ground, and Terminator). These blocks are
provided to enable you to create complex models with your desired levels of
abstraction. Simulink treats these blocks as virtual, meaning that they impose
no overhead during simulation or in the generated code.
Open and Extensible Modeling Environment
The Simulink / Real-Time Workshop environment is extensible in several
ways.
Custom Code Support
S-functions are dynamically linked objects (.DLL or .so) that bind with
Simulink to extend the modeling environment. By developing S-functions, you
can add custom block algorithms to Simulink. Such S-functions provide
supporting logic for the model. S-functions are flexible, allowing you to
1-34
Product Summary
implement complex algorithmic equations or basic low-level device drivers. The
Real-Time Workshop support for S-functions includes the ability to inline
S-function code directly into the generated code. Inlining, supported by the
Target Language Compiler, can significantly reduce memory usage and calling
overhead.
Support for Supervisory Code
The generated code implements an algorithm that corresponds exactly to the
algorithm defined in your model. With the embedded code format, you can call
the generated model code as a procedure. This enables you to incorporate the
generated code into larger systems that decide when to execute the generated
code. Conceptually, you can think of the generated code as set of equations,
wrapped in a function called by your supervisory code. This facilitates
integration of model code into large existing systems, or into environments that
consist of more than signal-flow processing (Simulink) and state machines
(Stateflow).
Monitoring and Parameter Tuning APIs
External mode provides a communication channel for interfacing the
generated code running on your target with Simulink. External mode lets you
use Simulink as a debugging front end for an executing model. Typically, the
external mode configuration works in conjunction with either the real-time
code format or the real-time malloc code format.
The Real-Time Workshop provides other mechanisms for making model
signals and block parameters visible to your own monitoring and tuning
interfaces. These mechanisms, suitable for use on all code formats, include:
• The Model Parameter Configuration dialog enables you to declare how to
allocate memory for variables that are used in your model. For example, if a
Gain block contains the variable k, you can declare k as an external variable,
a pointer to an external variable, a global variable, or let the Real-Time
Workshop decide where and how to declare the variable.
The Model Parameter Configuration feature enables you to specify block
parameters as tunable or global. This gives your supervisory code complete
access to any block parameter variables that you may need to alter while
your model is executing. You can also use this feature to interface
parameters to specific constant read-only memory locations.
1-35
1
Introduction to the Real-Time Workshop
• You can mark signals in your model as test points. Declaring a test point
indicates that you may want to see the signal’s value while the model is
executing. After marking a signal as a test point, you specify how the
memory for the signal is to be allocated. This gives your supervisory code
complete read-only access to signals in your model, so that you can monitor
the internal workings of your model.
• C and Target Language Compiler APIs provide another form of access to the
signals and parameters in your model. The Target Language Compiler API
is a means to access the internal signals and parameters during code
generation. With this information, you can generate monitoring/tuning code
that is optimized specifically for your model or target.
Interrupt Support
Interrupt blocks enable you to create models that handle synchronous and
asynchronous events, including interrupt service routines (ISRs),
hardware-generated interrupts, and asynchronous read and write operations.
The blocks provided work with the Tornado target. You can use these blocks as
templates when creating new interrupt blocks for your target environment.
Interrupt blocks include:
• Asynchronous Interrupt block
• Task Synchronization block
• Asynchronous Buffer block (read)
• Asynchronous Buffer block (write)
• Asynchronous Rate Transition block
Custom Code Library
The Custom Code library contains a set of blocks that allow you to easily insert
target-specific code into your model without the need of an inlined S-function.
Code can be placed strategically throughout the model.
1-36
Getting Started: Basic Concepts and Tutorials
Getting Started: Basic Concepts and Tutorials
This section is designed to help you to obtain hands-on experience with the
Real-Time Workshop in short order. There are two parts, which we recommend
you read in order:
1 “Basic Real-Time Workshop Concepts” on page 1-37 introduces concepts and
terminology you should know before working with the Real Time Workshop.
2 “Quick Start Tutorials” on page 1-40 provides several hands-on exercises
that demonstrate the Real-Time Workshop user interface, code generation
and build process, and other essential features.
Basic Real-Time Workshop Concepts
Target and Host
A target is an environment — hardware or operating system — on which your
generated code will run. The process of specifying this environment is called
targeting.
The process of generating target-specific code is controlled by a system target
file, a template makefile, and a make command. To select a desired target, you
can specify these items individually, or you can choose from a wide variety of
ready-to-run configurations.
The host is the system you use to run MATLAB, Simulink, and the Real-Time
Workshop. Using the build tools on the host, you create code and an executable
that runs on your target system.
Available Target Configurations
The Real-Time Workshop supports many target environments. These include
ready-to-run configurations and third-party targets. You can also develop your
own custom target.
For a complete list of bundled targets, with their associated system target files
and template makefiles, see “The System Target File Browser” on page 3-34.
Code Formats
A code format specifies a framework for code generation suited for specific
applications.
1-37
1
Introduction to the Real-Time Workshop
When you choose a target configuration, you implicitly choose a code format. If
you use the Real-Time Workshop Embedded Coder, for example, the code
generated will be in embedded C format. The embedded C code format is a
compact format designed for production code generation. Its small code size,
memory usage, and simple call structure make it optimal for embedded
applications.
Many other targets, such as the generic real-time (GRT) target, use the
real-time code format. This format, less compact but more flexible, is optimal
for rapid prototyping applications.
For a complete discussion of available code formats, see Chapter 4, “Generated
Code Formats.”
The Generic Real-Time Target
The Real-Time Workshop provides a generic real-time development target. The
generic real-time (GRT) target provides an environment for simulating
fixed-step models in single or multitasking mode. A program generated with
the GRT target runs your model, in simulated time, as a stand-alone program
on your workstation.
The GRT target allows you to perform code validation by logging system
outputs, states, and simulation time to a data file. The data file can then be
loaded into the MATLAB workspace for analysis or comparison with the output
of the original model.
The GRT target also provides a starting point for targeting custom hardware.
You can modify the GRT harness program, grt_main.c, to execute code
generated from your model at interrupt level under control of a real-time clock.
Target Language Compiler Files
The Real-Time Workshop uses Target Language Compiler files (or TLC files) to
translate your Simulink model into code. The Target Language Compiler uses
two types of TLC files during the code generation and build process. The system
target file, which describes how to generate code for a chosen target, is the entry
point for the TLC program that creates the executable. Block target files define
how the code looks for each of the Simulink blocks in your model.
System and block target files have the extension .tlc. By convention, a system
target file has a name corresponding to your target. For example, grt.tlc is
the system target file for the generic real-time (GRT) target.
1-38
Getting Started: Basic Concepts and Tutorials
Template Makefiles
The Real-Time Workshop uses template makefiles to build an executable from
the generated code.
The Real-Time Workshop build process creates a makefile from the template
makefile. Each line from the template makefile is copied into the makefile;
tokens encountered during this process are expanded into the makefile.
The name of the makefile created by the build process is model.mk. The
model.mk file is passed to a make utility. The make utility compiles and links
an executable from a set of files.
By convention, a template makefile has an extension of .tmf and a name
corresponding to your target and compiler. For example, grt_vc.tmf is the
template makefile for building a generic real-time program under Visual C/
C++.
The Build Process
A high-level M-file command controls the Real-Time Workshop build process.
The default command, used with most targets, is make_rtw.When you initiate
a build, the Real-Time Workshop invokes make_rtw.The make_rtw command, in
turn, invokes the Target Language Compiler and other utilities such as make.
The build process consists of the following stages:
1 First, make_rtw compiles the block diagram and generates a model
description file, model.rtw.
2 Next, make_rtw invokes the Target Language Compiler to generate
target-specific code, processing model.rtw as specified by the selected
system target file.
3 Next, make_rtw creates a makefile, model.mk, from the selected template
makefile.
4 Finally, make is invoked. make compiles and links a program from the
generated code, as instructed in the generated makefile.
“Automatic Program Building” in Chapter 2 gives an overview of the build
process. Chapter 3, “Code Generation and the Build Process” gives full details
on code generation and build options and parameters.
1-39
1
Introduction to the Real-Time Workshop
Model Parameters and Code Generation
The simulation parameters of your model directly affect code generation and
program building. For example, if your model is configured to stop execution
after 60 seconds, the program generated from your model will also run for 60
seconds. The Real-Time Workshop also imposes certain requirements and
restrictions on the model from which code is generated.
Before you generate code and build an executable, you must verify that you
have set the model parameters correctly in the Simulation Parameters dialog
box. See “Simulation Parameters and Code Generation” in Chapter 3 for more
information.
Quick Start Tutorials
This section provides hands-on experience with the code generation, program
building, data logging, and code validation capabilities of the Real-Time
Workshop.
“Tutorial 1: Building a Generic Real-Time Program” on page 1-42 shows how to
generate C code from a Simulink demonstration model and build an executable
program.
“Tutorial 2: Data Logging” on page 1-49 explains how to modify the
demonstration program to save data in a MATLAB MAT-file, for plotting.
“Tutorial 3: Code Validation” on page 1-52, demonstrates how to validate the
generated program by comparing its output to that of the original model.
“Tutorial 4: A First Look at Generated Code” on page 1-56 examines code
generated from a very simple model, illustrating the effect of one of the
Real-Time Workshop code generation options.
These tutorials assume basic familiarity with MATLAB and Simulink. You
should also read “Getting Started: Basic Concepts and Tutorials” on page 1-37
before proceeding.
The procedures for building, running, and testing your programs are almost
identical in UNIX and PC environments. The discussion notes differences
where applicable.
Make sure that a MATLAB compatible C compiler is installed on your system
before proceeding with these tutorials. See the “Preface” for more information
on supported compilers and compiler installation.
1-40
Getting Started: Basic Concepts and Tutorials
The f14 Demonstration Model
Tutorials 1-3 use a demonstration Simulink model, f14.mdl, from the
matlabroot/toolbox/simulink/simdemos/aerospace directory. (By default,
this directory is on your MATLAB path.) f14 is a model of a flight controller for
the longitudinal motion of a Grumman Aerospace F-14 aircraft.
1-41
1
Introduction to the Real-Time Workshop
This is the f14 model.
The model simulates the pilot’s stick input with a square wave having a
frequency of 0.5 (radians per second) and an amplitude of ± 1. The system
outputs are the aircraft angle of attack and the G forces experienced by the
pilot. The input and outputs are visually monitored by Scope blocks.
Tutorial 1: Building a Generic Real-Time Program
This tutorial walks through the process of generating C code and building an
executable program from the demonstration model. The resultant stand-alone
program runs on your workstation, independent of external timing and events.
Working and Build Directories
It is convenient to work with a local copy of the f14 model, stored in its own
directory, f14example. This discussion assumes that the f14example directory
resides on drive d:. Set up your working directory as follows:
1-42
Getting Started: Basic Concepts and Tutorials
1 Create the directory from the MATLAB command line by typing
!mkdir d:\f14example (on PC)
or
!mkdir ~/f14example (on UNIX)
2 Make f14example your working directory.
cd d:/f14example
3 Open the f14 model.
f14
The model appears in the Simulink window.
4 From the File menu, choose Save As. Save a copy of the f14 model
as d:/f14example/f14rtw.mdl.
Be aware that during code generation, the Real-Time Workshop creates a build
directory within your working directory. The build directory name is
model_target_rtw, derived from the name of the source model and the chosen
target. The build directory stores generated source code and other files created
during the build process. We examine the build directory and its contents at the
end of this tutorial.
Setting Program Parameters
To generate code correctly from the f14rtw model, you must change some of the
simulation parameters. In particular, note that the Real-Time Workshop
requires the use of a fixed-step solver. To set parameters, use the Simulation
Parameters dialog box as follows:
1 From the Simulation menu, choose Simulation Parameters. The
Simulation Parameters dialog box opens.
1-43
1
Introduction to the Real-Time Workshop
2 Click the Solver tab and enter the following parameter values on the Solver
page.
Start Time: 0.0
Stop Time: 60
Solver options: set Type to Fixed-step. Select the ode5 (Dormand-Prince)
solver algorithm.
Fixed step size: 0.05
Mode: Single Tasking
3 Click Apply. Then click OK to close the dialog box.
4 Save the model. Simulation parameters persist with the model, for use in
future sessions.
Figure 1-9 shows the Solver page with the correct parameter settings.
Figure 1-9: Solver Page of Simulation Parameters Dialog Box
1-44
Getting Started: Basic Concepts and Tutorials
Selecting the Target Configuration
To specify the desired target configuration, you choose a system target file, a
template makefile, and a make command.
In these tutorials, you do not need to specify these parameters individually.
Instead, you use the ready-to-run generic real-time (GRT) target configuration.
The GRT target is designed to build a stand-alone executable program that
runs on your workstation.
To select the GRT target:
1 From the Simulation menu, choose Simulation Parameters. The
Simulation Parameters dialog box opens.
2 Click on the Real-Time Workshop tab of the Simulation Parameters dialog
box. The Real-Time Workshop page activates.
3 The Real-Time Workshop page has several sub-pages, which are selected via
the Category pull-down menu. Select Target configuration from the
Category menu.
Figure 1-10: Real-Time Workshop Page (Target Configuration Category)
4 Click on the Browse button next to the System target file field. This opens
the System Target File Browser. The browser displays a list of all currently
available target configurations. When you select a target configuration, the
1-45
1
Introduction to the Real-Time Workshop
Real-Time Workshop automatically chooses the appropriate system target
file, template makefile, and make command.
Figure 1-11: The System Target File Browser
5 From the list of available configurations, select Generic Real-Time Target
(as in Figure 1-11) and then click OK.
6 The Real-Time Workshop page now displays the correct system target file
(grt.tlc), template makefile (grt_default_tmf), and make command
(make_rtw), as in Figure 1-10.
1-46
Getting Started: Basic Concepts and Tutorials
7 Select General code generation options from the Category menu. The
options displayed here are common to all target configurations. Check to
make sure that all options are set to their defaults, as below.
8 Select GRT code generation options from the Category menu. The options
displayed here are specific to the GRT target. Check to make sure that all
options are set to their defaults, as below.
9 Select TLC debugging from the Category menu. Make sure that all options
in this category are deselected.
1-47
1
Introduction to the Real-Time Workshop
10 Select Target configuration from the Category menu. Make sure that the
Generate code only option is deselected.
11 Save the model.
Building and Running the Program
The Real-Time Workshop build process generates C code from the model, and
then compiles and links the generated program. To build and run the program:
1 Click the Build button in the Simulation Parameters dialog box to start
the build process.
2 A number of messages concerning code generation and compilation appear
in the MATLAB command window. The initial messages are
### Starting Real-Time Workshop build procedure for model: f14rtw
### Generating code into build directory: .\f14rtw_grt_rtw
The content of the succeeding messages depends on your compiler and
operating system.The final message is
### Successful completion of Real-Time Workshop build procedure
for model: f14rtw
3 The working directory now contains an executable, f14rtw.exe (on PC), or
f14rtw (on UNIX). In addition, a build directory, f14rtw_grt_rtw, has been
created.
To observe the contents of the working directory after the build, type the dir
command from the MATLAB command window.
dir
.
..
f14rtw.exe
f14rtw.mdl
f14rtw_grt_rtw
4 To run the executable from the MATLAB command window, type:
!f14rtw
The “!” character passes the command that follows it to the operating
system, which runs the stand-alone f14rtw program.
The program produces one line of output.
1-48
Getting Started: Basic Concepts and Tutorials
**starting the model**
5 Finally, to see the contents of the build directory, type
dir f14rtw_grt_rtw
Contents of the Build Directory
The build process creates a build directory and names it model_target_rtw,
concatenating the name of the source model and the chosen target. In this
example, the build directory is named f14rtw_grt_rtw.
f14rtw_grt_rtw contains these generated source code files:
• f14rtw.c — the stand-alone C code that implements the model.
• f14rtw.h — an include header file containing information about the state
variables
• f14rtw_export.h — an include header file containing information about
exported signals and parameters
The build directory also contains other files used in the build process, such as
the object (.obj) files and the generated makefile (f14rtw.mk).
Tutorial 2: Data Logging
The Real-Time Workshop 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 tutorial, data
generated by the model f14rtw is logged to the file f14rtw.mat
To configure data logging, you use the Workspace I/O page of the Simulation
Parameters dialog. The process is nearly the same as configuring a Simulink
model to save output to the MATLAB workspace. For each workspace return
variable you define and enable, the Real-Time Workshop 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 (by
default) rt_tout.
In this tutorial, you will modify the f14rtw model such that the generated
program saves the simulation time and system outputs to the file f14rtw.mat.
1-49
1
Introduction to the Real-Time Workshop
Then, you will load the data into the MATLAB workspace and plot simulation
time against one of the outputs.
To use the data logging feature:
1 Select the Workspace I/O page of the Simulation Parameters dialog box.
The Workspace I/O page specifies how data is loaded from and saved to the
workspace.
2 Check the Time option. Enabling the Time option causes the Real-Time
Workshop to generate code that logs the simulation time to the MAT-file
matrix rt_tout.
3 Check the Output option. Enabling the Output option causes the Real-Time
Workshop to generate code that logs the root Output blocks (Angle of Attack
and Pilot G Force) to the MAT-file matrix rt_yout.
The sort order of the rt_yout array is based on the port number of the
Outport blocks, starting with 1. Angle of Attack and Pilot G Force will be
logged to rt_yout(:,1) and rt_yout(:,2), respectively.
4 If any other options are enabled, uncheck them. Set Decimation to 1 and
Format to Array. Then click Apply.
5 Open the Pilot G Force Scope block. To run the model, click on the Start
button in the toolbar of the Simulink window. The Scope displays below:
1-50
Getting Started: Basic Concepts and Tutorials
6 Verify that the simulation time and Pilot G Force outputs have been
correctly saved to the workspace by plotting simulation time versus Pilot G
Force.
plot(tout,yout(:,2))
The resultant plot is shown below.
1-51
1
Introduction to the Real-Time Workshop
7 The f14rtw program must be rebuilt, because you have changed the model
by enabling data logging. Select Build Model from the Real-Time
Workshop submenu of the Tools menu in the Simulink window. This is an
alternative way to start the Real-Time Workshop build process. It is
identical to using Build button in the Simulation Parameters dialog box.
8 When the build concludes, run the executable with the command
!f14rtw
9 The program now produces two message lines, indicating that the MAT-file
has been written.
**starting the model**
** created f14rtw.mat **
10 Clear the workspace, load the MAT-file data, and look at the workspace
variables.
clear
load f14rtw.mat
whos
11 Observe that the variables rt_tout (time) and rt_yout (G Force and Angle
of Attack) have been loaded from the file. Plot G Force as a function of time.
plot(rt_tout,rt_yout(:,2))
12 The plot should appear identical to the plot you produced in step 5 above.
Tutorial 3: Code Validation
In this tutorial, the code generated from the f14rtw model is validated against
the model. The code is validated by capturing and comparing data from runs of
the Simulink model and the generated program.
1-52
Getting Started: Basic Concepts and Tutorials
Note To obtain a valid comparison between outputs of the model and the
generated program, make sure that you have selected the same integration
scheme (fixed-step, ode5 (Dormand-Prince)) and the same step size (0.05)
for both the Simulink run and the Real-Time Workshop build process. Also,
make sure that the model is configured to save simulation time, as in Tutorial
2.
Logging Signals via Scope Blocks
This example uses Scope blocks (rather than Outport blocks) to log both input
and output data. To configure the Scope blocks to log data:
1 In the previous exercise, you cleared the workspace. Before proceeding with
this tutorial, reload the model so that the proper workspace variables are
declared and initialized.
f14rtw
2 Open the Stick Input Scope block and click on the Properties button on the
toolbar of the Scope window. The Scope Properties dialog opens.
3 Select the Data History page of the Scope Properties dialog.
4 Check the Save data to workspace option and enter the name of the
variable (Stick_input) that is to receive the Scope data.
In the example above, the Stick Input signal will be logged to the matrix
Stick_input during simulation. The generated code will log the same signal
1-53
1
Introduction to the Real-Time Workshop
data to the MAT-file variable rt_Stick_input during a run of the
executable program.
5 Click the Apply button.
6 Configure the Pilot G Force and Angle of Attack Scope blocks similarly,
using the variable names Pilot_G_force and Angle_of_attack.
7 Save the model.
Logging Simulation Data
The next step is to run the simulation and log the signal data from the Scope
blocks:
1 Open the Stick Input, Pilot G Force, and Angle of Attack Scope blocks.
2 Run the model. The Scope blocks display.
3 Use the whos command to observe that the matrix variables Stick_input,
Pilot_G_force, and Angle_of_attack have been saved to the workspace.
4 Plot one or more of the logged variables against simulation time. For
example,
plot(tout, Stick_input(:,2))
Logging Data from the Generated Program
Since you have modified the model, you must rebuild and run the f14rtw
executable in order to obtain a valid data file:
1-54
Getting Started: Basic Concepts and Tutorials
1 Select Build Model from the Real-Time Workshop submenu of the Tools
menu in the Simulink window.
2 When the build completes, run the stand-alone program from MATLAB.
!f14rtw
3 Load the data file f14rtw.mat and observe the workspace variables.
load f14rtw
whos
The data loaded from the MAT-file will include rt_Pilot_G_force,
rt_Angle_of_attack, rt_Stick_input, and rt_tout.
4 You can now use MATLAB to plot the three workspace variables as a
function of time.
plot(rt_tout,rt_Stick_input(:,2))
figure
plot(rt_tout,rt_Pilot_G_force(:,2))
figure
plot(rt_tout,rt_Angle_of_attack(:,2))
Comparing Results of the Simulation
and the Generated Program
Your Simulink simulations and the generated code should produce nearly
identical output.
1-55
1
Introduction to the Real-Time Workshop
You have now obtained data from a Simulink run of the model, and from a run
of the program generated from the model. It is a simple matter to compare the
f14rtw model output to the results achieved by the Real-Time Workshop.
Comparing Angle_of_attack (simulation output) to rt_Angle_of_attack
(generated program output) produces
max(abs(rt_Angle_of_attack-Angle_of_attack))
ans =
1.0e-015 *
0
0.4441
Comparing Pilot_G_force (simulation output) to rt_Pilot_G_force
(generated program output) produces
max(abs(rt_Pilot_G_force-Pilot_G_force))
ans =
1.0e-013 *
0
0.7283
So overall agreement is within 10-13. This slight error can be caused by many
factors, including:
• Different compiler optimizations
• Statement ordering
• Run-time libraries
For example, a function such as sin(2.0) may return a slightly different value,
depending on which C library you are using.
For the same reasons, your comparison results may not be identical to those
above.
Tutorial 4: A First Look at Generated Code
In this tutorial, you examine code generated from a from a simple model, to
observe the effects of one of the many code optimization features available in
the Real-Time Workshop.
1-56
Getting Started: Basic Concepts and Tutorials
Figure 1-12 shows the source model.
Figure 1-12: example.mdl
Setting up the Model
First, create the model and set up basic Simulink and Real-Time Workshop
parameters as follows:
1 Create a directory example_codegen, and make it your working directory.
!mkdir example_codegen
cd example_codegen
2 Create a new model and save it as example.mdl.
3 Add Sine Wave, Gain, and Out1 blocks to your model and connect them as
shown in Figure 1-12. Label the signals as shown.
4 From the Simulation menu, choose Simulation Parameters. The
Simulation Parameters dialog box opens.
5 Click the Solver tab and enter the following parameter values on the Solver
page:
Solver options: set Type to Fixed-step. Select the ode5 (Dormand-Prince)
solver algorithm.
Leave the other Solver page parameters set to their default values.
6 Click Apply.
7 Click the Workspace I/O tab and make sure all check boxes are deselected.
8 Click Apply.
9 Click the Real-Time Workshop tab. Select Target configuration from the
Category pull-down menu. Next, select the Generate code only option.
1-57
1
Introduction to the Real-Time Workshop
This option causes the Real-Time Workshop to generate code without
invoking make to compile and link the code. This option is convenient for this
exercise, as we are only interested in looking at the generated code. Note
that the Build button caption changes to Generate code.
Also, make sure that the generic real-time (GRT) target is selected. The page
should appear as below.
10 Click Apply.
11 Save the model.
Generating Code Without Buffer Optimization
When the block I/O optimization feature is enabled, the Real-Time Workshop
uses local storage for block outputs wherever possible. We now disable this
option to see what the generated code looks like:
1 From the Simulation menu, choose Simulation Parameters. The
Simulation Parameters dialog box opens.
1-58
Getting Started: Basic Concepts and Tutorials
2 Click the Advanced tab. Select the Signal storage reuse option and select
the Off radio button, as shown below.
3 Click Apply.
4 Click the Real-Time Workshop tab and select the Target configuration
category. Then click the Generate code button.
5 Because the Generate code only option was selected, the Real-Time
Workshop does not invoke your make utility. The code generation process
ends with the message
### Successful completion of Real-Time Workshop build procedure
for model: example
6 The generated code is in the build directory, example_grt_rtw. The file
example_grt_rtw\example.c contains the output computation for the
model. Open this file into the MATLAB editor.
edit example_grt_rtw\example.c
7 In example.c, find the function MdlOutputs.
The generated C code consists of procedures that implement the algorithms
defined by your Simulink block diagram. Your target’s execution engine
executes the procedures as time moves forward. The modules that implement
1-59
1
Introduction to the Real-Time Workshop
the execution engine and other capabilities are referred to collectively as the
run-time interface modules.
In our example, the generated MdlOutputs function implements the actual
algorithm for multiplying a sine wave by a gain. The MdlOutputs function
computes the model’s block outputs. The run-time interface must call
MdlOutputs at every time step.
With buffer optimizations turned off, MdlOutputs assigns buffers to each block
input and output. These buffers ( rtB.sin_out, rtB.gain_out) are members of
a global data structure, rtB. The code is shown below.
void MdlOutputs(int_T tid)
{
/* Sin Block: <Root>/Sine Wave */
rtB.sin_out = rtP.Sine_Wave_Amp *
sin(rtP.Sine_Wave_Freq * ssGetT(rtS) + rtP.Sine_Wave_Phase);
/* Gain Block: <Root>/Gain */
rtB.gain_out = rtB.sin_out * rtP.Gain_Gain;
/* Outport Block: <Root>/Out1 */
rtY.Out1 = rtB.gain_out;
}
We now turn buffer optimization on and observe how it improves the code.
Generating Code with Buffer Optimization
Enable buffer optimization and re-generate the code as follows:
1 From the Simulation menu, choose Simulation Parameters. The
Simulation Parameters dialog box opens.
2 Click the Advanced tab. Select the Signal storage reuse option and select
the On radio button.
3 Click Apply.
4 Click the Real-Time Workshop tab. Select General code generation
options from the Category pull-down menu.
1-60
Getting Started: Basic Concepts and Tutorials
5 Make sure that the Local block outputs option is both enabled and selected,
as shown above.
6 Click Apply and select the Target Configuration category again.
7 Click the Generate code button.
8 As before, the Real-Time Workshop generates code in the example_grt_rtw
directory. Note that the previously-generated code is overwritten.
9 Edit example_grt_rtw/example.c, and examine the function MdlOutputs.
With buffer optimization enabled, the code in MdlOutputs reuses rtb_temp0, a
temporary buffer with local scope, rather than assigning global buffers to each
input and output.
void MdlOutputs(int_T tid)
{
/* local block i/o variables */
real_T rtb_temp0;
/* Sin Block: <Root>/Sine Wave */
rtb_temp0 = rtP.Sine_Wave_Amp *
sin(rtP.Sine_Wave_Freq * ssGetT(rtS) + rtP.Sine_Wave_Phase);
/* Gain Block: <Root>/Gain */
rtb_temp0 *= rtP.Gain_Gain;
1-61
1
Introduction to the Real-Time Workshop
/* Outport Block: <Root>/Out1 */
rtY.Out1 = rtb_temp0;
}
This code is more efficient in terms of memory usage. The efficiency
improvement gained by enabling Local block outputs would be more
significant in a large model with many signals.
Note that, by default, Local block outputs is enabled. Chapter 3, “Code
Generation and the Build Process” contains details on this and other code
generation options.
For further information on the structure and execution of model.c files, refer
to Chapter 6, “Program Architecture.”
1-62
Where to Find Information in This Manual
Where to Find Information in This Manual
The list below will guide you to information relevant to your development tasks
and interests.
Single- and Multitasking Code Generation
The Real-Time Workshop fully supports single- and multitasking code
generation. See Chapter 6, “Program Architecture” and Chapter 7, “Models
with Multiple Sample Rates” for a complete description.
Customizing Generated Code
The Real-Time Workshop Custom Code library supports customization of the
generated code. See Chapter 14, “Custom Code Blocks” for a description of this
library.
An alternative approach to customizing generated code is to modify Target
Language Compiler (TLC) files. The Target Language Compiler is an
interpreted language that translates Simulink models into C code. Using the
Target Language Compiler, you can direct the code generation process.
There are two TLC files, hookslib.tlc and cachelib.tlc, that contain
functions you can use to customize Real-Time Workshop generated code. See
the Target Language Compiler Reference Guide for more information about
these TLC files. See also the source code, located in matlabroot/rtw/c/tlc.
Optimizing Generated Code
The default code generation settings are generic for flexible rapid prototyping
systems. The penalty for this flexibility is code that is less than optimal. There
are several optimization techniques that you can use to minimize the source
code size and memory usage once you have a model that meets your
requirements.
See Chapter 3, “Code Generation and the Build Process” and Chapter 8,
“Optimizing the Model for Code Generation” for details on code optimization
techniques available for all target configurations.
Chapter 9, “Real-Time Workshop Embedded Coder” contains information
about optimization specifically for embedded code.
1-63
1
Introduction to the Real-Time Workshop
Validating Generated Code
Using the Real-Time Workshop data logging features, you can create an
executable that runs on your workstation and creates a data file. You can then
compare the results of your program with the results of running an equivalent
Simulink simulation.
For more information on how to validate Real-Time Workshop generated code,
see “Workspace I/O Options and Data Logging” on page 3-18. See also “Tutorial
2: Data Logging” and “Tutorial 3: Code Validation” in this chapter.
Incorporating Generated Code into Larger Systems
If your Real-Time Workshop generated code is intended to function within an
existing code base (for example, if you want to use the generated code as a
plug-in function), you should use the Real-Time Workshop Embedded Coder.
Chapter 9, “Real-Time Workshop Embedded Coder” documents the entry
points and header files you will need to interface your code to Real-Time
Workshop Embedded Coder generated code.
Incorporating Your Code into Generated Code
To interface your hand-written code with Real-Time Workshop generated code,
you can use an S-function wrapper. See the Writing S-Functions manual for
more information.
Creating and Communicating with Device Drivers
S-functions provide a flexible method for communicating with device drivers.
See Chapter 17, “Targeting Real-Time Systems” for a description of how to
build device drivers. Also, for a complete discussion of S-functions, see the
Writing S-Functions manual.
Code Tracing
The Real-Time Workshop includes special tags throughout the generated code
that make it easy to trace generated code back to your Simulink model. See
“Tracing Generated Code Back to Your Simulink Model” on page 3-28 for more
information about this feature.
1-64
Where to Find Information in This Manual
Automatic Build Procedure
Using the Real-Time Workshop, you can generate code with the push of a
button. The automatic build procedure, initiated by a single mouse click,
generates code, a makefile, and optionally compiles (or cross-compiles) and
downloads a program. See “Automatic Program Building” on page 2-12 for an
overview, and Chapter 3, “Code Generation and the Build Process” for complete
details.
Parameter Tuning
Parameter tuning enables you to change block parameters while a generated
program runs, thus avoiding recompiling the generated code. The Real-Time
Workshop supports parameter tuning in four different environments:
• External mode: You can tune parameters from Simulink while running the
generated code on a target processor. See Chapter 5, “External Mode” for
information on this mode.
• External C application program interface (API): You can write your own C
API interface for parameter tuning using support files provided by The
MathWorks. See Chapter 17, “Targeting Real-Time Systems” for more
information.
• Rapid simulation: You can use the Rapid Simulation Target (rsim) in batch
mode to provide fast simulations for performing parametric studies.
Although this is not an on-the-fly application of parameter tuning, it is
nevertheless a useful way to evaluate a model. This mode is also useful for
Monte Carlo simulation. See Chapter 11, “Real-Time Workshop Rapid
Simulation Target” for further information.
• Simulink: Prior to generating real-time code, you can tune parameters
on-the-fly in your Simulink model.
See also “Interfacing Signals and Parameters” on page 1-66.
Monitoring Signals and Logging Data
There are several ways to monitor signals and data in the Real-Time
Workshop:
• External mode: You can monitor and log signals from an externally
executing program via Scope blocks and several other types of external mode
1-65
1
Introduction to the Real-Time Workshop
compatible blocks. See “External Signal & Triggering Dialog Box” on page
5-24 for a discussion of this method.
• External C application program interface (API): You can write your own C
API for signal monitoring using support files provided by The MathWorks.
See Chapter 17, “Targeting Real-Time Systems” for more information.
• MAT-file logging: You can use a MAT-file to log data from the generated
executable. See “Workspace I/O Options and Data Logging” on page 3-18 for
more information.
• Simulink: You can use any of Simulink’s data logging capabilities.
Interfacing Signals and Parameters
You can interface signals and parameters in your model to hand-written code
by specifying the storage declarations of signals and parameters. For more
information, see:
• “Parameters: Storage, Interfacing, and Tuning” on page 3-51
• “Signals: Storage, Optimization, and Interfacing” on page 3-65
• “Interfacing Parameters and Signals” on page 17-65
Sample Implementations
The Real-Time Workshop provides sample implementations that illustrate the
development of real-time programs under DOS and Tornado, as well as generic
real-time programs under Windows and UNIX.
These sample implementations are located in the following directories:
• matlabroot/rtw/c/grt: Generic real-time examples
• matlabroot/rtw/c/dos: DOS examples
• matlabroot/rtw/c/tornado: Tornado examples
1-66
2
Technical Overview
The Rapid Prototyping Process . . . . . .
Key Aspects of Rapid Prototyping . . . . . .
Rapid Prototyping for Digital Signal Processing
Rapid Prototyping for Control Systems . . . .
.
.
.
.
Open Architecture of the Real-Time Workshop
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2-2
2-2
2-5
2-6
. . . . . 2-8
Automatic Program Building . . . . . . . . . . . . . 2-12
Steps in the Build Process . . . . . . . . . . . . . . . 2-13
2
Technical Overview
The Rapid Prototyping Process
The Real Time Workshop supports rapid prototyping, a process that allows you
to:
• Conceptualize solutions graphically in a block diagram modeling
environment
• Evaluate system performance early on — before laying out hardware, coding
production software, or committing to a fixed design
• Refine your design by rapid iteration between algorithm design and
prototyping
• Tune parameters while your real-time model runs, using Simulink in
external mode as a graphical front-end
Key Aspects of Rapid Prototyping
Figure 2-1 contrasts the rapid prototyping development process with the
traditional development process.
Algorithm
development
Hardware and
software design
Implementation of
production system
Rapid Prototyping Process
Rapid Iteration
Manual Iteration
Traditional Approach
Algorithm design
and prototyping
Implementation of
production system
Figure 2-1: Traditional vs. Rapid Prototyping Development Processes
2-2
The traditional approach to real-time design and implementation typically
involves multiple teams of engineers, including an algorithm design team,
software design team, hardware design team, and an implementation team.
When the algorithm design team has completed its specifications, the software
design team implements the algorithm in a simulation environment and then
specifies the hardware requirements. The hardware design team then creates
the production hardware. Finally, the implementation team integrates the
hardware into the larger overall system.
This traditional development process can be lengthy, because the algorithm
design engineers do not work with the actual hardware. The rapid prototyping
process combines the algorithm, software, and hardware design phases,
eliminating potential bottlenecks. The process allows engineers to see the
results and rapidly iterate on the design before expensive hardware is
developed.
The key to rapid prototyping is automatic program building. Automatic
program building puts algorithm development (including coding, compiling,
linking, and downloading to target hardware) under control of a single process.
Automatic program building allows you to make design changes directly to the
block diagram.
You begin the rapid prototyping process with the development of a model in
Simulink. In control engineering, you model plant dynamics and other dynamic
components that constitute a controller and/or an observer. In digital signal
processing, your model typically explores input signal characteristics, such as
the signal-to-noise ratio.
You then simulate your model in Simulink. You use MATLAB, Simulink, and
toolboxes to aid in the development of algorithms and analysis of the results. If
the results are not satisfactory, you can iterate the modeling/analysis process
until results are acceptable.
Once you have achieved the desired results, you use the Real-Time Workshop
to generate downloadable C code that implements the appropriate portions of
the model. Using Simulink in external mode, you can tune parameters and
further refine your model, again rapidly iterating to achieve required results.
At this stage, the rapid prototyping process is complete. You can begin the final
implementation for production with confidence that the underlying algorithms
work properly in your real-time production system.
2-3
2
Technical Overview
The figure below shows the rapid prototyping process in more detail.
Algorithm Design and Prototyping
Identify system
and/ or algorithm
requirements
Build/edit model in
Simulink
Run simulations and analyze results
using Simulink and MATLAB
Are
No
results
OK?
Yes
Invoke the Real-Time Workshop build procedure,
download and run on your target hardware
Analyze results and tune the model
using external mode
Are
results
OK?
No
Yes
Implement production system
Figure 2-2: The Rapid Prototyping Development Process
2-4
This highly productive development cycle is possible because the Real-Time
Workshop is closely tied to MATLAB and Simulink. Each package contributes
to the design of your application:
• MATLAB: Provides design, analysis, and data visualization tools.
• Simulink: Provides system modeling, simulation, and validation.
• Real-Time Workshop: Generates C or Ada code from Simulink model;
provides framework for running generated code in real-time, tuning
parameters, and viewing real-time data.
Rapid Prototyping for Digital Signal Processing
The first step in the rapid prototyping process for digital signal processing is to
consider the kind and quality of the data to be worked on, and to relate it to the
system requirements. Typically this includes examining the signal-to-noise
ratio, distortion, and other characteristics of the incoming signal, and relating
them to algorithm and design choices.
System Simulation and Algorithm Design
In the rapid prototyping process, the block diagram plays two roles in
algorithm development. The block diagram helps to identify processing
bottlenecks, and to optimize the algorithm or system architecture. The block
diagram also functions as a high-level system description.That is, the diagram
provides a hierarchical framework for evaluating the behavior and accuracy of
alternative algorithms under a range of operating conditions.
Analyzing Results, Parameter Tuning, and Signal Monitoring
Using External Mode
After creating an algorithm (or a set of candidate algorithms), the next stage is
to consider architectural and implementation issues. These include
complexity, speed, and accuracy. In a conventional development environment,
this would mean running the algorithm and recoding it in C or in a hardware
design and simulation package.
Simulink’s external mode allows you to change parameters interactively, while
your signal processing algorithms execute in real time on the target hardware.
After building the executable and downloading it to your hardware, you tune
(modify) block parameters in Simulink. Simulink automatically downloads the
2-5
2
Technical Overview
new values to the hardware. You can monitor the effects of your parameter
changes by simply connecting Scope blocks to signals that you want to observe.
Rapid Prototyping for Control Systems
Rapid prototyping for control systems is similar to digital signal processing,
with one major difference. In control systems design, it is necessary to develop
a model of your plant prior to algorithm development in order to simulate
closed loop performance. Once your plant model is sufficiently accurate, the
rapid prototyping process for control system design continues in much the
same manner as digital signal processing design.
Rapid prototyping begins with developing block diagram plant models of
sufficient fidelity for preliminary system design and simulation. Once
simulations show encouraging system performance, the controller block
diagram is separated from the plant model and I/O device drivers are attached.
Automatic code generation immediately converts the entire system to real-time
executable code. The executable can be automatically loaded onto target
hardware, allowing the implementation of real-time control systems in a very
short time.
Modeling Systems in Simulink
The first step in the design process is development of a plant model. The
Simulink collection of linear and nonlinear components helps you to build
models involving plant, sensor, and actuator dynamics. Because Simulink is
customizable, you can further simplify modeling by creating custom blocks and
block libraries from continuous- and discrete-time components.
Using the System Identification Toolbox, you can analyze test data to develop
an empirical plant model; or you can use the Symbolic Math Toolbox to
translate the equations of the plant dynamics into state-variable form.
Analysis of Simulation Results
You can use MATLAB and Simulink to analyze the results produced from a
model developed in the first step of the rapid prototyping process. At this stage,
you can design and add a controller to your plant.
Algorithm Design and Analysis
From the block diagrams developed during the modeling stage, you can extract
state-space models through linearization techniques. These matrices can be
2-6
used in control system design. You can use the following toolboxes to facilitate
control system design, and work with the matrices that you derived:
• Control System Toolbox
• LMI Control Toolbox
• Model Predictive Control Toolbox
• Robust Control Toolbox
Once you have your controller designed, you can create a closed-loop system by
connecting it to the Simulink plant model. Closed-loop simulations allow you
to determine how well the initial design meets performance requirements.
Once you have a satisfactory model, it is a simple matter to generate C code
directly from the Simulink block diagram, compile it for the target processor,
and link it with supplied or user-written application modules.
Analyzing Results, Parameter Tuning, and Signal Monitoring
Using External Mode
You can load output data from your program into MATLAB for analysis, or
display the data with third party monitoring tools. You can easily make design
changes to the Simulink model and then regenerate the C code.
Simulink’s external mode allows you to change parameters interactively, while
your algorithms execute in real time on the target hardware. After building the
executable and downloading it to your hardware, you tune (modify) block
parameters in Simulink. Simulink automatically downloads the new values to
the hardware. You can monitor the effects of your parameter changes by simply
connecting Scope blocks to signals that you want to observe.
2-7
2
Technical Overview
Open Architecture of the Real-Time Workshop
The Real-Time Workshop is an open system designed for use with a wide
variety of operating environments and hardware types. There are many ways
to modify and extend the key elements of Real-Time Workshop. Figure 2-3
shows these elements.
2-8
Open Architecture of the Real-Time Workshop
C-code S-functions
Simulink
MATLAB
model.mdl
Real-Time Workshop
Real-Time Workshop build
system.tmf
model.rtw
TLC program:
• System target file
• Block target files
Target
Language
Compiler
• Target Language
Compiler function
library
Run-time interface
support files
model.c
or model.adb
model.h
model_export.h
model.mk
make
model.exe
Download to target hardware
Start execution using Simulink’s external mode
Figure 2-3: The Real-Time Workshop Architecture
2-9
2
Technical Overview
You can configure the Real-Time Workshop program generation process to
your own needs by modifying the following components:
• Simulink and the model file (model.mdl)
Simulink provides a very high-level language (VHLL) development
environment. The language elements are blocks and subsystems that
visually embody your algorithms. You can think of the Real-Time Workshop
as a compiler that processes a VHLL source program (model.mdl), and emits
code suitable for a traditional high-level language (HLL) compiler.
S-functions written in C or Ada let you extend Simulink’s VHLL by adding
new general purpose blocks, or incorporating legacy code into a block.
• The intermediate model description (model.rtw)
The initial stage of the code generation process is to analyze the source
model. The resultant description file contains a hierarchical structure of
records describing systems and blocks and their connections.
The S-function API includes a special function, mdlRTW, that lets you
customize the code generation process by inserting parameter data from
your own blocks into the model.rtw file.
• The Target Language Compiler (TLC) program
The Target Language Compiler interprets a program that reads the
intermediate model description and generates code that implements the
model as a program.
You can customize the elements of the TLC program in two ways. First, you
can implement your own system target file, which controls overall code
generation parameters. Second, you can implement block target files, which
control how code is generated from individual blocks such as your own
S-function blocks.
• Source code generated from the model.
There are several ways to customize generated code, or interface it to custom
code:
- Exported entry points let you interface your hand-written code to the
generated code. This makes it possible to develop your own timing and
execution engine, or to combine code generated from several models into a
single executable.
2-10
Open Architecture of the Real-Time Workshop
- You can automatically make signals, parameters, and other data
structures within generated code visible to your own code, facilitating
parameter tuning and signal monitoring.
- Custom code blocks allow you to insert your own code directly into the
generated code, either at the model or subsystem level.
• Run-time interface support files
The run-time interface consists of code interfacing to the generated model
code. You can create a custom set of run-time interface files, including:
- A harness (main) program
- Code to implement a custom external mode communication protocol
- Code that interfaces to parameters and signals defined in the generated
code
- Timer and other interrupt service routines
- Hardware I/O drivers
• The template makefile and model.mk
A makefile, model.mk, controls the compilation and linking of generated
code. The Real-Time Workshop generates model.mk from a template
makefile during the code generation/build process. You can create a custom
template makefile to control compiler options and other variables of the make
process.
All of these components contribute to the process of transforming a Simulink
model into an executable program. The next section is an overview of this
process.
2-11
2
Technical Overview
Automatic Program Building
The Real-Time Workshop automatic program building process creates
programs for real-time applications in a variety of host environments.
Automatic program building uses the make utility to control the compilation
and linking of generated source code.
A high-level M-file command controls the Real-Time Workshop build process.
The default command, used with most targets, is make_rtw.
The build process consists of the following steps:
1 Analysis of the model and compilation of a model description file
2 Generation of code from the model by the Target Language Compiler
3 Generation of a makefile, customized for a given build
4 Creation of an executable program by the make utility under the control of
the customized makefile
The shaded box in Figure 2-4 outlines these steps.
2-12
Automatic Program Building
Simulink
Model
Your
Template
Makefile
User-developed
model and
template makefile
system.tmf
Automated build
process
Generate
Code
Generate
Makefile
Model
Model
Code
Code
model.c
Custom
Makefile
c
or model.adb
h
model.h
model_export.h
model
make_rtw.m
model.mk
make –f mk
make –f model.mk
Executable C
program
Program
model.exe
Figure 2-4: Automatic Program Building
Steps in the Build Process
Analysis of the Model
The build process begins with the analysis of your Simulink block diagram. The
analysis process consists of these tasks:
• Evaluating simulation and block parameters
• Propagating signal widths and sample times
2-13
2
Technical Overview
• Determining the execution order of blocks within the model
• Computing work vector sizes such as those used by S-functions (for more
information about work vectors, refer to the Writing S-Functions manual.)
During this phase, the Real-Time Workshop reads your model file (model.mdl)
and compiles an intermediate representation of the model. This intermediate
description is stored, in a language-independent format, in an ASCII file
named model.rtw. The model.rtw file is the input to the next stage of the build
process.
model.rtw files are similar in format to Simulink model (.mdl) files. “Overview
of a model.rtw File” on page 2–17 explains the basic features of a .rtw file. For
a detailed description of the contents of model.rtw files, see the Target
Language Compiler Reference Guide.
Generation of Code by the Target Language Compiler
In the second stage of the build procedure, the Target Language Compiler
transforms the intermediate model description stored in model.rtw into
target-specific code.
The Target Language Compiler is an interpreted programming language
designed for the sole purpose of converting a model description into code. The
Target Language Compiler executes a TLC program comprising several target
files (.tlc files). The TLC program specifies how to generate code from the
model, using the model.rtw file as input.
The TLC program consists of:
• The system target file
The system target file is the entry point or main file.
• Block target files
For each block in a Simulink model, there is a block target file that specifies
how to translate that block into target-specific code.
• The Target Language Compiler function library
The Target Language Compiler function library contains functions that
support the code generation process.
The Target Language Compiler begins by reading in the model.rtw file. It then
compiles and executes the commands in the target files — first the system
2-14
Automatic Program Building
target file, then the individual block target files. The output of the Target
Language Compiler is a source code version of the Simulink block diagram.
Generation of the Customized Makefile
The third step in the build procedure is to generate a customized makefile,
model.mk. The generated makefile instructs the make utility to compile and link
source code generated from the model, as well as any required harness
program, libraries, or user-provided modules.
The Real-Time Workshop creates model.mk from a system template makefile,
system.tmf. The system template makefile is designed for your target
environment. The template makefile allows you to specify compilers, compiler
options, and additional information used during the creation of the executable.
The model.mk file is created by copying the contents of system.tmf and
expanding tokens that describe your model’s configuration.
The Real-Time Workshop provides many system template makefiles,
configured for specific target environments and development systems. “The
System Target File Browser” on page 3-34 lists all template makefiles that are
bundled with the Real-Time Workshop.
You can fully customize your build process by modifying an existing template
makefile or providing your own template makefile.
Creation of the Executable
Creation of an executable program is the final stage of the build process. This
stage is optional, as illustrated in Figure 2-5.
If you are targeting a system such as an embedded microcontroller or a DSP
board, you can choose to generate only source code. You can then cross compile
your code and download it to your target hardware. “Making an Executable” in
Chapter 3 discusses the options that control whether or not the build creates
an executable.
The creation of the executable, if enabled, takes place after the model.mk file
has been created. At this point, the build process invokes the make utility,
which in turn runs the compiler. To avoid unnecessary 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, make can also download the executable to your target hardware.
2-15
2
Technical Overview
Press Build
Button
Simulink
Model
Generate
Code
Template
Makefile
Generate
Makefile
Create
Executable?
model.c
or model.adb
model.h
model_export.h
Custom
Makefile
model.mk
No
Yes
Invoke
make
Stop
Figure 2-5: Automatic Program Building: Control Flow
2-16
Automatic Program Building
Summary of Files Created by the Build Procedure
The following is a list of the main of the model.* files created during the code
generation and build process. Each performs a specific function in the
Real-Time Workshop. Depending on code generation options, other files may
also be created by the build process.
• model.mdl, created by Simulink, is analogous to a high-level programming
language source file.
• model.rtw, generated by the Real-Time Workshop build process, is
analogous to the object file created from a high-level language source
program.
• model.c, generated by the Target Language Compiler, is the C source code
corresponding to the model.mdl file.
• model.h, generated by the Target Language Compiler, is a header file that
maps the links between blocks in the model.
• model_export.h, generated by the Target Language Compiler, is a header
file that contains exported signal, parameter, and function symbols.
• model.mk, generated by the Real-Time Workshop build process, is the
customized makefile used to build an executable.
• model.exe (on PC) or model (on UNIX), is an executable program, created
under control of the make utility by your development system.
Overview of a model.rtw File
This section examines the basic features of a model.rtw file. The .rtw file
shown is generated from the source model shown below.
sin_out
Sine Wave
1
Gain
gain_out
1
Out
This model is saved in a file called example.mdl. The Real-Time Workshop
generates example.rtw., an ASCII file. The example.rtw file consists of
parameter name/parameter value pairs, stored in a hierarchical structure
consisting of records.
2-17
2
Technical Overview
Below is an excerpt from example.rtw.
CompiledModel {
Name
.
.
.
System {
Type
.
.
.
}
NumBlocks
.
.
.
}
Block {
Type
.
.
.
}
Block {
Type
.
.
.
}
Block {
Type
.
.
.
}
}
All compiled information is placed
"example"
within the CompiledModel record.
This parameter name /parameter value
pair identifies the name of your model.
root
Your model consists of one or more
system records. There is one record for
your “root” window and one record for
each conditionally executed subsystem.
3
This is the number of nonvirtual blocks
in this system record. A nonvirtual block
is any block that performs some
algorithm, such as a Gain block. A
virtual block is a “connection” or
Sin
graphical block, for example, a Mux
block.
Gain
Outport
There is only one block record for each
nonvirtual block in this system record.
The block record contains information
such as the width of the input and
output ports.
For more information on .rtw files, see the Target Language Compiler
Reference Guide, which contains detailed descriptions of the contents of
model.rtw files.
2-18
3
Code Generation and the
Build Process
Introduction . . . . . . . . . . . . . . . . . . . . 3-2
Overview of the Real-Time Workshop User Interface . . . 3-4
Simulation Parameters and Code Generation . . . . . . 3-17
Selecting a Target Configuration
. . . . . . . . . . . 3-34
Nonvirtual Subsystem Code Generation
. . . . . . . . 3-41
Generating Code and Executables from Subsystems . . . 3-49
Parameters: Storage, Interfacing, and Tuning . . . . . . 3-51
Signals: Storage, Optimization, and Interfacing . . . . . 3-65
Simulink Data Objects and Code Generation . . . . . . 3-79
Configuring the Generated Code via TLC . . . . . . . . 3-93
Making an Executable . . . . . . . . . . . . . . . . 3-97
Directories Used in the Build Process
. . . . . . . . . 3-98
Choosing and Configuring Your Compiler
. . . . . . . 3-99
Template Makefiles and Make Options . . . . . . . . 3-102
3
Code Generation and the Build Process
Introduction
Chapter 2, “Technical Overview” introduced code generation and the build
process. This chapter covers these topics in detail.
The Real-Time Workshop page of the Simulation Parameters dialog enables
you to control most aspects of the code generation and build process. The first
section of this chapter,“Overview of the Real-Time Workshop User Interface”
on page 3-4, introduces the features controlled by the Real-Time Workshop
page.
The sections that follow concern the code generation phase of the build process:
• “Simulation Parameters and Code Generation” on page 3-17 discusses how
options on the Simulink Solver, Workspace I/O, Diagnostics, and Advanced
pages interact with code generation. These options include choice of singleor multitasking execution, and several methods of logging data to MAT-files.
The section also illustrates how to use tags in the generated code to trace
back to the blocks that generated the code.
The section ends with a discussion of “Other Interactions Between Simulink
and the Real-Time Workshop” such as sample time propagation and order of
execution of blocks.
• “Selecting a Target Configuration” on page 3-34 illustrates the use of the
System Target File Browser, and summarizes the target configurations that
you can access through the browser.
• “Nonvirtual Subsystem Code Generation” on page 3-41 describes generation
of separate code modules from nonvirtual subsystems.
• “Generating Code and Executables from Subsystems” on page 3-49 describes
how to generate and build a stand-alone executable from a subsystem.
• “Parameters: Storage, Interfacing, and Tuning” on page 3-51 documents how
to generate storage declarations in order to export and import model
parameters to and from user-written code.
• “Signals: Storage, Optimization, and Interfacing” on page 3-65 documents
how signal storage optimizations work, and how to generate storage
declarations in order to export and import model signals to and from
user-written code.
3-2
• “Simulink Data Objects and Code Generation” on page 3-79 documents how
to represent and store signals and parameters in Simulink data objects, and
how code is generated from these object.
The remaining sections cover the make (post-code generation) part of the build
process:
• “Making an Executable” on page 3-97 documents options that control
whether or not an executable is created during the build process.
• “Directories Used in the Build Process” on page 3-98 documents the output
directories used and/or created during the build process.
• “Choosing and Configuring Your Compiler” on page 3-99 discusses the
installation of a compiler and choice of a template makefile appropriate for
use with your compiler.
• “Template Makefiles and Make Options” on page 3-102 includes a summary
of available template makefiles and make command options.
3-3
3
Code Generation and the Build Process
Overview of the Real-Time Workshop User Interface
Many parameters and options affect the way that Real-Time Workshop
generates code from your model and builds an executable. To set these
parameters and options, you interact with the pages of the Simulation
Parameters dialog box.
The Simulink Solver, Workspace I/O, Diagnostics, and Advanced pages affect
both the behavior of the model in simulation, and the code generated from the
model. “Simulation Parameters and Code Generation” on page 3-17 discusses
how Simulink settings affect the code generation process.
The Real-Time Workshop page lets you set parameters that directly affect code
generation and optimization. You also initiate and control the build process
from the Real-Time Workshop page.
Using the Real-Time Workshop Page
There are two ways to open the Real-Time Workshop page:
• From the Simulation menu, choose Simulation Parameters. When the
Simulation Parameters dialog box opens, click on the Real-Time Workshop
tab.
• Alternatively, select Options from the Real-Time Workshop submenu of
the Tools menu in the Simulink window.
The Real-Time Workshop page is divided into two sections. The upper section
contains the Category pull-down menu and the Build button.
Category Menu
The Category menu lets you select and work with various groups of options
and controls. The selected group of options is displayed in the lower section of
the page. Figure 3-1 shows the Category menu in the Real-Time Workshop
page.
3-4
Overview of the Real-Time Workshop User Interface
Category menu selects groups of code
generation options and controls .
Build button initiates code generation and
build process.
Figure 3-1: Category Menu and Build Button in Real-Time Workshop Page
The categories of options available from the Category menu are:
• Target configuration: high-level options related to control of the code
generation and build process and selection of control files.
• TLC debugging: Target Language Compiler debugging and execution
profiling options.
• General code generation options: Code generation settings that are
common to all target configurations.
• Target-specific code generation options: One or more groups of options
that are specific to the selected target configuration. In Figure 3-1, for
example, the GRT target is selected.
Build Button
Click on the Build button to initiate the code generation and build process.
The following methods of initiating a build are exactly equivalent to clicking
the Build button:
• Select Build Model from the Real-Time Workshop submenu of the Tools
menu in the Simulink window (or use the key sequence Ctrl+B).
3-5
3
Code Generation and the Build Process
• Invoke the rtwbuild command from the MATLAB command line. The syntax
of the rtwbuild command is
rtwbuild modelname
or
rtwbuild('modelname')
where modelname is the name of the source model. If the source model is not
loaded into Simulink, rtwbuild loads the model.
Using ToolTips
The Real-Time Workshop page supports “ToolTip” online help. Place your
mouse over any edit field name or check box to display a message box that
explains the option.
The following sections summarize each category of options or parameters
controlled by the Real-Time Workshop page, with references to subsequent
sections that give details on each option or parameter.
3-6
Overview of the Real-Time Workshop User Interface
Target Configuration Options
Figure 3-2 shows the Target configuration options of the Real-Time
Workshop page.
Name of your model
Target configuration category shows current
configuration of system target file, template
makefile, and make command for your
desired target.
Browse button opens System Target File
Browser for selection of a target
configuration.
System target file name is
displayed or entered here.
Specify TLC options after
filename.
Make command name is
displayed or entered here.
Specify make options after
make command name.
Figure 3-2: The Real-Time Workshop Page: Target Configuration Options
Browse Button
The Browse button opens the System Target File Browser (See Figure 3-6 on
page 3-35). The browser lets you select a preset target configuration consisting
of a system target file, template makefile, and make command.
“Selecting a Target Configuration” on page 3-34 details the use of the browser
and includes a complete list of available target configurations.
System Target File Field
The System target file field has these functions:
3-7
3
Code Generation and the Build Process
• If you have selected a target configuration using the System Target File
Browser, this field displays the name of the chosen system target file
(target.tlc).
• If you are using a target configuration that does not appear in the System
Target File Browser, you must enter the name of the desired system target
file in this field.
• After the system target filename, you can enter code generation options and
variables for the Target Language Compiler. See “Target Language
Compiler Variables and Options” on page 3-93 for details.
Template Makefile Field
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 the chosen template makefile.
• You can enter the name of the desired template makefile in this field. You
must do this if you are using a target configuration that does not appear in
the System Target File Browser. This is necessary if you have written your
own template makefile for a custom target environment.
Make Command Field
A high-level M-file command, invoked when a build is initiated, controls the
Real-Time Workshop 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. “Targets Available from
the System Target File Browser” on page 3-36 lists the make command
associated with each target.
Third-party targets may 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 3-102 documents the Make
command arguments you can use with each supported compiler.
3-8
Overview of the Real-Time Workshop User Interface
Generate Code Only Option
When this option is selected, the build process generates code but does not
invoke the make command. The code is not compiled and an executable is not
built.
When this option is selected, the caption of the Build button changes to
Generate code.
Stateflow Options Button
If the model contains any Stateflow blocks, this button will launch the
Stateflow Options dialog. Refer to the Stateflow User’s Guide for information.
General Code Generation Options
These options are common to all target configurations.
Show Eliminated Statements Option
If this option is selected, statements that were eliminated as the result of
optimizations (such as parameter inlining) appear as comments in the
generated code.
3-9
3
Code Generation and the Build Process
Loop Rolling Threshold Field
The loop rolling threshold 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 rolling threshold value is set to the default, 5.
If myGainVec is declared as
myGainVec = [1:10];
an array of 10 elements, rtP.Gain_Gain[] is declared within the Parameters
data structure, rtP. The size of the gain array exceeds the loop rolling
threshold. Therefore the code generated for the Gain block iterates over the
array in a for loop, as shown in the following code fragment.
/* Gain Block: <Root>/Gain */
{
int_T i1;
real_T *y0 = &rtB.Gain[0];
const real_T *p_Gain_Gain = &rtP.Gain_Gain[0];
3-10
Overview of the Real-Time Workshop User Interface
for (i1=0; i1 < 10; i1++) {
y0[i1] = rtb_foo * (p_Gain_Gain[i1]);
}
}
If myGainVec is declared as
myGainVec = [1:3];
an array of 3 elements, rtP.Gain_Gain[] is declared within the Parameters
data structure, rtP. The size of the gain array is below the loop rolling
threshold. The generated code consists of inline references to each element of
the array, as in the code fragment below.
/* Gain Block: <Root>/Gain */
rtB.Gain[0] = rtb_foo * (rtP.Gain_Gain[0]);
rtB.Gain[1] = rtb_foo * (rtP.Gain_Gain[1]);
rtB.Gain[2] = rtb_foo * (rtP.Gain_Gain[2]);
See the Target Language Compiler Reference Guide for more information on
loop rolling.
Verbose Builds Option
If this option is selected, the MATLAB command window displays progress
information during code generation; compiler output is also made visible.
3-11
3
Code Generation and the Build Process
Inline Invariant Signals Option
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.
Note The Inline invariant signals option is unavailable unless the Inline
parameters option (on the Advanced page) is selected.
Given the model above, if both Inline parameters and Inline invariant
signals is selected, the Real-time Workshop inlines the invariant signal S3 in
the generated code.
Note that an invariant signal is not the same as an invariant constant. (See the
Using Simulink manual for information on invariant constants.) In the above
example, the two constants (1 and 2) and the gain value of 3 are invariant
constants. To inline these invariant constants, select Inline parameters.
Local Block Outputs Option
When this option is selected, block signals will be declared locally in functions
instead of being declared globally (when possible).
Note This check box is disabled when the Signal storage reuse item on the
Advanced page is turned off.
3-12
Overview of the Real-Time Workshop User Interface
For further information on the use of the Local block outputs option, see:
• “Signals: Storage, Optimization, and Interfacing” on page 3-65
• “Tutorial 4: A First Look at Generated Code” on page 1–56
Force Generation of Parameter Comments Option
The Force generation of parameter comments option controls the generation
of comments in the model parameter structure declaration in model_prm.h.
Parameter comments indicate parameter variable names and the names of
source blocks.
When this option is off (the default), 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 this option is on, parameter comments are generated regardless of the
number of parameters.
Target Specific Code Generation Options
Different target configurations support different code generation options that
are not supported by all available targets. For example, the grt, grt_malloc,
Tornado, xPC, and Real-Time Windows targets support external mode, but
other targets do not.
This section summarizes the options specific to the generic real-time (GRT)
target. For information on options specific to other targets, see the
documentation relevant to those targets. “Available Targets” on page 3-36 lists
targets and related chapters and manuals.
3-13
3
Code Generation and the Build Process
Figure 3-3: GRT Code Generation Options
MAT-file Variable Name Modifier Menu
This menu selects a string to be added to the variable names used when logging
data to MAT-files. You can select a prefix (rt_), suffix (_rt), or choose to have
no modifier. The Real-Time Workshop prepends or appends the string chosen
to the variable names for system outputs, states, and simulation time specified
in the Workspace I/O page.
See “Workspace I/O Options and Data Logging” on page 3-18 for information
on MAT-file data logging.
External Mode Option
Selecting this option turns on generation of code to support external mode
communication between host and target systems. This option is available for
GRT and other targets supporting external mode. For information see Chapter
5, “External Mode.”
3-14
Overview of the Real-Time Workshop User Interface
TLC Debugging Options
The TLC Debugging options are of interest to those who are writing TLC code.
These options are summarized here; refer to the Target Language Compiler
Reference Manual for details. The TLC Debugging options are:
• Retain .rtw file
Normally, the build process deletes the model.rtw file from the build
directory at the end of the build. When Retain .rtw file is selected,
model.rtw is not deleted. This option is useful if you are modifying the target
files, in which case you will need to look at the model.rtw file.
• Profile TLC
When this option is selected, the TLC profiler analyzes the performance of
TLC code executed during code generation, and generates a report. The
report is in HTML format and can be read by your Web browser.
• Start TLC debugger when generating code
This option starts the TLC debugger during code generation.This option is
equivalent to entering the -dc argument into the System Target File field
on the Real-Time Workshop page.
3-15
3
Code Generation and the Build Process
• Start TLC coverage when generating code
When this option is selected, the Target Language Compiler generates a
report containing statistics indicating how many times each line of TLC code
is hit during code generation.
This option is equivalent to entering the -dg argument into the System
Target File field on the Real-Time Workshop page.
Real-Time Workshop Submenu
• The Tools menu of the Simulink window contains a Real-Time Workshop
submenu. The submenu items are:
- Options: Open the Real-Time Workshop page of the Simulation
Parameters dialog.
- Build Model: Initiate code generation and build process; equivalent to
clicking the Build button in the Real-Time Workshop page.
- Build Subsystem: Generate code and build an executable from a
subsystem; enabled only when a subsystem is selected. See “Generating
Code and Executables from Subsystems” on page 3-49.
- Generate S-Function: Generate code and build an S-function from a
subsystem; enabled only when a subsystem is selected. See “Automated
S-Function Generation” on page 10-12.
3-16
Simulation Parameters and Code Generation
Simulation Parameters and Code Generation
This section discusses how the simulation parameters of your model interact
with Real-Time Workshop code generation. Only simulation parameters that
affect code generation are mentioned here. For a full description of simulation
parameters, see the Using Simulink manual.
This discussion is organized around the following pages of the Simulation
Parameters dialog box:
• Solver page
• Workspace I/O page
• Diagnostics page
• Advanced Page
To view these pages, choose Simulation parameters from the Simulation
menu. When the dialog box opens, click the appropriate tab.
Solver Options
Solver Type. If you are using the S-Function Target, you can specify either a
fixed-step or a variable-step solver. All other targets require a fixed-step solver.
Mode. Real-Time Workshop supports both single- and multitasking modes. See
Chapter 7, “Models with Multiple Sample Rates” for full details.
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 - 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.
Note that when using the GRT or Tornado targets, you can override the stop
time when running a generated program from the DOS or UNIX command line.
To override the stop time that was set during code generation, use the -tf
switch.
modelname -tf n
The program will run for n seconds. If n = inf, the program will run
indefinitely. See “Part 3: Running the External Mode Target Program” on page
5-11 for an example of the use of this option.
3-17
3
Code Generation and the Build Process
Note Certain blocks have a dependency on absolute time. If you are
designing a program that is intended to run indefinitely (Stop time = inf), you
must not use these blocks. See Appendix A for a list of blocks that depend on
absolute time.
Workspace I/O Options and Data Logging
This section discusses several different methods by which a Real-Time
Workshop generated program can save data to a MAT-file for later analysis.
These methods include:
• Using the Workspace I/O page to define and log workspace return variables
• Logging data from Scope and To Workspace blocks
• Logging data using To File blocks
“Tutorial 2: Data Logging” on page 1-49 is an exercise designed to give you
hands-on experience with data logging features of the Real-Time Workshop.
Note Data logging is available only for targets that have access to a file
system.
Logging States, Time, and Outputs
via the Workspace I/O Page
The Workspace I/O page 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 the Using Simulink manual.
For each workspace return variable that you define and enable, Real-Time
Workshop defines a MAT-file variable. For example, if your model saves
simulation time to the workspace variable tout, your generated program will
log the same data to a variable named (by default) rt_tout.
3-18
Simulation Parameters and Code Generation
The Real-Time Workshop 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.
Real-Time Workshop data logging follows the Workspace I/O Save options:
(Limit data points, Decimation, and Format).
Overriding the Default MAT-File Name. The MAT-file name defaults to model.mat.
To specify a different filename:
1 Choose Simulation parameters from the Simulation menu. The dialog box
opens. Click the Real-Time Workshop tab.
2 Append the following option to the existing text in the Make command field.
OPTS="-DSAVEFILE=filename"
Overriding Default MAT-File Variable Names. By default, the Real-Time Workshop
prepends 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 Choose Simulation parameters from the Simulation menu. The dialog box
opens. Click the Real-Time Workshop tab.
2 Select the target-specific code generation options item from the Category
menu.
3 Select a prefix(rt_) or suffix (_rt) from the MAT-file variable name
modifier field, or choose none for no prefix.
3-19
3
Code Generation and the Build Process
Logging Data with Scope and To Workspace Blocks
The Real-Time Workshop also logs data from these sources:
• All Scope blocks that have the save data to workspace option 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 page.
Logging 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 name(s), decimation, and sample time in the To File block’s
dialog box.
Note that the To File block cannot be used in DOS real-time targets because of
limitations of the DOS target.
Data Logging Differences
in Single- and Multitasking Models
When logging data in singletasking 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 singletasking mode,
the Real-Time Workshop logs states and outputs after the first time step.
See “Data Logging In Single- and Multitasking Model Execution” on page 6–14
for more details on the differences between single- and multitasking data
logging.
3-20
Simulation Parameters and Code Generation
Note The rapid simulation target (rsim) provides enhanced logging options.
See Chapter 11, “Real-Time Workshop Rapid Simulation Target” for more
information.
Diagnostics Page Options
The Diagnostics page specifies what action should be taken when various
model conditions such as unconnected ports are encountered. You can specify
whether to ignore a given condition, issue a warning, or raise an error. If an
error condition is encountered during a build, the build is terminated. The
Diagnostics page is fully documented in the Using Simulink manual.
3-21
3
Code Generation and the Build Process
Advanced Options Page
The Advanced page includes several options that affect the performance of
generated code. The Advanced page has two sections. Options in the Model
parameter configuration section let you specify how block parameters are
represented in generated code, and how they are interfaced to externally
written code. Options in the Optimizations section help you to optimize both
memory usage and code size and efficiency.
Note that the Zero crossing detection option affects only simulations with
variable step solvers. Therefore, this option is not applicable to code
generation. See Using Simulink for further information on the Zero crossing
detection option.
Inline Parameters Option
Selecting this option has two effects:
1 The Real-Time Workshop 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, since it has in effect been
3-22
Simulation Parameters and Code Generation
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 run-time.
2 The Configure button becomes enabled. Clicking the Configure button
opens the Model Parameter Configuration dialog.
The Model Parameter Configuration dialog lets you remove individual
parameters from inlining and declare them to be tunable variables (or global
constants). When you declare a parameter tunable, the Real-Time Workshop
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 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: Storage, Interfacing, and Tuning” on page 3-51 for further
information on interfacing parameters to externally-written code.
Inline parameters also instructs Simulink to propagate constant sample
times. Simulink computes the output signals of blocks that have constant
sample times once during model startup. This improves performance, since
such blocks do not compute their outputs at every time step of the model.
Selecting Inline parameters also interacts with other code generation
parameters as follows:
• When Inline parameters is selected, the Inline invariant signals code
generation option becomes available. See “Inline Invariant Signals Option”
on page 3-12.
• You cannot inline parameters when using external mode. External mode
requires that all parameters be tunable. See Chapter 5, “External Mode.”
• The Parameter pooling option is used only when Inline parameters is
selected. See “Parameter Pooling Option” on page 3-24.
Block Reduction Option
When this option is selected, Simulink collapses certain groups of blocks into a
single, more efficient block, or removes them entirely. This results in faster
model execution during simulation and in generated code. The appearance of
3-23
3
Code Generation and the Build Process
the source model does not change. The types of block reduction optimizations
currently supported are:
• Accumulator folding: Simulink recognizes certain constructs as
accumulators, and reduces them to a single block. For a detailed example,
see “Accumulators” on page 8-15.
• Unnecessary type conversion blocks are removed. For example, an int type
conversion block whose input and output are of type int is redundant and
will be removed.
Boolean Logic Signals Option
By default, Simulink does not signal an error when it detects that double
signals are connected to blocks that prefer Boolean input. This ensures
compatibility with models created by earlier versions of Simulink that support
only double data type. You can enable strict Boolean type checking by selecting
the Boolean logic signals option.
Selecting this option is recommended. Generated code will require less
memory, because a Boolean signal typically requires one byte of storage while
a double signal requires eight bytes of storage.
Parameter Pooling Option
Parameter pooling occurs when multiple block parameters refer to storage
locations that are separately defined but structurally identical. The
optimization is similar to that of a C compiler that encounters declarations
such as
int a[] = {1,2,3};
int b[] = {1,2,3};
In such a case, an optimizing compiler would collapse a and b into a single text
location containing the values 1,2,3 and initialize a and b from the same code.
3-24
Simulation Parameters and Code Generation
To understand the effect of parameter pooling in the Real-Time Workshop,
consider the following scenario.
Assume that the MATLAB workspace variables a and b are defined as follows.
a = [1:1000]; b = [1:1000];
Suppose that a and b are used as vectors of input and output values in two
Look-Up Table blocks in a model. Figure 3-4 shows the model.
Figure 3-4: Model with Pooled Storage for Look-Up Table Blocks
3-25
3
Code Generation and the Build Process
Figure 3-5 shows the use of a and b as a parameters of Look-Up Table1and
Look-Up Table2.
Figure 3-5: Pooled Storage in Look-Up Table Blocks
If Parameter pooling is on, pooled storage is used for the input/output data of
the Look-Up Table blocks. The following code fragment shows the definition of
the global parameter structure of the model (rtP). The input data references
to a and b are pooled in the field rtP.p2. Likewise, while the output data
references (expressions including a and b) are pooled in the field rtP.p3.
3-26
Simulation Parameters and Code Generation
typedef struct Parameters_tag {
real_T p2[1000]; /* Variable: p2
* External Mode Tunable: no
* Referenced by blocks:
* <Root>/Look-Up Table1
* <Root>/Look-Up Table2
*/
real_T p3[1000]; /* Expression: tanh(a)
* External Mode Tunable: no
* Referenced by blocks:
* <Root>/Look-Up Table1
* <Root>/Look-Up Table2
*/
} Parameters;
If Parameter pooling is off, separate arrays are declared for the input/output
data of the Look-Up Table blocks. Twice the amount of storage is used.
typedef struct Parameters_tag {
real_T root_Look_Up_Table1_XData[1000];
real_T root_Look_Up_Table1_YData[1000];
real_T root_Look_Up_Table2_XData[1000];
real_T root_Look_Up_Table2_YData[1000];
} Parameters;
The Parameter pooling option has the following advantages:
• Reduces ROM size
• Reduces RAM size for all compilers (rtP is a global vector)
• Speeds up code generation by reducing the size of model.rtw
• Can speed up execution
Note that the generated parameter names consist of the letter p followed by a
number generated by the Real-Time Workshop. Comments indicate what
parameters are pooled.
Note The Parameter pooling option affects code generation only when
Inline parameters is on.
3-27
3
Code Generation and the Build Process
Signal Storage Reuse Option
This option instructs the Real-Time Workshop to reuse signal memory. This
reduces the memory requirements of your real-time program. Selecting this
option is recommended. Disabling Signal storage reuse makes all block
outputs global and unique, which in many cases significantly increases RAM
and ROM usage.
For further details on the Signal storage reuse option, see “Signals: Storage,
Optimization, and Interfacing” on page 3-65.
Note Selecting Signal storage reuse also enables the Local block outputs
option in the General code generation options category of the Real-Time
Workshop page. See “Local Block Outputs Option” on page 3-12.
Tracing Generated Code Back to Your
Simulink Model
The Real-Time Workshop writes system/block identification tags in the
generated code. The tags are designed to help you identify the block, in your
source model, that generated a given line of code. Tags are located in comment
lines above each line of generated code.
The tag format is <system>/block_name, where:
• system is either:
- the string 'root', or
- a unique system number assigned by Simulink
• block_name is the name of the block.
The following code fragment illustrates a tag comment adjacent to a line of code
generated by a Gain block at the root level of the source model.
/* Gain Block: <Root>/Gain */
rtb_temp3 *= (rtP.root_Gain_Gain);
The following code fragment illustrates a tag comment adjacent to a line of code
generated by a Gain block within a subsystem one level below the root level of
the source model.
3-28
Simulation Parameters and Code Generation
/* Gain Block: <S1>/Gain */
rtB.temp0 *= (rtP.s1_Gain_Gain);
In addition to the tags, the Real-Time Workshop documents the tags for each
model in comments in the generated header file model.h. The following
illustrates such a comment, generated from a source model, foo. foo has a
subsystem Outer with a nested subsystem Inner.
/* Here is the system hierarchy for this model.
*
* <Root> : foo
* <S1>
: foo/Outer
* <S2>
: foo/Outer/Inner
*/
To trace a tag back to the generating block:
1 Open the source model.
2 Close any other model windows that are open.
3 Use the MATLAB hilite_system command to view the desired system and
block.
As an example, consider the model foo mentioned above. If foo is open,
hilite_system('<S1>')
opens the subsystem Outer and
hilite_system('<S2>/Gain1')
opens the subsystem Outer and selects and highlights the Gain block Gain1
within that subsystem.
Other Interactions Between Simulink
and the Real-Time Workshop
The Simulink engine propagates data from one block to the next along signal
lines. The data propagated are:
• Data type
• Line widths
3-29
3
Code Generation and the Build Process
• Sample times
The first stage of code generation is compilation of the block diagram. This
compile stage is analogous to that of a C program. The C compiler carries out
type checking and pre-processing. Similarly, Simulink verifies that input/
output data types of block ports are consistent, line widths between blocks are
of the correct thickness, and the sample times of connecting blocks are
consistent.
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.
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.
3-30
Simulation Parameters and Code Generation
Sample Time Propagation
Inherited sample times in source blocks (e.g., 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 which have not yet been assigned a sample
time. Thus, Simulink 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
according to the following rules:
1 If the current system has at least one rate in it, the block is assigned the
fastest rate.
2 If no rate exists and the model is configured for a variable-step solver, the
block is assigned a continuous sample time (but fixed in minor time steps).
Note that the Real-Time Workshop (with the exception of the S-Function
Target) does not currently support variable-step solvers.
3 If no rate exists and the model is configured for a fixed-step solver, the block
is assigned a discrete sample time of (Tf - Ti)/50, where Ti is the simulation
start time and Tf is the simulation stop time. If Tf is infinity, the default
sample time is set to 0.2.
To ensure a completely deterministic model (one where no sample times are set
using the above rules), you should explicitly specify the sample time 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
may want to do so, however, when creating modular systems.
3-31
3
Code Generation and the Build Process
An unconnected input implicitly sources ground. For ground blocks and ground
connections, the default sample time is derived from destination blocks or the
default rule.
All blocks have an inherited
sample time (Ts = -1). They will
all be assigned a sample time of
(Tf - Ti)/50.
Block Execution Order
Once Simulink compiles the block diagram, it creates a model.rtw file
(analogous to an object file generated from a C file). The model.rtw file
contains all the connection information of the model, as well as the necessary
signal attributes. Thus, the timing engine in the Real-Time Workshop knows
when blocks with different rates should be executed.
You cannot override this execution order by directly calling a block (in
hand-written code) in a model. For example, the disconnected_trigger model
below will have its trigger port source to ground, which may lead to all blocks
inheriting a constant sample time. Calling the trigger function, f(), directly
from hand-code will not work correctly and should never be done. Instead, you
should use a function-call generator to properly specify the rate at which f()
should be executed, as shown in the connected_trigger model below.
3-32
Simulation Parameters and Code Generation
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 Real-Time Workshop is to build
individual models separately and then hand-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 Simulink and the
Real-Time Workshop ensure data consistency between rates and generate
multirate code for use in a multitasking environment. The Real-Time
Workshop Interrupt Template and VxWorks Support libraries provide blocks
which allow synchronous and asynchronous data flow. For a description of the
Real-Time Workshop libraries, see Chapter 14, “Custom Code Blocks” and
Chapter 15, “Asynchronous Support.” For more information on multi-rate code
generation, see Chapter 7, “Models with Multiple Sample Rates.”
3-33
3
Code Generation and the Build Process
Selecting a Target Configuration
The process of generating target-specific code is controlled by a configuration
of:
• A system target file
• A template makefile
• A make command
The System Target File Browser lets you specify such a configuration in a
single step, choosing from a wide variety of ready-to-run configurations.
The System Target File Browser
To select a target configuration using the System Target File Browser:
1 Click the Real-Time Workshop tab of the Simulation Parameters dialog
box. The Real-Time Workshop page activates.
2 Select Target configuration from the Category menu.
3 Click the Browse button next to the System target file field. This opens the
System Target File Browser. The browser displays a list of all currently
available target configurations. When you select a target configuration, the
Real-Time Workshop automatically chooses the appropriate system target
file, template makefile, and make command.
Figure 3-6 shows the System Target File Browser with the generic real-time
target selected.
4 Double-click on the desired entry in the list of available configurations.
Alternatively, you can select the desired entry in the list and click OK.
3-34
Selecting a Target Configuration
Figure 3-6: The System Target File Browser
5 When you choose a target configuration, the Real-Time Workshop
automatically chooses the appropriate system target file, template makefile,
and make command for the selected target, and displays them in the
Real-Time Workshop page.
3-35
3
Code Generation and the Build Process
Available Targets
Table 3-10 lists all the supported system target files and their associated code
formats, template makefiles, and make commands. The table also gives
references to relevant manuals or chapters in this book.
Table 3-1: Targets Available from the System Target File Browser
3-36
Target/Code Format
System Target
File
Template Makefile
Make
Command
Relevant
Chapters
RTW Embedded
Coder (PC or UNIX)
ert.tlc
ert_default_tmf
make_rtw
9 and 4
RTW Embedded
Coder for Watcom
ert.tlc
ert_watc.tmf
make_rtw
9 and 4
RTW Embedded
Coder for Visual C/
C++
ert.tlc
ert_vc.tmf
make_rtw
9 and 4
RTW Embedded
Coder for Visual C/
C++ Project Makefile
ert.tlc
ert_msvc.tmf
make_rtw
9 and 4
RTW Embedded
Coder for Borland
ert.tlc
ert_bc.tmf
make_rtw
9 and 4
RTW Embedded
Coder for LCC
ert.tlc
ert_lcc.tmf
make_rtw
9 and 4
RTW Embedded
Coder for UNIX
ert.tlc
ert_unix.tmf
make_rtw
9 and 4
Generic Real-Time
for PC/UNIX
grt.tlc
grt_default_tmf
make_rtw
4
Generic Real-Time
for Watcom
grt.tlc
grt_watc.tmf
make_rtw
4
Generic Real-Time
for Visual C/C++
grt.tlc
grt_vc.tmf
make_rtw
4
Selecting a Target Configuration
Table 3-1: Targets Available from the System Target File Browser (Continued)
Target/Code Format
System Target
File
Template Makefile
Make
Command
Relevant
Chapters
Generic Real-Time
for Visual C/C++
Project
Makefile
grt.tlc
grt_msvc.tmf
make_rtw
4
Generic Real-Time
for Borland
grt.tlc
grt_bc.tmf
make_rtw
4
Generic Real-Time
for LCC
grt.tlc
grt_lcc.tmf
make_rtw
4
Generic Real-Time
for UNIX
grt.tlc
grt_unix.tmf
make_rtw
4
Generic Real-Time
(dynamic) for PC/
UNIX
grt_malloc.tlc
grt_malloc_default_
tmf
make_rtw
4
Generic Real-Time
(dynamic) for Watcom
grt_malloc.tlc
grt_malloc_watc.tmf
make_rtw
4
Generic Real-Time
(dynamic) for Visual
C/C++
grt_malloc.tlc
grt_malloc_vc.tmf
make_rtw
4
Generic Real-Time
(dynamic) for Visual
C/C++ Project
Makefile
grt_malloc.tlc
grt_malloc_msvc.tmf
make_rtw
4
Generic Real-Time
(dynamic) for Borland
grt_malloc.tlc
grt_malloc_bc.tmf
make_rtw
4
Generic Real-Time
(dynamic) for LCC
grt_malloc.tlc
grt_malloc_lcc.tmf
make_rtw
4
Generic Real-Time
(dynamic) for UNIX
grt_malloc.tlc
grt_malloc_unix.tmf
make_rtw
4
3-37
3
Code Generation and the Build Process
Table 3-1: Targets Available from the System Target File Browser (Continued)
3-38
Target/Code Format
System Target
File
Template Makefile
Make
Command
Relevant
Chapters
Rapid Simulation
Target (default for PC
or UNIX)
rsim.tlc
rsim_default_tmf
make_rtw
11
Rapid Simulation
Target for Watcom
rsim.tlc
rsim_watc.tmf
make_rtw
11
Rapid Simulation
Target for Visual
C/C++
rsim.tlc
rsim_vc.tmf
make_rtw
11
Rapid Simulation
Target for Borland
rsim.tlc
rsim_bc.tmf
make_rtw
11
Rapid Simulation
Target for LCC
rsim.tlc
rsim_lcc.tmf
make_rtw
11
Rapid Simulation
Target for UNIX
rsim.tlc
rsim_unix.tmf
make_rtw
11
Ada Simulation
Target for GNAT
rt_ada_sim.tlc
gnat_sim.tmf
make_rtw
-ada
16
Ada Real-Time
Multitasking Target
for GNAT
rt_ada_tasking
.tlc
gnat_tasking.tmf
make_rtw
-ada
16
S-Function Target for
PC or UNIX
rtwsfcn.tlc
rtwsfcn_default_tmf
make_rtw
4
S-Function Target for
Watcom
rtwsfcn.tlc
rtwsfcn_watc.tmf
make_rtw
4
S-Function Target for
Visual C/C++
rtwsfcn.tlc
rtwsfcn_vc.tmf
make_rtw
4
S-Function Target for
Borland
rtwsfcn.tlc
rtwsfcn_bc.tmf
make_rtw
4
Selecting a Target Configuration
Table 3-1: Targets Available from the System Target File Browser (Continued)
Target/Code Format
System Target
File
Template Makefile
Make
Command
Relevant
Chapters
S-Function Target for
LCC
rtwsfcn.tlc
rtwsfcn_lcc.tmf
make_rtw
4
Tornado (VxWorks)
Real-Time Target
tornado.tlc
tornado.tmf
make_rtw
12
Windows 95/98/NT
Real-Time Target for
Watcom
rtwin.tlc
win_watc.tmf
make_rtw
Real-Time
Windows
Target
User’s
Guide
Windows 95/98/NT
Real-Time Target for
Visual C/C++
rtwin.tlc
win_vc.tmf
make_rtw
Real-Time
Windows
Target
User’s
Guide
Texas Instruments
EVM67x Target
evm67x.tlc
evm67x.tmf
make_rtw
Texas
Instruments
DSP
Developer's
Kit User’s
Guide
Texas Instruments
Code Composer
Studio Target
ccs.tlc
ccs.tmf
make_rtw
Texas
Instruments
DSP
Developer's
Kit User’s
Guide
xPC Target for
Watcom C/C++ or
Visual C/C++
xpctarget.tlc
xpc_default_tmf
make_xpc
xPC Target
User’s
Guide
3-39
3
Code Generation and the Build Process
Table 3-1: Targets Available from the System Target File Browser (Continued)
Target/Code Format
System Target
File
Template Makefile
Make
Command
Relevant
Chapters
DOS (4GW)
drt.tlc
drt_watc.tmf
make_rtw
13 and 4
LE/O (Lynx
embedded OSEK)
Real-Time Target
osek_leo.tlc
osek_leo.tmf
make_rtw
MAT_FILE=
1
RUN=1
LEO_NODE=
osek
Readme file
in
matlabroot/
rtw/c/
osek_leo
Note The LE/O and DOS targets are included as examples only.
3-40
Nonvirtual Subsystem Code Generation
Nonvirtual Subsystem Code Generation
The Real-Time Workshop allows you to control generation of code at the
subsystem level, for any nonvirtual subsystem. The categories of nonvirtual
subsystems are:
• Conditionally executed subsystems: execution depends upon a control signal.
These include triggered subsystems, enabled subsystems, subsystems that
are both triggered and enabled, and function call subsystems. See Using
Simulink for information on conditionally executed subsystems.
• Atomic subsystems: Any virtual subsystem can be declared atomic (and
therefore nonvirtual) via the Treat as atomic unit option in the Block
Parameters dialog.
See Using Simulink for further information on virtual subsystems and atomic
subsystems.
You can control the code generated from nonvirtual subsystems as follows:
• You can instruct the Real-Time Workshop to generate separate functions,
within separate code files, for selected nonvirtual systems. You can control
both the names of the functions and of the code files generated from
nonvirtual subsystems.
• You can generate inlined code from selected nonvirtual subsystems within
your model. When you inline a nonvirtual subsystem, a separate function
call is not generated for the subsystem.
Nonvirtual Subsystem Code Generation Options
For any nonvirtual subsystem, you can choose the following code generation
options from the RTW system code pop-up menu in the subsystem Block
parameters dialog:
• Auto: This is the default option. See “Auto Option” below.
• Inline: This option explicitly directs the Real-Time Workshop to inline the
subsystem.
• Function: This option explicitly directs the Real-Time Workshop to generate
a separate function and file for the subsystem. In this case you can choose
further options to control the naming of the generated function and file.
The sections below discuss the Auto, Inline, and Function options.
3-41
3
Code Generation and the Build Process
Auto Option
In the current release, the Auto option causes the Real-Time Workshop to
inline the subsystem, unless it is a function-call subsystem with multiple
callers. In that case, a function is generated.
In a future release, the Auto option will also create functions when multiple
instances of a subsystem are detected. If there are multiple instances or
multiple callers of the subsystem, the subsystem will not be inlined. To take
advantage of this capability, you should choose the Auto option. Choose Inline
or Function when you want specifically to inline a subsystem or generate a
separate function and code module.
To use the Auto option:
1 Select the subsystem block. Then select Subsystem parameters from the
Simulink Edit menu. The Block Parameters dialog opens, as shown in
Figure 3-7.
Alternatively, you can open the Block Parameters dialog by:
- Shift-double-clicking on the Subsystem block
- Right-clicking on the Subsystem block and selecting Block parameters
from the pop-up menu.
2 If the subsystem is virtual, select Treat as atomic unit as shown in
Figure 3-7. This makes the subsystem nonvirtual, and the RTW system
code option becomes enabled.
If the system is already nonvirtual, the RTW system code option is already
enabled.
3 Select Auto from the RTW system code pop-up menu as shown in
Figure 3-7.
4 Click Apply and close the dialog.
3-42
Nonvirtual Subsystem Code Generation
Figure 3-7: Auto Code Generation Option for a Nonvirtual Subsystem
Inline Option
As noted above, subsystem code can be inlined only if the subsystem is
nonvirtual.
Exceptions to Inlining. Note that there are certain cases in which the Real-Time
Workshop will not inline a nonvirtual subsystem, even though the Inline
option is selected. These cases are:
• 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 such
calls via function pointers; therefore the function-call subsystem must
generate a function with all arguments present.
• In a feedback loop involving function-call subsystems, the Real-Time
Workshop will force one of the subsystems to be generated as a function
instead of inlining it. The Real-Time Workshop selects the subsystem to be
generated as a function based on the order in which the subsystems are
sorted internally.
3-43
3
Code Generation and the Build Process
• If a subsystem is called from an S-function block that sets the option
SS_OPTION_FORCE_NONINLINED_FCNCALL to TRUE, it will not be inlined. This
may be the case when user-defined Asynchronous Interrupt blocks or Task
Synchronization blocks are required. Such blocks must be generated as
functions. The VxWorks Asynchronous Interrupt and Task Synchronization
blocks, shipped with the Real-Time Workshop, use the
SS_OPTION_FORCE_NONINLINED_FCNCALL option.
To generate inlined subsystem code:
1 Select the subsystem block. Then select Subsystem parameters from the
Simulink Edit menu. The Block Parameters dialog opens, as shown in
Figure 3-8.
Alternatively, you can open the Block Parameters dialog by:
- Shift-double-clicking on the Subsystem block
- Right-clicking on the Subsystem block and selecting Block parameters
from the pop-up menu.
2 If the subsystem is virtual, select Treat as atomic unit as shown in
Figure 3-8. This makes the subsystem atomic, and the RTW system code
pop-up menu becomes enabled.
If the system is already nonvirtual, the RTW system code menu is already
enabled.
3 Select Inline from the RTW system code menu as shown in Figure 3-8.
4 Click Apply and close the dialog.
3-44
Nonvirtual Subsystem Code Generation
Figure 3-8: Inlined Code Generation for a Nonvirtual Subsystem
When you generate code from your model, the Real-Time Workshop writes
inline code within model.c to perform subsystem computations. You can
identify this code by system/block identification tags, such as the following.
/* Atomic SubSystem Block: <Root>/AtomicSubsys1 */
See “Tracing Generated Code Back to Your Simulink Model” on page 3-28 for
further information on system/block identification tags.
Function Option
This option lets you direct the Real-Time Workshop to generate a separate
function and file for the subsystem. When you select the Function option, two
additional options are enabled:
• The RTW function name options menu lets you control the naming of the
generated function.
• The RTW file name options menu lets you control the naming of the
generated file.
3-45
3
Code Generation and the Build Process
Figure 3-9 shows the Block Parameters dialog with the Function option
selected.
RTW Function Name Options Menu. This menu offers the following choices:
• Auto: the Real-Time Workshop assigns a unique function name using the
default naming convention: model_systemid(), where systemid is a
sequential identifier (s0, s1,...sn) assigned by Simulink.
• UseSubSystemName: the Real-Time Workshop uses the subsystem name as
the filename.
• UserSpecified: When this option is selected, the RTW function name text
entry field is enabled. Enter any legal function name. Note that the function
name must be unique.
RTW File Name Options Menu. This menu offers the following choices:
• Auto: the Real-Time Workshop assigns a unique filename using the default
naming convention: model_systemid.c, where systemid is a sequential
identifier (s0, s1,...sn) assigned by Simulink.
• UseSubSystemName: the Real-Time Workshop uses the subsystem name as
the filename.
• UseFunctionName: the Real-Time Workshop uses the function name (as
specified by the RTW function name options) as the filename.
• UserSpecified: When this option is selected, the RTW file name (no
extension) text entry field is enabled. Enter any filename desired, but do not
include the .c (or any other) extension. Note that this filename should be
unique.
To generate a separate subsystem function and file:
1 Select the subsystem block. Then select Subsystem parameters from the
Simulink Edit menu. The Block Parameters dialog opens, as shown in
Figure 3-9.
Alternatively, you can open the Block Parameters dialog by:
- Shift-double-clicking on the Subsystem block
- Right-clicking on the Subsystem block and selecting Block parameters
from the pop-up menu.
3-46
Nonvirtual Subsystem Code Generation
2 If the subsystem is virtual, select Treat as atomic unit as shown in
Figure 3-9. This makes the subsystem atomic, and the RTW system code
menu becomes enabled.
If the system is already nonvirtual, the RTW system code menu is already
enabled.
3 Select Function from the RTW system code menu as shown in Figure 3-9.
4 Set the function name, using the RTW function name options described in
“RTW Function Name Options Menu” on page 3-46.
5 Set the filename, using the RTW file name options described in “RTW File
Name Options Menu” on page 3-46.
6 Click Apply and close the dialog.
Figure 3-9: Subsystem Function Code Generation
with Default Naming Options
3-47
3
Code Generation and the Build Process
Modularity of Subsystem Code
Note that code generated from nonvirtual subsystems, when written to
separate files, is not completely independent of the generating model. For
example, subsystem code may reference global data structures of the model.
Each subsystem code file contains appropriate include directives and
comments explaining the dependencies.
3-48
Generating Code and Executables from Subsystems
Generating Code and Executables from Subsystems
The Real-Time Workshop can generate code and build an executable from any
subsystem within a model. The code generation and build process uses the code
generation and build parameters of the root model.
To generate code and build an executable from a subsystem:
1 Set up the desired code generation and build parameters in the Simulation
Parameters dialog, just as you would for code generation from a model.
2 Select the desired subsystem block.
3 Right-click on the subsystem block and select Build Subsystem from the
Real-Time Workshop submenu of the subsystem block’s context menu.
Alternatively, you can select Build Subsystem from the Real-Time
Workshop submenu of the Tools menu. This menu item is enabled when a
subsystem is selected in the current model.
4 A window displaying a list of the subsystem parameters opens. You can
declare any parameter to be tunable by selecting its check box in the
Tunable column.)
In the illustration above, the parameter K is declared tunable.
5 After selecting tunable parameters, click the Proceed button. This initiates
the code generation and build process.
6 The build process displays status messages in the MATLAB command
window. When the build completes, the generated executable is in your
3-49
3
Code Generation and the Build Process
working directory. The name of the generated executable is subsystem.exe
(PC) or subsystem (UNIX), where subsystem is the name of the source
subsystem block.
The generated code is in a build subdirectory, named
subsystem_target_rtw, where subsystem is the name of the source
subsystem block and target is the name of the target configuration.
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 Subsystem behaves identically to Generate S-function.
(See “Automated S-Function Generation” on page 10-12.)
3-50
Parameters: Storage, Interfacing, and Tuning
Parameters: Storage, Interfacing, and Tuning
Simulink external mode (see Chapter 5, “External Mode”) offers a quick and
easy way to monitor signals and modify parameter values while generated
model code executes. However, external mode may not be appropriate for your
application in some cases. Some targets (such as the Real-Time Workshop
Embedded Coder) do not support external mode. In other cases, you may want
your existing code to access parameters and signals of a model directly, rather
than using the external mode communications mechanism.
This section discusses how the Real-Time Workshop generates parameter
storage declarations, and how you can generate the storage declarations you
need to interface block parameters to your code.
Storage of Nontunable Parameters
By default, block parameters are not tunable in the generated code. In the
default case, the Real-Time Workshop has control of parameter storage
declarations and the symbolic naming of parameters in the generated code.
Nontunable parameters are stored as fields of a model-specific global
parameter data structure called rtP. The Real-Time Workshop initializes each
field of rtP 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. (A vector parameter, however, may be represented as an array of
constants within rtP.)
As an example of nontunable parameter storage, consider this model.
3-51
3
Code Generation and the Build Process
The workspace variable Kp sets the gain of the Gain1 block.
Assume that Kp is nontunable, and has a value of 5.0. Table 3-2 shows the
variable declarations and the code generated for Kp in the noninlined and
inlined cases.
Notice that the generated code does not preserve the symbolic name Kp. The
noninlined code represent the gain of the Gain1 block as rtP.Gain1_Gain.
3-52
Parameters: Storage, Interfacing, and Tuning
Table 3-2: Nontunable Parameter Storage Declarations and Code
Inline
Parameters
Generated Variable Declaration and Code
Off
typedef struct Parameters_tag {
real_T Sine_Wave_Amp;
real_T Sine_Wave_Freq;
real_T Sine_Wave_Phase;
real_T Gain1_Gain;
} Parameters;
.
.
Parameters rtP = {
1.0 , /*Sine_Wave_Amp :'<Root>/Sine Wave' */
1.0 , /*Sine_Wave_Freq:'<Root>/Sine Wave' */
0.0 , /*Sine_Wave_Phase:'<Root>/Sine Wave'*/
5.0
/*Gain1_Gain : '<Root>/Gain1' */
};
.
.
rtb_y = rtB.u * (rtP.Gain1_Gain);
On
rtb_y = 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. 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 rtP. You also control the symbolic name of the
parameter in the generated code.
3-53
3
Code Generation and the Build Process
When you declare a parameter tunable, you specify:
• The storage class of the parameter.
In the Real-Time Workshop, the storage class property of a parameter
specifies how the Real-Time Workshop declares the parameter in generated
code.
Note that the term “storage class,” as used in the Real-Time Workshop, 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 an string
that is included in the variable declaration, without error checking.
• (Implicitly) the symbolic name of the variable or field in which the parameter
is stored. The Real-Time Workshop derives variable and field names from
the names of tunable parameters.
The Real-Time Workshop 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 rtP or as a separate global variable.
You can use the generated storage declaration to make the variable visible to
your code. You can also make variables declared in your code visible to the
generated code. You are responsible for properly 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 3-61.)
To declare tunable parameters, you must first enable the Inline parameters
option. You then use the Model Parameter Configuration dialog 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.
The mechanics of declaring tunable parameters is discussed in “Using the
Model Parameter Configuration Dialog” on page 3-57.
3-54
Parameters: Storage, Interfacing, and Tuning
Storage Classes of Tunable Parameters
The Real-Time Workshop defines four storage classes for tunable parameters.
You must declare a tunable parameter to have one of the following storage
classes:
• SimulinkGlobal(Auto): SimulinkGlobal(Auto) is the default storage class.
The Real-Time Workshop stores the parameter as a member of rtP. Each
member of rtP 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_export.h exports it as a global variable. An exported
global variable is independent of the rtP data structure. Each exported
global variable is initialized to the value of the corresponding workspace
variable at code generation time.
• ImportedExtern: model.h declares the parameter as an extern variable.
Your code must supply the proper variable definition and initializer, if any.
• ImportedExternPointer: model.h declares the variable as an extern
pointer. Your code must supply the proper pointer variable definition and
initializer, if any.
As an example of how the storage class declaration affects the code generated
for a parameter, consider the model shown below.
The workspace variable Kp sets the gain of the Gain1 block. Assume that the
value of Kp is 5.0. Table 3-3 shows the variable declarations and the code
3-55
3
Code Generation and the Build Process
generated for the gain block when Kp is declared as a tunable parameter. An
example is shown for each storage class.
Note that the symbolic name Kp is preserved in the variable and field names in
the generated code.
Table 3-3: Tunable Parameter Storage Declarations and Code
Storage Class
3-56
Generated Variable Declaration and Code
SimulinkGlobal(Auto)
typedef struct Parameters_tag {
real_T Kp;
} Parameters;
.
.
Parameters rtP = {
5.0
};
.
.
rtb_y = rtB.u * (rtP.Kp);
ExportedGlobal
real_T Kp = 5.0;
.
.
rtb_y = rtB.u * (Kp);
ImportedExtern
extern real_T Kp;
.
.
rtb_y = rtB.u * (Kp);
ImporteExternPointer
extern real_T *Kp;
.
.
rtb_y = rtB.u * ((*Kp));
Parameters: Storage, Interfacing, and Tuning
Using the Model Parameter Configuration Dialog
The Model Parameter Configuration dialog is available only when the Inline
parameters option on the Advanced page is selected. Selecting this option
activates the Configure button.
3-57
3
Code Generation and the Build Process
Clicking on the Configure button opens the Model Parameter Configuration
dialog.
Figure 3-10: The Model Parameter Configuration Dialog
The Model Parameter Configuration dialog lets you select workspace
variables and declare them to be tunable parameters in the current model. The
dialog is divided into two panels:
• The Global (tunable) parameters panel displays and maintains a list of
tunable parameters associated with the model.
• The Source list panel displays a list of workspace variables and lets you add
them to the tunable parameters list.
To declare tunable parameters, you select one or more variables from the
source list, add them to the Global (tunable) parameters list, and set their
storage class and other attributes.
3-58
Parameters: Storage, Interfacing, and Tuning
Source List Panel. The Source list panel displays a menu and a scrolling table of
numerical workspace variables.
The menu lets you choose the source of the variables to be displayed in the list.
Currently there is only one choice: MATLAB workspace. The source list
displays names of the variables defined in the MATLAB base workspace.
Selecting one or more variables from the source list enables the Add to table
button. Clicking Add to table adds selected variables to the tunable
parameters list in the Global (tunable) parameters panel. This action is all
that is necessary to declare tunable parameters.
In the source list, the names of variables that have been added to the tunable
parameters list are displayed in italics (See Figure 3-10).
The Refresh list button updates the table of variables to reflect the current
state of the workspace. If you define or remove variables in the workspace
while the Model Parameter Configuration dialog is open, click the Refresh
list button when you return to the dialog. The new variables are added to the
source list.
Global (Tunable) Parameters Panel. The Global (tunable) parameters panel
displays a scrolling table of variables that have been declared tunable in the
current model, and lets you specify their attributes. The Global (tunable)
parameters panel also lets you remove entries from the list, or create new
tunable parameters.
You select individual variables and change their attributes directly in the
table. The attributes are:
• Storage class of the parameter in the generated code. Select one of
-
SimulinkGlobal(Auto)
ExportedGlobal
ImportedExtern
ImportedExternPointer
See “Storage Classes of Tunable Parameters” on page 3-55 for definitions.
• Storage type qualifier of the variable in the generated code. 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 additional qualifiers
to the list. Note that the code generator does not check the storage type
3-59
3
Code Generation and the Build Process
qualifier for validity. The code generator includes the qualifier string in the
generated code without syntax checking.
• Name of the parameter. This field is used only when creating a new tunable
variable.
The Remove button deletes selected variables from the Global (tunable)
parameters list.
The New button lets you create new tunable variables in the Global (tunable)
parameters list. At a later time, you can add references to these variables in
the model.
If the name you enter matches the name of an existing workspace variable in
the Source list, that variable is declared tunable, and is displayed in italics in
the Source list.
To define a new tunable variable, click the New button. This creates an empty
entry in the table. Then, enter the name and attributes of the variable and click
Apply.
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).
Declaring Tunable Variables
To declare an existing variable tunable:
1 Open the Model Parameter Configuration dialog.
2 In the Source list panel, click on the desired variable in the list to select it.
3 Click the Add to table button. The variable then appears in the table of
tunable variables in the Global (tunable) parameters panel.
4 Click on the variable in the Global (tunable) parameters panel.
5 Select the desired storage class from the Storage class menu.
6 Optionally, select (or enter) a storage type qualifier.
3-60
Parameters: Storage, Interfacing, and Tuning
7 Click Apply, or click OK to apply changes and close the dialog.
Tunable Expressions
The Real-time Workshop supports the use of tunable variables in expressions.
An expression that contains one or more tunable parameters is called a tunable
expression.
Currently, there are certain limitations on the use of tunable variables in
expressions. When an expression described below as not supported is
encountered during code generation, a warning is issued and a nontunable
expression 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 Table 3-4.
Table 3-4: Tunability Classification of Operators and Functions
Category
Operators or Functions
1
+ - .* ./ < > <= >= == ~= & |
2
* /
3
abs, acos, asin, atan, atan2, boolean, ceil, cos,
cosh, exp, floor, int8, int16, int32, log, log10,
rem, sign, sin, sinh, sqrt, tan, tanh, uint8,
uint16, uint32
4
: .^ ^ [] {} . \ .\ ' .' ; ,
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.
3-61
3
Code Generation and the Build Process
• 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 operators are not supported.
Note The “dot” (structure membership) operator is not supported. This
means that expressions that include a structure member are not tunable.
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. When
referenced in lower-level subsystems, such parameters remain tunable.
As an example, consider the masked subsystem depicted below. The masked
dialog variable k sets the gain parameter of theGain.
Suppose that the base workspace variable b is declared tunable with
SimulinkGlobal(Auto) storage class. Figure 3-11 shows the tunable
expression b*3 in the subsystem’s mask dialog.
Figure 3-11: Tunable Expression in Subsystem Mask Dialog
3-62
Parameters: Storage, Interfacing, and Tuning
The Real-Time Workshop produces the following output computation for
theGain.
/* Gain Block: <S1>/theGain */
rtb_temp0 *= (rtP.b * 3.0);
Note that b is represented as a member of the global parameters structure, rtP.
Limitations of Tunable Expressions in Masked Subsystems. 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 as in Figure 3-11.
Since the mask initialization code can only run once, k is evaluated at code
generation time as
4 + (3 * (2 * 3) )
The Real-Time Workshop inlines the result. Therefore, despite the fact that b
was declared tunable, the code generator produces the following output
computation for theGain.
/* Gain Block: <S1>/theGain */
rtb_temp0 *= (22.0);
Tunability of Linear Block Parameters
The following blocks have a Realization parameter that affects the tunability
of their parameters:
• Transfer Fcn
• State-Space,
• Discrete Transfer Fcn,
• Discrete State-Space
3-63
3
Code Generation and the Build Process
• Discrete Filter
The Realization parameter must be set via the MATLAB set_param
command, 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.
Note To tune the parameter values of a block of one of the above types
without restriction during an external mode simulation, you must use set
Realization to general .
3-64
Signals: Storage, Optimization, and Interfacing
Signals: Storage, Optimization, and Interfacing
The Real-Time Workshop 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 (i.e., in stack variables).
• Control the allocation of stack space when using local storage.
• Ensure that particular signals are stored in unique memory locations by
declaring them as test points.
• Reduce memory usage by instructing the Real-Time Workshop 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.
The discussion in the following sections refers to code generated from
Signals_examp, the model shown in Figure 3-12.
Figure 3-12: Signals_examp Model
Signal Storage Concepts
This section discusses structures and concepts you must understand in order
to choose the best signal storage options for your application:
• The global block I/O data structure rtB
• The concept of signal storage classes as used in the Real-Time Workshop
3-65
3
Code Generation and the Build Process
rtB: the Global Block I/O Structure
By default, the Real-Time Workshop attempts to optimize memory usage by
sharing signal memory and using local variables.
However, there are a number of circumstances in which it is desirable or
necessary to place signals in global memory. For example:
• You may 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 may 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 rtB.
The following code fragment illustrates how rtB is defined and declared in code
generated (with signal storage optimizations off) from the Signals_examp
model shown in Figure 3-12.
typedef struct BlockIO_tag {
real_T SinSig;
real_T Gain1Sig;
} BlockIO;
.
.
.
/* Block I/O Structure */
BlockIO rtB;
/* <Root>/Sine Wave */
/* <Root>/Gain1 */
Field names for signals stored in rtB are generated according to the rules
described in “Symbolic Naming Conventions for Signals in Generated Code” on
page 3-74.
Storage Classes for Signals
In the Real-Time Workshop, the storage class property of a signal specifies how
the Real-Time Workshop declares and stores the signal. In some cases this
specification is qualified by further options.
Note that in the context of the Real-Time Workshop, the term “storage class” is
not synonymous with the term storage class specifier, as used in the C
language.
3-66
Signals: Storage, Optimization, and Interfacing
Default Storage Class. Auto is the default storage class. Auto is the appropriate
storage class for signals that you do not need to interface to external code.
Signals with Auto storage class may be stored in local and/or shared variables,
or in a global data structure. The form of storage depends on the Signal
storage reuse and Local block outputs options, and on available stack space.
See “Signals with Auto Storage Class” on page 3-68 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 rtB, or in unstructured global variables,
independent of rtB. These storage classes are appropriate for signals that you
want to monitor and/or interface to external code.
The Signal storage reuse and Local block outputs optimizations do not apply
to signals with storage classes other than Auto.
Use the Signal Properties dialog to assign these storage classes to signals:
• SimulinkGlobal(Test Point): Test points are stored as fields of the rtB
structure that are not shared or reused by any other signal. See “Declaring
Test Points” on page 3-71 for further information.
• ExportedGlobal: The signal is stored in a global variable, independent of the
rtB data structure. model_export.h exports the variable. Signals with
ExportedGlobal storage class must have unique signal names. See
“Interfacing Signals to External Code” on page 3-72 for further information.
• ImportedExtern: model.h declares the signal as an extern variable. Your
code must supply the proper variable definition. Signals with
ImportedExtern storage class must have unique signal names. See
“Interfacing Signals to External Code” on page 3-72 for further information.
• ImportedExternPointer: model.h declares the signal as an extern pointer.
Your code must supply the proper pointer variable definition. Signals with
ImportedExtern storage class must have unique signal names. See
“Interfacing Signals to External Code” on page 3-72 for further information.
3-67
3
Code Generation and the Build Process
Signals with Auto Storage Class
This section discusses options that are available for signals with Auto storage
class. These options let you control signal memory reuse and choose local or
global (rtB) storage for signals.
The Signal storage reuse option controls signal memory reuse. This option is
on the Advanced page of the Simulation Parameters dialog box.
The Local block outputs option determines whether signals are stored as
members of rtB, or as local variables in functions. This option is in the General
code generation options category of the Real-Time Workshop page.
3-68
Signals: Storage, Optimization, and Interfacing
By default, both Signal storage reuse and Local block outputs are on.
Note that these options interact. When the Signal storage reuse option is on:
• Signal memory is reused whenever possible.
• The Local block outputs option is enabled. This lets you choose whether
reusable signal variables are declared as local variables in functions, or as
members of rtB.
The following code examples illustrate the effects of the Signal storage reuse
and Local block outputs options. The examples were generated from the
Signals_examp model (see Figure 3-12).
The first example illustrates maximal signal storage optimization, with both
Signal storage reuse and Local block outputs on (the default). The output
signals from the Sine Wave and Gain blocks reuse rtb_temp0, a variable local
to the MdlOutputs function.
/* local block i/o variables */
real_T rtb_temp0;
/* Sin Block: <Root>/Sine Wave */
rtb_temp0 = (rtP.Sine_Wave_Amp) * sin((rtP.Sine_Wave_Freq) *
ssGetT(rtS) + (rtP.Sine_Wave_Phase));
/* Gain Block: <Root>/Gain1 */
rtb_temp0 *= (rtP.Gain1_Gain);
If you are constrained by limited stack space, you can turn Local block
outputs off and still benefit from memory reuse. The following example was
generated with Local block outputs off and Signal storage reuse on. The
output signals from the Sine Wave and Gain blocks reuse rtB.temp0, a member
of rtB.
rtB.temp0 = (rtP.Sine_Wave_Amp) * sin((rtP.Sine_Wave_Freq) *
ssGetT(rtS) + (rtP.Sine_Wave_Phase));
/* Gain Block: <Root>/Gain1 */
rtB.temp0 *= (rtP.Gain1_Gain);
3-69
3
Code Generation and the Build Process
When the Signal storage reuse option is off, signal storage is not reused, and
the Local block outputs option is disabled. This makes all block outputs global
and unique, as in the following code fragment.
/* Sin Block: <Root>/Sine Wave */
rtB.SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS) + (rtP.Sine_Wave_Phase));
rtB.Gain1Sig = rtB.SinSig * (rtP.Gain1_Gain);
In large models, disabling Signal storage reuse can significantly increase
RAM and ROM usage. Therefore, this approach is not recommended.
Table 3-5 summarizes the possible combinations of the Signal storage reuse
and Local block outputs options.
Table 3-5: Global, Local and Reusable Signal Storage Options
Signal storage reuse ON
Signal storage reuse OFF
Local Block
Outputs ON
Reuse signals in local
memory (fully optimized)
N/A
Local Block
Outputs OFF
Reuse signals in rtB
structure
Individual signal storage in
rtB structure
Controlling Stack Space Allocation
When the Local block outputs option is on, the use of stack space is
constrained by the following TLC variables:
• MaxStackSize: the total allocation size of local variables that are declared by
all functions in the entire model may not exceed MaxStackSize (in bytes).
MaxStackSize can be any positive integer. If the total size of local variables
exceeds this maximum, the Target Language Compiler will allocate the
remaining variables in global, rather than local, memory.
• MaxStackVariableSize: limits the size of any local variable declared in a
function to N bytes, where N>0. A variable whose size exceeds
MaxStackVariableSize will be allocated in global, rather than local,
memory.
3-70
Signals: Storage, Optimization, and Interfacing
You can change the values of these variables in your system target file if
necessary. See “Assigning Target Language Compiler Variables” on page 3-93
for further information.
Declaring Test Points
A test point is a signal that is stored in a unique location that is not shared or
reused by any other signal. Test-pointing is the process of declaring a signal to
be a test point.
Test points are stored as members of the rtB structure, even when the Signal
storage reuse and Local block outputs option are selected. Test-pointing lets
you override these options for individual signals. Therefore, you can test-point
selected signals, without losing the benefits of optimized storage for the other
signals in your model.
3-71
3
Code Generation and the Build Process
To declare a test point, use the Simulink Signal Properties dialog box as
follows:
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, you can right-click the line that carries the signal, and select
Signal properties from the pull-down menu.
2 Check the SimulinkGlobal (Test Point) option.
3 Click Apply.
For an example of storage declarations and code generated for a test point, see
Table 3-6, Signal Properties Options and Generated Code, on page 3-76.
Interfacing Signals to External Code
The Simulink Signal Properties dialog lets you interface selected signals to
externally written code. In this way, your hand-written code has access to such
3-72
Signals: Storage, Optimization, and Interfacing
signals for monitoring or other purposes. To interface a signal to external code,
use 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:
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, you can right-click the line that carries the signal, and select
Signal properties from the pull-down menu.
2 Deselect the SimulinkGlobal (Test Point) option if necessary. This enables
the RTW storage class field.
3 Select the desired storage class (ExportedGlobal, ImportedExtern, or
ImportedExternPointer) from the RTW storage class menu.
3-73
3
Code Generation and the Build Process
4 Optional: For storage classes other than Auto and SimulinkGlobal, you can
enter a storage type qualifier such as const or volatile in the RTW storage
type qualifier field. Note that the Real-Time Workshop does not check this
string for errors; whatever you enter is included in the variable declaration.
5 Click Apply.
Note You can also interface test points and other signals that are stored as
members of rtB to your code. To do this, your code must know the address of
the rtB structure where the data is stored, and other information. This
information is not automatically exported. The Real-Time Workshop provides
C and Target Language Compiler APIs that give your code access to rtB and
other data structures. See “Interfacing Parameters and Signals” on page 17-65
for further information.
Symbolic Naming Conventions for Signals
in Generated Code
When signals have a storage class other than Auto, the Real-Time Workshop
preserves symbolic information about the signals or their originating blocks in
the generated code.
For labelled signals, field names in rtB derive from the signal names. In the
following example, the field names rtB.SinSig and rtB.Gain1Sig derive from
the corresponding labeled signals in the Signals_examp model (shown in
Figure 3-12).
typedef struct BlockIO_tag {
real_T SinSig;
real_T Gain1Sig;
} BlockIO;
/* <Root>/Sine Wave */
/* <Root>/Gain1 */
For unlabeled signals, rtB field names derive from the name of the source block
or subsystem. The naming format is
rtB.system#_BlockName_outport#
where system# is a unique system number assigned by Simulink, BlockName is
the name of the source block, and outport# is a port number. The port number
3-74
Signals: Storage, Optimization, and Interfacing
(outport#) is used only when the source block or subsystem has multiple
output ports.
When a signal has Auto storage class, the Real-Time Workshop controls
generation of variable or field names without regard to signal labels.
3-75
3
Code Generation and the Build Process
Summary of Signal Storage Class Options
Table 3-6 shows, for each signal storage class option, the variable declaration
and the code generated for Sine Wave output (SinSig) of the model shown in
Figure 3-12.
Table 3-6: Signal Properties Options and Generated Code
Storage Class
Auto
(with storage
optimizations
on)
Declaration
real_T rtb_temp0;
(declared in
model_common.h)
rtb_temp0 = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
Test point
typedef struct
BlockIO_tag {
real_T SinSig;
real_T Gain1Sig;
} BlockIO;
.
.
BlockIO rtB;
rtB.SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
Exported
Global
extern real_T SinSig;
SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
(declared in
model_export.h
Imported
Extern
extern real_T SinSig;
(declared in
model_common.h)
Imported
Extern
Pointer
3-76
Code
extern real_T *SinSig;
(declared in
model_common.h)
SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
*(SinSig) = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
Signals: Storage, Optimization, and Interfacing
C API for Parameter Tuning and Signal Monitoring
The Real-Time Workshop includes support for development of a C application
program interface (API) for tuning parameters and monitoring signals
independent of external mode. See “Interfacing Parameters and Signals” in
Chapter 17 for information.
Target Language Compiler API for Parameter
Tuning and Signal Monitoring
The Real-Time Workshop includes support for development of a Target
Language Compiler API for tuning parameters and monitoring signals
independent of external mode. See “Interfacing Parameters and Signals” in
Chapter 17 for information.
Parameter Tuning via MATLAB Commands
The Model Parameter Configuration dialog is the recommended way to see
or set the attributes of tunable parameters. However, you can also use
MATLAB get_param and set_param commands.
The following commands return the tunable parameters and/or their
attributes:
• get_param(gcs, 'TunableVars')
• get_param(gcs, 'TunableVarsStorageClass')
• get_param(gcs, 'TunableVarsTypeQualifier')
The following commands declare tunable parameters or set their attributes:
• 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
3-77
3
Code Generation and the Build Process
• 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.
set_param(gcs, 'TunableVars', 'k1')
set_param(gcs, 'ExportedGlobal')
set_param(gcs, 'TunableVarsTypeQualifier','const')
3-78
Simulink Data Objects and Code Generation
Simulink Data Objects and Code Generation
Prerequisites
Before using Simulink data objects with the Real-Time Workshop, please read
the following:
• The discussion of Simulink data objects in Using Simulink
• “Parameters: Storage, Interfacing, and Tuning” on page 3-51
• “Signals: Storage, Optimization, and Interfacing” on page 3-65
Overview
Within the class hierarchy of Simulink data objects, Simulink provides two
classes that are designed as base classes for signal and parameter storage.
These are:
• Simulink.Parameter: Objects that are instances of the Simulink.Parameter
class or any class derived from Simulink.Parameter are called parameter
objects.
• Simulink.Signal: Objects that are instances of the Simulink.Signal class
or any class derived from Simulink.Signal are called signal objects.
The RTWInfo properties of parameter and signal objects are used by the
Real-Time Workshop during code generation. These properties let you assign
storage classes and storage type qualifiers to the objects, thereby controlling
how the generated code stores and represents signals and parameters.
The Real-Time Workshop also writes information about the properties of
parameter and signal objects to the model.rtw file. This information, formatted
as ObjectProperties records, is accessible to Target Language Compiler
programs. For general information on ObjectProperties records, see “Object
Property Information in the model.rtw File” on page 3-88.
The general procedure for using Simulink data objects in code generation is as
follows:
1 Define a subclass of one of the built-in Simulink.Data classes.
- For parameters, define a subclass of Simulink.Parameter.
- For signals, define a subclass of Simulink.Signal.
3-79
3
Code Generation and the Build Process
2 Instantiate parameter or signal objects from your subclass and set their
properties appropriately, using the Simulink Explorer.
3 Use the objects as parameters or signals within your model.
4 Generate code and build your target executable.
The following sections describe the relationship between Simulink data objects
and code generation in the Real-Time Workshop.
3-80
Simulink Data Objects and Code Generation
Parameter Objects
This section discusses how to use parameter objects in code generation.
Configuring 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: Storage, Interfacing, and
Tuning” on page 3-51).
• Parameter object properties:
- Value. This property is the numeric value of the object, used as an initial
(or inlined) parameter value in generated code.
- RTWInfo.StorageClass. This property controls the generated storage
declaration and code for the parameter object.
- RTWInfo.TypeQualifier. This property is a string included as a prefix in
the generated storage declaration.
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 RTWInfo.StorageClass
and RTWInfo.TypeQualifier parameter object properties are ignored in code
generation.
Effect of Storage Classes on Code Generation for Parameter Objects
The Real-Time Workshop generates code and storage declarations based on the
RTWInfo.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.
3-81
3
Code Generation and the Build Process
You can also make variables declared in your hand-written code visible to
the generated code.
- The symbolic name of the parameter object is preserved in the generated
code.
See Table 3-7 for examples of code generated for each possible setting of
RTWInfo.StorageClass.
Example of Parameter Object Code Generation
In this section, we use the Gain block computations of the model shown in
Figure 3-13 as an example of how the Real-Time Workshop generates code for
a parameter object.
Figure 3-13: Model Using Parameter Object Kp As Block Parameter
In this model, Kp sets the gain of the Gain1 block.
To configure a parameter object such as Kp for code generation:
1 Define a subclass of Simulink.Parameter. In this example, the parameter
object is an instance of the example class UserDefined.Parameter, which is
3-82
Simulink Data Objects and Code Generation
provided with Simulink. For the definition of UserDefined.Parameter, see
the directory
matlabroot/toolbox/simulink/simdemos/@UserDefined.
2 Instantiate a parameter object from your subclass. The following example
instantiates Kp as a parameter object of class UserDefined.Parameter.
Kp = UserDefined.Parameter;
Make sure that the name of the parameter object matches the desired block
parameter in your model. This ensures that Simulink can associate the
parameter name with the correct object. For example, in the model of
Figure 3-13, the Gain block parameter Kp resolves to the parameter object
Kp.
3 Set the object properties.
- Set the Value property, for example:
Kp.Value = 5.0;
- Set the RTWInfo.StorageClass property, for example:
Kp.RTWInfo.StorageClass = 'ExportedGlobal';
- Optional: if the RTWInfo.StorageClass property is not Auto, you can
assign a storage type qualifier to the RTWInfo.TypeQualifier property,
for example:
Kp.RTWInfo.StorageClass = 'const';
Table 3-7 shows the variable declarations for Kp and the code generated for the
Gain block in the model shown in Figure 3-13, with Inline parameters on. An
example is shown for each possible setting of RTWInfo.StorageClass.
3-83
3
Code Generation and the Build Process
Table 3-7: Code Generation from Parameter Objects (Inline Parameters ON)
StorageClass Property
3-84
Generated Variable Declaration
and Code
Auto
rtB.y = rtB.u * (5.0);
Simulink Global
typedef struct Parameters_tag {
real_T Kp;
.
.
Parameters rtP = {
5.0
};
.
.
rtB.y = rtB.u * (rtP.Kp);
Exported Global
real_T Kp = 5.0;
.
.
rtB.y = rtB.u * (Kp);
Imported Extern
extern real_T Kp;
.
.
rtB.y = rtB.u * (Kp);
Imported Extern Pointer
extern real_T *Kp;
.
.
rtB.y = rtB.u * ((*Kp));
Simulink Data Objects and Code Generation
Signal Objects
This section discusses how to use signal objects in code generation.
Configuring 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: Storage,
Optimization, and Interfacing” on page 3-65).
• The Local block outputs code generation option (see “Signals: Storage,
Optimization, and Interfacing” on page 3-65).
• Signal object properties:
- RTWInfo.StorageClass. The storage classes defined for signal objects, and
their effect on code generation, are the same for model signals and signal
objects (see “Storage Classes for Signals” on page 3–66).
- RTWInfo.TypeQualifier. This property is a storage type qualifier. The
string is included as a prefix in the generated storage declaration. The
syntax of the string is not checked for validity.
Other signal object properties (such as user-defined properties of classes
derived from Simulink.Signal) do not affect code generation.
Effect of Storage Classes on Code Generation for Signal Objects
The way in which the Real-Time Workshop 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 RTWInfo.StorageClass
property is used in place of the port configuration of the signal.
The default storage class is Auto. If the storage type is Auto, the Real-Time
Workshop follows the Signal storage reuse and Local block outputs code
generation options to determine whether signal objects are stored in reusable
and/or local variables. Make sure that these options are set correctly for your
application.
To generate a a test point or externally-interfaceable signal storage
declaration, use an explicit RTWInfo.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.RTWInfo.StorageClass = 'SimulinkGlobal';
3-85
3
Code Generation and the Build Process
Example of Signal Object Code Generation
The discussion and code examples in this section refers to the model shown in
Figure 3-14.
Figure 3-14: Example Model With Signal Object
To configure a signal object, you must first create it and associate it with a
labelled 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 example class UserDefined.Signal, which is provided
with Simulink. For the definition of UserDefined.Signal, see the directory
matlabroot/toolbox/simulink/simdemos/@UserDefined.
2 Instantiate a signal object from your subclass. The following example
instantiates SinSig, a signal object of class UserDefined.Signal.
SinSig = UserDefined.Signal;
Make sure that the name of the signal object matches the label of the desired
signal in your model. This ensures that Simulink can resolve the signal label
to the correct object. For example, in the model shown in Figure 3-14, the
signal label SinSig would resolve to the signal object SinSig.
3 Set the object properties as required:
- Assign the signal object’s storage class by setting the
RTWInfo.StorageClass property, for example,
SinSig.RTWInfo.StorageClass = 'ExportedGlobal';
- Optional: if the RTWInfo.StorageClass property is not Auto, you can
assign a storage type qualifier to the RTWInfo.TypeQualifier property,
for example,
SinSig.RTWInfo.StorageClass = 'const';
3-86
Simulink Data Objects and Code Generation
Table 3-8 shows, for each setting of RTWInfo.StorageClass, the variable
declaration and the code generated for Sine Wave output (SinSig) of the model
shown in Figure 3-14.
Table 3-8: Signal Properties Options and Generated Code
Storage Class
Auto
(with storage
optimizations
on)
Declaration
real_T rtb_temp0;
(declared in
model_common.h)
Code
rtb_temp0 = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
Simulink
Global
typedef struct
BlockIO_tag {
real_T SinSig;
real_T Gain1Sig;
} BlockIO;
.
.
BlockIO rtB;
rtB.SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
Exported
Global
extern real_T SinSig;
SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
(declared in
model_export.h
Imported
Extern
extern real_T SinSig;
(declared in
model_common.h)
Imported
Extern
Pointer
extern real_T *SinSig;
(declared in
model_common.h)
SinSig = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
*(SinSig) = (rtP.Sine_Wave_Amp) *
sin((rtP.Sine_Wave_Freq) * ssGetT(rtS)
+ (rtP.Sine_Wave_Phase));
3-87
3
Code Generation and the Build Process
Object Property Information in the model.rtw File
During code generation, the Real-Time Workshop writes property information
about signal and parameter objects to the model.rtw file. An
ObjectProperties record is written for each parameter or signal that meets
certain conditions. These conditions are described in “ObjectProperties Records
For Parameters” on page 3-88 and “ObjectProperties Records For Signals” on
page 3-89.
The ObjectProperties records contain all of the property information from the
associated object. To access ObjectProperties records, you must write Target
Language Compiler code (see “Accessing Object Property Information via TLC”
on page 3-90).
ObjectProperties Records For Parameters
An ObjectProperties record is included in the in the ModelParameters section
of model.rtw file for each parameter, under the following conditions:
1 Inline parameters is on.
2 The parameter resolves to a Simulink.Parameter object (or to a parameter
object that comes from a class derived from the Simulink.Parameter class).
3 The parameter’s RTWInfo.StorageClass is set to anything but 'Auto'.
3-88
Simulink Data Objects and Code Generation
The following is an example of an ObjectProperties record for a parameter.
ModelParameters {
...
Parameter {
Identifier
Kp
Tunable
yes
...
Value
[5.0]
Dimensions
[1, 1]
ObjectProperties {
RTWInfo {
StorageClass "SimulinkGlobal"
TypeQualifier ""
}
Value 5.0
...
}
}
}
ObjectProperties Records For Signals
An ObjectProperties record is included in the BlockOutputs section of the
model.rtw file for each signal which meets the following conditions:
1 The signal resolves to a Simulink.Signal object (or to an object that comes
from a class derived from the Simulink.Signal class).
2 The signal’s symbol is preserved in the generated code. The symbol is
preserved if:
- The signal’s RTWInfo.StorageClass should be set to anything but 'Auto'.
- The signal label must be a valid variable name.
- The signal label must be unique throughout the model.
3-89
3
Code Generation and the Build Process
Note If the signal is configured to be an unstructured global variable in the
generated code, its validity and uniqueness are enforced and its symbol is
always preserved.
The following is an example of an ObjectProperties record for a signal.
BlockOutputs {
...
BlockOutput {
Identifier
SinSig
...
SigLabel "SinSig"
ObjectProperties {
RTWInfo {
StorageClass "SimulinkGlobal"
TypeQualifier ""
}
...
}
}
}
Accessing Object Property Information via TLC
This section provides sample code to illustrate how to access object property
information from the model.rtw file using TLC code. For more information on
TLC and the model.rtw file, see the Target Language Compiler Reference
Guide.
3-90
Simulink Data Objects and Code Generation
Accessing Parameter Object Property Records. The following code fragment iterates
over the ModelParameters section of the model.rtw file and extracts
information from any parameter ObjectProperties records encountered.
%with CompiledModel.ModelParameters
%foreach modelParamIdx = NumParameters
%assign thisModelParam = ModelParameter[modelParamIdx]
%assign paramName = thisModelParam.Identifier
%if EXISTS("thisModelParam.ObjectProperties")
%with thisModelParam.ObjectProperties
%assign valueInObject = Value
%with RTWInfo
%assign storageClassInObject = StorageClass
%assign typeQualifierInObject = TypeQualifier
%endwith
%% ***********************************
%% Access user-defined properties here
%% ***********************************
%if EXISTS("MY_PROPERTY_NAME")
%assign userDefinedPropertyName = MY_PROPERTY_NAME
%endif
%% ***********************************
%endwith
%endif
%endforeach
%endwith
3-91
3
Code Generation and the Build Process
Accessing Signal Object Property Records. The following code fragment iterates over
the BlockOutputs section of the model.rtw file and extracts information from
any signal ObjectProperties records encountered.
%with CompiledModel.BlockOutputs
%foreach blockOutputIdx = NumBlockOutputs
%assign thisBlockOutput = BlockOutput[blockOutputIdx]
%assign signalName = thisBlockOutput.Identifier
%if EXISTS("thisBlockOutput.ObjectProperties")
%with thisBlockOutput.ObjectProperties
%with RTWInfo
%assign storageClassInObject = StorageClass
%assign typeQualifierInObject = TypeQualifier
%endwith \
%% ***********************************\
%% Access user-defined properties here\
%% ***********************************
%if EXISTS("MY_PROPERTY_NAME")
%assign userDefinedPropertyName = MY_PROPERTY_NAME
%endif
%% ***********************************
%endwith
%endif
%endforeach
%endwith
Using Object Properties to Export ASAP2 Files
The ASAM-ASAP2 Data Definition Target provides special signal and
parameter subclasses that support exporting of signal and parameter object
property information to ASAP2 data files. For information about the ASAP2
target and its associated classes and TLC files, see “Generating ASAP2 Files”
in the Real-Time Workshop online documentation.
3-92
Configuring the Generated Code via TLC
Configuring the Generated Code via TLC
This section covers features of the Real-Time Workshop Target Language
Compiler that help you to fine-tune your generated code. To learn more about
TLC, read the Target Language Compiler Reference Guide.
Target Language Compiler Variables and Options
The Target Language Compiler supports extended code generation variables
and options in addition to those included in the code generation options
categories of the Real-Time Workshop page.
There are two ways to set TLC variables and options:
• Assigning TLC variables in the system target file
• Entering TLC options or variables into the System Target File field on the
Real-Time Workshop page
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.
The %assign statement is described in the Target Language Compiler
Reference Guide. It is recommended that you write your %assign statements in
the Configure RTW code generation settings section of the system target
file.
3-93
3
Code Generation and the Build Process
The following table lists the code generation variables you can set with the
%assign statement.
Table 3-9: Target Language Compiler Optional Variables
Variable
Description
MaxStackSize=N
When Local block outputs is enabled, the
total allocation size of local variables that
are declared by all functions in the entire
model may not exceed MaxStackSize (in
bytes). N can be any positive integer.
MaxStackVariableSize=N
When Local block outputs is enabled, this
limits the size of any local variable declared
in a function to N bytes, where N>0. A
variable whose size exceeds
MaxStackVariableSize will be allocated in
global, rather than local, memory
FunctionInlineType=
"mode"
Controls how functions are inlined. There
are two modes:
• CodeInsertion
• PragmaInline
Using CodeInsertion, the code is actually
inserted where the function call would have
been made. PragmaInline directs the
Target Language Compiler to declare the
function when the appropriate compiler
directive occurs.
PragmaInlineString=
"string"
3-94
If FunctionInlineType is set to
PragmaInline, this should be set to the
directive that your compiler uses for
inlining a function (for example, for
Microsoft Visual C/C++, "__inline").
Configuring the Generated Code via TLC
Table 3-9: Target Language Compiler Optional Variables (Continued)
Variable
Description
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
BlockIOSignals=value
Supports monitoring signals in a running
model. See “Signal Monitoring via Block
Outputs” on page 17-65. Setting the
variable causes the model_bio.c file to be
generated. These are the options:
• 0 — deactivates this feature
• 1 — creates model_bio.c
ParameterTuning=value
Setting the variable to 1 causes a
parameter tuning file (model_pt.c) to be
generated. model_pt.c contains data
structures that enable a running program
to access model parameters independent of
external mode. See “Parameter Tuning via
model_pt.c” on page 17-71.
Setting Target Language Compiler Options
You can enter TLC options directly into the System target file field in the
Target configuration category of the Real-Time Workshop page, by
appending the options and arguments to the system target filename. This is
equivalent to invoking the Target Language Compiler with options on the
MATLAB command line.
3-95
3
Code Generation and the Build Process
The common options are shown in the table below.
Table 3-10: Target Language Compiler Options
Option
Description
−Ipath
Adds path to the list of paths in which to search
for target files (.tlc files).
−m[N|a]
Maximum number of errors to report when an
error is encountered (default is 5). For example,
−m3 specifies that at most three errors will be
reported. To report all errors, specify −ma.
−d[g|n|o]
Specifies debug mode (generate, normal, or
off). Default is off. When −dg is specified,
a .log file is create for each of your TLC files.
When debug mode is enabled (i.e., generate or
normal), the Target Language Compiler displays
the number of times each line in a target file is
encountered.
−aVariable=val
Equivalent to the TLC statement
%assign Variable = val
Note: It is recommended that you use %assign
statements in the TLC files, rather than the -a
option.
3-96
Making an Executable
Making an Executable
After completing code generation, the build process determines whether or not
to continue and compile and link an executable program. This decision is
governed by the following parameters:
• Generate code only option
When this option is selected, the build process always omits the make phase.
• Makefile-only target
The Visual C/C++ Project Makefile versions of the grt, grt_malloc, and
Real-Time Workshop Embedded Coder target configurations generate a
Visual C/C++ project makefile (model.mak). To build an executable, you must
open model.mak in the Visual C/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 HOST variable can take on one
of three possible values: PC, UNIX, or ANY.
By default, HOST is set to UNIX in template makefiles designed for use with
UNIX (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 Simulink is running on the same type of system as that specified by the
HOST variable, then the executable is built. Otherwise:
- 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 Simulink
is running on.
- 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
3-97
3
Code Generation and the Build Process
Directories Used in the Build Process
The Real-Time Workshop creates output files in two directories during the
build process:
• The working directory
If an executable is created, it is written to your working directory. The
executable is named model.exe (on PC) or model (on UNIX).
• The build directory
The build process creates a subdirectory, called the build directory, within
your working directory. The build directory name is model_target_rtw,
where model is the name of the source model and target is the name of the
chosen target. The build directory stores generated source code and all other
files created during the build process (except the executable).
The build directory always contains the generated code modules model.c,
model.h, and model_export.h, and the generated makefile model.mk.
Depending upon the target and code generation and build options selected,
additional files in the build directory may include:
• model.rtw
• Object (.obj) files
• Code modules generated from subsystems
• TLC profiler report files
• Block I/O (model_bio.c) and parameter tuning (model_pt.c) information
files
• Real-Time Workshop project (model.tmw) files
3-98
Choosing and Configuring Your Compiler
Choosing and Configuring Your Compiler
The Real-Time Workshop build process depends upon the correct installation
of one or more supported compilers. Note that compiler, in this context, refers
to a development environment containing a linker and make utility, in addition
to a high-level language compiler.
The build process also requires the selection of a template makefile. The
template makefile determines which compiler will be run, during the make
phase of the build, to compile the generated code.
This section discusses how to install a compiler and choose an appropriate
template makefile, on both Windows and UNIX systems.
Choosing and Configuring Your Compiler on Windows
On Windows, you must install one or more supported compilers, In addition,
you must define an environment variable associated with each compiler.Make
sure that your compiler is installed as described in“Third-Party Compiler
Installation on Windows” on page -xxii.
You can select a template makefile that is specific to your compiler. For
example, grt_bc.tmf designates the Borland C/C++ compiler, and grt_vc.tmf
designates the Visual C/C++ compiler.
Alternatively, you can choose a default template makefile that will select the
default compiler for your system. The default compiler is the compiler
MATLAB uses to build MEX-files. You can set up the default compiler by using
the MATLAB mex command as shown below.
mex –setup
See the MATLAB Application Program Interface Guide for information on the
mex command.
Default template makefiles are named target_default_tmf. For example, the
default template makefile for the generic real-time (GRT) target is
grt_default_tmf.
The build process uses the following logic to locate a compiler for the generated
code:
1 If a specific compiler is named in the template makefile, the build process
uses that compiler.
3-99
3
Code Generation and the Build Process
2 If the template makefile designates a default compiler (as in
grt_default_tmf), the build process uses the same compiler as those used
for building C MEX-files.
3 If no default compiler is established, the build process examines
environment variables which define the path to installed compilers, and
selects the first compiler located. The variables are searched in the following
order:
- MSDevDir or DEVSTUDIO (defining the path to the Microsoft Visual C/C++)
- WATCOM (defining the path to the Watcom C/C++ compiler)
- BORLAND (defining the path to the Borland C/C++ compiler)
4 If none of the above environment variables is defined, the build process
selects the lcc compiler, which is shipped and installed with MATLAB.
Compile/Build Options for Visual C/C++. The Real-Time Workshop offers two sets of
template makefiles designed for use with Visual C/C++.
To compile under Visual C/C++ and build an executable within the Real-Time
Workshop build process, use one of the target_vc.tmf template makefiles:
• ert_vc.tmf
• grt_malloc_vc.tmf
• grt_vc.tmf
• rsim_vc.tmf
Alternatively, you can choose to create a project makefile (model.mak) suitable
for use with the Visual C/C++ IDE. In this case, you must compile and link your
code within the Visual C/C++ environment. To create a Visual C/C++ project
makefile, choose one of the Visual C/C++ Project Makefile versions of the grt,
ert, or grt_malloc target configurations. These configurations use the
target_msvc.tmf template makefiles:
• ert_msvc.tmf
• grt_malloc_msvc.tmf
• grt_msvc.tmf
3-100
Choosing and Configuring Your Compiler
Choosing and Configuring Your Compiler On UNIX
On UNIX, the Real-Time Workshop build process uses the default compiler. cc
is the default on all platforms except SunOS, where gcc is the default.
You should choose the UNIX-specific template makefile that is appropriate to
your target. For example, grt_unix.tmf is the correct template makefile to
build a generic real-time program under UNIX.
Available Compiler/Makefile/Target Configurations
To determine which template makefiles are appropriate for your compiler and
target, see the table “Targets Available from the System Target File Browser”
on page 3-36.
3-101
3
Code Generation and the Build Process
Template Makefiles and Make Options
The Real-Time Workshop 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
Visual C/C++; ert_lcc.tmf is the template makefile for building a
Real-Time Workshop Embedded Coder program under the LCC compiler.
• Default template makefiles make your model designs more portable, by
choosing the correct compiler-specific makefile and compiler for your
installation. “Choosing and Configuring Your Compiler” on page 3-99
describes the operation of default template makefiles in detail.
Default template makefiles are named target_default_tmf. 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
building a Real-Time Workshop Embedded Coder program.
You can supply options to makefiles via arguments to the Make command
field of the Target configuration category of the Real-Time Workshop page.
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.
Compiler-Specific Template Makefiles
This section documents the available compiler-specific template makefiles and
common options you can use with each.
Template Makefiles for UNIX
• ert_unix.tmf
3-102
Template Makefiles and Make Options
• grt_malloc_unix.tmf
• grt_unix.tmf
• rsim_unix.tmf
• rtwsfcn_unix.tmf
The template makefiles for UNIX platforms are designed to be used with GNU
Make. These makefile are set up to conform to the guidelines specified in the
IEEE Std 1003.2-1992 (POSIX) standard.
You can supply options via arguments to the make command.
• OPTS — User-specific options, for example,
make_rtw OPTS="-DMYDEFINE=1"
• OPT_OPTS — Optimization options. The default optimization option is -O. To
turn off optimization and add debugging symbols, specify the -g compiler
switch in the make command, for example,
make_rtw OPT_OPTS="-g"
For additional options, see the comments at the head of each template
makefile.
Template Makefiles for Visual C/C++
The Real-Time Workshop offers two sets of template makefiles designed for use
with Visual C/C++.
To build an executable within the Real-Time Workshop 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 via arguments to the make command.
• OPTS — User-specific options, for example,
make_rtw OPTS="-DMYDEFINE=1"
3-103
3
Code Generation and the Build Process
• OPT_OPTS — Optimization options. The default optimization option is -Ot. To
turn off optimization and add debugging symbols, specify the -Zd compiler
switch in the make command.
make_rtw OPT_OPTS="-Zd"
For additional options, see the comments at the head of each template
makefile.
To create a Visual C/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 Visual C/C++.
You can supply the following options via arguments to the nmake command:
• OPTS — User-specific options, for example,
make_rtw OPTS="/D MYDEFINE=1"
For additional options, see the comments at the head of each template
makefile.
Template Makefiles for Watcom C/C++
Note As of this printing, the Watcom C compiler is no longer available from
the manufacturer. The Real-Time Workshop continues to ship Watcom-related
template makefiles at this time. However, this policy may be subject to change
in the future.
• drt_watc.tmf
• ert_watc.tmf
• grt_malloc_watc.tmf
• grt_watc.tmf
• rsim_watc.tmf
3-104
Template Makefiles and Make Options
• rtwsfcn_watc.tmf
• win_watc.tmf
The Real-Time Workshop provides template makefiles to create an executable
for Windows 95, Windows 98, and Windows NT using Watcom C/C++. These
template makefiles are designed to be used with wmake, which is bundled with
Watcom C/C++.
You can supply options via 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"
For additional options, see the comments at the head of each template
makefile.
Template Makefiles for Borland C/C++
• ert_bc.tmf
• grt_bc.tmf
• grt_malloc_bc.tmf
• rsim_bc.tmf
• rtwsfcn_bc.tmf
The Real-Time Workshop provides template makefiles to create an executable
for Windows 95, Windows 98, and Windows NT using Borland C/C++.
You can supply these options via arguments to the make command:
• OPTS — User-specific options, for example,
make_rtw OPTS="-DMYDEFINE=1"
3-105
3
Code Generation and the Build Process
• OPT_OPTS — Optimization options. Default is none. To turn off optimization
and add debugging symbols, specify the -v compiler switch in the make
command.
make_rtw OPT_OPTS="-v"
For additional options, see the comments at the head of each template
makefile.
Template Makefiles for LCC
• ert_lcc.tmf
• grt_lcc.tmf
• grt_malloc_lcc.tmf
• rsim_lcc.tmf
• rtwsfcn_lcc.tmf
The Real-Time Workshop provides template makefiles to create an executable
for Windows 95, Windows 98, and Windows NT using LCC compiler Version
2.4 and GNU Make (gmake).
You can supply options via 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"
For additional options, see the comments at the head of each template
makefile.
Template Makefile Structure
The detailed structure of template makefiles is documented in “Template
Makefiles” on page 17-25. This information is provided for those who want to
customize template makefiles.
3-106
4
Generated Code Formats
Introduction . . . . . . . . . . . . . . . . . . . . 4-2
. . . . . 4-3
Choosing a Code Format for Your Application
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-6
4-6
4-6
4-6
Real-Time malloc Code Format
Unsupported Blocks . . . . .
System Target Files . . . . .
Template Makefiles . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4-8
4-8
4-8
4-8
Real-Time Code Format
Unsupported Blocks . .
System Target Files . .
Template Makefiles . . .
.
.
.
.
.
.
.
.
S-Function Code Format . . . . . . . . . . . . . . . 4-10
Embedded C Code Format
. . . . . . . . . . . . . . 4-11
4
Generated Code Formats
Introduction
The Real-Time Workshop 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 .dll or MEX-file objects, code
reuse, and speeding up your simulation
• Embedded C: Deeply embedded systems
• Ada
Note Generation of Ada code requires the Real-Time Workshop Ada Coder, a
separate product. See Chapter 16, “Real-Time Workshop Ada Coder” for more
information.
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, and embedded C code formats.
4-2
Choosing a Code Format for Your Application
Choosing a Code Format for Your Application
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 real-time or real-time malloc code format for rapid prototyping. If
your application does not have significant restrictions in code size, memory
usage, or stack usage, you may want to continue using the generic real-time
(GRT) target throughout development. The real-time format is the most
comprehensive code format and supports almost all the built-in blocks.
If your application demands that you limit source code size, memory usage, or
maintain a simple call structure, then you should choose the Real-Time
Workshop Embedded Coder target, which uses the embedded C format.
Finally, you should choose the S-function format 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 .dll or MEX-file object
• Interface the generated code using the S-function C API
• Speed up your simulation
Table 4-1 summarizes the various options available for each code format/target
available in the Real-Time Workshop.
4-3
4
Generated Code Formats
Table 4-1: Features Supported by Real-Time Workshop Targets and Code Formats
Feature
GRT
Static
memory
allocation
X
Dynamic
memory
allocation
RealTime
malloc
DOS
Ada
Tornado
SFunc
X
X
X
X
X
X
X
X
X
RSIM
RT
Win
xPC
TI
DSP
X
X
X
Continuous
time
X
X
X
X
X
X
X
X
C MEX
S-functions
(noninline)
X
X
X
X
X
X
X
X
X
Any
S-function
(inlined)
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
Optimized
for min.
RAM/ ROM
usage
X
X
Intended
for rapid
prototyping
X
X
Batch
parameter
tuning and
Monte
Carlo
methods
X
X
X
Supports
external
mode
Intended
for
production
code
4-4
RTW
Embedded
Coder
X
X
X
X
X
X
Choosing a Code Format for Your Application
Table 4-1: Features Supported by Real-Time Workshop Targets and Code Formats (Continued)
Feature
GRT
RealTime
malloc
RTW
Embedded
Coder
DOS
Ada
Tornado
Executes in
hard real
time
X
X
X
X
X
X
Non
real-time
executable
included
X
X
X
Multiple
instances
of one
model (if no
Stateflow
blocks in
model)
X
SFunc
X
RSIM
RT
Win
xPC
TI
DSP
X
X
X
X
X
4-5
4
Generated Code Formats
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 MEX S-functions (inlined and noninlined)
For more information on inlining S-functions, see the Target Language
Compiler Reference Guide.
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 blocks:
• Functions & Tables
- MATLAB Fcn
- S-Function — M-file and Fortran S-functions, C MEX S-functions that call
into MATLAB.
System Target Files
• drt.tlc — DOS real-time target
• grt.tlc — generic real-time target
• osek_leo.tlc — Lynx-Embedded OSEK target
• rsim.tlc — rapid simulation target
• tornado.tlc — Tornado (VxWorks) real-time target
Template Makefiles
• drt.tmf
• grt
- grt_bc.tmf — Borland C
4-6
Real-Time Code Format
- grt_vc.tmf — Visual C
- grt_watc.tmf — Watcom C
- grt_lcc.tmf — LCC compiler
- grt_unix.tmf — UNIX host
• osek_leo.tmf
• rsim
- rsim_bc.tmf — Borland C
- rsim_vc.tmf — Visual C
- rsim_watc.tmf — Watcom C
- rsim_lcc.tmf — LCC compiler
- rsim_unix.tmf — UNIX host
• tornado.tmf
• win_watc.tmf
4-7
4
Generated Code Formats
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.
• Real-time malloc allows you to multiply instance 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 Real-Time Workshop will not
necessarily create uniquely named data structures for each model,
potentially resulting in name clashes.
grt_malloc_main.c, the main routine for the generic real-time malloc
(grt_malloc) target, supports one model by default. See“Combining
Multiple Models” on page 17–82 for information on modifying
grt_malloc_main to support multiple models. grt_malloc_main.c is located
in the directory matlabroot/rtw/c/grt_malloc.
Unsupported Blocks
The real-time malloc format does not support the following built-in blocks:
• Functions & Tables
- MATLAB Fcn
- S-Function — M-file and Fortran S-functions, C MEX S-functions that call
into MATLAB.
System Target Files
• grt_malloc.tlc
• tornado.tlc — Tornado (VxWorks) real-time target
Template Makefiles
• grt_malloc
- grt_malloc_bc.tmf — Borland C
4-8
Real-Time malloc Code Format
- grt_malloc_vc.tmf — Visual C
- grt_malloc_watc.tmf — Watcom C
- grt_malloc_lcc.tmf — LCC compiler
- grt_malloc_unix.tmf — UNIX host
• tornado.tmf
4-9
4
Generated Code Formats
S-Function Code Format
The S-function code format (corresponding to the S-Function Target) generates
code that conforms to the Simulink C 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 Simulink Accelerator to create
the Accelerator MEX-file.
In general you should not use the S-function code format in a system target file.
However, you may 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 a Simulink Accelerator MEX-file.
See Chapter 10, “The S-Function Target” for further information.
4-10
Embedded C Code Format
Embedded C Code Format
The embedded C code format corresponds to the Real-Time Workshop
Embedded Coder target. This code format includes a number of memory-saving
and performance optimizations. See Chapter 9, “Real-Time Workshop
Embedded Coder” for full details.
4-11
4
Generated Code Formats
4-12
5
External Mode
Introduction . . . . . . . . . . . . . . . . . . . . 5-2
Tutorial: Getting Started with External Mode Using GRT
Part 1: Setting Up the Model . . . . . . . . . . . . .
Part 2: Building the Target Executable . . . . . . . . .
Part 3: Running the External Mode Target Program . . .
Part 4: Tuning Parameters . . . . . . . . . . . . . .
. 5-4
. 5-4
. 5-6
. 5-11
. 5-14
Using the External Mode User Interface . .
External Mode Related Menu and Toolbar Items
External Mode Control Panel . . . . . . . .
Connection and Start/Stop Controls . . . . .
Target Interface Dialog Box . . . . . . . .
External Signal & Triggering Dialog Box . . .
Data Archiving . . . . . . . . . . . . .
Parameter Download Options . . . . . . .
. 5-16
. 5-16
. 5-21
. 5-22
. 5-23
. 5-24
. 5-28
. 5-31
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
External Mode Compatible Blocks and Subsystems . . . 5-32
Compatible Blocks . . . . . . . . . . . . . . . . . . 5-32
Signal Viewing Subsystems . . . . . . . . . . . . . . 5-32
Overview of External Mode Communications . . . . . . 5-36
The Download Mechanism . . . . . . . . . . . . . . . 5-36
The TCP/IP Implementation . . . . . . .
Overview . . . . . . . . . . . . . . . .
Using the TCP/IP Implementation . . . . .
The External Interface MEX-File . . . . . .
External Mode Compatible Targets . . . . .
Running the External Program . . . . . . .
Error Conditions . . . . . . . . . . . . .
Implementing an External Mode Protocol Layer
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 5-38
. 5-38
. 5-38
. 5-40
. 5-41
. 5-41
. 5-44
. 5-44
Limitations of External Mode . . . . . . . . . . . . . 5-45
5
External Mode
Introduction
External mode allows two separate systems — a host and a target — to
communicate. The host is the computer where MATLAB and Simulink are
executing. The target is the computer where the executable created by the
Real-Time Workshop runs.
The host (Simulink) 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 on a client/server
architecture, in which Simulink 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, Simulink automatically
downloads them to the executing target program. This lets you tune your
program’s parameters without recompiling. In external mode, the Simulink
model becomes a graphical front end to the target program.
• 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
Simulink and the Real-Time Workshop generated code. This channel is
implemented by a low-level transport layer that handles physical transmission
of messages. Both Simulink and the generated model code are independent of
this layer. The transport layer and the code directly interfacing to the transport
layer are 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. For example, the GRT, GRT malloc, and Tornado targets support host/
target communication via TCP/IP, whereas the xPC Target supports both
RS232 (serial) and TCP/IP communication. The Real-Time Windows Target
implements external mode communication via shared memory.
5-2
This chapter discusses the following topics:
• “Tutorial: Getting Started with External Mode Using GRT” on page 5–4
covers the basics of how to use external mode on a single computer.
• “Using the External Mode User Interface” on page 5–16 covers all elements
of the external mode user interface in detail.
• “External Mode Compatible Blocks and Subsystems” on page 5–32 discusses
the types of blocks that you can use to receive and view signals in external
mode.
• “Signal Viewing Subsystems” on page 5-32 shows how you can use
subsystems to encapsulate processing and viewing of signals received from
the target system. This feature can help you generate a smaller and more
efficient target program.
• “Overview of External Mode Communications” on page 5-36 summarizes the
communications process between Simulink and the target program.
• “The TCP/IP Implementation” on page 5-38 discusses the TCP/IP-based
implementation of the external mode protocol that is provided by the
Real-Time Workshop. This section includes information on bundled targets
that support this implementation, and on how to build and run target
programs that support the TCP/IP implementation.
• “Limitations of External Mode” on page 5-45 discusses limitations on the use
of external mode that are imposed by the structure of the model.
Additional Reading
“Creating an External Mode Communication Channel” on page 17–73 contains
advanced information for those who want to implement their own external
mode communications layer. You may want to read it for additional insight into
the architecture and code structure of external mode communications.
Chapter 12, “Targeting Tornado for Real-Time Applications” discusses the use
of external mode in the VxWorks Tornado environment.
5-3
5
External Mode
Tutorial: Getting Started with External Mode Using GRT
This section provides step-by-step instructions for getting started with
external mode. This tutorial assumes you have basic familiarity with MATLAB
and Simulink. In addition, you should read Chapter 1, “Introduction to the
Real-Time Workshop.” Read “Getting Started: Basic Concepts and Tutorials”
on page 1-37 and do the “Quick Start Tutorials” on page 1-40 before proceeding.
The example presented uses the generic real-time (GRT) target. The example
does not require any hardware other than the computer on which you run
Simulink and the Real-Time Workshop. The generated executable in this
example runs on the host computer under a separate process from MATLAB
and Simulink. This technique is called self-targeting.
The procedures for building, running, and testing your programs are almost
identical in UNIX and PC environments. The discussion notes differences
where applicable.
For a more thorough description of external mode, including a discussion of all
the options available, see “Using the External Mode User Interface” on page
5-16.
Part 1: Setting Up the Model
In this part of the tutorial, you create a simple model, ext_example, and a
directory called ext_mode_example to store the model and the generated
executable:
1 Create the directory from the MATLAB command line by typing
mkdir ext_mode_example
2 Make ext_mode_example your working directory.
cd ext_mode_example
5-4
Tutorial: Getting Started with External Mode Using GRT
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.
Label the Gain and Scope blocks as shown.
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 sets its Gain parameter to the variable A as shown
below.
6 Similarly, open Gain block B and sets its Gain parameter to the variable B.
When the target program is built and connected to Simulink in external
mode, new gain values can be downloaded to the executing target program
by assigning new values to workspace variables A and B, or by editing the
values in the block parameter dialog boxes.
5-5
5
External Mode
7 Verify correct operation of the model. Open the Scope blocks and run the
model. Given that A=2 and B=3, the output should look like this.
8 From the File menu, choose Save As. Save the model as ext_example.mdl.
Part 2: Building 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.
9 Open the Simulation Parameters dialog box. On the Solver page, set the
Solver options Type to Fixed-step, and the algorithm to discrete (no
continuous states). Set Fixed-step Size to 0.01. Leave the other
parameters at their default values.
10 On the Workspace I/O page, deselect Time and Output. In this exercise,
data will not be logged to the workspace or to a MAT-file.
5-6
Tutorial: Getting Started with External Mode Using GRT
11 On the Real-Time Workshop page, select Target configuration from the
Category menu.
By default, the GRT target should be selected, as shown in this picture.
If the GRT target is not selected, click the Browse button and select the GRT
target from the System Target File Browser. Then click OK to close the
browser. Return to the Real-Time Workshop page and click Apply.
5-7
5
External Mode
12 Select GRT code generation options from the Category menu and check
the External mode option.This enables generation of external mode support
code.
13 Click Apply.
5-8
Tutorial: Getting Started with External Mode Using GRT
14 On the Advanced page, make sure that the Inline parameters option is
deselected. External mode does not currently support the Inline
parameters option.
The Advanced page should look like this picture.
15 From the Tools menu, select External Mode Control Panel. The External
Mode Control Panel, lets you configure host/target communications, 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 four buttons are for use after the target program has been launched.
The three lower buttons open three separate dialog boxes:
5-9
5
External Mode
- The Target interface button opens the External Target Interface dialog
box, which configures the external mode communications channel.
- The Signal & triggering button opens the External Signal & Triggering
dialog box, which configures which signals are viewed and how signals are
acquired.
- 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 5-28 for more information.
16 Click the Target interface button to open the External Target Interface
dialog box. This dialog box configures the external mode interface options.
The MEX-file for external interface field specifies the name of a MEX-file
that supports host/target communications on the host side. The default is
ext_comm, a MEX-file provided by the Real-Time Workshop. ext_comm
supports communication via the TCP/IP communications protocol.
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 file you are using.
For information on these arguments, see “The External Interface MEX-File”
on page 5-40.
This exercise uses the default arguments. Leave the MEX-file arguments
field blank.
The External Target Interface dialog box should appear as shown below.
5-10
Tutorial: Getting Started with External Mode Using GRT
17 Click OK to close the External Target Interface dialog box and return to
the External Mode Control Panel.
18 Close the External Mode Control Panel.
19 Save the model.
20 Return to the Real-Time Workshop page. Click Build to generate code and
create the target program. The content of the succeeding messages depends
on your compiler and operating system.The final message is
### Successful completion of Real-Time Workshop build procedure
for model: ext_example
In the next section, you will run the ext_example executable and use Simulink
as an interactive front end to the running target program.
Part 3: Running the External Mode Target Program
The target executable, ext_example, is now in your working directory. In this
section, you run the target program and establish communication between
Simulink and the target.
The External Signal & Triggering dialog box displays a list of all the blocks
in your model that support external mode signal monitoring and logging. The
External Signal & Triggering dialog box also lets you configure which signals
are viewed and how they are acquired and displayed. You can reconfigure the
External Signal & Triggering dialog box while the target program runs.
In this exercise you will observe and use the default settings of the External
Signal & Triggering dialog box.
21 From the Tools menu, select External Mode Control Panel.
22 In the External Mode Control Panel, click the Signal & triggering button.
23 The External Signal & Triggering dialog box opens. The default
configuration of the External Signal & Triggering dialog box is designed to
ensure that all signals are selected for monitoring. The default configuration
also ensures that signal monitoring will begin as soon as the host and target
5-11
5
External Mode
programs have connected. The figure below shows the default configuration
for ext_example.
24 Make sure that the External Signal and Triggering dialog box is set to the
defaults as shown:
- Select all check box is selected. All signals in the Signal selection list are
are marked with an X in the Block column.)
- Trigger Source: manual
- Trigger Mode: normal
- Duration: 1000
- Delay: 0
- Arm when connect to target: selected
Click Close and return to the External Mode Control Panel. Close the
External Mode Control Panel.
5-12
Tutorial: Getting Started with External Mode Using GRT
25 To run the target program, you must open an MS-DOS command prompt (on
UNIX systems, an Xterm window). At the command prompt, type
ext_example -tf inf -w
and the target program begins execution.
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 will run 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.
26 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.
27 The model 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 in the toolbar of the Simulink
window. Alternatively, you can select External from the Simulation menu.
28 Reopen the External Mode Control Panel 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 caption of the Connect button changes to Disconnect.
5-13
5
External Mode
29 Click the Start real-time code button.You should see the outputs of Gain
blocks A and B on the two scopes in your model. With A=2 and B=3, the
output looks like this.
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 will do this in the next
section.
Part 4: Tuning Parameters
You can change the gain factor of either Gain block by assigning new values to
the variables 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. To tune the
variables A and B:
30 In the MATLAB command window, assign new values to both variables, for
example
A = 0.5;B = 3.5;
31 Activate the ext_example model window. Select Update Diagram from the
Edit menu, or type 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.
5-14
Tutorial: Getting Started with External Mode Using GRT
You can also enter gain values directly into the Gain blocks. To do this:
32 Open the dialog box for Gain block A or B in the model.
33 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 dialog box for the Sine Wave block and entering
a new numerical value in the appropriate field.
Note, however, that 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 and rebuild the
executable.
34 To simultaneously disconnect host/target communication and end execution
of the target program, pull down the Simulation menu and select Stop
real-time code.
5-15
5
External Mode
Using the External Mode User Interface
This section discusses the elements of the Simulink and Real-Time Workshop
user interface that control the operation of external mode. These elements
include:
• External mode related menu items in Simulation and Tools menus and in
the Simulink toolbar.
• External Mode Control Panel
• External Target Interface dialog box
• External Signal & Triggering dialog box
• External Data Archiving dialog box
External Mode Related Menu and Toolbar Items
To communicate with a target program, the model must be operating in
external mode. The Simulation menu and the toolbar provide two ways to
enable external mode:
• Select External from the Simulation menu.
• Select External from the simulation mode menu in the toolbar. The
simulation mode menu is shown in this picture.
Simulation mode
menu
Once external mode is enabled, you can use the Simulation menu or the
toolbar to connect to and control the target program.
5-16
Using the External Mode User Interface
Note You can enable external mode, and simultaneously connect to the
target system, by using the External Mode Control Panel. See “External
Mode Control Panel” on page 5-21.
Simulation Menu
When Simulink is in external mode, the upper section of the Simulation menu
contains external mode options. Initially, Simulink is disconnected from the
target program, and the menu displays the options shown in this picture.
Figure 5-1: 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 may be
executing model code, or it may be awaiting a command from the host to start
executing model code.
If the target program is executing model code, the Simulation menu contents
change, as shown in this picture.
Figure 5-2: Simulation Menu External Mode Options
(Target Executing Model Code)
5-17
5
External Mode
The Disconnect from target option disconnects Simulink from the target
program, which continues to run. The Stop real-time code option terminates
execution of the target program and disconnects Simulink from the target
system.
If the target program is in a wait state, the Start real-time code option is
enabled, as shown in this picture. The Start real-time code option instructs
the target program to begin executing the model code.
Figure 5-3: Simulation Menu External Mode Options
(Target Awaiting Start Command)
Toolbar Controls
The Simulink toolbar controls, shown in Figure 5-4, let you control the same
external mode functions as the Simulation menu. Simulink displays external
mode icons to the left of the Simulation mode menu. Initially, the toolbar
displays a Connect to target icon and a disabled Start real-time code button
(shown in Figure 5-4). Click on the Connect to target icon to connect Simulink
to the target program.
5-18
Using the External Mode User Interface
Simulation mode
menu
Connect to target
icon
Start real-time
code button
(disabled)
Figure 5-4: External Mode Toolbar Controls (Host Disconnected from Target)
When a connection is established, the target program may be executing model
code, or it may 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 icon (shown in
Figure 5-5). Click on the Stop real-time code button to command the target
program to stop executing model code and disconnect Simulink from the target
system. Click on the Disconnect from target icon to disconnect Simulink from
the target program while leaving the target program running.
5-19
5
External Mode
Disconnect from
target icon
Stop real-time
code button
Figure 5-5: External Mode Toolbar Controls (Target Executing Model Code)
If the target program is in a wait state, the toolbar displays a Start real-time
code button and a Disconnect from target icon (shown in Figure 5-6). Click
on the Start real-time code button to instruct the target program to start
executing model code. Click on the Disconnect from target icon to disconnect
Simulink from the target program.
5-20
Using the External Mode User Interface
Disconnect from
target icon
Start real-time
code button
Figure 5-6: External Mode Toolbar Controls (Target in Wait State)
External Mode Control Panel
The External Mode Control Panel 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
• Timing of parameter downloads
• Selection of signals from the target program to be viewed and monitored on
the host
• Configuration of data archiving features
5-21
5
External Mode
Select External mode control panel from the Simulink Tools menu to open
the External Mode Control Panel.
These buttons control the
connection between host and
manual arming of the data
uploading trigger.
This check box and button
control the timing of
parameter downloads.
These buttons 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.
Connection and Start/Stop Controls
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 5-16.)
The Connect/Disconnect button connects to or disconnects from the target
program. The button text changes in accordance with the state of the
connection.
Note that 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.
5-22
Using the External Mode User Interface
Target Interface Dialog Box
Pressing the Target Interface button activates the External Target
Interface dialog box.
Specify name of external
interface MEX-file here. Default
is ext_comm.
Enter optional arguments to the external interface MEX-file here.
The External Target Interface dialog box lets you specify the name of a
MEX-file that implements host/target communications. This is known as the
external interface MEX-file. The fields of the External Target Interface dialog
box are:
• MEX-file for external interface: Name of the external interface MEX-file.
The default is ext_comm, the TCP/IP-based external interface file provided
for use with the GRT and Tornado targets
The external interface MEX-file for the Real-Time Windows Target is
win_tgt.
Custom or third-party targets may use a different external interface
MEX-file.
• MEX-file arguments: Arguments for the external interface MEX-file. For
example, ext_comm allows three optional arguments: the network name of
your target, the verbosity level, and a TCP/IP server port number.
See “The External Interface MEX-File” on page 5-40 for details on ext_comm
and its arguments.
5-23
5
External Mode
External Signal & Triggering Dialog Box
Clicking the Signal & triggering button activates the External Signal &
Triggering dialog box.
Figure 5-7: Default Settings of the External Signal & Triggering Dialog Box
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 5-32 for
information on which types of blocks are external mode compatible.
The External Signal & Triggering dialog box lets you select which signals 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.
5-24
Using the External Mode User Interface
Default Operation
Figure 5-7 shows the default settings of the External Signal and Triggering
dialog box. The default operation of the External Signal and Triggering
dialog box is designed to simplify monitoring the target program. If you use the
default settings, you do not need to preconfigure signals and triggers. Simply
start the target program and connect the Simulink model to it. All external
mode compatible blocks will be selected and the trigger will be armed. Signal
uploading will begin immediately upon connection to the target program.
The default configuration is:
• Arm when connect 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 on the desired list entry and click the
on radio button. To deselect a signal, click on 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 box contains options that control when and how signal data
is collected (uploaded) from the target system. These options are:
5-25
5
External Mode
• 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 connect to target: If this option is selected, external mode arms
the trigger automatically when Simulink has connected 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 connect 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. For example, if the fastest rate in the model is 1 second
and a signal sampled at 1 Hz is being logged for a duration of 10 seconds,
then external mode will collect 10 samples. If a signal sampled at 2 Hz is
logged, only 5 samples will be collected.
• 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 5-28 for further 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. A negative delay corresponds
to pretriggering. When the delay is negative, data from the time preceding
the trigger is collected and uploaded.
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 Figure 5-8). Then, click on the desired entry in the Signal
selection list, and click the Trigger signal button.
5-26
Using the External Mode User Interface
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 Figure 5-8, the Pilot G force Scope signal is
the trigger. Pilot G force Scope is also selected for viewing, as indicated by
the X to the left of the block name.
The Trigger Signal panel
Figure 5-8: Signals & Triggering Window with Trigger Selected
After selecting the trigger signal, you can define the trigger conditions in the
Trigger signal panel, and set the Port and Element fields located on the right
side of the Trigger panel.
5-27
5
External Mode
Setting Trigger Conditions
Note The Trigger signal panel and the Port and Element fields of the
External Signal & Trigger 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 (i.e., Port 1, any element). You can modify this behavior
by adjusting the Port and Element fields located on the right side of the
Trigger 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. These are:
• 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 travelling 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
Pressing the Data Archiving button of the External Mode Control Panel
opens the External Data Archiving dialog box.
5-28
Using the External Mode User Interface
This panel supports the following features:
Directory Notes. Use this option to add annotations that pertain to a collection of
related data files in a directory.
Pressing the Edit directory note button opens the MATLAB editor. Place
comments that you want saved to a file in the specified directory in this
window. By default, the comments are saved to the directory last written to by
data archiving.
File Notes. Pressing 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.
Data Archiving. Clicking the Enable Archiving check box activates the
automated data archiving features of external mode. To understand how the
archiving features work, it is necessary to 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 will be 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 sufficient 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.
Note that 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:
5-29
5
External Mode
• Directory: Specifies the directory in which data is saved. External mode
appends a suffix if you select Increment directory when trigger armed.
• 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
directory for writing log files each time that you press the Arm trigger
button. The directories 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, etc. Note that this happens automatically in
normal mode.
• Append file suffix to variable names: Whenever external mode increments
filenames, each file contains variables with identical names. Choosing
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, etc.) 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 in MATLAB. Without the unique names, each instance of
xdata would overwrite the previous one in the MATLAB workspace.
This picture shows the External Data Archiving dialog box with archiving
enabled.
Unless you select Enable archiving, entries for the Directory and File fields
are not accepted.
5-30
Using the External Mode User Interface
Parameter Download Options
The batch download check box on the External Mode Control Panel enables
or disables batch parameter changes.
By default, batch download is not enabled. When batch download is not
enabled, changes made directly to block parameters are sent immediately to
the target. Changes to MATLAB workspace variables are sent when an
Update diagram is performed.
When 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 Figure 5-9.) This message
disappears after Simulink receives notification from the target that the new
parameters have been installed into the parameter vector of the target system.
Figure 5-9 shows the External Mode Control Panel with the batch download
option activated.
Parameter changes
pending... message
appears if unsent
parameter value changes
are awaiting download.
Figure 5-9: External Mode Control Panel in Batch Download Mode
5-31
5
External Mode
External Mode Compatible Blocks and Subsystems
Compatible Blocks
In external mode, you can use the following types of blocks to receive and view
signals uploaded from the target program:
• Scope blocks
• Blocks in the Dials & Gauges Blockset
• Display blocks
• To Workspace blocks
• User-written S-Function blocks
An external mode method has been added to 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 5-32 for
further information.
External mode compatible blocks and subsystems are selected, and the trigger
is armed, via the External Signal and Triggering dialog box. For example,
Figure 5-7 shows two Scope blocks, a Display block, and a Signal Viewing
Subsystem (theSink). All of these are selected and the 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
5-32
External Mode Compatible Blocks and Subsystems
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 and Triggering dialog box.
To declare a subsystem to be a Signal Viewing Subsystem:
1 Select the Treat as atomic unit option in the Block Parameters dialog box.
See “Nonvirtual Subsystem Code Generation” on page 3-41 for further
information on atomic subsystems.
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 may contain Goto blocks only if the corresponding
from blocks are contained within the subsystem boundaries.
- It must have no continuous states.
The model shown below, sink_examp, contains an atomic subsystem, theSink.
The subsystem theSink, shown below, applies a gain and an offset to its input
signal, and displays it on a Scope block.
5-33
5
External Mode
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 and Triggering dialog box (as shown in
Figure 5-10), 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.
Figure 5-10: Signal Viewing Subsystem Selected in External
Signals & Triggering Dialog Box
5-34
External Mode Compatible Blocks and Subsystems
Note that 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 Simulink 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 block parameter changes from the
host.
5-35
5
External Mode
Overview of External Mode Communications
In external mode, Simulink does not simulate the system represented by the
block diagram. When external mode is enabled, Simulink downloads current
values of all parameters to the target system. After the initial download,
Simulink remains in a waiting mode until you change parameters in the block
diagram or until Simulink receives data from the target.
The Download Mechanism
When you change a parameter in the block diagram, Simulink 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 via
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 target’s
parameter structure (rtP).
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, shared memory can
be used to transfer data.
5-36
Overview of External Mode Communications
The following diagram illustrates this relationship.
Simulink Process
External
Program
Process
mexFunction
External Program
Client
IPC Code
External Interface
MEX-file (ext_comm)
Server
IPC Code
ext_svr.c
Interprocess Communication Channel Transport Layer
Figure 5-11: External Mode Architecture
Simulink 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 via the communication channel.
5-37
5
External Mode
The TCP/IP Implementation
Overview
The Real-Time Workshop provides code to implement both the client and
server side based on TCP/IP. You can use the socket-based external mode
implementation provided by the Real-Time Workshop with the generated code,
provided that your target system supports TCP/IP.
A low-level transport layer handles physical transmission of messages. Both
Simulink 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.
This design makes it possible for different targets to use different transport
layers. For example, the grt, grt_malloc, and Tornado targets support host/
target communication via TCP/IP, whereas the xPC target supports both
RS232 (serial) and TCP/IP communication.
Using the TCP/IP Implementation
This section discusses how to use the TCP/IP-based client/server
implementation of external mode with real-time programs on a UNIX or PC
system. Chapter 12, “Targeting Tornado for Real-Time Applications”
illustrates the use of external mode in the Tornado environment.
In order to use Simulink external mode, you must:
• Specify the name of the external interface MEX-file in the External Target
Interface dialog box. By default, this is ext_comm.
• Configure the template makefile so that it links the proper source files for
the TCP/IP server code and defines the necessary compiler flags when
building the generated code.
• Build the external program.
• Run the external program.
• Set Simulink to external mode and connect to the target.
5-38
The TCP/IP Implementation
This figure shows the structure of the TCP/IP-based implementation.
UNIX or PC Host
Target
Simulink in External Mode
Target Code
Process block
parameter
ext_svr.c
Update block
ext_comm
TCP/IP on Ethernet
External Mode Message Format
header data in target format
Figure 5-12: TCP/IP-Based Client/Server Implementation for External Mode
The following sections discuss the details of how to use the external mode of
Simulink.
5-39
5
External Mode
The External Interface MEX-File
You must specify the name of the external interface MEX-file in the External
Target Interface dialog box.
Enter the name of the external
interface MEX-file in the box
(you do not need to enter the
.mex extension). This file must
be in the current directory or in a
directory that is on your
MATLAB path.
The default external interface MEX-file is ext_comm. ext_comm implements
TCP/IP-based communications. ext_comm has three optional arguments,
discussed in the next section.
MEX-File Optional Arguments
In the External Target Interface dialog box, you can specify optional
arguments that are passed to the MEX-file. These are:
• Target network name: the network name of the computer running the
external program. By default, this is the computer on which Simulink is
running. The name can be:
- a string delimited by single quotes, such as 'myPuter'
- an 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 if
necessary.
5-40
The TCP/IP Implementation
You must specify these options in order. For example, if you want to specify the
verbosity level (the second argument), then you must also specify the target
host name (the first argument).
Note that you can specify command line options to the external program. See
“Running the External Program” on page 5-41 for more information.
External Mode Compatible Targets
The GRT and Tornado targets support external mode. To enable external mode
code generation, check External mode in the target-specific code generation
options section of the Real-Time Workshop page. The following illustration
shows the GRT code generation options with external mode enabled.
Running the External Program
The external program must be running before you can use Simulink 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 5–
42). In the examples in this section, we assume the name of the external
program to be ext_example.
5-41
5
External Mode
Running the External Program Under Windows
In the Windows environment, you can run the external programs in either of
the following ways:
• Open an MS-DOS command prompt. 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 &
Running the External Program Under UNIX
In the UNIX environment, you can run the external programs in either of the
following ways:
• Open an 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
program from MATLAB, you must run it in the background so that you can
still access Simulink. 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 MATLAB by spawning another process to run it.
Command Line Options for the External Program
External mode target executables generated by the Real-Time Workshop
support the following command line options:
• -tf n option
The -tf option overrides the stop time set for the model in Simulink. The
argument n specifies the number of seconds the program will run. The value
5-42
The TCP/IP Implementation
inf value directs the model to run indefinitely. In this case, the model code
will run until the target program receives a stop message from Simulink.
The following example sets the stop time to 10 seconds.
ext_example -tf 10
Note The -tf option is supported by the GRT and Tornado targets. If you are
implementing a custom target and want to support the -tf option, you must
implement the option yourself. See “Creating an External Mode
Communication Channel” on page 17–73 for further information.
• -w option
The -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 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
the -port 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 -w and -port options are supported by the TCP/IP transport layer
modules shipped with the Real-Time Workshop. 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. See “Creating an External Mode
Communication Channel” on page 17–73 for further information. See
matlabroot/rtw/c/src/ext_transport.c for example code.
5-43
5
External Mode
Error Conditions
If the Simulink block diagram does not match the external program, Simulink
displays an error box informing you that the checksums do not match (i.e., the
model has changed since you generated code). This means you must rebuild the
program from the new block diagram (or reload the correct one) in order to use
external mode.
If the external program is not running, Simulink displays an error informing
you that it cannot connect to the external program.
Implementing 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
Real-Time Workshop, and rebuild ext_comm, the external interface MEX-file.
This advanced topic is described in detail in “Creating an External Mode
Communication Channel” on page 17–73.
5-44
Limitations of External Mode
Limitations of External Mode
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, parameters in transfer function and state space representation
blocks can be changed 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 (i.e., 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 blocks, 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.
5-45
5
External Mode
5-46
6
Program Architecture
Introduction . . . . . . . . . . . . . . . . . . . . 6-2
Model Execution . . . . . . . . .
Program Timing . . . . . . . . . .
Program Execution . . . . . . . . .
External Mode Communication . . . .
Data Logging In Singleand Multitasking Model Execution
Rapid Prototyping and Embedded
Model Execution Differences . . .
Rapid Prototyping Model Functions . .
Embedded Model Functions . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6-5
6-13
6-14
6-14
. . . . . . . . . 6-14
. . . . . . . . . 6-15
. . . . . . . . . 6-16
. . . . . . . . . 6-22
Rapid Prototyping Program Framework . . .
Rapid Prototyping Program Architecture . . . . .
Rapid Prototyping System Dependent Components .
Rapid Prototyping System Independent Components
Rapid Prototyping Application Components . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 6-24
. 6-25
. 6-26
. 6-27
. 6-30
Embedded Program Framework . . . . . . . . . . . 6-35
6
Program Architecture
Introduction
The Real-Time Workshop generates two styles of code. One code style is
suitable for rapid prototyping (and simulation via code generation). The other
style is suitable for embedded applications. This chapter discusses the program
architecture, that is, the structure of the Real-Time Workshop generated code,
associated with these two styles of code. The table below classifies the targets
shipped with the Real-Time Workshop.
Table 6-1: Code Styles Listed By Target
6-2
Target
Code Style (using C unless noted)
Real-Time Workshop
Embedded Coder target
Embedded — useful as a starting point
when using the generated C code in an
embedded application.
Generic real-time (GRT)
target
Rapid prototyping — nonreal-time
simulation on your workstation. Useful
as a starting point for creating a rapid
prototyping real-time target that does not
use real-time operating system tasking
primitives. Also useful for validating the
generated code on your workstation.
Real-time malloc target
Rapid prototyping — very similar to the
generic real-time (GRT) target except
that this target allocates all model
working memory dynamically rather
than statically declaring it in advance.
Rapid simulation target
Rapid prototyping — nonreal-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.
Table 6-1: Code Styles Listed By Target (Continued)
Target
Code Style (using C unless noted)
Tornado (VxWorks) real-time
target
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.
Real-Time Windows target
Rapid prototyping — runs model in
real-time at interrupt level while your PC
is running Microsoft Windows in the
background.
Ada simulation target
Embedded — nonreal-time simulation on
your workstation using Ada. Useful for
validating the generated code on your
workstation.
Ada multitasking real-time
target
Embedded — uses Ada tasking primitives
to run your model in real time. Useful as
a starting point when using the
generated Ada code in an embedded
application.
xPC target
Rapid prototyping — runs model in real
time on target PC running xPC kernel.
DOS real-time target
Rapid prototyping — runs model in real
time at interrupt level under DOS.
Third-party vendors supply additional targets for the Real-Time Workshop.
Generally, these can be classified as rapid prototyping targets. For more
information about third-party products, see the MATLAB Connections Web
page: http://www.mathworks.com/products/connections.
You can identify the rapid prototyping style of generated code by its use of the
SimStruct data structure (i.e., #include "simstruc.h"). In contrast, the
embedded code style does not have a SimStruct.
6-3
6
Program Architecture
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.
6-4
Model Execution
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 Real-Time
Workshop generates algorithmic code as defined by your model. You may
include your own code into your model via S-functions. S-functions can range
from high-level signal manipulation algorithms to low-level device drivers.
The Real-Time Workshop 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 diagram below 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
Figure 6-1: 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 singletasking and multitasking
environments both for simulation (nonreal-time) and for real-time. For most
models, the multitasking environment will provide the most efficient model
execution (i.e., fastest sample rate).
The following concepts are useful in describing how models execute:
• Initialization — Initializing the run-time interface code and the model
code.
• ModelOutputs — Calling all blocks in your model that have a time hit at the
current point in time and having them produce their output. ModelOutputs
can be done in major or minor time steps. In major time steps, the output is
6-5
6
Program Architecture
a given simulation time step. In minor time steps, the run-time interface
integrates the derivatives to update the continuous states.
• ModelUpdate — Calling all blocks in your model that have a sample hit at the
current point in time and having 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. ModelDerivatives is only
called in minor time steps.
The pseudocode below shows the execution of a model for a singletasking
simulation (nonreal-time).
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
Shutdown
}
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 t new = t + h , where h is the step
size. Time then moves forward to t new and the process repeats.
6-6
Model Execution
During the ModelOutputs and ModelUpdate phases of model execution, only
blocks that have hit the current point in time execute. They determine if they
have hit by using a macro (ssIsSampleHit, or ssIsSpecialSampleHit) that
checks for a sample hit.
The pseudocode below shows the execution of a model for a multitasking
simulation (nonreal-time).
main()
{
Initialization
While (time < final time)
ModelOutputs(tid=0)
-- Major time step.
LogTXY
-- Log time, states, and root outports.
ModelUpdate(tid=1)
-- Major time step.
For i=1:NumTids
ModelOutputs(tid=i) -- Major time step.
ModelUpdate(tid=i) -- Major time step.
EndFor
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
EndWhile
Shutdown
}
The multitasking operation is more complex when compared with the
singletasking 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 there were no preemption in a real-time
system.
6-7
6
Program Architecture
Note that the multitasking execution assumes that all tasks are multiples of
the base rate. Simulink enforces this when you have created a fixed-step
multitasking model.
The multitasking execution loop is very similar to that of singletasking, except
for the use of the task identifier (tid) argument to ModelOutputs and
ModelUpdate. The ssIsSampleHit or ssIsSpecialSampleHit macros use the
tid to determine when blocks have a hit. For example, ModelOutputs (tid=5)
will execute only the blocks that have a sample time corresponding to task
identifier 5.
The pseudocode below shows the execution of a model in a real-time
singletasking 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.
6-8
Model Execution
Shutdown
}
Real-time singletasking execution is very similar to the nonreal-time single
tasking execution, except that the execution of the model code is done at
interrupt level.
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 rate 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 of these steps must occur before the next interrupt.
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)
6-9
6
Program Architecture
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
}
Running models at interrupt level in real-time multitasking environment is
very similar to the previous singletasking environment, except that overlapped
interrupts are employed for concurrent execution of the tasks.
The execution of a model in a singletasking 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
singletasking 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.)
6-10
Model Execution
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
}
In this singletasking environment, the model is executed using real-time
operating system tasking primitives. In this environment, we 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 will wait for the semaphore before executing.
The clock ticks are configured to occur at the fundamental step size (base rate)
for your model.
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)
6-11
6
Program Architecture
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()
{
Initialization
Start/spawn task "tSingleRate".
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. In this environment, it is necessary to
create 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. Since 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
6-12
Model Execution
resumes waiting for the clock semaphore. The clock ticks are configured to
occur at executing at the fundamental step size for your model.
Program Timing
Real-time programs require careful timing of the task invocations (either via
an interrupt or a real-time operating system tasking primitive) to ensure 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 following diagram illustrates interrupt timing.
Sample interval is appropriate for this model code execution.
time
Time to execute
the model code
Time available to process background tasks
Sample interval is too short for this model code execution.
time
Time to execute the model code
Figure 6-2: 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
6-13
6
Program Architecture
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 (i.e., the final
time is 0 or infinite so the while loop never exits), then the shutdown code never
executes.
Program Execution
As the previous section indicates, a real-time program may not require 100% of
the CPU’s time. This provides an opportunity to run background tasks during
the free time.
Background tasks include operations like 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 at the appropriate time to ensure real-time execution of the model code.
The way the program manages tasks depends on capabilities of the
environment in which it operates.
External Mode Communication
External mode allows communication between the Simulink block diagram
and the stand-alone 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 Simulink.
Data Logging In Singleand Multitasking Model Execution
The Real-Time Workshop data-logging features, described in “Workspace I/O
Options and Data Logging” in Chapter 3, 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
singletasking and multitasking environments.
If you examine how LogTXY is called in the singletasking and multitasking
environments, you will notice that for singletasking LogTXY is called after
ModelOutputs. During this ModelOutputs call, all blocks that have a hit at time
t are executed, whereas in multitasking, LogTXY is called after
6-14
Model Execution
ModelOutputs(tid=0) that 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 singletasking 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 have a hit. When
executing in multitasking mode, when LogTXY is called, the slow blocks will
have a hit, but the previous value will be logged, whereas in singletasking the
current value will be 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 will see a delay of
one sample period, thus the logged values will show these differences.
To summarize differences in logged data between singletasking 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
For the first two cases, even though the logged values are different between
singletasking 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.
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 Real-Time Workshop Embedded Coder provides a different framework
that we will refer to as the embedded program framework. The embedded
program framework provides a optimized API that is tailored to your model. It
6-15
6
Program Architecture
is intended that 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.
The single largest difference between the rapid prototyping and embedded
style of generated code is that the embedded code does not contain the
SimStruct data structure. The SimStruct defines a common API that the rapid
prototyping style of generated code relies heavily on. However, the SimStruct
data structure supports many options and therefore consumes memory that is
not needed in an embedded application.
Another 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. You can define a single run-time function because the embedded
target:
• Can only be used with models that do not have continuous sample time (and
therefore no continuous states)
• Requires that all S-functions must be inlined with the Target Language
Compiler, which means that they do not access the SimStruct data structure
Thus, when looking at the model execution pseudocode presented earlier in this
chapter, you can eliminate the Loop...EndLoop statements, and group the
ModelOutputs, LogTXY, and ModelUpdate into a single statement, model_step.
For a detailed discussion of how generated embedded code executes, see
“Program Execution” on page 9-9.
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 for initializes the
work areas (e.g., allocating and setting pointers to various data structures)
needed 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.
6-16
Model Execution
• 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” routine 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 at
appropriate times. 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 (i.e., 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 outputs. These integration stages are used to compute
the derivatives used in advancing the continuous states.
• MdlUpdate(int_T tid) — MdlUpdate updates the discrete states and work
vector state information (i.e., 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 states of only active blocks. This routine is invoked by
the run-time interface after the major MdlOutputs has been executed.
• MdlDerivatives(void) — MdlDerivatives returns the block derivatives.
This routine is called in minor steps by the solver during its integration
stages. All blocks that have continuous states have an identical number of
6-17
6
Program Architecture
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 = f 0 ( t, x c, x d, u )
Output, y, is a function of continuous state, xc, discrete state, xd, and input, u.
Each block writes its specific equation in the appropriate section of MdlOutput.
x d + 1 = fu ( t, x d, 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· = f d ( t, x c, u )
The derivatives, x, are a function of the current input. Each block that has
continuous states provides its derivatives to the solver (e.g., ode5) in
MdlDerivatives. 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
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 Real-Time Workshop
generates.
6-18
Model Execution
Figure 6-3 shows the general content of the rapid prototyping style of C code.
/*
* Version, Model options, TLC options,
* and code generation information are placed here.
*/
<includes>
void MdlStart(void)
{
/*
* State initialization code.
* Model start-up code - one time initialization code.
* Execute any block enable methods.
* Initialize output of any blocks with constant sample times.
*/
}
void MdlOutputs(int_T tid)
{
/* Compute: y = f0(t,xc,xd,u) for each block as needed. */
}
void MdlUpdate(int_T tid)
{
/* Compute: xd+1 = fu(t,xd,u) for each block as needed. */
}
void MdlDerivatives(void)
{
/* Compute: dxc = fd(t,xc,u) for each block as needed. */
}
void MdlTerminate(void)
{
/* Perform shutdown code for any blocks that
have a termination action */
}
Figure 6-3: Content of model.c for the Rapid Prototyping Code Style
6-19
6
Program Architecture
Figure 6-4 shows a flow chart describing the execution of the rapid prototyping
generated code.
Start Execution
MdlStart
MdlOutput
MdlDerivatives
MdlOutput
MdlDerivatives
Integration
Execution Loop
MdlUpdate
MdlTerminate
End
Figure 6-4: Rapid Prototyping Execution Flow Chart
Each block places code into 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 (rtB). Block inputs can also come from the
external input structure (rtU) or the state structure when connected to a state
port of an integrator (rtX), or ground (rtGround) if unconnected or grounded.
6-20
Model Execution
Block outputs can also go to the external output structure (rtY). The following
figure shows the general mapping between these items.
External
Inputs
Struct,
rtU
rtGround
External
Outputs
Struct,
Block I/O
Struct,
rtB
rtY
Block
Work
Structs,
States
Struct,
Parameter
Struct,
rtX
rtP
rtRWork,
rtIWork,
rtPWork,
....
Figure 6-5: Data View of the Generated Code
Structure definitions:
• Block I/O Structure (rtB) — This structure consists of all 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, Simulink and the Real-Time Workshop reduce the size of
the rtB structure by:
- Reusing the entries in the rtB structure
- Making other entries local variables
See “Signals: Storage, Optimization, and Interfacing” on page 3–65 for
further information on these optimizations.
Structure field names are determined by either 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 Structure (rtX) — The states structure contains the continuous
and discrete state information for any blocks in your model that have states.
6-21
6
Program Architecture
The states structure has two sections: the first is for the continuous states;
the second is for the discrete states.
• Block Parameters Structure (rtP) — The parameters structure contains all
block parameters that can be changed during execution (e.g., the parameter
of a Gain block).
• External Inputs Structure (rtU) —The external inputs structure consists of
all root-level Inport block signals. Field names are determined by either 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 (rtY) —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 (rtRWork, rtIWork,
rtPWork) — Blocks may 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.
Embedded Model Functions
The Real-Time Workshop Embedded Coder and Ada Coder targets generate
the following functions:
• model_intialize — Performs all 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 will see:
- model_step(int_T tid) — Contains the output and update code for all
blocks in your model.
Otherwise you will see:
- model_output(int_T tid) — Contains the output code for all blocks in
your model.
- model_update(int_T tid) — This contains the update code for all blocks
in your model.
6-22
Model Execution
• If the Terminate function required code generation option is selected, then
you will see:
- model_terminate — This contains all model shutdown code and should be
called as part of system shutdown.
See “Code Modules” on page 9–5 and “Program Execution” on page 9–9 for
complete descriptions of these functions in the context of the Real-Time
Workshop Embedded Coder.
6-23
6
Program Architecture
Rapid Prototyping Program Framework
The code modules generated from a a Simulink model — model.c, model.h, and
other files — implement the model’s system equations, contain block
parameters, and perform initialization.
The Real-Time Workshop’s program framework provides the additional source
code necessary to build the model code into a complete, stand-alone program.
The program framework consists of application modules (files containing
source code to implement required functions) designed for a number of
different programming environments.
The automatic program builder ensures the program is created with the proper
modules once you have configured your template makefile.
The application modules and the code generated for a Simulink model are
implemented using a common API. This API defines a data structure (called a
SimStruct) that encapsulates all data for your model. Note that the Real-Time
Workshop Embedded Coder target does not have a SimStruct, but does have a
common calling syntax for model execution.
This API is similar to that of S-functions, with one major exception: the API
assumes that there is only one instance of the model, whereas S-functions can
have multiple instances. The function prototypes also differ from S-functions.
6-24
Rapid Prototyping Program Framework
Rapid Prototyping Program Architecture
The structure of a real-time program consists of three components. Each
component has a dependency on a different part of the environment in which
the program executes. The following diagram illustrates this structure.
Rapid Prototyping Real-Time Program Architecture
System
Dependent
Components
Main Program
Timing
Interrupt handling
I/O drivers
Data logging
System
Independent
Components
Integration solvers: ode1.c — ode5.c
Model execution scheduler: rt_sim.c
SimStruct: simstruc.h
External mode
communication
Run-Time Interface
Application
Components
Generated (Model) Code
MdlOutputs, etc.
Inlined S-functions
Model parameters
Noninlined
S-functions
mysfun.c
Figure 6-6: The Rapid Prototyping Program Architecture
6-25
6
Program Architecture
The Real-Time Workshop architecture consists of three parts. The first two
components, system dependent and independent, together form the run-time
interface.
This architecture readily adapts to a wide variety of environments by isolating
the dependencies of each program component. The following sections discuss
each component in more detail and include descriptions of the application
modules that implement the functions carried out by the system dependent,
system independent, and application components.
Rapid Prototyping System Dependent Components
These components contain the program’s main function, which controls
program timing, creates tasks, installs interrupt handlers, enables data
logging, and performs error checking.
The way in which application modules implement these operations depends on
the type of computer. This means that, for example, the components used for a
DOS-based program perform the same operations, but differ in method of
implementation from components designed to run under Tornado on a VME
target.
The main Function
The main function in a C program is the point where execution begins. In
Real-Time Workshop application programs, the main function must perform
certain operations. These operations can be grouped into three categories:
initialization, model execution, and program termination.
Initialization
• Initialize special numeric parameters: rtInf, rtMinusInf, and rtNaN. These
are variables that the model code can use.
• Call the model registration function to get a pointer to the SimStruct. The
model registration function has the same name as your model. It is
responsible for initializing SimStruct fields and any S-functions in your
model.
• Initialize the model size information in the SimStruct. This is done by calling
MdlInitializeSizes.
• Initialize a vector of sample times and offsets (for systems with multiple
sample rates). This is done by calling MdlInitializeSampleTimes.
6-26
Rapid Prototyping Program Framework
• Get the model ready for execution by calling MdlStart, which initializes
states and similar items.
• Set up the timer to control execution of the model.
• Define background tasks and enable data logging, if selected.
Model Execution
• Execute a background task, for example, communicate with the host during
external mode simulation or introduce a wait state until the next sample
interval.
• Execute model (initiated by interrupt).
• Log data to buffer (if data logging is used).
• Return from interrupt.
Program Termination
• Call a function to terminate the program if it is designed to run for a finite
time — destroy the SimStruct, deallocate memory, and write data to a file.
Rapid Prototyping Application Modules
for System Dependent Components
The application modules contained in the system dependent components
generally include a main module such as rt_main.c containing the main entry
point for C. There may also be additional application modules for such things
as I/O support and timer handling.
Rapid Prototyping System Independent
Components
These components are collectively called system independent because all
environments use the same application modules to implement these
operations. This section steps through the model code (and if the model has
continuous states, calls one of the numerical integration routines). This section
also includes the code that defines, creates, and destroys the Simulink data
structure (SimStruct). The model code and all S-functions included in the
program define their own SimStruct.
The model code execution driver calls the functions in the model code to
compute the model outputs, update the discrete states, integrate the
6-27
6
Program Architecture
continuous states (if applicable), and update time. These functions then write
their calculated data to the SimStruct.
Model Execution
At each sample interval, the main program passes control to the model
execution function, which executes one step though the model. This step reads
inputs from the external hardware, calculates the model outputs, writes
outputs to the external hardware, and then updates the states.
The following diagram illustrates these steps.
Read system inputs
from A/D
Calculate system outputs
Write system outputs
to D/A
Execute Model
Calculate and update
discrete states
Calculate and update
continuous states
Increment time
Figure 6-7: Executing the Model
6-28
Integration
Algorithm
Rapid Prototyping Program Framework
Note that this scheme writes the system outputs to the hardware before the
states are updated. Separating the state update from the output calculation
minimizes the time between the input and output operations.
Integration of Continuous States
The real-time program calculates the next values for the continuous states
based on the derivative vector, dx/dt, for the current values of the inputs and
the state vector.
These derivatives are then used to calculate the next value of the states using
a state-update equation. This is the state-update equation for the first order
Euler method (ode1)
dx
x = x + ------- h
dt
where h is the step size of the simulation, x represents the state vector, and
dx/dt is the vector of derivatives. Other algorithms may make several calls to
the output and derivative routines to produce more accurate estimates.
Note, however, that real-time programs use a fixed-step size since it is
necessary to guarantee the completion of all tasks within a given amount of
time. This means that, while you should use higher order integration methods
for models with widely varying dynamics, the higher order methods require
additional computation time. In turn, the additional computation time may
force you to use a larger step size, which can diminish the accuracy increase
initially sought from the higher order integration method.
Generally, the stiffer the equations, (i.e., the more dynamics in the system with
widely varying time constants), the higher the order of the method that you
must use.
In practice, the simulation of very stiff equations is impractical for real-time
purposes except at very low sample rates. You should test fixed-step size
integration in Simulink to check stability and accuracy before implementing
the model for use in real-time programs.
For linear systems, it is more practical to convert the model that you are
simulating to a discrete time version, for instance, using the c2d function in the
Control System Toolbox.
6-29
6
Program Architecture
Application Modules for System Independent Components
The system independent components include these modules:
• ode1.c, ode2.c, ode3.c, ode4.c, ode5.c — These modules implement the
integration algorithms supported for real-time applications. See the
Simulink documentation for more information about these fixed-step
solvers.
• rt_sim.c — Performs the activities necessary for one time step of the model.
It calls the model function to calculate system outputs and then updates the
discrete and continuous states.
• simstruc.h — Contains actual definition of the Simulink data structure and
the definition of the SimStruct access macros.
• simstruc_types.h — Contains definitions of various events, including
subsystem enable/disable and zero crossings. It also defines data logging
variables.
The system independent components also include code that defines, creates,
and destroys the Simulink data structure (SimStruct). The model code and all
S-functions included in the program define their own SimStruct.
The SimStruct data structure encapsulates all the data relating to the model
or S-function, including block parameters and outputs. See Writing
S-Functions for more information about the SimStruct.
Rapid Prototyping Application Components
The application components contain the generated code for the Simulink
model, including the code for any S-functions in the model. This code is referred
to as the model code because these functions implement the Simulink model.
However, the generated code contains more than just functions to execute the
model (as described in the previous section). There are also functions to
perform initialization, facilitate data access, and complete tasks before
program termination. To perform these operations, the generated code must
define functions that:
• Create the SimStruct.
• Initialize model size information in the SimStruct.
• Initialize a vector of sample times and sample time offsets and store this
vector in the SimStruct.
6-30
Rapid Prototyping Program Framework
• Store the values of the block initial conditions and program parameters in
the SimStruct.
• Compute the block and system outputs.
• Update the discrete state vector.
• Compute derivatives for continuous models.
• Perform an orderly termination at the end of the program (when the current
time equals the final time, if a final time is specified).
• Collect block and scope data for data logging (either with the Real-Time
Workshop or third-party tools).
The SimStruct Data Structure
The generated code includes the file simstruc.h, which contains the definition
of the SimStruct data structure. Each instance of a model (or an S-function) in
the program creates its own SimStruct, which it uses for reading and writing
data.
All functions in the generated code are public. For this reason, there can be only
one instance of a model in a real-time program. This function, which always
has the same name as the model, is called during program initialization to
return a pointer to the SimStruct and initialize any S-functions.
Rapid Prototyping Model Code Functions
The functions defined by the model code are called at various stages of program
execution (i.e., initialization, model execution, or program termination).
6-31
6
Program Architecture
The following diagram illustrates the functions defined in the generated code
and shows what part of the program executes each function.
Model Code
Main Program Initialization
Model registration function — model
Initialize sizes in the SimStruct — MdlInitializeSizes
Initialize sample times and offsets — MdlInitializeSampleTimes
Start model (initialize conditions, etc.) — MdlStart
Model Execution
Compute block and system outputs — MdlOutputs
Update discrete state vector — MdlUpdate
Compute derivatives for continuous models — MdlDerivatives
Main Program Termination
Orderly termination at end of the program — MdlTerminate
Figure 6-8: Execution of the Model Code
The Model Registration Function
The model registration function has the same name as the Simulink model
from which it is generated. It is called directly by the main program during
initialization. Its purpose is to initialize and return a pointer to the SimStruct.
Models Containing S-Functions
A noninlined S-function is any C MEX S-function that is not implemented
using a customized TLC file. If you create a C MEX S-function as part of a
Simulink model, it is by default noninlined unless you write your own TLC file
that inlines it within the body of the model.c code. The Real-Time Workshop
6-32
Rapid Prototyping Program Framework
automatically incorporates your non-inlined C code S-functions into the
program if they adhere to the S-function API described in the Simulink
documentation.
This format defines functions and a SimStruct that are local to the S-function.
This allows you to have multiple instances of the S-function in the model. The
model’s SimStruct contains a pointer to each S-function’s SimStruct.
Code Generation and S-Functions
If a model contains S-functions, the source code for the S-function must be on
the search path the make utility uses to find other source files. The directories
that are searched are specified in the template makefile that is used to build
the program.
S-functions are implemented in a way that is directly analogous to the model
code. They contain their own public registration function (which is called by the
top-level model code) that initializes static function pointers in its SimStruct.
When the top-level model needs to execute the S-function, it does so via the
function pointers in the S-function’s SimStruct. The S-functions use the same
SimStruct data structure as the generated code; however, there can be more
than one S-function with the same name in your model. This is accomplished
by having function pointers to static functions.
Inlining S-Functions
You can incorporate C MEX S-functions, along with the generated code, into
the program executable. You can also write a target file for your C MEX
S-function to inline the S-function, thus improving performance by eliminating
function calls to the S-function itself. For more information on inlining
S-functions, see the Target Language Compiler Reference Guide.
6-33
6
Program Architecture
Application Modules for Application Components
When the Real-Time Workshop generates code, it produces the following files:
• model.c — The C code generated from the Simulink block diagram. This code
implements the block diagram’s system equations as well as performing
initialization and updating outputs.
• model.h — Header file containing the block diagram’s simulation
parameters, I/O structures, work structures, and other declarations.
• model_export.h — Header file containing declarations of exported signals
and parameters.
These files are named for the Simulink model from which they are generated.
If you have created custom blocks using C MEX S-functions, you need the
source code for these S-functions available during the build process.
6-34
Embedded Program Framework
Embedded Program Framework
The Real-Time Workshop Embedded Coder provides a framework for
embedded programs. Its architecture is outlined by the following figure.
Embedded Program Architecture
System
Dependent
Components
Main Program
Timing
Interrupt handling
I/O drivers
Data logging
System
Independent
Components
Integration solvers: ode1.c — ode5.c
Model execution scheduler: rt_sim.c
Run-time Interface
Application
Components
Generated (Model) Code
MdlOutputs, etc.
Inlined S-functions
Model parameters
Figure 6-9: Embedded Program Architecture
6-35
6
Program Architecture
Note the similarity between this architecture and the rapid prototyping
architecture on page 6-25. The main difference is the lack of the SimStruct
data structure and the removal of the noninlined S-functions.
Using this figure, you can compare the embedded style of generated code, used
in the Real-Time Workshop Embedded Coder, with the rapid prototyping style
of generated code of the previous section. Most of the rapid prototyping
explanations in the previous section hold for the Real-Time Workshop
Embedded Coder target. The Real-Time Workshop Embedded Coder target
simplifies the process of using the generated code in your custom-embedded
applications by providing a model- specific API and eliminating the SimStruct.
This target contains the same conceptual layering as the rapid prototyping
target, but each layer has been simplified.
For a discussion of the structure of embedded real-time code, see Chapter 9,
“Real-Time Workshop Embedded Coder.”
6-36
7
Models with Multiple
Sample Rates
Introduction . . . . . . . . . . . . . . . . . . . . 7-2
Single- Versus Multitasking Environments . .
Executing Multitasking Models . . . . . . . .
Multitasking and Pseudomultitasking . . . . .
Building the Program for Multitasking Execution
Singletasking . . . . . . . . . . . . . . .
Building the Program for Singletasking Execution
Model Execution . . . . . . . . . . . . . .
Simulating Models with Simulink . . . . . . .
Executing Models in Real Time . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 7-3
. 7-5
. 7-5
. 7-8
. 7-9
. 7-9
. 7-9
. 7-10
. 7-10
Sample Rate Transitions . . . . . . .
Faster to Slower Transitions in Simulink .
Faster to Slower Transitions in Real Time
Slower to Faster Transitions in Simulink .
Slower to Faster Transitions in Real Time
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7-12
7-13
7-14
7-16
7-17
7
Models with Multiple Sample Rates
Introduction
Every Simulink block can be classified according to its sample time as
constant, continuous-time, discrete-time, inherited, or variable. Examples of
each type include:
• Constant — Constant block, Width
• Continuous-time — Integrator, Derivative, Transfer Function
• Discrete-time — Unit Delay, Digital Filter
• Inherited — Gain, Sum, Lookup Table
• Variable — These are S-Function blocks that set their time of next hit based
upon current information. These blocks work only with variable step solvers.
Blocks in the inherited category assume the sample time of the blocks that are
driving them. Every Simulink block therefore has a sample time, whether it is
explicit, as in the case of continuous or discrete blocks (continuous blocks have
a sample time of zero), or implicit, as in the case of inherited blocks.
Simulink allows you to create models without any restrictions on connections
between blocks with different sample times. It is therefore possible to have
blocks with differing sample times in a model (a mixed-rate system). A possible
advantage of employing multiple sample times is improved efficiency when
executing in a multitasking real-time environment.
Simulink provides considerable flexibility in building these mixed-rate
systems. However, the same flexibility also allows you to construct models for
which the code generator cannot generate correct real-time code for execution
in a multitasking environment. But to make these models operate correctly in
real time (i.e., give the right answers), you must modify your model. In general,
the modifications involve placing Unit Delay and Zero Order Hold blocks
between blocks that have unequal sample rates. The sections that follow
discuss the issues you must address to use a mixed-rate model successfully in
a multitasking environment.
7-2
Single- Versus Multitasking Environments
Single- Versus Multitasking Environments
There are two basic ways in which you can execute a fixed-step Simulink
model: singletasking and multitasking. You use the Solver options pull-down
menu on the Solver page of the Simulation Parameters dialog box to specify
how to execute your model. The default is auto, which specifies that your model
will use multitasking if your model contains two or more different rates.
Otherwise, it will use singletasking.
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).
Note that the fact that a system (such as UNIX or Microsoft Windows) is
multitasking does not guarantee that the program can execute in real time.
This is because it is not guaranteed that the program can preempt other
processes when required.
In 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.
Tornado, on the other hand, provides 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.
7-3
7
Models with Multiple Sample Rates
Figure 7-1 illustrates this difference.
Real-Time Clock
Hardware
Interrupt Service
Routine
Interrupt
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 Service
Routine
Context
Switch
Model Execution
Task
Interrupt
semGive
semTake
Execute Model
Program execution using a real-time
operating system primitive. See the
Tornado target for an example.
Figure 7-1: Real-Time Program Execution
7-4
Collect Data
Single- Versus Multitasking Environments
This chapter focuses on when and how the run-time interface executes your
model. See “Program Execution” on page 6-14 for a description of what happens
during model execution.
Executing 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
rates, the code assigns each block a task identifier (tid) to associate it with the
task that executes at its sample rate.
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 (i.e., the
fastest) sample rate. The base sample rate is determined by the fixed step
size specified on the Solver page of the Simulation parameters dialog box
(if a model has continuous blocks) or by the fastest sample time specified in
the model (if the model is purely discrete). Continuous blocks always execute
via an integration algorithm that runs at the base sample rate.
• 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
In a multitasking environment, the blocks with the fastest sample rates are
executed by the task with the highest priority, the next slowest blocks are
executed by a task with the next lower 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.
See “Multitasking System Execution” on page 7-7 for a graphical
representation of task timing.
In multitasking environments (i.e., a real-time operating system), you can
define separate tasks and assign them priorities. In a bare-board target (i.e.,
no real-time operating system present), you cannot create separate tasks.
However, the Real-Time Workshop application modules implement what is
effectively a multitasking execution scheme using overlapped interrupts,
accompanied by manual context switching.
7-5
7
Models with Multiple Sample Rates
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 (i.e., faster sample rate) code. Once complete,
control is returned to the preempted ISR.
7-6
Single- Versus Multitasking Environments
The following diagrams illustrate how mixed-rate systems are handled by the
Real-Time Workshop in these two environments.
t0
t1
Highest Priority
t2
t3
t4
rate 1
rate 2
rate 3
Lowest Priority
Vertical arrows indicate sample times.
Dotted lines with downward pointing
arrows indicate the release of control
to a lower priority task.
Dark gray areas indicate task execution.
Hashed areas indicate task preemption by a
higher priority task.
Dotted lines with upward pointing
arrows indicate preemption by a
higher priority task.
Light gray areas indicate task execution
is pending.
Figure 7-2: Multitasking System Execution
7-7
7
Models with Multiple Sample Rates
Figure 7-3 illustrates how overlapped interrupts are used to implement
pseudomultitasking. Note that in this case, Interrupt 0 does not return until
after Interrupts 1, 2, and 3.
.
Interrupt 0
Begins
t0
Interrupt 1
t1
Interrupt 2
Begins
t2
Interrupt 3
t3
t4
Highest Priority
Interrupt 2
Ends
Interrupt 0
Ends
Lowest Priority
Figure 7-3: Pseudomultitasking Using Overlapped Interrupts
Building the Program for Multitasking Execution
To use multitasking execution, select auto (the default) or multitasking as the
mode on the Solver page of the Simulation Parameters dialog box. The Mode
menu is only active if you have selected fixed-step as the Solver options type.
auto solver mode will result in a multitasking environment if your model has
more than two sample times or it has two different sample times. In particular,
a model with a continuous and a discrete sample time will run in singletasking
mode if the fixed-step size is equal to the discrete sample time.
7-8
Single- Versus Multitasking Environments
Singletasking
It is possible to execute the model code in a strictly singletasking manner.
While this method is less efficient with regard to execution speed, in certain
situations it may allow you to simplify your model.
In a singletasking environment, the base sample rate must define a time
interval that is long enough to allow the execution of all blocks within that
interval.
The following diagram illustrates the inefficiency inherent in singletasking
execution.
t0
t1
t2
t3
t4
Figure 7-4: Singletasking System Execution
Singletasking system execution requires a sample interval that is long enough
to execute one step through the entire model.
Building the Program for Singletasking Execution
To use singletasking execution, select the singletasking mode on the Solver
page of the Simulation Parameters dialog box. If the solver mode is auto,
singletasking 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
To generate code that executes correctly in real time, you may need to modify
sample rate transitions within the model before generating code. To
understand this process, first consider how Simulink simulations differ from
real-time programs.
7-9
7
Models with Multiple Sample Rates
Simulating Models with Simulink
Before Simulink simulates a model, it orders all of the blocks based upon their
topological dependencies. This includes expanding 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 proper ordering of blocks. Any block whose output
is directly dependent on its input (i.e., any block with direct feedthrough)
cannot execute until the block driving its input has executed.
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, all necessary computations are
performed prior to advancing the variable corresponding to time. In essence,
this results in all computations occurring instantaneously (i.e., no
computational delay).
Executing 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 Simulink), which leads to less
efficient execution.
t0
t1
t2
Time
Figure 7-5: Unused Time in Sample Interval
Sample interval t1 cannot be compressed to increase execution speed because
by definition, sample times are clocked in real time.
Real-Time Workshop application programs are designed to circumvent this
potential inefficiency by using a multitasking scheme. This technique defines
tasks with different priorities to execute parts of the model code that have
different sample rates.
7-10
Single- Versus Multitasking Environments
See “Multitasking and Pseudomultitasking” on page 7–5 for a description of
how this works. It is important to understand that section before proceeding
here.
Multitasking Operation
The use of multitasking can improve the efficiency of your program if the model
is large and has many blocks executing at each rate. It can also degrade
performance if your model is dominated by a single rate, and only a few blocks
execute at a slower rate. In this situation, the overhead incurred in task
switching can be greater than the time required to execute the slower blocks.
It is more efficient to execute all blocks at the dominant rate.
If you have a model that can benefit from multitasking execution, you may
need to modify your Simulink model for this scheme to generate correct results.
Singletasking Operation
Alternatively, you can run your real-time program in singletasking mode.
Singletasking programs require longer sample intervals due to the inherent
inefficiency of that mode of execution.
7-11
7
Models with Multiple Sample Rates
Sample Rate Transitions
There are two possible sample rate transitions that can exist within a model:
• A faster block driving a slower block
• A slower block driving a faster block
In singletasking systems, there are no issues involved with multiple sample
rates. In multitasking and pseudomultitasking systems, however, differing
sample rates can cause problems. To prevent possible errors in calculated data,
you must control model execution at these transitions. In transitioning from
faster to slower blocks, you must add Zero-Order Hold blocks between fast to
slow transitions and set the sample rate of the Zero-Order Hold block to that of
the slower block.
This diagram
T = 1 sec
Faster
Block
T = 2 sec
Slower
Block
becomes
T = 1 sec
Faster
Block
T = 2 sec
Zero-Order
Hold
T = 2 sec
Slower
Block
Figure 7-6: Transitioning from Faster to Slower Blocks (T = sample period)
7-12
Sample Rate Transitions
In transitioning from slower to faster blocks, you must add Unit Delay blocks
between slow to fast transitions and set the sample rate of the Unit Delay block
to that of the slower block.
This diagram
T = 2 sec
Slower
Block
T = 1 sec
Faster
Block
becomes
T = 2 sec
Slower
Block
T = 2 sec
Unit Delay
T = 1 sec
Faster
Block
Figure 7-7: Transitioning from Slower to Faster Blocks (T = Sample Period)
The next four sections describe the theory and reasons why Unit Delay and
Zero-Order Hold blocks are necessary for sample time transitions.
Faster to Slower Transitions in Simulink
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.
7-13
7
Models with Multiple Sample Rates
The following diagram illustrates this situation.
t1
t0
T = 1 sec
T = 2 sec
Faster
Block
Slower
Block
T=1s
T=2s
t2
T=1s
t3
T=1s
T=2s
T=1s
Time
Simulink does not execute in real time, which means that it is not bound by
real-time constraints. Simulink waits for, or moves ahead to, whatever tasks
are necessary to complete simulation flow. The actual time interval between
sample time steps can vary.
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 may span more than one execution
period of the faster block. This means that the outputs of the faster block may
change before the slower block has finished computing its outputs. The
following diagram illustrates a situation where this problem arises. The
hashed area indicates times when tasks are preempted by higher priority
before completion.
T = 1 sec
T = 2 sec
Faster
Block
Slower
Block
2 Sec
Task
1 Sec
Task
1
T=1s
T=2s
2
1
T=1s
3
T=2s
T=1s
1
Time
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.
2
Figure 7-8: Time Overlaps in Faster to Slower Transitions (T=Sample Time)
7-14
T=1s
3
Sample Rate Transitions
In Figure 7-8, 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.
To avoid this situation, you 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 Zero-Order Hold block between the 1 second and 2 second
blocks. The sample time of the Zero Order Hold block must be set to 2 seconds
(i.e., the sample time of the slower block).
T = 1 sec
T = 2 sec
Zero-Order
Hold
Faster
Block
T = 2 sec
Slower
Block
The Zero Order Hold block executes at the sample rate of the slower block, but
with the priority of the faster block.
t0
t2
2 Sec
Task
T=0.5
T=2s
t1
t0
1 Sec
Task
T=0.5
T=2s
T=1s
ZOH
t2
T=1s
t3
T=1s
ZOH
T=1s
Time
This ensures that the Zero Order Hold block executes before the 1 second block
(its priority is higher) and that its output value is held constant while the 2
second block executes (it executes at the slower sample rate).
7-15
7
Models with Multiple Sample Rates
Slower to Faster Transitions in Simulink
In a model where a slower block drives a faster block, Simulink again computes
the output of the driving block first. During sample intervals where only the
faster block executes, the simulation progresses more rapidly.
The following diagram illustrates the execution sequence.
t0
T = 2 sec
T = 1 sec
Slower
Block
Faster
Block
t1
T=2s
t2
T=1s T=1s
t3
T=2s
T=1s T=1s
Time
As you can see from the preceding diagrams, Simulink can simulate models
with multiple sample rates in an efficient manner. However, Simulink does not
operate in real time.
7-16
Sample Rate Transitions
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
t2
2 Sec
Task
T = 2 sec
T = 1 sec
Block
Faster
Block
T=2s
1
t0
1 Sec
Task
T=1s
T=2s
2
t1
T=1s
1
t2
t3
T=1s
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.
Figure 7-9: Time Overlaps in Slower to Faster Transitions
This timing diagram illustrates two problems:
1 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 slower
task has completed execution. This means the inputs to the slower task can
change, causing unpredictable results.
2 The faster block executes before the slower block (which is backwards from
the way Simulink 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.
7-17
7
Models with Multiple Sample Rates
To eliminate these problems, you must insert a Unit Delay block between the
slower and faster blocks. The sample rate for a Unit Delay block must be set to
that of the block that is driving it (i.e., the slower block).
T = 2 sec
T = 2 sec
T = 1 sec
Unit Delay
Slower
Block
Faster
Block
The picture below shows the timing sequence that results with the added Unit
Delay block.
2
2 Sec
Task
1/z
update
T=2s
t1
t0
1 Sec
Task
1/z
T=1s
output
t2
1
1
T=1s
1/z
update
T=2s
t3
1
1
3
1/z
T=1s
output
T=1s
Time
Three key points about this diagram:
1 Unit delay output runs in 1 second task, but only at its rate (2 seconds). The
output of the unit delay block feeds the 1 second task blocks.
2 The unit delay update uses the output of the 2 second task in its update of
its internal state.
3 The unit delay update uses the state of the unit delay in the 1 second task.
7-18
Sample Rate Transitions
The output portion of a Unit Delay block is executed at the sample rate of the
slower block, but with the priority of the faster block. Since a Unit Delay block
drives the faster block and has effectively the same priority, it is executed
before the faster block. This solves the first problem.
The second problem is alleviated because the Unit Delay block executes at a
slower rate and its output does not change during the computation of the faster
block it is driving.
Note Inserting a Unit Delay block changes the model. The output of the
slower block is now delayed by one time step compared to the output without a
Unit Delay block.
7-19
7
Models with Multiple Sample Rates
7-20
8
Optimizing the Model for
Code Generation
Overview . . . . . . . . . . . . . . . . . . . . . . 8-2
General Modeling Techniques
. . . . . . . . . . . . 8-3
Block Diagram Performance Tuning
Look-Up Tables and Polynomials . .
Accumulators . . . . . . . . . .
Use of Data Types . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 8-4
. 8-4
. 8-15
. 8-17
Stateflow Optimizations . . . . . . . . . . . . . . . 8-23
Simulation Parameters
. . . . . . . . . . . . . . . 8-24
Compiler Options . . . . . . . . . . . . . . . . . . 8-26
8
Optimizing the Model for Code Generation
Overview
There are a number of ways that you can optimize code generated by the
Real-Time Workshop from your model, with respect to both memory usage and
performance.
This chapter discusses optimization techniques that are common to all target
configurations and code formats. For optimizations specific to a particular
target configuration, see the chapter relevant to that target.
8-2
General Modeling Techniques
General Modeling Techniques
The following are techniques that you can use with any code format:
• The slupdate command automatically converts older models to use current
features. Run slupdate on old models.
• Directly inline C code S-functions into the generated code by writing a TLC
file for the S-function. See the Target Language Compiler Reference Guide for
more information on inlining S-functions. Also see “Creating Device Drivers”
on page 17-34 for information on inlining device driver 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. See Using Simulink for more
information on data types.
• Remove repeated values in lookup table data.
• Use the Merge block to merge the output of function-call subsystems. This
block is particularly helpful when controlling the execution of function-call
subsystems with Stateflow.
This diagram is an example of how to use the Merge block.
8-3
8
Optimizing the Model for Code Generation
Block Diagram Performance Tuning
Certain block constructs in Simulink will run faster, or require less code or
data memory, than other seemingly equivalent constructs. Knowing the
trade-offs between similar blocks and block parameter options will enable you
to create Simulink models that have intuitive diagrams, and to produce the
tight code that you want from Real-Time Workshop. Many of the options and
constructs discussed in this section will improve the simulation speed of the
model itself, even without code generation.
Look-Up Tables and Polynomials
Simulink provides several blocks that allow approximation of functions. These
include blocks that perform direct, interpolated and cubic spline lookup table
operations, and a polynomial evaluation block.
There are currently six different blocks in Simulink that perform lookup table
operations:
• Look-Up Table
• Look-Up Table (2-D)
• Look-Up Table (n-D)
• Direct Look-Up Table (n-D)
• PreLook-Up Index Search
• Interpolation (n-D) Using PreLook-Up Index Search
In addition, the Repeating Sequence block uses a lookup table operation, the
output of which is a function of the real-time (or simulation-time) clock.
To get the most out of the following discussion, you should familiarize yourself
with the features of these blocks, as documented in the Using Simulink
manual.
Each type of lookup table block has its own set of options and associated
trade-offs. The examples in this section show how to use lookup tables
effectively. The techniques demonstrated here will help you achieve maximal
performance with minimal code and data sizes.
8-4
Block Diagram Performance Tuning
Multi-Channel Nonlinear Signal Conditioning
Figure 8-1 shows a Simulink model that reads input from two 8-channel,
high-speed 8-bit analog/digital converters (ADCs). The ADCs are connected to
Type K thermocouples through a gain circuit with an amplification of 250.
Since the popular Type K thermocouples are highly nonlinear, there is an
international standard for converting their voltages to temperature. In the
range of 0 to 500 degrees Celsius, this conversion is a tenth-order polynomial.
One way to perform the conversion from ADC readings (0-255) into
temperature (in degrees Celsius) is to evaluate this polynomial. In the best
case, the polynomial evaluation requires 9 multiplications and 10 additions per
channel.
A polynomial evaluation is not the fastest way to convert these 8-bit ADC
readings into measured temperature. Instead, the model uses a Direct Look-Up
(n-D) Table block (named TypeK_TC) to map 8-bit values to temperature
values. This block performs one array reference per channel.
Figure 8-1: Direct Look-Up Table (n-D) Block Conditions ADC Input
The block’s table parameter is populated with 256 values that correspond to
the temperature at an ADC reading of 0, 1, 2, … up to 255. The table data,
calculated in MATLAB, is stored in the workspace variable TypeK_0_500. The
block’s Table data parameter field references this variable, as shown in
Figure 8-2.
8-5
8
Optimizing the Model for Code Generation
Figure 8-2: Parameters of Direct Look-Up Table (n-D) Block
The model uses a Mux block to collect all similar signals (e.g., Type K
thermocouple readings) and feed them into a singleDirect Look-Up Table block.
This is more efficient than using one Direct Look-Up Table block per device. If
multiple blocks share a common parameter (such as the table in this example),
the Real-Time Workshop creates only one copy of that parameter in the
generated code.
This is the recommended approach for signal conditioning when the size of the
table can fit within your memory constraints. In this example, the table stores
256 double (8-byte) values, utilizing 2 KB of memory.
Note that the TypeK_TC block processes 16 channels of data sequentially.
The Real-Time Workshop generates the following code for the TypeK_TC block
shown in Figure 8-1.
/* (LookupNDDirect) Block: <Root>/TypeK_TC */
/* 1-dimensional Direct Look-Up Table returning 16 Scalars */
{
int_T i1;
const uint8_T *u0 = &rtb_s1_Data_Type_Conversion[0];
real_T *y0 = &rtb_root_TypeK_TC[0];
for (i1=0; i1 < 8; i1++) {
8-6
Block Diagram Performance Tuning
y0[i1] = (rtP.root_TypeK_TC_table[(uint8_T)u0[i1]]);
}
u0 = &rtb_s2_Data_Type_Conversion[0];
y0 = &rtb_root_TypeK_TC[8];
for (i1=0; i1 < 8; i1++) {
y0[i1] = (rtP.root_TypeK_TC_table[(uint8_T)u0[i1]]);
}
}
Notice that the core of each loop is one line of code that directly retrieves a table
element from the table and places it in the block output variable. There are two
loops in the generated code because the two simulated ADCs are not merged
into a contiguous memory array in the Mux block. Instead, to avoid a copy
operation, the Direct Look-Up Table block performs the lookup on two sets of
data using a single table array (rtP.root_TypeK_TC_table[]).
If the input accuracy for your application (not to be confused with the number
of I/O bits) is 24 bits or less, you can use a single precision table for signal
conditioning. Then, cast the lookup table output to double precision for use in
the rest of the block diagram. This technique, shown in Figure 8-3, causes no
loss of precision.
Figure 8-3: Single Precision Lookup Table Output Is Cast to Double Precision
Note that a direct lookup table covering 24 bits of accuracy would require 64
megabytes of memory, which is typically not practical. To create a single
precision table, use the MATLAB single() cast function in your table
calculations. Alternatively, you can perform the type cast directly in the Table
data parameter, as shown in Figure 8-4.
8-7
8
Optimizing the Model for Code Generation
Figure 8-4: Type Casting Table Data in a Direct Look-Up Block
When table size becomes impractical, you must use other nonlinear techniques,
such as interpolation or polynomial techniques. The Look-Up Table (n-D) block
supports linear interpolation and cubic spline interpolation.The Polynomial
block supports evaluation of noncomplex polynomials.
Compute-Intensive Equations
The blocks described in this section are useful for simplifying fixed, complex
relationships that are normally too time consuming to compute in real time.
The only practical way to implement some compute-intensive functions or
arbitrary nonlinear relationships in real time is to use some form of lookup
table. On processors that do not have floating-point instructions, even
functions like sqrt() can become too expensive to evaluate in real time.
An approximation to the nonlinear relationship in a known range will work in
most cases. For example, your application might require a square root
calculation that your target processor’s instruction set does not support. The
illustration below shows how you can use a Look-Up Table block to calculate
an approximation of the square root function that covers a given range of the
function.
8-8
Block Diagram Performance Tuning
The interpolated values are plotted on the block icon.
8-9
8
Optimizing the Model for Code Generation
For more accuracy on widely spaced points, use a cubic spline interpolation in
the Look-Up Table (n-D) block, as shown below.
Techniques available in Simulink include n-dimensional support for direct
lookup, linear interpolations in a table, cubic spline interpolations in a table,
and 1-D real polynomial evaluation.
The Look-Up Table (n-D) block supports flat interval lookup, linear
interpolation and cubic spline interpolation. Extrapolation for the Look-Up
Table (n-D) block can either be disabled (clipping) or enabled for linear or
spline extrapolations.
The icons for the Direct Look-Up Table (n-D) and Look-Up Table (n-D) blocks
change depending on the type of interpolation selected and the number of
dimensions in the table, as illustrated below.
8-10
Block Diagram Performance Tuning
Tables with Repeated Points
The Look-Up Table and Look-Up Table (2-D) blocks, shown below, support
linear interpolation with linear extrapolation. In these blocks, the row and
column parameters can have repeated points, allowing pure step behavior to be
mixed in with the linear interpolations. Note that this capability is not
supported by the Look-Up Table (n-D) block.
Slowly vs. Rapidly Changing
Look-Up Table Block Inputs
You can optimize lookup table operations using the Look-Up Table (n-D) block
for efficiency if you know the input signal’s normal rate of change. Figure 8-5
shows the parameters for the Look-Up Table (n-D) block.
8-11
8
Optimizing the Model for Code Generation
Figure 8-5: Parameter Dialog for the Look-Up Table (n-D) Block
If you do not know the input signal’s normal rate of change in advance, it would
be better to choose the Binary Search option for the index search in the
Look-Up Table (n-D) block and the PreLook-Up Index Search block.
Regardless of signal behavior, if the table’s breakpoints are evenly spaced, it is
best to select the Evenly Spaced Points option from the Look-Up Table (n-D)
block’s parameter dialog.
8-12
Block Diagram Performance Tuning
If the breakpoints are not evenly spaced, first decide which of the following best
describes the input signal behavior.
• Behavior 1: The signal stays in a given breakpoint interval from one time
step to the next. When the signal moves to a new interval, it tends to move
to an adjacent interval.
• Behavior 2: The signal has many discontinuities. It jumps around in the
table from one time step to the next, often moving three or more intervals per
time step.
Given behavior 1, the best optimization for a given lookup table is to use the
Linear search option and Begin index searches using previous index
results options, as shown below.
Given behavior 2, the Begin index searches using previous index results
option does not necessarily improve performance. Choose the Binary Search
option, as shown below.
The choice of an index search method can be more complicated for lookup table
operations of two or more dimensions with linear interpolation. In this case,
several signals are input to the table. Some inputs may have evenly spaced
points, while others may exhibit behavior 1 or behavior 2.
Here it may be best to use PreLook-Up Index Search blocks with different
search methods (evenly spaced, linear search or binary search) chosen
according to the input signal characteristics. The outputs of these search blocks
are then connected to an Interpolation (n-D) Using PreLook-Up Index Search
block, as shown in the block diagram below.
8-13
8
Optimizing the Model for Code Generation
You can configure each PreLook-Up Index Search block independently to use
the best search algorithm for the breakpoints and input time variation cases.
Multiple Tables with Common Inputs
The index search can be the most time consuming part of flat or linear
interpolation calculations. In large block diagrams, lookup table blocks often
have the same input values as other lookup table blocks. If this is the case in
your block diagram, you can obtain a large savings in computation time by
making the breakpoints common to all tables. This savings is obtained by using
one set of PreLook-Up Index Search blocks to perform the searches once for all
tables, so that only the interpolation remains to be calculated. Figure 8-6 is an
example of a block diagram that can be optimized by this method.
Figure 8-6: Before Optimization
Assume that Table A’s breakpoints are the same as Table B’s first input
breakpoints, and that Table C’s breakpoints are the same as Table B’s second
input breakpoints.
8-14
Block Diagram Performance Tuning
A 50% reduction in index search time is obtained by pulling these common
breakpoints out into a pair of PreLook-Up Index Search blocks, and using
Interpolation (n-D) Using PreLook-Up Index Search blocks to perform the
interpolation. Figure 8-7 shows the optimized block diagram.
Figure 8-7: After Optimization
In Figure 8-7, the Look-Up Table (n-D) blocks have been replaced with
Interpolation (n-D) Using PreLook-Up blocks.The PreLook-Up Index Search
blocks have been added to perform the index searches separately from the
interpolations, in order to realize the savings in computation time.
In large controllers and simulations, it is not uncommon for hundreds of
multidimensional tables to rely on a dozen or so breakpoint sets. Using the
optimization technique shown in this example, you can greatly increase the
efficiency of your application.
Accumulators
Simulink recognizes the block diagram shown in Figure 8-8 as an accumulator.
An accumulator construct — comprising a Constant block, a Sum block, and
feedback through a Unit Delay block — is recognized anywhere across a block
diagram, or within subsystems at lower levels.
8-15
8
Optimizing the Model for Code Generation
Figure 8-8: An Accumulator Algorithm
By using the Block reduction option, you can significantly optimize code
generated from an accumulator. Turn this option on in the Advanced page of
the Simulink Simulation parameters dialog, as shown in Figure 8-9.
Figure 8-9: Block Reduction Option
With the Block reduction option on, Simulink creates a synthesized block,
Sum_sythesized_accumulator. This synthesized block replaces the block
diagram of Figure 8-8, resulting in a simple increment calculation.
/* Compute block outputs */
void MdlOutputs(int_T tid)
{
/* UnadornAccum Block: <Root>/Sum_sythesized_accumulator */
8-16
Block Diagram Performance Tuning
rtB.Sum_sythesized_accumulator++;
/* Outport Block: <Root>/Out1 */
rtY.Out1 = rtB.Sum_sythesized_accumulator;
}
With Block reduction turned off, the generated code reflects the block
diagram more literally, but less efficiently.
/* Compute block outputs */
void MdlOutputs(int_T tid)
{
/* local block i/o variables */
real_T rtb_Unit_Delay;
/* UnitDelay Block: <Root>/Unit Delay */
rtb_Unit_Delay = rtDWork.Unit_Delay_DSTATE;
/* Sum Block: <Root>/Sum */
rtB.Sum = rtC_Constant + rtb_Unit_Delay;
/* Outport Block: <Root>/Out1 */
rtY.Out1 = rtB.Sum;
}
/* Perform model update */
void MdlUpdate(int_T tid)
{
/* UnitDelay Block: <Root>/Unit Delay */
rtDWork.Unit_Delay_DSTATE = rtB.Sum;
}
Use of Data Types
In most processors, the use of integer data types can result in a significant
reduction in data storage requirements, as well as a large increase in the speed
of operation. You can achieve large performance gains on most processors by
identifying those portions of your block diagram that are really integer
calculations (such as accumulators), and implementing them with integer data
types.
8-17
8
Optimizing the Model for Code Generation
Floating-point DSP targets are an obvious exception to this rule.
The accumulator from the previous example used 64-bit floating-point
calculations by default. The block diagram in Figure 8-9 implements the
accumulator with 16-bit integer operations.
Figure 8-10: Accumulator Implemented with 16-bit Integers
If the Saturate on integer overflow option of the Sum block is turned off, the
code generated from the integer implementation looks the same as code
generated from the floating-point block diagram. However, since
Sum_sythesized_accumulator is performing integer arithmetic internally, the
accumulator executes more efficiently.
Note that, by default, the Saturate on integer overflow option is on. This
option generates extra error-checking code from the integer implementation,
as in the following example.
void MdlOutputs(int_T tid)
{
/* UnadornAccum Block: <Root>/Sum_sythesized_accumulator */
{
int16_T tmpVar = rtB.Sum_sythesized_accumulator;
rtB.Sum_sythesized_accumulator = tmpVar + (1);
if ((tmpVar >= 0) && ((1) >= 0) &&
(rtB.Sum_sythesized_accumulator < 0)) {
rtB.Sum_sythesized_accumulator = MAX_int16_T;
} else if ((tmpVar < 0) && ((1) < 0) &&
(rtB.Sum_sythesized_accumulator >= 0)) {
rtB.Sum_sythesized_accumulator = MIN_int16_T;
}
}
/* Outport Block: <Root>/Out1 */
8-18
Block Diagram Performance Tuning
rtY.Out1 = rtB.Sum_sythesized_accumulator;
}
The floating-point implementation would not have generated the saturation
error checks, which apply only to integers. When using integer data types,
consider whether or not you need to generate saturation checking code.
Figure 8-11 shows an efficient way to add reset capability to the accumulator.
When resetSig is greater than or equal to the threshold of the Switch block,
the Switch block passes the reset value (0) back into the accumulator.
Figure 8-11: Integer Accumulator with Reset via External Input
The size of the resultant code is minimal. The code uses no floating-point
operations.
/* Compute block outputs */
void MdlOutputs(int_T tid)
{
/* local block i/o variables */
int16_T rtb_temp3;
/* UnitDelay Block: <Root>/accumState */
rtb_temp3 = rtDWork.accumState_DSTATE;
/* Sum Block: <Root>/Sum */
{
int16_T tmpVar1 = 0;
int16_T tmpVar2;
8-19
8
Optimizing the Model for Code Generation
/* port 0 */
tmpVar1 = rtC_Increment;
/* port 1 */
tmpVar2 = tmpVar1 + rtb_temp3;
if ((tmpVar1 >= 0) && (rtb_temp3 >= 0) &&
(tmpVar2 < 0)) {
tmpVar2 = MAX_int16_T;
} else if ((tmpVar1 < 0) && (rtb_temp3 < 0) &&
(tmpVar2 >= 0)) {
tmpVar2 = MIN_int16_T;
}
rtb_temp3 = tmpVar2;
}
/* Outport Block: <Root>/accumVal */
rtY.accumVal = rtb_temp3;
/* Switch Block: <Root>/Switch */
if (rtU.resetSig) {
rtB.Switch = rtC_ResetValue;
} else {
rtB.Switch = rtb_temp3;
}
}
/* Perform model update */
void MdlUpdate(int_T tid)
{
/* UnitDelay Block: <Root>/accumState */
rtDWork.accumState_DSTATE = rtB.Switch;
}
In this example, it would be easy to use an input to the system as the reset
value, rather than a constant.
Generating Pure Integer Code
The Real-Time Workshop Embedded Coder target provides the Integer code
only option to ensure that generated code contains no floating-point data or
operations. When this option is selected, an error is raised if any noninteger
8-20
Block Diagram Performance Tuning
data or expressions are encountered during compilation of the model. The error
message reports the offending blocks and parameters.
If pure integer code generation is important to your design, you should consider
using the Real-Time Workshop Embedded Coder target (or a target of your
own, based on the Real-Time Workshop Embedded Coder target).
To use the Integer code only option, select ERT code generation options
from the Category menu in the Real-Time Workshop page. Then enable the
Integer code only option, as shown below.
The Real-Time Workshop Embedded Coder target offers many other
optimizations. See Chapter 9, “Real-Time Workshop Embedded Coder” for
further information.
Data Type Optimizations with Fixed-Point Blockset
and Stateflow
The Fixed-Point Blockset (a separate product) is designed to deliver the highest
levels of performance for noninteger algorithms on processors lacking
floating-point hardware. The Fixed-Point Blockset’s code generation in
Real-Time Workshop implements calculations using a processor’s integer
operations. The code generation strategy maps the integer value set to a range
of expected real world values to achieve the high efficiency.
8-21
8
Optimizing the Model for Code Generation
Finite-state machine or flowchart constructs can often represent decision logic
(or mode logic) efficiently. Stateflow (a separate product) provides these
capabilities. Stateflow, which is fully integrated into Simulink, supports
integer data-typed code generation.
8-22
Stateflow Optimizations
Stateflow Optimizations
If your model contains Stateflow blocks, select the Use Strong Data Typing
with Simulink I/O check box (on the Chart Properties dialog box) on a
chart-by-chart basis.
See the Stateflow User’s Guide for more information about the Chart
Properties dialog box.
8-23
8
Optimizing the Model for Code Generation
Simulation Parameters
Options on each page of the Simulation Parameters dialog box affect the
generated code.
Advanced Page
• Turn on the Signal storage reuse option. The directs the Real-Time
Workshop to store signals in reusable memory locations. It also enables the
Local block outputs option (see “General Code Generation Options” on page
8-25).
Disabling Signal storage reuse makes all block outputs global and unique,
which in many cases significantly increases RAM and ROM usage.
• Enable strict Boolean type checking by selecting the Boolean logic signals
option.
Selecting this check box is recommended. Generated code will require less
memory, because a Boolean signal typically requires one byte of storage
while a double signal requires eight bytes of storage.
• Select the Inline parameters check box. Inlining parameters reduces global
RAM usage, since parameters are not declared in the global parameters
structure. Note that you can override the inlining of individual parameters
by using the Model Parameter Configuration dialog box.
8-24
Simulation Parameters
• Consider using the Parameter pooling option if you have multiple block
parameters referring to workspace locations that are separately defined but
structurally identical. See “Parameter Pooling Option” on page 3-24 for
further information.
General Code Generation Options
To access these options, select General code generation options from the
Category menu on the Real-Time Workshop page.
• Set an appropriate Loop rolling threshold. The loop rolling 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 “Loop Rolling Threshold Field” on page 3-10 details on loop rolling.
• Select the Inline invariant signals option. The Real-Time Workshop will
not generate code for blocks with a constant (invariant) sample time.
• Select the Local block outputs option. Block signals will be declared locally
in functions instead of being declared globally (when possible). You must
turn on the Signal storage reuse option in the Advanced page to enable the
Local block outputs check box.
8-25
8
Optimizing the Model for Code Generation
Compiler Options
• If you do not require double precision for your application, define real_T as
float in your template make file, or you can simply specify -DREAL_T=float
after make_rtw in the Make command field.
• Turn on the optimizations for the compiler (e.g., -O2 for gcc, -Ot for Microsoft
Visual C).
8-26
9
Real-Time Workshop
Embedded Coder
Introduction . . . . . . . . . . . . . . . . . . . . 9-2
Data Structures and Code Modules . . . . . . . . . . 9-4
Real-Time Object . . . . . . . . . . . . . . . . . . . 9-4
Code Modules . . . . . . . . . . . . . . . . . . . . 9-5
Program Execution
Overview . . . . .
Main Program . . .
rt_OneStep . . . .
Model Entry Points .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 9-9
. 9-9
. 9-10
. 9-11
. 9-14
Automatic S-Function Wrapper Generation . . . . . . . 9-17
Optimizing the Generated Code . .
Basic Code Generation Options . . .
Generating Code from Subsystems .
Generating Block Comments . . . .
Generating a Code Generation Report
Controlling Stack Space Allocation .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 9-20
. 9-20
. 9-22
. 9-22
. 9-23
. 9-25
Advanced Code Generation Options
Create Simulink (S-Function) Block .
Generate HTML Report . . . . . .
Generate ASAP2 File . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9-27
9-27
9-27
9-28
Requirements and Restrictions . . . . . . . . . . . . 9-29
Unsupported Blocks . . . . . . . . . . . . . . . . . 9-30
System Target File and Template Makefiles . . . . . . . 9-31
9
Real-Time Workshop Embedded Coder
Introduction
The Real-Time Workshop Embedded Coder is a separate, add-on product for
use with the Real-Time Workshop.
The Real-Time Workshop Embedded Coder provides a framework for the
production of code that is optimized for speed, memory usage, and simplicity.
The Real-Time Workshop Embedded Coder is intended for use in embedded
systems.
The Real-Time Workshop Embedded Coder generates code in the Embedded-C
format. Optimizations inherent in the Embedded-C code format include:
• Use of model-specific real-time object data structure rather than generic
SimStruct significantly reduces code size and memory usage.
• Simplified calling interface reduces overhead. Model output and update
functions are combined into a single routine.
• In-lined S-functions (required) reduce calling overhead and code size.
• Static memory allocation reduces overhead and promotes deterministic
performance.
The Real-Time Workshop Embedded Coder supports the following key
features:
• Integer only code generation
• Floating-point code generation
• Supports asynchronous interrupt-driven execution of models with either
single or multiple sample rates
• Automatic generation of S-function wrappers, allowing you to validate the
generated code in Simulink (Software-in-the-loop)
• Web-viewable code generation report describes code modules and helps to
identify code generation optimizations relevant to your program
This chapter describes the components of the Real-Time Workshop Embedded
Coder provided with Real-Time Workshop. It also describes options for
optimizing your generated code, and for automatically generating an
S-function wrapper that calls your Real-Time Workshop Embedded Coder
generated code from Simulink. In addition, certain restrictions that apply to
the use of the Real-Time Workshop Embedded Coder are discussed.
9-2
We assume you have read Chapter 6, “Program Architecture” and Chapter 7,
“Models with Multiple Sample Rates” in this manual. Those chapters give a
general overview of the architecture and execution of programs generated by
Real-Time Workshop.
9-3
9
Real-Time Workshop Embedded Coder
Data Structures and Code Modules
This section describes the main data structures of the Real-Time Workshop
Embedded Coder. It also summarizes the code modules and header files that
make up a Real-Time Workshop Embedded Coder program, and describes
where to find them.
Real-Time Object
Unlike other Real-Time Workshop code formats, Real-Time Workshop
Embedded Coder generated code does not employ the SimStruct. Instead, the
Real-Time Workshop Embedded Coder uses a data structure called the
real-time object. The real-time object, like the SimStruct, contains essential
timing and scheduling data, as well as model information. The real-time object
is much more compact than the SimStruct, achieving a significant reduction in
code size. For example, the real-time object for a single-rate model typically
requires 4 bytes.
Note that the real-time object is a model-specific data structure. The real-time
object for a particular model is defined in model_export.h.
Your code should not reference fields of the real-time object directly. The
Real-Time Workshop provides accessor macros for the real-time object. These
macros are defined in matlabroot/rtw/c/ert/ertformat.h. The macros are
syntactically and functionally identical to the SimStruct macros used with
other code formats. If you are interfacing your code to a single model, you
should refer to its real-time object generically as RT_OBJ, and use the macros to
access RT_OBJ, as in the following code fragment.
#include "ertformat.h"
const char_T *errStatus = ssGetErrorStatus(RT_OBJ);
For an example of how to interface your code to the real-time objects of more
than one model, see “How to Call the Entry Points Directly” on page 9-16.
The logging object is a subobject of the real-time object. This data structure is
used in generated code if the MAT-file logging code generation option is
enabled.
9-4
Data Structures and Code Modules
Code Modules
This section summarizes the code modules and header files of the Real-Time
Workshop Embedded Coder, and describes where to find them.
Generated Code Modules
The Real-Time Workshop creates a build directory in your working directory to
store generated source code. The build directory also contains object ( .obj)
files, a makefile, and other files created during the code generation process.
The default name of the build directory is model_ert_rtw. The build directory
contains the following generated source code modules:
• model.c
model.c defines all entry points to the generated code. These are:
- model_step implements all computations required for one time step of
your model.
- model_initialize initializes the real-time object. If logging is enabled, it
also initializes the logging object.
- model_terminate performs any cleanup operations required after your
program’s main loop has stopped executing. Real-Time Workshop
generates model_terminate if you select the Terminate function
required code generation option (by default, this option is selected).
A standard way to call these entry points is via the macros MODEL_STEP,
MODEL_INITIALIZE, and MODEL_TERMINATE. These macros are defined in
matlabroot/rtw/c/ert/ertformat.h. The following code fragment
illustrates their use.
#include "ertformat.h"
MODEL_INITIALIZE(1);
• model_export.h
model_export.h defines the real-time object and provides a public interface
to the entry points of the model code. See “How to Call the Entry Points
Directly” on page 9-16 for an example of how to use this interface.
• model.h
This header defines parameters and data structures private to model.c.
• autobuild.h is generated only for use in test and simulation. This file is not
required in production environments. You can replace
9-5
9
Real-Time Workshop Embedded Coder
#include "autobuild.h"
with
#include "model_export.h"
Note that the Real-Time Workshop Embedded Coder code generation report
contains further information about code modules generated during a build.
(See “Generating a Code Generation Report” on page 9-23).
Main Program Module
Real-Time Workshop provides the module
matlabroot/rtw/c/ert/ert_main.c as a template example for developing
embedded applications. ert_main.c is not part of the generated code; it is
provided as a basis for your custom modifications, and for use in simulation.
We recommend that you copy ert_main.c to your working directory and
rename it to model_ert_main.c before making modifications. The Build
process will create model_ert_main.obj in the build directory.
ert_main.c contains:
• rt_OneStep, a timer interrupt service routine (ISR). rt_OneStep calls
MODEL_STEP to execute processing for one clock period of the model.
• A skeletal main function. As provided, main is useful in simulation only. You
must modify main for real-time interrupt-driven execution.
“Program Execution” on page 9-9 contains a detailed discussion of the main
module, as well as guidelines for modifying it to meet your requirements.
Utility Header Files
The following support header files are provided in the directory
matlabroot/rtw/c/ert:
• ertformat.h defines accessor macros for the real-time object, as well as the
Real-Time Workshop Embedded Coder entry-point macros.
• tmwtypes.h and simstruc_types.h define Real-Time Workshop data types.
These headers are included by ertformat.h.
• log_object.h defines the logging object.
• log_macros.h defines macros that perform logging functions.
9-6
Data Structures and Code Modules
You can include these header files generically for all models. Inclusion of the
header files adds no overhead to the generated code.
9-7
9
Real-Time Workshop Embedded Coder
Table 9-1 summarizes the Real-Time Workshop Embedded Coder header files.
Table 9-1: Real-Time Workshop Embedded Coder Header Files
File
Directory
autobuild.h
Build directory
ertformat.h
matlabroot/rtw/c/ert
log_object.h,log_macros.h
matlabroot/rtw/c/ert
(Used only if MAT-file logging is
enabled)
model.h
Build directory
model_export.h
Build directory
User-Written Code Modules
Code that you write to interface with generated model code will include a
customized main module, and may also include interrupt handlers, device
driver blocks and other S-functions, and other supervisory or supporting code.
We recommend that you establish a working directory for your own code
modules. Your working directory should be on the MATLAB path. You must
also modify the Real-Time Workshop Embedded Coder template makefile and
system target file so that the build process can find your source and object files.
See Chapter 17, “Targeting Real-Time Systems” for information.
9-8
Program Execution
Program Execution
The Real-Time Workshop Embedded Coder generates self-sufficient,
standalone programs that do not require an external real-time executive or
operating system. The architecture of Real-Time Workshop Embedded Coder
generated programs supports execution of models with either single or
multiple sample rates.
If your application requires interfacing Real-Time Workshop Embedded Coder
generated code to a real-time operating system, we suggest that you study the
interface between Real-Time Workshop code and the VxWorks operating
system, discussed in Chapter 12, “Targeting Tornado for Real-Time
Applications.” OSEK example code is also available for study in
matlabroot/rtw/c/osek_leo.
This section describes how Real-Time Workshop Embedded Coder programs
execute, from the top level down to timer interrupt level.
Overview
The core of a Real-Time Workshop Embedded Coder program is typically the
main loop. On each iteration, the main loop executes a background or null task
and checks for a termination condition.
The main loop is periodically interrupted by a timer. The Real-Time Workshop
function rt_OneStep is either installed as a timer ISR, or called from a timer
ISR at each clock step.
The execution driver, rt_OneStep, sequences calls to the model_step function.
The operation of rt_OneStep differs depending on whether the generating
model is single-rate or multirate. In a single-rate model, rt_OneStep simply
calls the model_step function. In a multirate model, rt_OneStep prioritizes
and schedules execution of blocks according to the rates at which they run.
If your model includes device driver blocks, the model_step function will
incorporate your in-lined driver code to perform I/O functions such as reading
inputs from an analog-digital converter (ADC) or writing computed outputs to
a digital-analog converter (DAC).
9-9
9
Real-Time Workshop Embedded Coder
Main Program
Overview of Operation
The following pseudocode shows the execution of a Real-Time Workshop
Embedded Coder main program.
main()
{
Initialization (including installation of rt_OneStep as an
interrupt service routine for a real-time clock).
Initialize and start timer hardware
Enable interupts
While(not Error) and (time < final time)
Background task.
EndWhile
Disable interrupts (Disable rt_OneStep from executing.)
Complete any background tasks.
Shutdown
}
The pseudocode is a design for a harness program to drive your model. The
ert_main.c program, as shipped, only partially implements this design. You
must modify it according to your specifications.
Guidelines for Modifying the Main Program
This section describes the minimal modifications you should make in your
production version of ert_main.c to implement your harness program.
• After calling model_initialize:
- Initialize target-specific data structures and hardware such as ADCs or
DACs.
- Install rt_OneStep as a timer ISR.
- Initialize timer hardware.
- Enable timer interrupts and start the timer.
9-10
Program Execution
Note The real-time object is not in a valid state until model_initialize has
been called. Servicing of timer interrupts should not begin until
model_initialize has been called.
• Replace the rt_OneStep call in the main loop with a background task call or
null statement.
• On termination of main loop (if applicable):
- Disable timer interrupts.
- Perform target-specific cleanup such as zeroing DACs.
- Detect and handle errors. Note that even if your program is designed to
run indefinitely, you may need to handle severe error conditions such as
timer interrupt overruns.
You can use the macros ssGetErrorStatus, ssSetErrorStatus, and
ssSetStopRequested to detect and signal errors, or to stop execution.
These macros are documented in the Writing S-Functions manual.
rt_OneStep
Overview of Operation
The operation of rt_OneStep depends upon whether your model is single-rate
or multirate. Code compilation is controlled by the symbol NUMST, which
represents the number of sample times (i.e., rates) in the model. NUMST is
defined to be 1 for a single-rate model; otherwise NUMST is greater than 1. NUMST
is defined in the generated makefile model.mk.
Single-Rate Operation. The following pseudocode shows the design of rt_OneStep
in a single-rate program.
rt_OneStep()
{
Check for interrupt overflow or other error
Enable "rt_OneStep" (timer) interrupt
ModelStep-- Time step combines output,logging,update.
}
9-11
9
Real-Time Workshop Embedded Coder
Single-rate rt_OneStep is designed to execute model_step within a single clock
period. To enforce this timing constraint, rt_OneStep maintains and checks a
timer overrun flag. On entry, timer interrupts are disabled until the overrun
flag and other error conditions have been checked. If the overrun flag is clear,
rt_OneStep sets the flag, and proceeds with timer interrupts enabled.
The overrun flag is cleared only upon successful return from model_step.
Therefore, if rt_OneStep is reinterrupted before completing model_step, the
reinterruption will be detected through the overrun flag.
Reinterruption of rt_OneStep by the timer is an error condition. If this
condition is detected rt_OneStep signals an error and returns immediately.
(Note that you can change this behavior if you want to handle the condition
differently.)
Note that the design of rt_OneStep assumes that interrupts are disabled before
rt_OneStep is called. rt_OneStep should be non-interruptible until the
interrupt overflow flag has been checked.
Multirate Operation. The following pseudocode shows the design of rt_OneStep in
a multirate program.
rt_OneStep()
{
Check for base-rate interrupt overflow
Enable "rt_OneStep" interrupt
ModelStep(tid=0)
--base-rate time step.
For i=1:NumTasks
-- iterate over sub-rate tasks
Check for sub-rate interrupt overflow
If (sub-rate task i is scheduled)
ModelStep(tid=i)
--Sub-rate time step.
EndIf
EndFor
}
In a multirate system, rt_OneStep uses a prioritized, preemptive multitasking
scheme to execute the different sample rates in your model.
The execution of blocks having different sample rates is broken into tasks.
Each block that executes at a given sample rate is assigned a task identifier
9-12
Program Execution
(tid), which associates it with a task that executes at that rate. Where there
are NUMST tasks in the system, the range of task identifiers is 0..NUMST-1.
rt_OneStep prioritizes tasks, in descending order, by rate. The base-rate task
is the task that runs at the fastest rate in the system (the hardware clock rate).
The base-rate task has highest priority (tid 0) . The next fastest task (tid 1)
has the next highest priority, and so on down to the slowest, lowest priority
task (tid NUMST-1).
The slower tasks, running at submultiples of the base rate, are called sub-rate
tasks.
On each invocation, rt_OneStep makes one or more calls to model_step,
passing in the appropriate tid. The tid informs model_step that all blocks
having that tid should execute. rt_OneStep always calls model_step (tid = 0)
because the base-rate task must execute on every clock step.
On each clock tick, rt_OneStep also maintains scheduling counters and event
flags for each sub-rate task. Both the counters and the event flags are
implemented as arrays, indexed on tid.
The counters are, in effect, clock rate dividers that count up the sample period
associated with each sub-rate task. The event flags indicate whether or not a
given task is scheduled for execution. When a counter indicates that a task’s
sample period has elapsed, rt_OneStep sets the event flag for that task.
After updating its scheduling data structures and stepping the base-rate task,
rt_OneStep iterates over the scheduling flags in tid order, calling
model_step(tid) for any task whose flag is set. This ensures that tasks are
executed in order of priority.
The event flag array and loop variables used by rt_OneStep are stored as local
(stack) variables. This ensures that rt_OneStep is reentrant. If rt_OneStep is
reinterrupted, higher priority tasks will preempt lower priority tasks. Upon
return from interrupt, lower priority tasks will resume in the previously
scheduled order.
Multirate rt_OneStep also maintains an array of timer overrun flags.
rt_OneStep detects timer overrun, per task, by the same logic as single-rate
rt_OneStep.
Note that the design of rt_OneStep assumes that interrupts are disabled before
rt_OneStep is called. rt_OneStep should be non-interruptible until the
base-rate interrupt overflow flag has been checked (see pseudo-code above).
9-13
9
Real-Time Workshop Embedded Coder
Guidelines for Modifying rt_OneStep
rt_OneStep does not require extensive modification. The only required
modification is to re-enable interrupts after the overrun flag(s) and error
conditions have been checked. Comments in rt_OneStep indicate the
appropriate place to add your code.
In multirate rt_OneStep, you can improve performance by unrolling for and
while loops.
You may also want to replace the MODEL_STEP macro call(s) with model-specific
call(s). If so, see “How to Call the Entry Points Directly” on page 9-16.
In addition, you may choose to modify the overrun behavior to continue
execution after error recovery is complete.
You should not modify the way in which the counters are set in rt_OneStep.
The rt_OneStep timing data structures (including the real-time object) and
logic are critical to correct operation of any Real-Time Workshop Embedded
Coder program.
Model Entry Points
model_step
Calling Interface. The MODEL_STEP macro is the standard way to call your model’s
generated step function.
In a single-rate model, the macro expands to a function call with the prototype
void model_step(void);
In a multirate model, the macro expands to a function call with the prototype
void model_step(int_T tid);
where tid is a task identifier. The tid is determined by logic within
rt_OneStep. (See “rt_OneStep” on page 9-11.)
Operation. model_step combines the model output and update functions into a
single routine. model_step is designed to be called at interrupt level from
rt_OneStep, which is assumed to be invoked as a timer ISR.
9-14
Program Execution
Single-Rate Operation. In a single-rate model, model_step computes the current
value of all blocks. If logging is enabled, model_step updates logging variables.
If the model’s stop time is finite, model_step signals the end of execution when
the current time equals the stop time.
Multirate Operation. In a multirate model, model_step execution is almost
identical to single-rate execution, except for the use of the task identifier (tid)
argument.
The caller (rt_OneStep) assigns each block a tid. (See “rt_OneStep” on page
9-11.) model_step uses the tid argument to determine which blocks have a
sample hit (and therefore should execute).
Note If the model’s stop time is set to inf, or if logging is disabled,
model_step does not check the current time against the stop time. Therefore,
the program runs indefinitely.
model_initialize
Calling Interface. The MODEL_INITIALIZE macro is the standard way to call your
model’s generated initialization code. The macro expands to a function call
with the prototype
void model_initialize(boolean_T firstTime);
Operation. If firstTime equals 1 (TRUE), model_initialize initializes the
real-time object and other data structures private to the model. If firstTime
equals 0 (FALSE), model_initialize resets the model’s states.
The generated code calls model_initialize once, passing in firstTime as
1(TRUE).
model_terminate
Calling Interface. The MODEL_TERMINATE macro is a standard way to call your
model’s generated termination code. The macro expands to a function call with
the prototype
void model_terminate(void);
9-15
9
Real-Time Workshop Embedded Coder
Operation. When model_terminate is called, blocks that have a terminate
function execute their terminate code. If logging is enabled, model_terminate
ends data logging. model_terminate should only be called once. If your
application runs indefinitely, you do not need the model_terminate function.
If you do not require a terminate function, see “Basic Code Generation Options”
on page 9–20 for information on using the Terminate function required
option.
How to Call the Entry Points Directly
You can replace the generated macro calls with direct calls to the entry points.
This is necessary when interfacing your code with code generated from more
than one model. In such cases, the macro calls are ambiguous. Include
model_export.h to make the entry points visible to your code, as in the
following code fragment.
#include "modelA_Export.h" /* Make model A entry points visible */
#include "modelB_Export.h" /* Make model B entry points visible */
void myHandWrittenFunction(void)
{
const char_T *errStatus;
modelA_initialize(1); /* Call model A initializer */
modelB_initialize(1); /* Call model B initializer */
/* Refer to model A’s real-time Object */
errStatus = ssGetErrorStatus(modelA_rtO);
/* Refer to model B’s real-time Object */
errStatus = ssGetErrorStatus(modelB_rtO);
}
Note If you are modifying model_step calls in multirate rt_OneStep, take
care to pass in the correct tid argument. The first call, which steps the model
for the base sample time, always passes in tid 0. The calls made in the
sub-rate loop always pass in the loop variable i.
9-16
Automatic S-Function Wrapper Generation
Automatic S-Function Wrapper Generation
An S-function wrapper is an S-function that calls your C code from within
Simulink. S-function wrappers provide a standard interface between Simulink
and externally written code, allowing you to integrate your code into a model
with minimal modification. For a complete description of wrapper S-functions,
see the Writing S-Functions manual.
Using the Real-Time Workshop Embedded Coder Create Simulink
(S-Function) block option, you can build, in one automated step:
• A noninlined C MEX S-function wrapper that calls Real-Time Workshop
Embedded Coder generated code.
• A model containing the generated S-function block, ready for use with other
blocks or models.
This is useful for code validation and simulation acceleration purposes.
When Create Simulink (S-Function) block option is on, the Real-Time
Workshop generates an additional source code file, model_sf.c, in the build
directory. This module contains the S-function that calls the Real-Time
Workshop Embedded Coder code that you deploy. This S-function can be used
within Simulink.
The build process then compiles and links model_sf.c with model.c and the
other Real-Time Workshop Embedded Coder generated code modules, building
a MEX-file.The MEX-file is named model_sf.mexext. (mexext is the file
extension for MEX-files on your platform, as given by the MATLAB mexext
command.) The MEX-file is stored in your working directory. Finally, the
Real-Time Workshop creates and opens an untitled model containing the
generated S-Function block.
Limitations
It is not possible to create multiple instances of a Real-Time Workshop
Embedded Coder generated S-Function block within a model, because the code
uses static memory allocation.
9-17
9
Real-Time Workshop Embedded Coder
To generate an S-function wrapper for your Real-Time Workshop Embedded
Coder code:
1 Select the Real-Time Workshop tab of the Simulation Parameters dialog
box. Then select ERT advanced options from the Category menu.
2 Enable the Create Simulink (S-Function) block option, as shown.
3 Configure the other code generation options as required.
4 Click the Build button.
9-18
Automatic S-Function Wrapper Generation
5 When the build process completes, an untitled model window opens. This
model contains the generated S-Function block.
6 Save the new model.
7 The generated S-Function block is now ready to use with other blocks or
models in Simulink.
9-19
9
Real-Time Workshop Embedded Coder
Optimizing the Generated Code
The Real-Time Workshop Embedded Coder features a number of code
generation options that can help you further optimize the generated code. The
Real-Time Workshop Embedded Coder can also produce a code generation
report in HTML format. This report documents code modules and helps you to
identify optimizations that are relevant to your model.
“Basic Code Generation Options” on page 9-20 documents code generation
options you can use to improve performance and reduce code size.
“Generating a Code Generation Report” on page 9-23 describes how to generate
and use a code generation report.
“Controlling Stack Space Allocation” on page 9-25 discusses options related to
the storage of signals.
Please see Chapter 8, “Optimizing the Model for Code Generation” for
information about code optimization techniques common to all code formats.
Basic Code Generation Options
To access the basic code generation options, select the Real-Time Workshop tab
of the Simulation Parameters dialog box. Then select ERT code generation
options from the Category menu.
Figure 9-1 displays the basic code generation options for the Real-Time
Workshop Embedded Coder.
9-20
Optimizing the Generated Code
Figure 9-1: Basic Code Generation Options
Note ert_main.c contains certain compile-time error checks on code
generation options, intended for use during simulation only. You should
remove these error checks, as instructed below, from your production version
of ert_main.c
Setting the code generation options as follows will result in more highly
optimized code:
• Deselect the MAT-file logging check box.
Also, remove or comment out the #if MAT_FILE... error check in your
production version of ert_main.c.
Note that disabling logging causes the program to run indefinitely,
regardless of the setting of the model’s stop time.
• Deselect the Initialize internal data and Initialize external I/O data check
boxes.
Initializing the internal and external data is a precaution and may not be
necessary for your application. Many embedded application environments
9-21
9
Real-Time Workshop Embedded Coder
initialize all RAM to zero at startup. Therefore, reinitializing RAM to zero is
redundant.
Note that nonzero initialization of your program’s data structures is still
performed when Initialize internal data and Initialize external I/O data
are selected.
• Deselect the Terminate function required check box if you do not require a
terminate function for your model.
Also, remove or comment out the following in your production version of
ert_main.c:
- The #if TERMFCN... error check
- The call to MODEL_TERMINATE
• Select the Single output/update function check box. Combining the output
and update functions is the default. This option generates the model_step
call, which reduces overhead and allows the Real-Time Workshop to use
more local variables in the step function of the model.
If you do not want to combine output and update functions, make the
following changes in your production version of ert_main.c:
- Replace calls to MODEL_STEP with calls to model_output and
model_update.
- Remove the #if ONESTEPFCN... error check.
• If your application uses only integer arithmetic, select the Integer code only
option to ensure that generated code contains no floating-point data or
operations. When this option is selected, an error is raised if any noninteger
data or expressions are encountered during code generation. The error
message reports the offending blocks and parameters.
Generating Code from Subsystems
Note that when generating code from a subsystem, it is recommended that you
set the sample times of all subsystem inports explicitly.
Generating Block Comments
When the Insert block descriptions in code option is selected, comments are
inserted into the code generated for any blocks that have text in their
Description fields.
9-22
Optimizing the Generated Code
To generate block comments:
1 Right-click on the block you want to comment. Select Block Properties from
the context menu. The Block Properties dialog box opens.
2 Type the comment into the Description field.
3 Select the Insert block descriptions in code option in the ERT code
generation options category of the Real-Time Workshop page.
Note For virtual blocks or blocks that have been removed due to block
reduction optimizations, no comments are generated.
Generating a Code Generation Report
The Real-Time Workshop Embedded Coder code generation report is an HTML
file consisting of several sections:
• The Summary section lists version and date information, TLC options used
in code generation, and Simulink model settings.
• The Optimizations section lists the optimizations used during the build, and
also those that are available. If options were chosen that generated
non-optimal code, they are marked in red. This section can help you select
options that will better optimize your code.
• The Generated Source Files section contains a table of source code files
generated from subsystems (if any) in your model. Each row contains a
hyperlink to the relevant subsystem. You can click on the hyperlink to view
the subsystem in a Simulink model window.
To generate a code generation report:
1 Select the Real-Time Workshop tab of the Simulation Parameters dialog
box. Then select Advanced code generation options from the Category
menu.
2 Select Generate HTML report, as shown in this picture.
9-23
9
Real-Time Workshop Embedded Coder
3 Click the Build button.
4 The Real-Time Workshop writes the code generation report file in the build
directory. The file is named model_codegen_rpt.html.
5 The Real-Time Workshop automatically opens the MATLAB Help Browser
and displays the code generation report.
Alternatively, you can view the code generation report in your Web browser.
9-24
Optimizing the Generated Code
Controlling Stack Space Allocation
The Real-Time Workshop 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 options that:
• Let you control whether signal storage is declared in global memory space,
or locally in functions (i.e., in stack variables).
• Control the allocation of stack space when using local storage.
For a complete discussion of signal storage options, see “Signals: Storage,
Optimization, and Interfacing” on page 3-65.
If you want to store signals in stack space, you must turn the Local block
outputs option on. To do this:
1 Select the Advanced tab of the Simulation Parameters dialog box. Make
sure that the Signal storage reuse is on. If Signal storage reuse is off, the
Local block outputs option is not available.
2 Click Apply if necessary.
3 Select the Real-Time Workshop tab of the Simulation Parameters dialog
box.
4 From the Category menu, select General code generation options.
5 Check the Local block outputs option. Click Apply if necessary.
Your embedded application may be constrained by limited stack space. When
the Local block outputs option is on, you can limit the use of stack space by
using the following Target Language Compiler variables:
• MaxStackSize: the total allocation size of local variables that are declared by
all functions in the entire model may not exceed MaxStackSize (in bytes).
MaxStackSize can be any positive integer. If the total size of local variables
exceeds this maximum, the Target Language Compiler will allocate the
remaining variables in global, rather than local, memory.
• MaxStackVariableSize: limits the size of any local variable declared in a
function to N bytes, where N>0. A variable whose size exceeds
9-25
9
Real-Time Workshop Embedded Coder
MaxStackVariableSize will be allocated in global, rather than local,
memory.
To set either of these variables, use assign statements in the system target file
(ert.tlc), as in the following example.
%assign MaxStackSize = 4096
It is recommended that you write your %assign statements in the Configure
RTW code generation settings section of the system target file. The %assign
statement is described in the Target Language Compiler Reference Guide.
9-26
Advanced Code Generation Options
Advanced Code Generation Options
To access the advanced Real-Time Workshop Embedded Coder code generation
options, select the Real-Time Workshop tab of the Simulation Parameters
dialog box. Then select Advanced code generation options from the
Category menu.
Figure 9-2 displays the advanced code generation options for the Real-Time
Workshop Embedded Coder.
Figure 9-2: Advanced Code Generation Options
Create Simulink (S-Function) Block
See “Automatic S-Function Wrapper Generation” on page 9-17 for information
on this feature.
Generate HTML Report
See “Generating a Code Generation Report” on page 9-23 for information on
this feature.
9-27
9
Real-Time Workshop Embedded Coder
Generate ASAP2 File
The Real-Time Workshop Embedded Coder Generate ASAP2 File code
generation option lets you export an ASAP2 file containing information about
your model during the code generation process.
The ASAP2 file generation process requires information about your model's
parameters and signals. Some of this information is contained in the model
itself. The rest must be supplied by using Simulink data objects with the
necessary properties. Simulink provides two data classes to assist you in
providing the necessary information. See “Generating ASAP2 Files” in the
Real-Time Workshop online documentation for information on this feature.
9-28
Requirements and Restrictions
Requirements and Restrictions
• By definition, a Real-Time Workshop Embedded Coder program functions in
discrete time. Your model must use the following solver options:
- Solver type: fixed-step
- Algorithm: discrete (no continuous states)
• You must select the SingleTasking or Auto solver mode when the model is
single-rate. The following table indicates permitted solver modes for
single-rate and multirate models.
Table 9-2: Permitted Solver Modes for
Real-Time Workshop Embedded Coder-Targeted Models
Mode
Single-rate
Multirate
SingleTasking
Allowed
Allowed
MultiTasking
Disallowed
Allowed
Auto
Allowed
Allowed
(defaults to
(defaults to MultiTasking)
SingleTasking)
• You cannot have any continuous time blocks in your model. (See
“Unsupported Blocks” on page 9-30.).
• If you are designing a program that is intended to run indefinitely, you
should not use blocks that have a dependency on absolute time. See
Appendix A for a list of blocks that depend on absolute time.
• You must inline all S-functions with a corresponding Target Language
Compiler (TLC) file. The reason for this is that Real-Time Workshop
Embedded Coder generated code uses the real-time object, rather than the
SimStruct. Since noninlined S-functions require reference to the SimStruct,
they cannot be used in Real-Time Workshop Embedded Coder generated
programs. See the Writing S-Functions manual for information about
inlining S-functions.
9-29
9
Real-Time Workshop Embedded Coder
Unsupported Blocks
The Embedded-C format does not support the following built-in blocks:
• Continuous
- No blocks in this library are supported
• Discrete
- First-Order Hold
• Functions and Tables
- MATLAB Fcn
- The following S-functions: M-file and Fortran S-functions, or noninlined
C-MEX S-functions that call into MATLAB.
• Math
- Algebraic Constraint
- Matrix Gain
• Nonlinear
- Rate Limiter
• Sinks
- XY Graph
- Display
• Sources
- Clock
- Chirp Signal
- Pulse Generator
- Ramp
- Repeating Sequence
- Signal Generator
9-30
System Target File and Template Makefiles
System Target File and Template Makefiles
The Real-Time Workshop Embedded Coder system target file is ert.tlc.
The Real-Time Workshop provides template makefiles for the Real-Time
Workshop Embedded Coder in the following development environments:
• ert_bc.tmf — Borland C
• ert_lcc.tmf — LCC compiler
• ert_unix.tmf — UNIX host
• ert_vc.tmf — Visual C
• ert_watc.tmf — Watcom C
9-31
9
Real-Time Workshop Embedded Coder
9-32
10
The S-Function Target
Introduction . . . . . . . . . . . . . . . . . . . . 10-2
Intellectual Property Protection . . . . . . . . . . . . . 10-3
Creating an S-Function Block from a Subsystem
. . . . 10-4
Tunable Parameters in Generated S-Functions . . . . 10-10
Automated S-Function Generation
Restrictions
. . . . . . . . . 10-12
. . . . . . . . . . . . . . . . . . . 10-15
Unsupported Blocks . . . . . . . . . . . . . . . . 10-16
System Target File and Template Makefiles . . . . . . 10-17
System Target File . . . . . . . . . . . . . . . . . 10-17
Template Makefiles . . . . . . . . . . . . . . . . . 10-17
10
The S-Function Target
Introduction
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:
• 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 “Creating an
S-Function Block from a Subsystem” on page 10-4 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. You can generate an
executable from a model that contains generated S-functions by using the
generic real-time or real-time malloc targets. You cannot use the Real-Time
Workshop Embedded Coder target for this purpose, since it requires inlined
S-functions.
You can place a generated S-Function block into another model from which you
can generate another S-function format. This allows any level of nested
S-functions.
Note that sample times propagation for the S-function code format is slightly
different from the other code formats. A generated S-Function block will
inherit its sample time from the model in which it is placed if no blocks in the
original model specify their sample times.
10-2
Introduction
Intellectual Property Protection
In addition to the technical applications of the S-function target listed above,
you can use the S-function target to protect your designs and algorithms. By
generating an S-function from a proprietary model or algorithm, you can share
the model’s functionality without providing the source code. You need only
provide the binary .dll or MEX-file object to users.
10-3
10
The S-Function Target
Creating an S-Function Block from a Subsystem
This section demonstrates how to extract a subsystem from a model and
generate a reusable S-function component from it.
Figure 10-1 illustrates SourceModel, a simple model that inputs signals to a
subsystem. Figure 10-2 illustrates 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
• A Constant block whose value is the vector [-2 3]
Figure 10-1: SourceModel
Figure 10-2: SourceSubsys
10-4
Creating an S-Function Block from a Subsystem
Our objective is to extract SourceSubsys from the model and build an
S-Function block from it, using the S-function target. We want the S-Function
block to perform identically to the subsystem from which it was generated.
Note that in this model, SourceSubsys inherits sample times and signal widths
from its input signals. If an S-Function block is built from SourceSubsys,
without explicitly setting input widths and sample times, the new block will
inherit its sample times and signal widths from the model in which it is placed.
In this example, however, we want the S-Function block to retain the
properties of SourceSubsys as it exists in SourceModel. Before building the
subsystem as a separate S-function component, the inport sample times and
widths must be set explicitly. In addition, the solver parameters of the
S-function component must be the same as those of the original model. This
ensures that the generated S-function component will operate identically to the
original subsystem.
To build SourceSubsys as an S-function component:
1 Create a new model and copy/paste SourceSubsys 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 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 an
inherited sample time of 1.
10-5
10
The S-Function Target
3 The generated S-Function block should have three inports and one outport.
Connect inports and an outport to SourceSubsys, as shown below.
Note that the correct signal widths and sample times propagate to these
ports.
4 Set the solver type, mode, and other solver parameters such that they are
identical to those of the source model.
5 Save the new model.
6 Open the Simulation Parameters dialog and click the Real-Time-Workshop
tab. On the Real-Time-Workshop page, select Target configuration from
the Category menu.
7 Click the Browse button to open the System Target Browser. Select the
S-function target in the System Target Browser, and click OK. The
Real-Time-Workshop page parameters should appear as below.
10-6
Creating an S-Function Block from a Subsystem
8 Select RTW S-function code generation options from the Category menu.
Make sure that Create New Model is selected.
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.
10-7
10
The S-Function Target
9 Click Apply if necessary and select Target configuration from the
Category menu.
10 Click Build.
11 Real-Time Workshop builds the S-function component in the working
directory. After the build, a new model window displays.
12 You can now copy the Real-Time Workshop S-Function block from the new
model and use it in other models or in a library. Figure 10-3 shows the
S-Function block plugged in to the original model. Given identical input
signals, the S-Function block will perform identically to the original
subsystem.
10-8
Creating an S-Function Block from a Subsystem
Figure 10-3: Generated S-Function Plugged into SourceModel
Note that 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.
10-9
10
The S-Function Target
Tunable Parameters in Generated S-Functions
You can utilize tunable parameters in generated S-functions in two ways:
• Use the Generate S-function feature (see “Automated S-Function
Generation” on page 10-12).
or
• Use the Model Parameter Configuration dialog (see “Parameters: Storage,
Interfacing, and Tuning” on page 3-51) 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.
Note that these parameters do not become part of a generated rtP parameter
data structure, as they would in code generated from other targets. Instead,
the generated code accesses these parameters via MEX API calls such as
mxGetPr or mxGetData. Your code should access these parameters in the
same way.
For further information on MEX API calls, see Writing S-Functions and the
MATLAB Application Program Interface Guide.
S-Function blocks created via 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.
10-10
Tunable Parameters in Generated S-Functions
You can choose to display the value of the parameter rather than its variable
name. To do this, select Use Value for Tunable Parameters in the Options
section.
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.
10-11
10
The S-Function Target
Automated 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 subsystem illustrated in
Figure 10-2. Our objective is to automatically extract SourceSubsys from the
model and build an S-Function block from it, as in the previous example. In
addition, we want to set the gain factor of the Gain block within SourceSubsys
to the workspace variable K (as illustrated below) and declare K as a tunable
parameter.
To auto-generate an S-function from SourceSubsys with tunable parameter K:
1 Click on the subsystem to select it.
2 Select Generate S-function from the Real-Time Workshop submenu of the
Tools menu. This menu item is enabled when a subsystem is selected in the
current model.
Alternatively, you can choose Generate S-function from the Real-Time
Workshop submenu of the subsystem block's context menu.
3 A window displaying a list of the subsystem parameters opens.
10-12
Automated S-Function Generation
In the illustration above, the parameter K is declared tunable.
4 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.
5 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.
10-13
10
The S-Function Target
6 The model window contains an S-Function block, subsys_blk, where subsys
is the name of the subsystem from which the block was generated.
The generated S-function component, subsys, is stored in the working
directory. The generated source code for the S-function is written to a build
directory, subsys_sfcn_rtw.
7 Note that the untitled generated model does not persist, unless you save it
via the File menu.
8 Note that the generated S-Function block has inports and outports whose
widths and sample times correspond to those of the original model.
The following code fragment, from the mdlOutputs routine of the generated
S-function code (in SourceSubsys_sf.c), illustrates how the tunable variable K
is referenced via calls to the MEX API.
static void mdlOutputs(SimStruct *S, int_T tid)
...
real_T rtb_temp3[2];
...
/* Gain Block: <S1>/Gain */
rtb_temp3[0] *= ((*(real_T *)(mxGetData(K(S)))));
rtb_temp3[1] *= ((*(real_T *)(mxGetData(K(S)))));
Note In automatic S-function generation, the Use Value for Tunable
Parameters option is always set to its default value (off).
10-14
Restrictions
Restrictions
• Hand-written S-functions without corresponding TLC files must contain
exception-free code. For more information on exception-free code, refer to
“Exception-Free Code” in Writing S-Functions.
• If you modify the source model that generated an S-Function block, the
Real-Time Workshop does not automatically rebuild models containing the
generated S-Function block.
10-15
10
The S-Function Target
Unsupported Blocks
The S-function format does not support the following built-in blocks:
• MATLAB Fcn Block
• S-Function blocks containing any of the following:
- M-file S-functions
- Fortran S-functions
- C MEX S-functions that call into MATLAB
• Scope block
• To Workspace block
10-16
System Target File and Template Makefiles
System Target File and Template Makefiles
The following system target file and template makefiles are provided for use
with the S-function target.
System Target File
• rtwsfcn.tlc
Template Makefiles
• rtwsfcn_bc.tmf — Borland C
• rtwsfcn_lcc.tmf — LCC compiler
• rtwsfc_unix.tmf — UNIX host
• rtwsfcn_vc.tmf — Visual C
• rtwsfcn_watc.tmf — Watcom C
10-17
10
The S-Function Target
10-18
11
Real-Time Workshop
Rapid Simulation Target
Introduction . . . . . . . . . . . . . . . . . . . . 11-2
Building for the Rapid Simulation Target
Running a Rapid Simulation . . . . . . .
Simulation Performance . . . . . . . . .
Batch and Monte Carlo Simulations . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 11-4
. 11-5
11-12
11-12
11
Real-Time Workshop Rapid Simulation Target
Introduction
The Real-Time Workshop rapid simulation target (rsim) consists of a set of
target files for nonreal-time execution on your host computer. You can use rsim
to generate fast, stand-alone simulations that allow batch parameter tuning
and loading of new simulation data (signals) from a standard MATLAB
MAT-file without needing to recompile your model.
C code generated from Real-Time Workshop is highly optimized to provide fast
execution of discrete-time systems or systems that use a fixed-step solver. The
speed of the generated code also makes it ideal for batch or Monte Carlo
simulation. The run-time interface for the rapid simulation target enables the
generated code to read and write data to standard MATLAB MAT-files. Using
these support files, rsim reads new signals and parameters from MAT-files at
the start of the simulation.
After building an rsim executable with Real-Time Workshop and an
appropriate C compiler for your host computer, you can perform any
combination of the following by using command line options. Without
recompiling, the rapid simulation target allows you to:
• Specify a new file(s) that provides input signals for From File blocks
• Specify a new file that provides input signals with any Simulink data type
(double, float, int32, uint32, int16, uint16, int8, uint8, and complex data
types) by using the From Workspace block
• Replace the entire block diagram parameter vector and run a simulation
• Specify a new stop time for ending the stand-alone simulation
• Specify a new name of the MAT-file used to save model output data
• Specify name(s) of the MAT-files used to save data connected to To File
blocks
You can run these options:
• Directly from your operating system command line (for example, DOS box or
UNIX shell) or
• By using the bang (!) command with a command string at the MATLAB
prompt
Therefore, you can easily write simple scripts that will run a set of simulations
in sequence while using new data sets. These scripts can be written to provide
11-2
unique filenames for both input parameters and input signals, as well as
output filenames for the entire model or for To File blocks.
11-3
11
Real-Time Workshop Rapid Simulation Target
Building for the Rapid Simulation Target
To generate and build an rsim executable, press the Browse button on the
Real-Time Workshop page of the Simulation Parameters dialog box, and
select the rapid simulation target from the System Target File Browser. This
picture shows the dialog box settings for the rapid simulation target.
Press the Browse button and
select the rapid simulation
target from the System Target
File Browser. This
automatically selects the
correct settings for the system
target file, the template
makefile, and the make
command.
Figure 11-1: Specifying Target and Make Files for rsim
After specifying system target and make files as noted above, select any desired
Workspace I/O settings, and press Build. The Real-Time Workshop will
automatically generate C code and build the executable for your host machine
using your host machine C compiler. See “Choosing and Configuring Your
Compiler” on page 3-99 and “Template Makefiles and Make Options” on page
3-102 for additional information on compilers that are compatible with
Simulink and the Real-Time Workshop.
Note rsim executables can be transferred and run on computers that do not
have MATLAB installed. When running an rsim executable on such a
machine, it is necessary to have the following dlls in your working directory:
libmx.dll, libut.dll, and libmat.dll. These dlls are required for any rsim
executable that writes or reads data to or from a .mat file.
11-4
Building for the Rapid Simulation Target
Running a Rapid Simulation
The rapid simulation target lets you run a simulation similar to the generic
real-time (GRT) target provided by the Real-Time Workshop. This simulation
does not use timer interrupts, and therefore is a nonreal-time simulation
environment. The difference between GRT and rsim simulations is that rsim
allows you to change parameter values or input signals at the start of a
simulation without the need to generate code or recompile. The GRT target, on
the other hand, is a starting point for targeting a new processor.
A single build of your model can be used to study effects from varying
parameters or input signals. Command line arguments provide the necessary
mechanism to specify new data for your simulation. This table lists all
available command line options.
Table 11-1: rsim Command Line Options
Command Line Option
Description
model -f old.mat=new.mat
Read From File block input signal data from
a replacement MAT-file.
model -o newlogfile.mat
Write MAT-file logging data to a file named
newlogfile.mat.
model -p filename.mat
Read a new (replacement) parameter vector
from a file named filename.mat.
model -s <stoptime>
Run the simulation until the time value
<stoptime> is reached.
model -t old.mat=new.mat
The original model specified saving signals
to the output file old.mat. For this run use
the file new.mat for saving signal data.
model -v
Run in verbose mode.
model -h
Display a help message listing options.
Specifying a New Signal Data File for a From File Block
To understand how to specify new signal data for a From File block, create a
working directory and connect to that directory. Open the model rsimtfdemo
by typing
11-5
11
Real-Time Workshop Rapid Simulation Target
rsimtfdemo
at the MATLAB prompt. Type
w = 100;
zeta = 0.5;
to set parameters. rsimtfdemo requires a data file, rsim_tfdata.mat. Make a
local copy of matlabroot/toolbox/rtw/rtwdemos/rsim_tfdata.mat in your
working directory.
Be sure to specify rsim.tlc as the system target file and rsim_default_tmf as
the template makefile. Then press the Build button on the Real-Time
Workshop page to create the rsim executable.
!rsimtfdemo
load rsimtfdemo
plot(rt_yout)
The resulting plot shows simulation results using the default input data.
11-6
Building for the Rapid Simulation Target
Replacing Input Signal Data. New data for a From File block can be placed in a
standard MATLAB MAT-file. As in Simulink, the From File block data must
be stored in a matrix with the first row containing the time vector while
subsequent rows contain u vectors as input signals. After generating and
compiling your code, you can type the model name rsimtfdemo at a DOS
prompt to run the simulation. In this case, the file rsim_tfdata.mat provides
the input data for your simulation.
For the next simulation, create a new data file called newfrom.mat and use this
to replace the original file (rsim_tfdat.mat) and run an rsim simulation with
this new data. This is done by typing
t=[0:.001:1];
u=sin(100*t.*t);
tu=[t;u];
save newfrom.mat tu;
!rsimtfdemo -f rsim_tfdata.mat=newfrom.mat
at the MATLAB prompt. Now you can load the data and plot the new results
by typing
load rsimtfdemo
plot(rt_yout)
11-7
11
Real-Time Workshop Rapid Simulation Target
This picture shows the resulting plot.
As a result the new data file is read and the simulation progresses to the stop
time specified in the Solver page of the Simulation Parameters dialog box.
It is possible to have multiple instances of From File blocks in your Simulink
model.
Since rsim does not place signal data into generated code, it reduces code size
and compile time for systems with large numbers of data points that originate
in From File blocks. The From File block requires the time vector and signals
to be data of type double. If you need to import signal data of a data type other
than double, use a From Workspace block with the data specified as a
structure.
11-8
Building for the Rapid Simulation Target
The workspace data must be in the format
variable.time
variable.signals.values
If you have more than one signal, the format must be
variable.time
variable.signals(1).values
variable.signals(2).values
Specifying a New Output Filename for the Simulation
If you have specified Save to Workspace options (that is, checked Time,
States, Outputs, or Final States check boxes on the Workspace I/O page of the
Simulation Parameters dialog box), the default is to save simulation logging
results to the file model.mat. You can now specify a replacement filename for
subsequent simulations. In the case of the model rsimtfdemo, by typing
!rsimtfdemo
at the MATLAB prompt, a simulation runs and data is normally saved to
rsimtfdemo.mat.
!rsimtfdemo
created rsimtfdemo.mat
You can specify a new output filename for data logging by typing
!rsimtfdemo -o sim1.mat
In this case, the set of parameters provided at the time of code generation,
including any From File block data, is run. You can combine a variety of rsim
flags to provide new data, parameters, and output files to your simulation.
Note that the MAT-file containing data for the From File blocks is required.
This differs from the grt operation, which inserts MAT-file data directly into
the generated C code that is then compiled and linked as an executable. In
contrast, rsim allows you to provide new or replacement data sets for each
successive simulation. A MAT-file containing From File or From Workspace
data must be present, if any From File or From Workspace blocks exist in your
model.
11-9
11
Real-Time Workshop Rapid Simulation Target
Changing Block Parameters for an rsim Simulation
Once you have altered one or more parameter in the Simulink block diagram,
you can extract the parameter vector, rtP, for the entire model. The rtP vector,
along with a model checksum, can then be saved to a MATLAB MAT-file. This
MAT-file can be read in directly by the stand-alone rsim executable, allowing
you to replace the entire parameter vector quickly, for running studies of
variations of parameter values where you are adjusting model parameters or
coefficients or importing new data for use as input signals.
The model checksum provides a safety check to ensure that any parameter
changes are only applied to rsim models that have the same model structure.
If any block is deleted, or a new block added, then when generating a new rtP
vector, the new checksum will no longer match the original checksum. rsim will
detect this incompatibility in parameter vectors and exit to avoid returning
incorrect simulation results. In this case, where model structure has changed,
you must regenerate the code for the model.
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
In general, the Real-Time Workshop evaluates side-effects functions prior to
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, rtP. You must create
this new structure by using rsimgetrtp.m. and then save it in a MAT-file. For
the rsimtfdemo example, type
zeta = .2;
myrtp = rsimgetrtp('modelname');
save myparamfile myrtp;
at the MATLAB prompt.
In turn, rsim can read the MAT-file and replace the entire rtP structure
whenever you need to change one or more parameters — without recompiling
the entire model.
For example, assume that you have changed one or more parameters in your
model, generated the new rtP vector, and saved rtP to a new MAT-file called
11-10
Building for the Rapid Simulation Target
myparamfile.mat. In order to run the same rsimtfdemo model and use these
new parameter values, execute the model by typing
!rsimtfdemo -p myparamfile.mat
load rsimtfdemo
plot(rt_yout)
Note that the p is lower-case and represents “Parameter file.”
Specifying a New Stop Time for an rsim Simulation
If a new stop time is not provided, the simulation will run until reaching the
value specified in the Solver page at the time of code generation. You can
specify a new stop time value as follows.
!rsimtfdemo -s 6.0
In this case, the simulation will run until it reaches 6.0 seconds. At this point
it will stop and log the data according to the MAT-file data logging rules as
described above.
If your model includes From File blocks that also include a time vector in the
first row of the time and signal matrix, the end of the simulation is still
regulated by the original setting in the Solver page of the Simulation
Parameters dialog box or from the -s option as described above. However, if
the simulation time exceeds the end points of the time and signal matrix (that
is, if the final time is greater than the final time value of the data matrix), then
the signal data will be extrapolated out to the final time value as specified
above.
Specifying New Output Filenames for To File Blocks
In much the same way as you can specify a new system output filename, you
can also provide new output filenames for data saved from one or more To File
blocks. This is done by specifying the original filename at the time of code
generation with a new name as follows.
!mymodel -t original.mat=replacement.mat
In this case, assume that the original model wrote data to the output file called
original.mat. Specifying a new filename forces rsim to write to the file
replacement.mat. This technique allows you to avoid over-writing an existing
simulation run.
11-11
11
Real-Time Workshop Rapid Simulation Target
Simulation Performance
It is not possible to predict accurately the simulation speedup of an rsim
simulation compared to a standard Simulink simulation. Performance will
vary. Larger simulations have achieved speed improvements of up to 10 times
faster than standard Simulink simulations. Some models may not show any
noticeable improvement in simulation speed. The only way to determine
speedup is to time your standard Simulink simulation and then compare its
speed with the associated rsim simulation.
Batch and Monte Carlo Simulations
The rsim target is intended to be used for batch simulations in which
parameters and/or input signals are varied for each new simulation. New
output filenames allow you run new simulations without over-writing prior
simulation results. A simple example of such a set of batch simulations can be
run by creating a .bat file for use under Microsoft Windows 95 or Windows NT.
This simple file (for Windows 95 or Windows NT) is created with any text editor
and executed by typing the filename, for example, mybatch, where the name of
the text file is mybatch.bat.
rsimtfdemo
rsimtfdemo
rsimtfdemo
rsimtfdemo
-f
-f
-f
-f
rsimtfdemo.mat=run1.mat
rsimtfdemo.mat=run2.mat
rsimtfdemo.mat=run3.mat
rsimtfdemo.mat=run4.mat
-o
-o
-o
-o
results1.mat
results2.mat
results3.mat
results4.mat
-s
-s
-s
-s
10.0
10.0
10.0
10.0
In this case, batch simulations are run using the four sets of input data in files
run1.mat, run2.mat, and so on. rsim saves the data to the corresponding files
specified after the -o option.
The variable names containing simulation results in each of these files are
identical. Therefore, loading consecutive sets of data without renaming the
data once it is in the MATLAB workspace will result in over-writing the prior
workspace variable with new data. If you want to avoid over-writing, you can
copy the result to a new MATLAB variable prior to loading the next set of data.
You can also write M-file scripts to create new signals, and new parameter
structures, as well as to save data and perform batch runs using the bang
command (!).
For additional insight into the rapid simulation target, explore rsimdemo1 and
rsimdemo2, located in matlabroot/toolbox/rtw/rtwdemos. These examples
11-12
Building for the Rapid Simulation Target
demonstrate how rsim can be called repeatedly within an M-file for Monte
Carlo simulations.
11-13
11
Real-Time Workshop Rapid Simulation Target
11-14
12
Targeting Tornado for
Real-Time Applications
Introduction . . . . . . . . . . . . . . . . . . . . 12-2
Confirming Your Tornado Setup Is Operational . . . . . . 12-2
VxWorks Library . . . . . . . . . . . . . . . . . . . 12-3
Run-Time Architecture Overview . . . . . . . . . . 12-5
Parameter Tuning and Monitoring . . . . . . . . . . . 12-5
Run-Time Structure . . . . . . . . . . . . . . . . . 12-8
Implementation Overview . . . . . .
Adding Device Driver Blocks . . . . . .
Configuring the Template Makefile . . .
Tool Locations . . . . . . . . . . . .
Building the Program . . . . . . . . .
Downloading and Running the Executable
Interactively . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
12-12
12-14
12-14
12-15
12-15
. . . . . . . 12-19
12
Targeting Tornado for Real-Time Applications
This chapter contains the following topics:
• Introduction. Overview of the Tornado (VxWorks) Real-Time Target and
the VxWorks Support library.
• Run-Time Architecture Overview. Single- and multitasking architecture
and host/target communications.
• Implementation Overview. Designing, implementing and running a
VxWorks-based real-time program using the Real-Time Workshop.
12-2
Introduction
Introduction
This chapter describes how to create real-time programs for execution under
VxWorks, which is part of the Tornado environment.
The VxWorks real-time operating system is available from Wind River
Systems, Inc. It provides many UNIX-like features and comes bundled with a
complete set of development tools.
Note Tornado is an integrated environment consisting of VxWorks (a
high-performance real-time operating system), application building tools
(compiler, linker, make, and archiver utilities), and interactive development
tools (editor, debugger, configuration tool, command shell, and browser).
This chapter discusses the run-time architecture of VxWorks-based real-time
programs generated by the Real-Time Workshop and provides specific
information on program implementation. Topics covered include:
• Configuring device driver blocks and makefile templates
• Building the program
• Downloading the object file to the VxWorks target
• Executing the program on the VxWorks target
• Using Simulink external mode to change model parameters and download
them to the executing program on the VxWorks target
• Using the StethoScope data acquisition and graphical monitoring tool, which
is available as an option with VxWorks. It allows you to access the output of
any block in the model (in the real-time program) and display the data on the
host.
Confirming Your Tornado Setup Is Operational
Before beginning, you must install and configure Tornado on your host and
target hardware, as discussed in the Tornado documentation. You should then
run one of the VxWorks demonstration programs to ensure you can boot your
VxWorks target and download object files to it. See the Tornado User’s Guide
for additional information about installation and operation of VxWorks and
Tornado products.
12-3
12
Targeting Tornado for Real-Time Applications
VxWorks Library
Selecting VxWorks Support under the Real-Time Workshop library in the
Simulink Library Browser opens the VxWorks Support library.
The blocks discussed in this chapter are located in the Asynchronous Support
library, a sublibrary of the VxWorks Support library:
• Interrupt Control
• Rate Transition
• Read Side
12-4
Introduction
• Task Synchronization
• Write Side
A second sublibrary, the IO Devices library, contains support for these drivers:
• Matrix MS-AD12
• Matrix MS-DA12
• VME Microsystems VMIVM-3115-1
• Xycom XVME-500/590
• Xycom XVME-505/595
Each of these blocks has online help available through the Help button on the
block’s dialog box. Refer to the Tornado User’s Guide for detailed information
on these blocks.
12-5
12
Targeting Tornado for Real-Time Applications
Run-Time Architecture Overview
In a typical VxWorks-based real-time system, the hardware consists of a UNIX
or PC host running Simulink and the Real-Time Workshop, connected to a
VxWorks target CPU via Ethernet. In addition, the target chassis may contain
I/O boards with A/D and D/A converters to communicate with external
hardware. The following diagram shows the arrangement.
Host
VxWorks Target
Simulink
Real-Time Workshop
Target
CPU
Tornado Compiler
ADC/DAC
Boards
Ethernet
Port
model.lo
Ethernet
Figure 12-1: Typical Hardware Setup for a VxWorks Application
The real-time code is compiled on the UNIX or PC host using the cross compiler
supplied with the VxWorks package. The object file (model.lo) output from the
Real-Time Workshop program builder is downloaded, using WindSh (the
command shell) in Tornado, to the VxWorks target CPU via an Ethernet
connection.
The real-time program executes on the VxWorks target and interfaces with
external hardware via the I/O devices installed on the target.
Parameter Tuning and Monitoring
You can change program parameters from the host and monitor data with
Scope blocks while the program executes using Simulink external mode. You
can also monitor program outputs using the StethoScope data analysis tool.
Using Simulink external mode and/or StethoScope in combination allows you
to change model parameters in your program, and to analyze the results of
these changes, in real time.
12-6
Run-Time Architecture Overview
External Mode
Simulink external mode provides a mechanism to download new parameter
values to the executing program and to monitor signals in your model. In this
mode, the external link MEX-file sends a vector of new parameter values to the
real-time program via the network connection. These new parameter values
are sent to the program whenever you make a parameter change without
requiring a new code generation or build iteration.
You can use the BlockIOSignals code generation option to monitor signals in
VxWorks. See “Interfacing Parameters and Signals” on page 17-65 for further
information and example code.
The real-time program (executing on the VxWorks target) runs a low priority
task that communicates with the external link MEX-file and accepts the new
parameters as they are passed into the program.
Communication between Simulink and the real-time program is accomplished
using the sockets network API. This implementation requires an Ethernet
network that supports TCP/IP. See Chapter 5, “External Mode” for more
information on external mode.
Changes to the block diagram structure (for example, adding or removing
blocks) require generation of model and execution of the build process.
Configuring VxWorks to Use Sockets
If you want to use Simulink external mode with your VxWorks program, you
must configure your VxWorks kernel to support sockets by including the
INCLUDE_NET_INIT, INCLUDE_NET_SHOW, and INCLUDE_NETWORK options in your
VxWorks image. For more information on configuring your kernel, see the
VxWorks Programmer’s Guide.
Before using external mode, you must ensure that VxWorks can properly
respond to your host over the network. You can test this by using the host
command
ping <target_name>
12-7
12
Targeting Tornado for Real-Time Applications
Note You may need to enter a routing table entry into VxWorks if your host
is not on the same local network (subnet) as the VxWorks system. See
routeAdd in the VxWorks Reference Guide for more information.
Configuring Simulink to Use Sockets
Simulink external mode uses a MEX-file to communicate with the VxWorks
system. The MEX-file is
matlabroot/toolbox/rtw/ext_comm.*
where * is a host-dependent MEX-file extension. See Chapter 5, “External
Mode” for more information.
To use external mode with VxWorks, specify ext_comm as the MEX-file for
external interface in the External Target Interface dialog box (accessed
from the External Mode Control Panel). In the MEX-file arguments field
you must specify the name of the VxWorks target system and, optionally, the
verbosity and TCP port number. Verbosity can be 0 (the default) or 1 if extra
information is desired. The TCP port number ranges from 256 to 65535 (the
default is 17725). If there is a conflict with other software using TCP port
17725, you can change the port that you use by editing the third argument of
the MEX-file for external interface on the External Target Interface dialog
box. The format for the MEX-file arguments field is
'target_network_name' [verbosity] [TCP port number]
For example, this picture shows the External Target Interface dialog box
configured for a target system called halebopp with default verbosity and the
port assigned to 18000.
12-8
Run-Time Architecture Overview
StethoScope
With StethoScope, you can access the output of any block in the model (in the
real-time program) and display this data on a host. Signals are installed in
StethoScope by the real-time program using the BlockIOSignals data
structure (See “Interfacing Parameters and Signals” on page 17-65 for
information on BlockIOSignals), or interactively from the WindSh while the
real-time program is running. To use StethoScope interactively, see the
StethoScope User’s Manual.
To use StethoScope you must specify the proper options with the build
command. See “Code Generation Options” on page 12-18 for information on
these options.
Run-Time Structure
The real-time program executes on the VxWorks target while Simulink and
StethoScope execute on the same or different host workstations. Both Simulink
and StethoScope require tasks on the VxWorks target to handle
communication.
12-9
12
Targeting Tornado for Real-Time Applications
This diagram illustrates the structure of a VxWorks application using
Simulink external mode and StethoScope.
UNIX or PC Host
VxWorks Target
StethoScope
Simulink in
external mode
tRaten
tRate2
tRate1
Process GUI Events
tExtern
tBaseRate
tScope
ext_comm
Ethernet
Figure 12-2: The Run-Time Structure
The program creates VxWorks tasks to run on the real-time system: one
communicates with Simulink, the others execute the model. StethoScope
creates its own tasks to collect data.
Host Processes
There are two processes running on the host side that communicate with the
real-time program:
• Simulink running in external mode. Whenever you change a parameter in
the block diagram, Simulink calls the external link MEX-file to download
any new parameter values to the VxWorks target.
• The StethoScope user interface module. This program communicates with
the StethoScope real-time module running on the VxWorks target to retrieve
model data and plot time histories.
12-10
Run-Time Architecture Overview
VxWorks Tasks
You can run the real-time program in either singletasking or multitasking
mode. The code for both modes is located in
matlabroot/rtw/c/tornado/rt_main.c
The Real-Time Workshop compiles and links rt_main.c with the model code
during the build process.
Singletasking. By default, the model is run as one task, tSingleRate. This may
actually provide the best performance (highest base sample rate) depending on
the model.
The tSingleRate task runs at the base rate of the model and executes all
necessary code for the slower sample rates. Execution of the tSingleRate task
is normally blocked by a call to the VxWorks semTake routine. When a clock
interrupt occurs, the interrupt service routine calls the semGive routine, which
causes the semTake call to return. Once enabled, the tSingleRate task
executes the model code for one time step. The loop then waits at the top by
again calling semTake. For more information about the semTake and semGive
routines, refer to the VxWorks Reference Manual. By default, it runs at a
relatively high priority (30), which allows it to execute without interruption
from background system activity.
Multitasking. Optionally, the model can run as multiple tasks, one for each
sample rate in the model:
• tBaseRate — This task executes the components of the model code run at the
base (highest) sample rate. By default, it runs at a relatively high priority
(30), which allows it to execute without interruption from background
system activity.
• tRaten — The program also spawns a separate task for each additional
sample rate in the system. These additional tasks are named tRate1,
tRate2, …, tRaten, where n is slowest sample rate in the system. The
priority of each additional task is one lower than its predecessor (tRate1 has
a lower priority than tBaseRate).
12-11
12
Targeting Tornado for Real-Time Applications
Supporting Tasks. If you select external mode and/or StethoScope during the
build process, these tasks will also be created:
• tExtern — This task implements the server side of a socket stream
connection that accepts data transferred from Simulink to the real-time
program. In this implementation, tExtern waits for a message to arrive from
Simulink. When a message arrives, tExtern retrieves it and modifies the
specified parameters accordingly.
tExtern runs at a lower priority than tRaten, the lowest priority model task.
The source code for tExtern is located in matlabroot/rtw/c/src/ext_svr.c.
• tScopeDaemon and tScopeLink — StethoScope provides its own VxWorks
tasks to enable real-time data collection and display. In singletasking mode,
tSingleRate collects signals; in multitasking mode, tBaseRate collects them.
Both perform the collection on every base time step. The StethoScope tasks
then send the data to the host for display when there is idle time, that is,
when the model is waiting for the next time step to occur. rt_main.c starts
these tasks if they are not already running.
12-12
Implementation Overview
Implementation Overview
To implement and run a VxWorks-based real-time program using the
Real-Time Workshop, you must:
• Design a Simulink model for your particular application.
• Add the appropriate device driver blocks to the Simulink model, if desired.
• Configure the tornado.tmf template makefile for your particular setup.
• Establish a connection between the host running Simulink and the VxWorks
target via Ethernet.
• Use the automatic program builder to generate the code and the custom
makefile, invoke the make command to compile and link the generated code,
and load and activate the tasks required.
The figure below shows the Real-Time Workshop Tornado run-time interface
modules and the generated code for the f14 example model.
12-13
12
Targeting Tornado for Real-Time Applications
Generated Code
f14.c
f14.h
f14.bio
Main Program
rt_main.c
Model
Execution
rt_sim.c
Template
Makefile
tornado.tmf
Integration
Module
ode5.c
Simulink
Data Structure
simstruc.h
Makefile
f14.mk
Executable File
f14.lo
Data Logger
rtwlog.c
External mode
ext_svr.c
ext_svr.h
ext_msg.h
Figure 12-3: Source Modules Used to Build the VxWorks Real-Time Program
This diagram illustrates the code modules used to build a VxWorks real-time
program. Dashed boxes indicate optional modules.
12-14
Implementation Overview
Adding Device Driver Blocks
The real-time program communicates with the I/O devices installed in the
VxWorks target chassis via a set of device drivers. These device drivers contain
the necessary code that runs on the target processor for interfacing to specific
I/O devices.
To make device drivers easy to use, they are implemented as Simulink
S-functions using C code MEX-files. This means you can connect them to your
model like any other block and the code generator automatically includes a call
to the block’s C code in the generated code.
You can also inline S-functions via the Target Language Compiler. Inlining
allows you to restrict function calls to only those that are necessary for the
S-function. This can greatly increase the efficiency of the S-function. For more
information about inlining S-functions, see Writing S-Functions and the Target
Language Compiler Reference Guide.
You can have multiple instances of device driver blocks in your model. See
Targeting Real-Time Systems for more information about creating device
drivers.
Configuring the Template Makefile
To configure the VxWorks template, tornado.tmf, you must specify
information about the environment in which you are using VxWorks. This
section lists the lines in the file that you must edit.
VxWorks Configuration
To provide information used by VxWorks, you must specify the type of target
and the specific CPU on the target. The target type is then used to locate the
correct cross compiler and linker for your system.
The CPU type is used to define the CPU macro which is in turn used by many of
the VxWorks header files. Refer to the VxWorks Programmer’s Guide for
information on the appropriate values to use.
This information is in the section labeled
#-------------- VxWorks Configuration --------------
12-15
12
Targeting Tornado for Real-Time Applications
Edit the following lines to reflect your setup.
VX_TARGET_TYPE = 68k
CPU_TYPE = MC68040
Downloading Configuration
In order to perform automatic downloading during the build process, the target
name and host name that the Tornado target server will run on must be
specified. Modify these macros to reflect your setup.
#-------------- Macros for Downloading to Target-------------TARGET = targetname
TGTSVR_HOST = hostname
Tool Locations
In order to locate the Tornado tools used in the build process, the following
three macros must either be defined in the environment or specified in the
template makefile. Modify these macros to reflect your setup.
#-------------- Tool Locations -------------WIND_BASE = c:/Tornado
WIND_HOST_TYPE = x86–win32
WIND_REGISTRY = $(COMPUTERNAME)
Building the Program
Once you have created the Simulink block diagram, added the device drivers,
and configured the makefile template, you are ready to set the build options
and initiate the build process.
Specifying the Real-Time Build Options
Set the real-time build options using the Solver and Real-Time Workshop
pages of the Simulation Parameters dialog box. To access this dialog box,
select Parameters from the Simulink Simulation menu.
In the Solver page, for models with continuous blocks, set the Type to
Fixed-step, the Step Size to the desired integration step size, and select the
integration algorithm. For models that are purely discrete, set the integration
algorithm to discrete.
12-16
Implementation Overview
Next, use the System Target File Browser to select the correct Real-Time
Workshop page settings for Tornado. To access the browser, open the
Real-Time Workshop page of the Simulation Parameters dialog box and select
Target configuration from the Category menu.
Then click the Browse button. The System Target Browser opens.
12-17
12
Targeting Tornado for Real-Time Applications
Select Tornado (VxWorks) Real-Time Target and click OK. This sets the
Target configuration options correctly:
• System target file — tornado.tlc
• Template makefile — tornado.tmf template, which you must configure
according to the instructions in “Configuring the Template Makefile” on page
12-15. (You can rename this file; simply change the dialog box accordingly.)
• Make command — make_rtw
You can optionally inline parameters for the blocks in the C code, which can
improve performance. Inlining parameters is not allowed when using external
mode.
Code Generation Options. To specify code generation options specific to Tornado,
open the Real-Time Workshop page and select Tornado code generation
options from the Category menu.
The Real-Time Workshop provides flags that set the appropriate macros in the
template makefile, causing any necessary additional steps to be performed
during the build process.
The flags and switches are as follows:
• MAT-file logging: Select this option to enable data logging during program
execution. The program will create a file named model.mat at the end of
12-18
Implementation Overview
program execution; this file will contain the variables that you specified in
the Solver page of the Simulation Parameters dialog box.
Real-Time Workshop adds a prefix or suffix to the names of the Solver page
variables that you select for logging. The MAT-file variable name modifier
menu lets you select the prefix or suffix.
By default, the MAT-file is created in the root directory of the current default
device in VxWorks. This is typically the host file system that VxWorks was
booted from. Other remote file systems can be used as a destination for the
MAT-file using rsh or ftp network devices or NFS. See the VxWorks
Programmer’s Guide for more information. If a device or filename other than
the default is desired, add "-DSAVEFILE=filename" to the OPTS flag to the
make command. For example,
make_rtw OPTS="-DSAVEFILE=filename"
• External mode: Select this option to enable the use of external mode in the
generated executable. You can optionally enable a verbose mode of external
mode by appending -DVERBOSE to the OPTS flag in the make command. For
example,
make_rtw OPTS="-DVERBOSE"
causes parameter download information to be printed to the console of the
VxWorks system.
• Code format: Selects RealTime or RealTimeMalloc code generation format.
• StethoScope: Select this option to enable the use of StethoScope with the
generated executable. When starting rt_main, there are two command line
arguments that control the block names used by StethoScope; you can use
them when starting the program on VxWorks. See the section, “Running the
Program” on page 12-21 for more information on these arguments.
• Download to VxWorks target: Enables automatic downloading of the
generated program.
Additional options are available on the Real-Time Workshop page. See “Using
the Real-Time Workshop Page” on page 3-4 for information.
Initiating the Build
To build the program, click on the Build button in the Real-Time Workshop
page of the Simulation parameters dialog. The resulting object file is named
with the .lo extension (which stands for loadable object). This file has been
12-19
12
Targeting Tornado for Real-Time Applications
compiled for the target processor using the cross compiler specified in the
makefile. If automatic downloading (Download to VxWorks target) is enabled
in the Tornado code generation options, the target server is started and the
object file is downloaded and started on the target. If StethoScope was checked
on the Tornado code generation options, you can now start StethoScope on
the host. The StethoScope object files, libxdr.so, libutilstssip.so, and
libscope.so, will be loaded on the VxWorks target by the automatic download.
See the StethoScope User’s Manual for more information.
Downloading and Running the Executable
Interactively
If automatic downloading is disabled, you must use the Tornado tools to
complete the process. This involves three steps:
1 Establishing a communication link to transfer files between the host and the
VxWorks target
2 Transferring the object file from the host to the VxWorks target
3 Running the program
Connecting to the VxWorks Target
After completing the build process, you are ready to connect the host
workstation to the VxWorks target. The first step is starting the target server
that is used for communication between the Tornado tools on the host and the
target agent on the target. This is done either from the DOS command line or
from within the Tornado development environment. From the DOS command
line use
tgtsvr target_network_name
Downloading the Real-Time Program
To download the real-time program, use the VxWorks ld routine from within
WindSh. WindSh (wind shell) can also be run from the command line or from
within the Tornado development environment. (For example, if you want to
download the file vx_equal.lo, which is in the /home/my_working_dir
directory, use the following commands at the WindSh prompt.
12-20
Implementation Overview
cd "/home/my_working_dir"
ld <vx_equal.lo
You will also need to load the StethoScope libraries if the StethoScope option
was selected during the build. The Tornado User’s Guide describes the ld
library routine.
Running the Program
The real-time program defines a function, rt_main(), that spawns the tasks to
execute the model code and communicate with Simulink (if you selected
external mode during the build procedure.) It also initializes StethoScope if you
selected this option during the build procedure.
The rt_main function is defined in the rt_main.c application module. This
module is located in the matlabroot/rtw/c/tornado directory.
The rt_main function takes six arguments, and is defined by the following
ANSI C function prototype.
SimStruct *rt_main(void (*model)(SimStruct *),
char *optStr,
char *scopeInstallString,
int scopeFullNames,
int priority,
int TCPport);
Table 12-1 lists the arguments to this function.
12-21
12
Targeting Tornado for Real-Time Applications
Table 12-1: Arguments to the rt_main simStruct
Argument
Description
model
A pointer to the entry point function in the generated code. This
function has the same name as the Simulink model. It registers the
local functions that implement the model code by adding function
pointers to the model’s SimStruct. See Chapter 6, “Program
Architecture” for more information.
optStr
The options string used to specify a stop time (-tf) and whether to wait
(-w) in external mode for a message from Simulink before starting the
simulation. An example options string is
"-tf 20 -w"
The -tf option overrides the stop time that was set during code
generation. If the value of the -tf option is inf, the program runs
indefinitely.
scopeInstallString
A character string that determines which signals are installed to
StethoScope. Possible values are:
• NULL — Install no signals. This is the default value.
• "*" — Install all signals.
• "[A-Z]*" — Install signals from blocks whose names start with an
uppercase letter.
Specifying any other string installs signals from blocks whose names
start with that string.
scopeFullNames
This argument determines whether StethoScope uses full hierarchical
block names for the signals it accesses or just the individual block
name. Possible values are:
• 1 Use full block names.
• 0 Use individual block names. This is the default value.
It is important to use full block names if your program has multiple
instances of a model or S-function.
12-22
Implementation Overview
Table 12-1: Arguments to the rt_main simStruct (Continued)
Argument
Description
priority
The priority of the program’s highest priority task (tBaseRate). Not
specifying any value (or specifying a value of zero) assigns tBaseRate
to the default priority, 30.
TCPport
The port number that the external mode sockets connection should
use. The valid range is 256 to 65535. When nothing is specified, the
port number defaults to 17725.
Passing optStr Via the Template Makefile. You can also pass the -w and -tf options
(see optStr in Table 12-1) to rt_main by using the PROGRAM_OPTS macro in
tornado .tmf. PROGRAM_OPTS passes a string of the form
-opt1 val1 -opt2 val2
For example, the following sets an infinite stop time and instructs the program
to wait for a message from Simulink before starting the simulation.
PROGRAM_OPTS = "-tf inf -w”
Calling rt_main. To begin program execution, call rt_main from WindSh. For
example,
sp(rt_main, vx_equal, "-tf 20 -w", "∗", 0, 30, 17725)
• Begins execution of the vx_equal model
• Specifies a stop time of 20 seconds
• Provides access to all signals (block outputs) in the model by StethoScope
• Uses only individual block names for signal access (instead of the
hierarchical name)
• Uses the default priority (30) for the tBaseRate task
• Uses TCP port 17725, the default
12-23
12
Targeting Tornado for Real-Time Applications
12-24
13
Targeting DOS for
Real-Time Applications
Introduction . . . . . . . . . . . . . . . . . . . . 13-2
DOS Device Drivers Library . . . . . . . . . . . . . . 13-2
Implementation Overview . . . . . . . . . . . . . . 13-4
System Configuration . . . . . . . . . . . . . . . . . 13-5
Sample Rate Limits . . . . . . . . . . . . . . . . . 13-7
Device Driver Blocks . . . . . . . .
Device Driver Block Library . . . . . .
Configuring Device Driver Blocks . . . .
Adding Device Driver Blocks to the Model
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13-10
13-10
13-11
13-16
Building the Program . . . . . . . . . . . . . . . 13-17
Running the Program . . . . . . . . . . . . . . . . 13-18
13
Targeting DOS for Real-Time Applications
Introduction
This section provides information on using the Real-Time Workshop in a DOS
environment.
Note The xPC Target and the Real-Time Windows Target provide
significantly greater capabilities than does the DOS target. We recommend
use of these targets for real-time development on PC platforms. The DOS
target is provided only as an unsupported example. Also, note that the DOS
target requires the Watcom C compiler. See “A Note on the Watcom Compiler”
on page 13-6.
This chapter includes a discussion of:
• DOS-based Real-Time Workshop applications
• Supported compilers and development tools
• Device driver blocks — adding them to your model and configuring them for
use with your hardware
• Building the program
The DOS target creates an executable for DOS, using Watcom for DOS. The
executable runs on a computer running the DOS operating system. It will not
run under the Microsoft Windows DOS command prompt. This executable
installs interrupt service routines and effectively takes over the computer,
which allows the generated code to run in real time. If you want to run the
generated code in real time under Microsoft Windows, you should use the
Real-Time Windows Target. See the Real-Time Windows Target User’s Guide
for more information about this product.
DOS Device Drivers Library
The Real-Time Workshop provides DOS-compatible analog and digital I/O
device driver blocks in the DOS Device Drivers library. Select DOS Device
Drivers under the Real-Time Workshop library in the Simulink Library
Browser to open the DOS Device Drivers library.
13-2
13-3
13
Targeting DOS for Real-Time Applications
Implementation Overview
The Real-Time Workshop includes DOS run-time interface modules designed
to implement programs that execute in real time under DOS. These modules,
when linked with the code generated from a Simulink model, build a complete
program that is capable of executing the model in real time. The DOS run-time
interface files can be found in the matlabroot/rtw/c/dos/rti directory.
Real-Time Workshop DOS run-time interface modules and the generated code
for the f14 demonstration model are shown in Figure 13-1.
Generated Code
f14.c
f14.h
Template
Makefile
Timer
drt_time.c
Keyboard
drt_key.c
Interrupt
Support
drt_cpu.c
drt_cpu.h
drt_fpu.asm
Main Program
drt_watc.tmf
drt_main.c
Model
Execution
rt_sim.c
Makefile
f14.mk
Executable File
f14[.exe]
Integration
Module
ode5.c
Data Logger
rtwlog.c
Simulink
Data Structure
simstruc.h
Figure 13-1: Source Modules Used to Build the DOS Real-Time Program
13-4
Implementation Overview
This diagram illustrates the code modules that are used to build a DOS
real-time program.
To execute the code in real time, the program runs under the control of an
interrupt driven timing mechanism. The program installs its own interrupt
service routine (ISR) to execute the model code periodically at predefined
sample intervals. The PC-AT’s 8254 Programmable Interval Timer is used to
time these intervals.
In addition to the modules shown in Figure 13-1, the DOS run-time interface
also consists of device driver modules to read from and write to I/O devices
installed on the DOS target.
Figure 13-2 shows the recommended hardware setup for designing control
systems using Simulink, and then building them into DOS real-time
applications using the Real-Time Workshop. The figure shows a robotic arm
being controlled by a program (i.e., the controller) executing on the target PC.
The controller senses the arm position and applies inputs to the motors
accordingly, via the I/O devices on the target PC. The controller code executes
on the PC and communicates with the apparatus it controls via I/O hardware.
Host Workstation PC
Target PC
Running Windows 95/NT
with MATLAB, Simulink
and Real-Time Workshop
DOS
Executing
Real-time
Program
I/O Devices
A/D
D/A
Motor
Drive
Control
Position
Sensor
Output
Figure 13-2: Typical Hardware Setup
System Configuration
You can use the Real-Time Workshop with a variety of system configurations,
as long as these systems meet the following hardware and software
requirements.
13-5
13
Targeting DOS for Real-Time Applications
Hardware Requirements
The hardware needed to develop and run a real-time program includes:
• A workstation running Windows 95, Windows 98, or Windows NT and
capable of running MATLAB/Simulink. This workstation is the host where
the real-time program is built.
• A PC-AT (386 or later) running DOS. This system is the target, where the
real-time program executes.
• I/O boards, which include analog to digital converter and digital to analog
converters (collectively referred to as I/O devices), on the target.
• Electrical connections from the I/O devices to the apparatus you want to
control (or to use as inputs and outputs to the program in the case of
hardware-in-the-loop simulations).
Once built, you can run the executable on the target hardware as a stand-alone
program that is independent of Simulink.
Software Requirements
The development host must have the following software:
• MATLAB and Simulink to develop the model, and Real-Time Workshop to
create the code for the model. You also need the run-time interface modules
included with the Real-Time Workshop. These modules contain the code that
handles timing, interrupts, data logging, and background tasks.
• Watcom C/C++ compiler, Version 10.6 or 11.0. (see “A Note on the Watcom
Compiler” below.)
The target PC must have the following software:
• DOS4GW extender dos4gw.exe, included with your Watcom compiler
package) must be on the search path on the DOS-targeted PC.
You can compile the generated code (i.e., the files model.c, model.h, etc.) along
with user-written code using other compilers. However, the use of 16-bit
compilers is not recommended for any application.
A Note on the Watcom Compiler
As of this writing, the Watcom C compiler is no longer available from the
manufacturer. The Real-Time Workshop continues to ship Watcom-related
13-6
Implementation Overview
target configurations at this time. However, this policy may be subject to
change in the future.
Device Drivers
If your application needs to access its I/O devices on the target, then the
real-time program must contain device driver code to handle communication
with the I/O boards. The Real-Time Workshop DOS run-time interface includes
source code of the device drivers for the Keithley Metrabyte DAS-1600/1400
Series I/O boards. See “Device Driver Blocks” on page 13-10 for information on
how to use these blocks.
Simulink Host
The development host must have Windows 95, Windows 98, or Windows NT to
run Simulink. However, the real-time target requires only DOS, since the
executable built from the generated code is not a Windows application. The
real-time target will not run in a “DOS box” (i.e., a DOS window on Windows
95/98/NT).
Although it is possible to reboot the host PC under DOS for real-time execution,
the computer would need to be rebooted under Windows 95/NT for any
subsequent changes to the block diagram in Simulink. Since this process of
repeated rebooting the computer is inconvenient, we recommend a second PC
running only DOS as the real-time target.
Sample Rate Limits
Program timing is controlled by installing an interrupt service routine that
executes the model code. The target PC’s CPU is then interrupted at the
specified rate (this rate is determined from the step size).
The rate at which interrupts occur is controlled by application code supplied
with the Real-Time Workshop. This code uses the PC-AT’s 8254 Counter/Timer
to determine when to generate interrupts.
The code that sets up the 8254 Timer is in drt_time.c, which is in the
matlabroot\rtw\c\dos\rti directory. It is automatically linked in when you
build the program using the DOS real-time template makefile.
The 8254 Timer is a 16-bit counter that operates at a frequency of 1.193 MHz.
However, the timing module drt_time.c in the DOS run-time interface can
extend the range by an additional 16 bits in software, effectively yielding a
13-7
13
Targeting DOS for Real-Time Applications
32-bit counter. This means that the slowest base sample rate your model can
have is
6
1
3600
1.193 ×10 ÷ ( 2 32 – 1 ) ≈ ------------- Hz
This corresponds to a maximum base step size of approximately one hour.
The fastest sample rate you can define is determined by the minimum value
from which the counter can count down. This value is 3, hence the fastest
sample rate that the 8254 is capable of achieving is
1.193 × 10 6 ÷ 3 ≈ 4 × 10 5 Hz
This corresponds to a minimum base step size of
1 ÷ 4 × 10 5 ≈ 2.5 × 10 – 6 sec onds
However, note that the above number corresponds to the fastest rate at which
the timer can generate interrupts. It does not account for execution time for the
model code, which would substantially reduce the fastest sample rate possible
for the model to execute in real time. Execution speed is machine dependent
and varies with the type of processor and the clock rate of the processor on the
target PC.
The slowest and fastest rates computed above refer to the base sample times in
the model. In a model with more than one sample time, you can define blocks
that execute at slower rates as long as the sample times are an integer multiple
of the base sample time.
Modifying Program Timing
If you have access to an alternate timer (e.g., some I/O boards include their own
clock devices), you can replace the file drt_time.c with an equivalent file that
makes use of the separate clock source. See the comments in drt_time.c to
understand how the code works.
You can use your version of the timer module by redefining the TIMER_OBJS
macros with the build command. For example, in the Real-Time Workshop
page of the Simulation parameters dialog box, changing the build command
to
make_rtw TIMER_OBJS=my_timer.obj
13-8
Implementation Overview
replaces the file drt_time.c with my_timer.c in the list of source files used to
build the program.
13-9
13
Targeting DOS for Real-Time Applications
Device Driver Blocks
The real-time program communicates with external hardware via a set of
device drivers. These device drivers contain the necessary code for interfacing
to specific I/O devices.
The Real-Time Workshop includes device drivers for commercially available
Keithley Metrabyte DAS-1600/1400 Series I/O boards. These device drivers are
implemented as C MEX S-functions to interface with Simulink. This means
you can add them to your model like any other block.
In addition, each of these S-function device drivers has a corresponding target
file to inline the device driver in the model code. See “Creating Device Drivers”
on page 17-34 for information on implementing your own device drivers.
Since the device drivers are provided as source code, you can use these device
drivers as a template to serve a a starting point for creating custom device
drivers for other I/O boards.
Device Driver Block Library
The device driver blocks for the Keithley Metrabyte DAS-1600/1400 Series I/O
boards designed for use with DOS applications are contained in a block library
called doslib (matlabroot\toolbox\rtw\doslib.mdl). To display this library,
type
doslib
at the MATLAB prompt. This window will appear.
13-10
Device Driver Blocks
To access the device driver blocks, double-click on the sublibrary icon.
The blocks in the library contain device drivers that can be used for the
DAS-1600/1400 Series I/O boards. The DAS-1601/1602 boards have 16 analog
input (ADC) channels, two 12-bit analog output (DAC) channels and 4-bits of
digital I/O. The DAS-1401/1402 boards do not have DAC channels. The
DAS-1601/1401 boards have high programmable gains (1, 10, 100 and 500),
while the DAS-1602/1402 boards offer low programmable gains (1, 2, 4 and 8).
For more information, contact the manufacturer via the Web site:
http://www.keithley.com. The documentation for the DAS-1600/1400 Series
I/O boards is the DAS-1600/1400 Series User’s Guide, Revision B (Part
Number: 80940).
Configuring Device Driver Blocks
Each device driver block has a dialog box that you use to set configuration
parameters. As with all Simulink blocks, double-clicking on the block displays
the dialog box. Some of the device driver block parameters (such as Base I/O
Address) are hardware specific and are set either at the factory or configured
via DIP switches at the time of installation.
13-11
13
Targeting DOS for Real-Time Applications
Analog Input (ADC) Block Parameters
• Base I/O Address: The
beginning of the I/O address space
assigned to the board. The value
specified here must match the
board’s configuration. Note that
this parameter is a hexadecimal
number and must be entered in
the dialog as a MATLAB string
(e.g., '0x300').
• Analog Input Range: This
two-element vector specifies the
range of values supported by the
ADC. The specified range must
match the
I/O board’s settings. Specifically,
the DAS-1600/1400 Series boards
switches can be configured to
either [0 10] for unipolar or [-10
10] for bipolar input signals.
• Hardware Gain: This parameter specifies the programmable gain that is
applied to the input signal before presenting it to the ADC. Specifically, the
DAS-1601/1401 boards have programmable gains of 1, 10, 100, and 500. The
DAS-1602/1402 boards have programmable gains of 1, 2, 4, and 8. Configure
the Analog Input Range and the Hardware Gain parameters depending on
the type and range of the input signal being measured. For example, a
DAS-1601 board in bipolar configuration with a programmable gain of 100 is
best suited to measure input signals in the range between [±10v] ÷ 100 =
±0.1v.
Voltage levels beyond this range will saturate the block output form the ADC
block. Please adhere to manufacturers’ electrical specifications to avoid
damage to the board.
• Number of Channels: The number of analog input channels enabled on the
I/O board. The DAS-1600/1400 Series boards offer up to 16 ADC channels
when configured in unipolar mode (8 ADC channels if you select differential
mode). The output port width of the ADC block is equal to the number of
channels enabled.
13-12
Device Driver Blocks
• Sample Time (sec): Device drivers are discrete blocks that require you to
specify a sample time. In the generated code, these blocks are executed at the
specified rate. Specifically, when the ADC block is executed, it causes the
ADC to perform a single conversion on the enabled channels, and the
converted values are written to the block output vector.
Analog Output (DAC) Block Parameters
• Base I/O Address: The
beginning of the I/O address
space assigned to the board. The
value specified here must match
the board’s configuration. Note
that this parameter is a
hexadecimal number and must be
entered in the dialog as a
MATLAB string (e.g., '0x300').
• Analog Output Range: This
parameter specifies the output
range settings of the DAC section
of the I/O board. Typically,
unipolar ranges are between
[0 10] volts and bipolar ranges
are between [-10 10] volts. Refer
to the DAS-1600 documentation
for other supported output
ranges.
• Initial Output(s): This
parameter can be specified either
as a scalar or as an N element vector, where N is the number of channels. If
a single scalar value is entered, the same scalar is applied to output. The
specified initial output(s) is written to the DAC channels in the
mdlInitializeConditions function.
• Final Output(s): This parameter is specified in a manner similar to the
Initial Output(s) parameter except that the specified final output values are
written out to the DAC channels in the mdlTerminate function. Once the
generated code completes execution, the code sets the final output values
prior to terminating execution.
13-13
13
Targeting DOS for Real-Time Applications
• Number of Channels: Number of DAC channels enabled. The DAS-1600
Series I/O boards have two 12-bit DAC channels. The DAS-1400 Series I/O
boards do not have any DAC channels. The input port width of this block is
equal to the number of channels enabled.
• Sample Time (sec): DAC device drivers are discrete blocks that require you
to specify a sample time. In the generated code, these blocks are executed at
the specified rate. Specifically, when the DAC block is executed, it causes the
DAC to convert a single value on each of the enabled DAC channels, which
produces a corresponding voltage on the DAC output pin(s).
Digital Input Block Parameters
• Base I/O Address: The beginning
of the I/O address space assigned
to the board. The value specified
here must match the board’s
configuration. Note that this
parameter is a hexadecimal
number and must be entered in
the dialog as a MATLAB string
(e.g., '0x300').
• Number of Channels: This
parameter specifies the number of
1-bit digital input channels being
enabled. This parameter also
determines the output port width
of the block in Simulink.
Specifically, the DAS-1600/1400 Series boards provide four bits (i.e.,
channels) for digital I/O.
• Sample Time (sec): Digital input device drivers are discrete blocks that
require you to specify a sample time. In the generated code, these blocks are
executed at the specified rate. Specifically, when the digital input block is
executed, it reads a boolean value from the enabled digital input channels.
The corresponding input values are written to the block output vector.
13-14
Device Driver Blocks
Digital Output Block Parameters
• Base I/O Address: The beginning
of the I/O address space assigned
to the board. The value specified
here must match the board’s
configuration. Note that this
parameter is a hexadecimal
number and must be entered in
the dialog as a MATLAB string
(e.g., '0x300').
• Low/High Threshold Values:
This parameter specifies the
threshold levels, [lo hi], for
converting the block inputs into
0/1 digital values. The signal in
the block diagram connected to
the block input should rise above
the high threshold level for a
0 to 1 transition in the
corresponding digital output
channel on the I/O board.
Similarly, the input should fall
below the low threshold level for a 1 to 0 transition.
• Initial Output(s): Same as the Analog Output block, except the specified
values are converted to 0 or 1 based on the lower threshold value before they
are written to the corresponding digital output channel.
• Final Output(s): Same as the Analog Output block, except the specified
values are converted to 0 or 1 based on the lower threshold value before they
are written to the corresponding digital output channel on the I/O board.
• Number of Channels: This parameter specifies the number of 1-bit digital
I/O channels being enabled. This parameter also determines the output port
width of the block. Specifically, the DAS-1600/1400 Series boards provide
four bits (i.e., channels) for digital I/O.
• Sample Time (sec): Digital output device drivers are discrete blocks that
require you to specify a sample time. In the generated code, these blocks are
executed at the specified rate. Specifically, when the digital output block is
13-15
13
Targeting DOS for Real-Time Applications
executed, it causes corresponding boolean values to be output from the
board’s digital I/O channels.
Adding Device Driver Blocks to the Model
Add device driver blocks to the Simulink block diagram as you would any other
block — simply drag the block from the block library and insert it into the
model. Connect the ADC or Digital Input block to the model’s inputs and
connect the DAC or Digital Output block to the model’s outputs.
Including Device Driver Code
Device driver blocks are implemented as S-functions written in C. The C code
for a device driver block is compiled as a MEX-file so that it can be called by
Simulink. See the MATLAB Application Program Interface Guide for
information on MEX-files.
The same C code can also be compiled and linked to the generated code just like
any other C-coded, S-function. However, by using the target (.tlc) file that
corresponds to each of the C file S-functions, the device driver code is inlined in
the generated code.
The matlabroot\rtw\c\dos\devices directory contains the MEX-files, C files,
and target files (.tlc) for the device driver blocks included in doslib. This
directory is automatically added to your MATLAB path when you include any
of the blocks from doslib in your model.
13-16
Building the Program
Building the Program
Once you have created your Simulink model and added the appropriate device
driver blocks, you are ready to build a DOS target application. To do this, select
the Real-Time Workshop page of the Simulink parameters dialog box, and
select Target configuration from the Category menu.
Click Browse to open the System Target File Browser. Select drt.tlc; this
automatically fills in the correct files as shown above:
• drt.tlc as the System target file
• drt_watc.tmf as the Template makefile. This is used with the Watcom
compiler, assembler, linker, and WMAKE utility.
• make_rtw as the Make command
You can specify Target Language Compiler options in the System target file
field following drt.tlc. You can also specify and make options in the Make
command field. See Chapter 3, “Code Generation and the Build Process” for
descriptions of the available Target Language Compiler and make options.
The DOS system target file, drt.tlc, and the template makefile,
drt_watc.tmf, are located in the matlab\rtw\c\dos directory.
The template makefile assumes that the Watcom C/386 compiler, assembler,
and linker have been correctly installed on the host workstation. You can verify
13-17
13
Targeting DOS for Real-Time Applications
this by checking the environment variable, WATCOM, which correctly points to
the directory where the Watcom files are installed.
The program builder invokes the Watcom wmake utility on the generated
makefile, so the directory where wmake is installed must be on your path.
Running the Program
The result of the build process is a DOS 32-bit protected-mode executable. The
default name of the executable is model.exe, where model is the name of your
Simulink model. You must run this executable in DOS; you cannot run the
executable in Windows 95/98/NT.
13-18
14
Custom Code Blocks
Introduction . . . . . . . . . . . . . . . . . . . . 14-2
Custom Code Library . . . . . . . . . . . . . . . . 14-5
Model Code Sublibrary . . . . . . . . . . . . . . . . 14-5
Subsystem Code Sublibrary . . . . . . . . . . . . . . 14-9
14
Custom Code Blocks
Introduction
This chapter discusses the Custom Code library, a collection of blocks that
allow you to insert custom code into the generated source code files and/or
functions associated with your model.
The Custom Code library is part of the Real-Time Workshop library. You can
access the Real-Time Workshop library via the Simulink Library Browser as
shown in Figure 14-1. Alternatively, you can access the Real-Time Workshop
library by typing the command
rtwlib
at the MATLAB command prompt.
14-2
Figure 14-1: Custom Code Library and its Sublibraries
This chapter discusses only the C Custom Code library and its sublibraries.
Note that, depending on which MathWorks products you have installed, your
browser may show a different collection of libraries.
There are four other sublibraries in the Real-Time Workshop library:
• DOS Device Drivers — Blocks for use with DOS. See Chapter 13, “Targeting
DOS for Real-Time Applications” for information.
14-3
14
Custom Code Blocks
• Interrupt Templates — A collection of blocks that you can use as templates
for building your own asynchronous interrupts. See Chapter 15,
“Asynchronous Support” for information.
• S-Function Target — The S-Function Target sublibrary contains only one
block type, the Real-Time Workshop S-Function block. This block is intended
for use with generated S-functions. See Chapter 10, “The S-Function Target”
for more information.
• VxWorks Support — A collection of blocks that support VxWorks (Tornado).
See Chapter 12, “Targeting Tornado for Real-Time Applications” for
information on VxWorks.
14-4
Custom Code Library
Custom Code Library
The Custom Code library contains blocks that allow you to place your own code,
in C or in Ada, inside the code generated by the Real-Time Workshop.
Figure 14-1 illustrates the hierarchy of sublibraries under the Real-Time
Workshop library. First, the Custom Code library has two sublibraries:
• C Custom Code
• Ada Custom Code
Both the C Custom Code and Ada Custom Code libraries, in turn, have
identically named sublibraries:
• Model Code
• Subsystem Code
Both sublibraries contain blocks that target specific files and subsystems
within which you can place your code.
The following sections discuss the Model Code and Subsystem Code
sublibraries of the C Custom Code library.
Model Code Sublibrary
The Model Code sublibrary contains 10 blocks that insert custom code into the
generated model files and functions. You can view the blocks either by:
• Expanding the Model Code sublibrary (under C Custom Code) in the
Simulink Library Browser
• Right-clicking on the Model Code sublibrary icon in the right pane of the
Simulink Library Browser
14-5
14
Custom Code Blocks
The latter method opens this window.
The four blocks on the top row contain texts fields to insert custom code at the
top and bottom of the following files:
• model.h — Header File block
• model_prm.h — Parameter File block
• model.c — Source File block
• model_reg.h — Registration File block
The six function blocks in the second and third rows contain text fields to insert
critical code sections at the top and bottom of these designated model functions:
• Registration function — Registration Function block
• MdlStart — MdlStart Function block
• MdlTerminate — MdlTerminate Function block
• MdlOutputs — MdlOutputs Function block
• MdlUpdate — MdlUpdate Function block
• MdlDerivatives — MdlDerivatives Function block
Each block provides a dialog box that contains three fields.
14-6
Custom Code Library
Example: Using a Custom Code Block
The following example uses an MdlStart Function block to introduce code into
the MdlStart function. The diagram below shows a simple model with the
Model Start Function block inserted.
14-7
14
Custom Code Blocks
Double-clicking the Model Start Function block opens the Model Start
Function Custom Code dialog box.
The Real-Time Workshop inserts the
code entered here into the MdlStart
function in the generated code.
You can insert custom code into any or all of the available text fields.
14-8
Custom Code Library
The code below is the MdlStart function for this example (mymodel).
void MdlStart(void)
{
/* user code (Start function Header) */
/* System: <Root> */
unsigned int *ptr = 0xFFEE;
/* user code (Start function Body) */
/* System: <Root> */
/* Initialize hardware */
*ptr = 0;
/* state initialization */
/* DiscreteFilter Block: <Root>/Discrete Filter */
rtX.d.Discrete_Filter = 0.0;
}
The custom code entered in the Model Start Function Custom Code dialog
box is embedded directly in the generated code. Note that each block of custom
code is tagged with a comment such as
/* user code (Start function Header) */
Subsystem Code Sublibrary
The Subsystem Code sublibrary contains eight blocks to insert critical code
sections into system functions.
14-9
14
Custom Code Blocks
Each of these blocks has a dialog box containing two text fields that allow you
to place data at the top and the bottom of system functions. The eight blocks
are:
• Subsystem Start
• Subsystem Initialize
• Subsystem Terminate
• Subsystem Enable
• Subsystem Disable
• Subsystem Outputs
• Subsystem Update
• Subsystem Derivatives
The location of the block in your model determines the location of the custom
code. In other words, the code is local to the subsystem that you select. For
example, the Subsystem Outputs block places code in mdlOutputs when the
code block resides in the root model. If the Subsystem 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
3 Update entry
4 Update exit code
14-10
15
Asynchronous Support
Introduction . . . . . . . . . . . . . . . . . . . . 15-2
Interrupt Handling . . . .
Asynchronous Interrupt Block
Task Synchronization Block .
Asynchronous Buffer Block .
Rate Transition Block . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Creating a Customized Asynchronous Library
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 15-5
. 15-5
15-12
15-16
15-18
. . . 15-20
15
Asynchronous Support
Introduction
The Interrupt Templates are blocks that you can use as templates for building
your own asynchronous interrupts.
The Interrupt Templates library is part of the Real-Time Workshop library.
You can access the Real-Time Workshop library via the Simulink Library
Browser as shown in Figure 15-1. Alternatively, you can access the Real-Time
Workshop library by typing the command
rtwlib
at the MATLAB command prompt.
15-2
Figure 15-1: Interrupt Templates in Simulink Library Browser
Note that, depending on which MathWorks products you have installed, your
browser may show a different collection of libraries.
15-3
15
Asynchronous Support
Other sublibraries in the Real-Time Workshop library are:
• DOS Device Drivers: Blocks for use with DOS. See Chapter 13, “Targeting
DOS for Real-Time Applications” for information.
• Custom Code Blocks: Blocks that allow you to insert custom code into the
generated source code files and/or functions associated with your model. See
Chapter 14, “Custom Code Blocks.” for information.
• S-Function Target: The S-Function Target sublibrary contains only one
block type, the RTW S-Function block. This block is intended for use with
generated S-functions. See Chapter 10, “The S-Function Target” for more
information.
• VxWorks Support: A collection of blocks that support VxWorks (Tornado).
See Chapter 12, “Targeting Tornado for Real-Time Applications” for
information on VxWorks.
15-4
Interrupt Handling
Interrupt Handling
The blocks in the Interrupt Templates library allow you to model synchronous/
asynchronous event handling, including interrupt service routines (ISRs).
These blocks include:
• Asynchronous Buffer block (read)
• Asynchronous Buffer block (write)
• Asynchronous Interrupt block
• Asynchronous Rate Transition block
• Task Synchronization block
Using these blocks, you can create models that handle asynchronous events,
such as hardware generated interrupts and asynchronous read and write
operations. The following sections discuss each of these blocks in the context of
VxWorks Tornado operating system.
Asynchronous Interrupt Block
Interrupt service routines (ISR) are realized by connecting the outputs of the
VxWorks Asynchronous Interrupt block to the control input of a function-call
subsystem, the input of a VxWorks Task Synchronization block, or the input to
a Stateflow chart configured for a function-call input event.
The Asynchronous Interrupt block installs the downstream (destination)
function-call subsystem as an ISR and enables the specified interrupt level.
The current implementation of the VxWorks Asynchronous Interrupt block
supports VME interrupts 1-7 and uses the VxWorks system calls
sysIntEnable, sysIntDisable, intConnect, intLock and intUnlock. Ensure
that your target architecture (BSP) for VxWorks supports these functions.
When a function-call subsystem is connected to an Asynchronous Interrupt
block output, the generated code for that subsystem becomes the ISR. For large
subsystems, this can have a large 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. To do this, you should only connect
function-call subsystems that contain few blocks.
A better solution for large systems is to use the Task Synchronization block to
synchronize the execution of the function-call subsystem to an event. The Task
Synchronization block is placed between the Asynchronous Interrupt block and
15-5
15
Asynchronous Support
the function-call subsystem (or Stateflow chart). The Asynchronous Interrupt
block then installs the Task Synchronization block as the ISR, which releases
a synchronization semaphore (performs a semGive) to the function-call
subsystem and then returns. See the VxWorks Task Synchronization block for
more information.
Using the Asynchronous Interrupt Block
The Asynchronous Interrupt block has two modes that help support rapid
prototyping:
• RTW mode. In RTW mode, the Asynchronous Interrupt block configures the
downstream system as an ISR and enables interrupts during model startup.
You can select this mode using the Asynchronous Interrupt block dialog box
when generating code.
• Simulation mode. In Simulation mode, simulated Interrupt Request (IRQ)
signals are routed through the Asynchronous Interrupt block’s trigger port.
Upon receiving a simulated interrupt, the block calls the associated system.
You should select this mode when simulating, in Simulink, the effects of an
interrupt signal. Note that there can only be one VxWorks Asynchronous
Interrupt block in a model and all desired interrupts should be configured by
it.
In both RTW and Simulation mode, in the event that two IRQ signals occur
simultaneously, the Asynchronous Interrupt block executes the downstream
systems according to their priority interrupt level.
The Asynchronous Interrupt block provides these two modes to make the
development and implementation of real-time systems that include ISRs easier
and quicker. You can develop two models, one that includes a plant and a
controller for simulation, and one that only includes the controller for code
generation.
Using the Library feature of Simulink, you can implement changes to both
models simultaneously. Figure 15-1 illustrates how changes made to the plant
or controller, both of which are in a library, propagate to the models.
15-6
Interrupt Handling
Plant
Controller
Library: Changes made here
affect both models.
Plant
Interrupt
Block
(Simulation
mode)
Interrupt
Block
Real-Time Workshop library
Interrupt
Block
(RTW mode)
Model
(for simulation)
Controller
Model
(for code generation)
Controller
Figure 15-1: Using the Asynchronous Interrupt Block with Simulink Library Feature
in Rapid Prototyping Process
Real-Time Workshop models normally run from a periodic interrupt. All blocks
in a model run at their desired rate by executing them in multiples of the timer
interrupt rate. Asynchronous blocks, on the other hand, execute based on other
interrupt(s) that may or may not be periodic.
The hardware that generates the interrupt is not configured by the
Asynchronous Interrupt block. Typically, the interrupt source is a VME I/O
board, which generates interrupts for specific events (e.g., 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 Asynchronous Interrupt block dialog to the level and vector
setup on the I/O board.
15-7
15
Asynchronous Support
Asynchronous Interrupt Block Parameters
The picture below shows the VxWorks Asynchronous Interrupt block dialog
box.
Parameters associated with the Asynchronous Interrupt block are:
• Mode: In Simulation mode, the ISRs are executed nonpreemptively. If they
occur simultaneously, signals are executed in the order specified by their
number (1 being the highest priority). Interrupt mapping during simulation
is left to right, top to bottom. That is, the first control input signal maps to
the topmost ISR. The last control input signal maps to the bottom most ISR.
In RTW mode, the Real-Time Workshop uses vxinterrupt.tlc to realize
asynchronous interrupts in the generated code. The ISR is passed one
argument, the root SimStruct, and the Simulink definition of the
function-call subsystem is remapped to conform with the information in the
SimStruct.
• VME Interrupt Number(s): Specify the VME interrupt numbers for the
interrupts to be installed. The valid range is 1-7; for example: [4 2 5]).
• VME Interrupt Vector Offset Number(s): The Real-Time Workshop uses this
number in the call to intConnect(INUM_TO_IVEC(#),...). You should
specify a unique vector offset number for each interrupt number.
• Preemption Flag(s): By default, higher priority interrupts can preempt lower
priority interrupts in VxWorks. If desired, you can lock out interrupts during
15-8
Interrupt Handling
the execution of a ISR by setting the preemption flag to 0. This causes
intLock() and intUnlock() calls to be inserted at the beginning and end of
the ISR respectively. This should be used carefully since it increases the
system’s interrupt response time for all interrupts at the
intLockLevelSet() level and below.
• IRQ Direction: In simulation mode, a scalar IRQ direction is applied to all
control inputs, and is specified as 1 (rising), -1 (falling), or 0 (either).
Configuring inputs separately in simulation is done prior to the control
input. For example, a Gain block set to -1 prior to a specific IRQ input will
change the behavior of one control input relative to another. In RTW mode
the IRQ direction parameter is ignored.
Asynchronous Interrupt Block Example - Simulation Mode
This example shows how the Asynchronous Interrupt block works in
simulation mode.
Simulated Interrupt Signals
15-9
15
Asynchronous Support
The Asynchronous Interrupt block works as a “handler” that routes signals and
sets priority. If two interrupts occur simultaneously, the rule for handling
which signal is sent to which port is left to right and top to bottom. This means
that IRQ2 receives the signal from Plant 1 and IRQ1 receives the signal from
Plant 2 simultaneously. IRQ1 still has priority over IRQ2 in this situation.
Note that the Asynchronous Interrupt block executes during simulation by
processing incoming signals and executing downstream functions. Also,
interrupt preemption cannot be simulated.
Asynchronous Interrupt Block Example - RTW Mode
This example shows the Asynchronous Interrupt block in RTW mode.
(Note that Plant is removed.)
Stand-alone functions are
installed as ISR’s.
Interrupt Vector Table
Offset
192
&f()
In this example, the simulated plant signals that were included in the previous
example have been removed. In RTW mode, the Asynchronous Interrupt block
receives interrupts directly from the hardware.
During the Target Language Compiler phase of code generation, the
Asynchronous Interrupt block installs the code in the Stateflow chart and the
Subsystem block as interrupt service routines. Configuring a function-call
subsystem as an ISR requires two function calls, int_connect and int_enable.
For example, the function f(u) in the Function block requires that the
Asynchronous Interrupt block inserts a call to int_connect and sysIntEnable
in the mdlStart function, as shown below.
15-10
Interrupt Handling
/* model start function */
MdlStart()
{
. . .
int_connect(f,192,1);
. . .
sysIntEnable(1);
. . .
}
Locking and Unlocking ISRs. It is possible to lock ISRs so that they are not
preempted by a higher priority interrupt. Configuring the interrupt as
nonpreemptive has this effect. The following code fragment shows where the
Real-Time Workshop places the int_lock and int_unlock functions to
configure the interrupt as nonpreemptive.
f()
{
lock = int_lock();
. . .
. . .
. . .
int_unlock(lock);
Real-Time Workshop code
}
Finally, the model’s terminate function disables the interrupt:
/* model terminate function */
MdlTerminate()
{
...
int_disable(1);
...
}
15-11
15
Asynchronous Support
Task Synchronization Block
The VxWorks Task Synchronization block is a function-call subsystem that
spawns, as an independent VxWorks task, the function-call subsystem
connected to its output. Typically it would be placed between the VxWorks
Asynchronous Interrupt block and a function-call subsystem block or a
Stateflow chart. Another example would be to place the Task Synchronization
block at the output of a Stateflow diagram that has an Event, “Output to
Simulink,” configured as a function-call.
The VxWorks Task Synchronization block performs the following functions:
• The downstream function-call subsystem is spawned as an independent task
using the VxWorks system call taskSpawn(). The task is deleted using
taskDelete() during model termination.
• A semaphore is created to synchronize the downstream system to the
execution of the Task Synchronization block.
• Code is added to this spawned function-call subsystem to wrap it in an
infinite while loop.
• Code is added to the top of the infinite while loop of the spawned task to wait
on a the semaphore, using semTake(). When semTake() is first called,
NO_WAIT is specified. This allows the task to determine if a second semGive()
has occurred prior to the completion of the function-call subsystem. This
would indicate the interrupt rate is too fast or the task priority is too low.
• Synchronization code, i.e., semgive(), is generated for the Task
Synchronization block (a masked function-call subsystem). This allows the
output function-call subsystem to run. As an example, if you connect the
Task Synchronization block to the output of a VxWorks Asynchronous
Interrupt block, only a semGive() would occur inside an ISR.
15-12
Interrupt Handling
Task Synchronization Parameters
The picture below shows the VxWorks Task Synchronization block dialog box.
Parameters associated with the Task Synchronization block are:
• Task Name — An optional name, which if provided, is used as the first
argument to the taskSpawn() system call. This name is used by VxWorks
routines to identify the task they are called from to aid in debugging.
• Task Priority — The task priority is the VxWorks priority that the
function-call subsystem task is given when it is spawned. The priority can be
a very important consideration in relation to other tasks priorities in the
VxWorks system. In particular, the default priority of the model code is 30
and, when multitasking is enabled, the priority of the each subrate task
increases by one from the default model base rate. Other task priorities in
the system should also be considered when choosing a task priority.
VxWorks priorities range from 0 to 255 where a lower number is a higher
priority.
• Stack Size — The function-call subsystem is spawned with the stack size
specified. This is maximum size to which the task’s stack can grow. The value
should be chosen based on the number of local variables in the task.
By default, Real-Time Workshop limits the number of bytes for local
variables in all of the generated code to 8192 bytes (see assignment of
MaxStackSize in
matlabroot/rtw/c/tornado/tornado.tlc). As a rule, providing twice 8192
bytes (16384) for the one function that is being spawned as a task should be
sufficient.
15-13
15
Asynchronous Support
Task Synchronization Block Example
This example shows a Task Synchronization block as a simple ISR.
The Task Synchronization block inserts this code during the Target Language
Compiler phase of code generation:
• In MdlStart, the Task Synchronization block is registered by the
Asynchronous Interrupt block as an ISR. The Task Synchronization block
creates and initializes the synchronization semaphore. It also spawns the
function-call subsystem as an independent task.
/* Create and spawn task: <Root>/Faster Rate(.015) */
if ((*(SEM_ID *)rtPWork.s6_S_Function.SemID =
semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == NULL)
ssSetErrorStatus(rtS,"semBCreate call failed "
"for block <Root>/Faster Rate(.015).\n ");
}
if ((rtIWork.s6_S_Function.TaskID = taskSpawn("root_Faster_", 20, VX_FP_TASK,
1024, (FUNCPTR)Sys_root_Faster__OutputUpdate,
(int_T)rtS, 0, 0, 0, 0, 0, 0, 0, 0, 0)) == ERROR) {
ssSetErrorStatus(rtS,"taskSpawn call failed for block <Root>/ Faster Rate "
"(.015).\n");
}
• The Task Synchronization block modifies the downstream function-call
subsystem by wrapping it inside an infinite loop and adding semaphore
synchronization code.
/* Output and update for function-call system: <Root>/Faster
Rate(.015) */
void Sys_root_Faster__OutputUpdate(void *reserved, int_T
controlPortIdx, int_T tid)
{
/* Wait for semaphore to be released by system: <Root>/Task Synchronization */
for(;;) {
if (semTake(*(SEM_ID *)rtPWork.s6_S_Function.SemID,NO_WAIT) != ERROR) {
logMsg("Rate for function-call subsystem"
"Sys_root_Faster__OutputUpdate() fast.\n",0,0,0,0,0,0);
#if STOPONOVERRUN
15-14
Interrupt Handling
logMsg("Aborting real-time simulation.\n",0,0,0,0,0,0);
semGive(stopSem);
return(ERROR);
#endif
} else {
semTake(*(SEM_ID *)rtPWork.s6_S_Function.SemID, WAIT_FOREVER);
}
/* UniformRandomNumber Block: <S3>/Uniform Random Number */
rtB.s3_Uniform_Random_Number =
rtRWork.s3_Uniform_Random_Number.NextOutput;
.
.
.
}
15-15
15
Asynchronous Support
Asynchronous Buffer Block
The VxWorks Asynchronous Buffer blocks are meant to be used to interface
signals to asynchronous function-call subsystems in a model. This is needed
whenever a function-call subsystem has input or output signals and its control
input ultimately connects (sources) to the VxWorks Asynchronous Interrupt
block or Task Synchronization block.
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 it. The issue is that signals passed to and/or from
the function-call subsystem can be in the process of being written or read when
the preemption occurs. Thus, partial old and partial new data will be 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 may require two
assembly instructions.
The Asynchronous Buffer blocks can be used to guarantee the data passed to
and/or from the function-call subsystem is all from the same iteration.
The Asynchronous Buffer blocks are used in pairs, with a write side driving the
read side. To ensure the data integrity, no other connections are allowed
between the two Asynchronous Buffer blocks. The pair works by using two
buffers (“double buffering”) to pass the signal and, by using mutually exclusive
control, allow only exclusive access to each buffer. For example, if the write side
is currently writing into one buffer, the read side can only read from the other
buffer.
The initial buffer is filled with zeros so that if the read side executes before the
write side has had time to fill the other buffer, the read side will collect zeros
from the initial buffer.
15-16
Interrupt Handling
Asynchronous Buffer Block Parameters
There are two kinds of Asynchronous Buffer blocks, a reader and a writer. The
picture below shows the Asynchronous Buffer block’s dialog boxes.
Both blocks require the Sample Time parameter. The sample time should be
set to -1 inside a function call and to the desired time otherwise.
Asynchronous Buffer Block Example
This example shows how you might use the Asynchronous Buffer block to
control the data flow in an interrupt service routine.
15-17
15
Asynchronous Support
The ISR0 subsystem block, which is configured as a function-call subsystem,
contains another set of Asynchronous Buffer blocks.
Rate Transition Block
The VxWorks Rate Transition block provides a sample time for blocks
connected to an asynchronous function-call subsystem when double buffering
is not required. There are two options for connecting I/O to an asynchronous
function-call subsystem:
• Use the Rate Transition block, or some other block that requires a sample
time to be set, at the input or output of the asynchronous function-call
subsystem. This will cause blocks up- or downstream from it, which would
otherwise inherit from the function-call subsystem, to use the sample time
specified. Note that if the signal width is greater than 1, data consistency is
not guaranteed, which may or may not an issue. See next option.
The Rate Transition block does not introduce any system delay. It only
specifies the sample time of the downstream blocks. It also informs Simlink
to allow a non-buffered asynchronous connection. This block is typically used
for scalar signals that do not require double buffering.
• Use the Asynchronous Buffer block pair. This not only will set the sample
time of the blocks up or downstream that would otherwise inherit from the
function-call subsystem, and also guarantees consistency of the data on the
signal. See the Asynchronous Buffer block for more information on data
consistency.
15-18
Interrupt Handling
Rate Transition Block Parameters
This picture shows the VxWorks Rate Transition block’s dialog box.
The Sample time parameter sets the sample time to the desired rate.
Rate Transition Block Example
This picture shows a sample application of the Rate Transition block in an ISR.
In this example, the Rate Transition block on the input to the function-call
subsystem causes both the In and Gain1 blocks to run at the 0.1 second rate.
The Rate Transition block on the output of the function-call subsystem causes
both the Gain2 and Out blocks to run at the 0.2 second rate. Using this scheme
informs Simlink to allow non-buffered connections to an asynchronous
function-call subsystem.
15-19
15
Asynchronous Support
Creating a Customized Asynchronous Library
You can use the Real-Time Workshop’s VxWorks asynchronous blocks as
templates that provide a starting point for creating your own asynchronous
blocks. Templates are provided for these blocks:
• Asynchronous Buffer block
• Asynchronous Interrupt block
• Rate Transition block
• Task Synchronization block
You can customize each of these blocks by implementing a set of modifications
to files associated with each template. These files are:
• The block’s underlying S-function C MEX-file
• The block’s mask and the associated mask M-file
• The TLC files that control code generation of the block
At a minimum, you must rename the system calls generated by the TLC files
to the correct names for the new real-time operating system (RTOS) and supply
the correct arguments for each file. There is a collection of files that you must
copy (and rename) from matlabroot/rtw/c/tornado/devices into a new
directory, for example, matlabroot/rtw/c/my_os/devices. These files are:
• Asynchronous Buffer block — vxdbuffer.tlc, vxdbuffer.c
• Asynchronous Interrupt block — vxinterrupt.tlc, vxinterrupt.c,
vxintbuild.m
• O/S include file — vxlib.tlc
• Task Synchronization block — vxtask.tlc, vxtask.c
15-20
16
Real-Time Workshop Ada
Coder
Introduction . . . . . . . . . . . . . . . . . . . . 16-2
Getting Started . . . . . . . . . . . . . . . . . . . 16-6
Configuring and Interfacing Parameters and Signals
. 16-16
Code Validation . . . . . . . . . . . . . . . . . . 16-18
Supported Blocks . . . . . . . . . . . . . . . . . 16-21
16
Real-Time Workshop Ada Coder
Introduction
This chapter presents an introduction to the Real-Time Workshop Ada Coder.
It compares and contrasts the Real-Time Workshop Ada Coder with the
Real-Time Workshop, shows you how to use the product by presenting an
example, and concludes with a discussion of code validation.
Note The Real-Time Workshop Ada Coder is a separate product from the
Real-Time Workshop.
Like the Real-Time Workshop, the Real-Time Workshop Ada Coder provides a
real-time development environment that features:
• A rapid and direct path from system design to hardware implementation
• Seamless integration with MATLAB and Simulink
• A simple, easy-to-use interface
• An open and extensible architecture
The package includes application modules that allow you to build complete
programs targeting a wide variety of environments. Program building is fully
automated. Automatic program building provides a standard means to create
programs for real-time applications. This chapter contains examples of
automatic program building on DOS and UNIX platforms.
The Real-Time Workshop Ada Coder is an automatic Ada language code
generator. It produces Ada83 or Ada95 code directly from Simulink models and
automatically builds programs that can be run in real time in a variety of
environments. The Real-Time Workshop Ada Coder is an extension of the
Real-Time Workshop.
With the Real-Time Workshop Ada Coder, you can run your Simulink model in
real time on a remote processor. You can run accelerated, stand-alone
simulations on your host machine or on an external computer.
16-2
Real-Time Workshop Ada Coder Applications
Like the Real-Time Workshop, the Real-Time Workshop Ada Coder supports a
variety of real-time applications:
• Real-Time Control — You can design your control system using MATLAB
and Simulink and generate Ada code from your block diagram model. You
can then compile and download the Ada code directly to your target
hardware.
• Hardware-in-the-Loop Simulation — You can use Simulink to model real-life
measurement and actuation signals. You can use the code generated from
the model on special-purpose hardware to provide a real-time representation
of the physical system. Applications include control system validation,
training simulation, and fatigue testing using simulated load variations.
Supported Compilers
The generated code will work with any validated Ada83 or Ada95 compiler.
Real-Time Workshop provides an example target that uses the GNAT Ada95
compiler. You can download a free version of this compiler from the GNAT ftp
site (ftp://cs.nyu.edu/pub/gnat). You can also purchase a professional
version from Ada Core Technologies (www.gnat.com).
Supported Targets
The Real-Time Workshop Ada Coder supports the following targets:
• Ada Simulation Target — Useful for validating generated code. This does not
use Ada tasking primitives.
• Ada Multitasking Real-Time Target — Useful as a starting point for
targeting real-time systems. This uses Ada tasking primitives.
• Ada83 target — The generated Ada83 code does not support data logging,
but is suitable for generating embedded code for use with legacy Ada83
compilers. The Ada83 target is available from the System Target File
Browser by selecting the system target file rt_ada83.tlc (Ada83 Target for
GNAT). The accompanying template makefile gnat83.tmf uses the -gnat83
switch in the GNAT Ada95 compiler.
16-3
16
Real-Time Workshop Ada Coder
You can also add your own target by creating a system target file, make
process, and run-time interface files along with any device drivers using
inlined Ada or C S-functions.
The Generated Code
The generated code (i.e., the model code) is highly optimized, fully commented,
and can be generated from any discrete-time Simulink model — linear or
nonlinear.
All Simulink blocks are automatically converted to code, with the exception of:
• MATLAB function blocks
• Any continuous sample time blocks
• S-functions that are not inlined using the Target Language Compiler
Types of Output
The Real-Time Workshop Ada Coder’s interface supports two forms of output:
• Ada code − Generate code that contains system equations and initialization
functions for the Simulink model. You can use this code in real-time
applications.
• A real-time program − Transform the generated code into a real-time
program suitable for use with dedicated real-time hardware. The resulting
code is designed to interface with an external clock source and hence runs at
a fixed, user-specified sample rate.
Supported Blocks
See “Supported Blocks” on page 16–21 for a complete list of the Simulink blocks
supported by the Real-Time Workshop Ada Coder.
Restrictions
The Real-Time Workshop Ada Coder has the same constraints imposed upon it
as the Real-Time Workshop Embedded Coder target. The code generator does
not produce code that solves algebraic loops, and Simulink blocks that are
dependent on absolute time can be used only if the program is not intended to
run for an indefinite period of time.
16-4
There are additional constraints for the Ada code generation. The Real-Time
Workshop Ada Coder does not provide:
• Nonreal-time variable step integration models
• Continuous-time integration
• Since Ada does not support implicit upcasting of data types, all numerical
operations in your model must be of homogeneous data types for Ada code
generation. You can, however, perform explicit upcasting using the Data
Type Conversion block in Simulink.
• You must inline all Ada S-functions with a corresponding TLC file (see the
Target Language Compiler Reference Guide for more information about
inlining S-functions)
• External mode is not supported with the Real-Time Workshop Ada Coder.
16-5
16
Real-Time Workshop Ada Coder
Getting Started
This section illustrates, through a simple example, how to transform a
Simulink model into a stand-alone executable program. This program runs
independently of Simulink, allowing accelerated execution on the development
host or a different target computer.
Generating Ada code from a Simulink model is very similar to generating C
code. Begin by typing
countersdemo
at the MATLAB prompt. This block diagram appears.
Figure 16-1: Counter Demonstration with Subsystems Open
16-6
Getting Started
Setting Options for Ada Code Generation
You must specify the correct options before you generate Ada code from this
model. These are the steps:
1 Select Parameters under the Simulation menu. This opens the Simulation
Parameters dialog box.
2 On the Solver page, set the Solver options to Fixed-step discrete (no
continuous states)
3 Select the Real-Time Workshop page. In the Category menu, select Target
configuration.
4 Click the Browse button. This opens the System Target File Browser.
16-7
16
Real-Time Workshop Ada Coder
5 Select Ada Simulation Target for GNAT and click OK. This automatically
sets the correct System target file, Template makefile, and Make
command fields for Ada code generation.
Figure 16-2 shows the System Target File Browser with the correct selection
for Ada code generation.
Figure 16-2: The System Target File Browser
Alternatively, you can specify the settings on the Real-Time Workshop page
manually by following these steps:
1 Select Options under the Real-Time Workshop submenu of the Tools
menu. This opens the Real-Time Workshop page of the Simulation
Parameters dialog box.
2 In the Category menu, select Target configuration.
3 Specify rt_ada_sim.tlc as the System target file.
4 Specify gnat_sim.tmf as the Template makefile.
16-8
Getting Started
5 Specify make_rtw -ada as the Make command.
Figure 16-3 shows the Real-Time Workshop page with the correct settings.
Figure 16-3: Target Configuration Settings in the Real-Time Workshop Page
In addition, you can use the make command to pass compiler switches to the
code compilation phase. For example, if you want to compile with debugging
symbols, add a -g after the -ada switch in the Make command field (there
must be a space between each switch). This switch is applied on a model basis;
for more permanent changes, see “Configuring the Template Makefile” on page
14-13.
Generating Ada Code
To generate Ada code and build an Ada executable, open the Real-Time
Workshop page. In the Category menu, select Target configuration. Click the
Build button.
Alternatively, select Build Model under the Real-Time Workshop submenu of
the Tools menu.
16-9
16
Real-Time Workshop Ada Coder
Generated Files
The Real-Time Workshop Ada Coder creates output files in two directories
during the build process:
• The working directory
If an executable is created, it is written to your working directory. The
executable is named model.exe (on PC) or model (on UNIX).·
• The build directory
The build process creates a subdirectory, called the build directory, within
your working directory. The build directory name is model_adaXX_rtw,
where model is the name of the source model, and adaXX is either ada83 or
ada95, depending on the selected target. The build directory stores generated
source code and all other files (other than the executable) created during the
build process.
This table lists the Ada files generated by the Real-Time Workshop Ada Coder
from the counter demonstration (countersdemo).
Table 16-1: Ada Files Generated by the Real-Time Workshop
Ada Coder
16-10
Filename
Description
countersdemo.adb
Package body with the implementation
details of the model.
countersdemo.ads
Package specification that defines the callable
procedures of the model and any external
inputs and outputs to the model.
countersdemo_types.ads
Package specification of data types used by
the model. The Real-Time Ada Coder derives
the data types from the block name and signal
width.
register.ads
Package specification that defines model rate
information and renames program entry
points in countersdemo.ads.
Getting Started
Table 16-1: Ada Files Generated by the Real-Time Workshop
Ada Coder (Continued)
Filename
Description
register2.ads
Package specification that contains the subset
of register.ads required for elimination of
circular compilation dependencies.
rt_engine-rto_data.ads
Package specification that contains the timing
information for executing the model
encapsulated in the real-time object.
Models with S-Functions
Real-Time Workshop Ada Coder does not currently support non-inlined
S-functions. For Real-Time Workshop code generation purposes, you can create
a wrapper S-function that calls an Ada S-function.
It is possible, however, to generate Ada code for models with inlined Ada or C
S-functions. To do so, you must create a TLC file that incorporates the
algorithm from your S-function.
The following example shows how to write a TLC file to inline a simple Ada
S-function. For more information on writing TLC files, see the Target
Language Compiler Reference Guide.
Create model times2 using these blocks:
• Sine Wave (sample time = 0.1)
• timestwo Ada S-function (provided in the
matlabroot/toolbox/simulink/blocks/tlc_ada directory) with no
parameters set (i.e., leave the Parameters field blank)
• Two Outport blocks
16-11
16
Real-Time Workshop Ada Coder
Your model should look like this picture.
The times2 model contains a simple S-function, called timestwo, that takes the
input sine wave signal and doubles its amplitude. The TLC file corresponding
to the S-function is shown below.
%% Copyright (c) 1990-2000 by The MathWorks, Inc.
%%
%% Abstract:
%%
TLC file for timestwo.c used in Real-Time Workshop
%%
S-Function test.
%implements "timestwo" "Ada"
%% Function: Outputs
==========================================================
%function Outputs(block, system) Output
-- %<Type> Block: %<Name>
-- Multiply input by two
%<LibBlockOutputSignal(0, "", "", 0)> := ...
%<LibBlockInputSignal(0, "", "", 0) > * 2.0;
%endfunction
%% [EOF] timestwo.tlc
16-12
Getting Started
The key line in this TLC file is the assignment of two times the
LibBlockInputSignal to the LibBlockOutputSignal. This line directs the
Target Language Compiler to place the algorithm directly into the generated
Ada code.
This TLC file is located in
matlabroot/toolbox/simulink/blocks/tlc_ada/timestwo.tlc.
Generating the Ada Code
The build process is similar to the case where your model does not contain any
S-functions. The only additional requirement for generating Ada code for
models containing S-functions is to provide a TLC file with the same name as
the S-function. Otherwise, the build procedure is exactly the same.
Configuring the Template Makefile
Template makefiles specify the compiler, link, and make directives native to
the target computer’s operating system and compiler you are using. Two
examples of template makefiles are provided in the directory
matlab/rtw/ada/gnat. File gnat_sim.tmf is the template makefile that builds
that real-time Ada simulation program. The automatic build process expands
the macros defined at the top of the .tmf file to create the call to gnatmake.
gnatmake then compiles and links the program.
There are two ways to make permanent changes to the template makefile if you
need to make modifications either to target a different Ada95 compiler or to
make minor adjustments to the gnat make directive:
• Copy the template makefile into the directory where the model is located.
• Copy the template makefile to a unique name in matlab/rtw/ada/gnat and
make modifications to the new file.
Data Logging
You can use the Ada real-time simulation target (rt_ada_sim) to perform the
same data logging as a Simulink simulation. To enable MAT-file logging, select
Ada-specific code generation options item in the Category menu of the
Real-Time Workshop page. Then select the MAT-file logging option. When
this option is selected, the Ada program executes for the duration specified by
the Stop time field on the Solver page of the Simulation Parameters dialog
box.
16-13
16
Real-Time Workshop Ada Coder
When the Ada Coder finishes its run, a model.mat file is created that contains
all workspace variables that would have been created by running a Simulink
simulation. The names of these workspace variables are the same as the names
that would have been created by Simulink, except that an rt_ prefix is
attached. See “Workspace I/O Options and Data Logging” in Chapter 3 for more
information about data logging.
Note If you do not select MAT-file logging, the stop time is ignored and the
Ada program runs without stopping.
Generating Block Comments
When the Insert block descriptions in code option is selected, comments are
inserted into the code generated for any blocks that have text in their
Description fields. To generate block comments:
1 Right-click on the block you want to comment. Select Block Properties from
the context menu. The Block Properties dialog box opens.
2 Type the comment into the Description field.
3 Select the Insert block descriptions in code option in the Ada-specific code
generation options category of the Real-Time Workshop page.
Note For virtual blocks or blocks that have been removed due to block
reduction optimizations, no comments are generated.
Application Modules Required for the
Real-Time Program
Building the real-time program requires a number of support files in addition
to the generated code. These support files contain:
• A main program
• Code to drive execution of the model code
• Code to carry out data logging
16-14
Getting Started
The makefile automatically compiles and links these source modules. This
diagram shows the modules used to build the countersdemo example.
Generated Code
Main Program
mr_ada_sim.adb
sr_ada_sim.adb
rt_ada_tasking.adb*
Data Logging
data_log.ads
data_log.adb
countersdemo_types.ads
countersdemo.ads
countersdemo.adb
register.ads
register2.ads
rt_engine-rto_data.ads
Makefile
Template
gnat_sim.tmf
gnat_tasking.tmf*
Model
Execution
rt_engine.ads
rt_engine.adb
rt_crossing.ads
rt_crossing.adb
rt_tasks.ads*
rt_tasks.adb*
ada make
Executable File
countersdemo
Data Types
tmw_types.ads
tmw_types-math.adb
tmw_types-ops.ads
tmw_types-strings.ads
*Ada multitasking real-time
implementation only
Figure 16-4: Source Modules Used to Build the countersdemo Program
16-15
16
Real-Time Workshop Ada Coder
Configuring and Interfacing Parameters and Signals
Model Parameter Configuration
The Model Parameter Configuration dialog provides a mechanism for
interfacing your model’s block parameters to code that you have written. This
is useful in situations where you want your hand-written code to change
parameter values while the generated program executes.
Read “Parameters: Storage, Interfacing, and Tuning” on page 3-51 to learn
about general parameter storage concepts and the Model Parameter
Configuration dialog.
Using the Model Parameter Configuration dialog does not differ greatly
between between Ada and other target languages such as C. However, you
should note the following Ada-specific differences:
• The Storage Type Qualifier field is only used when specifying the package
specification to fully qualify the variable name for the ImportedExtern
option. This field is ignored in all other cases.
• ImportedExtern variables are assumed to be declared in the package
specification entered in the Storage Type Qualifier field. The generated
code accesses this variable as Your_Package.Your_variable.
• ImportedExternPointer storage class is not permitted in Ada.
Signal Properties
The Simulink Signal Properties dialog 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.
Read “Signals: Storage, Optimization, and Interfacing” on page 3-65 to learn
about general signal storage concepts and the Signal Properties dialog. Then
note the Ada-specific differences described below.
The Real-Time Workshop Ada Coder has logic for supporting Simulink signal
labels. This logic automatically maps signal labels to Simulink blocks based on
the block name, signal name, and connectivity. You can override the default
behavior and either specify an external declaration for the signal name or
direct the Real-Time Workshop Ada Coder to declare a unique declaration of
the signal that is visible in the generated model package specification. The
16-16
Configuring and Interfacing Parameters and Signals
heuristics are implemented on a signal basis as specified by the Signal name,
RTW storage class, and RTW storage type qualifier (externally declared
signals only).
The options relevant to the Real-Time Workshop Ada Coder are:
• SimulinkGlobal (Test Point): Clicking this check box directs the Real-Time
Workshop Ada Coder to place the signal in a unique global memory location
(rtB structure). This is useful for testing purposes since it eliminates the
possibility of overwriting the signal data. Note that selecting this option
forces the RTW storage class to be Auto.
• RTW storage class : The storage class options are:
- Auto: directs the Real-Time Workshop to store the signal in a persistent
data structure. Specifically, an element called Signal_Name is declared in
the External_Inputs structure defined in the Model_Types package
specification. The generated code accesses this signal as
RT_U.Signal_Name.
- ExportedGlobal: Declares the signal as a global variable that can be
accessed from outside the generated code. The signal is declared in the
model package specification but not in the External_Inputs structure.
The generated code accesses this signal as Signal_Name. The signal will be
globally visible as Model.Signal_Name.
- ImportedExtern: The signal is assumed to be declared in the package
specification entered in the RTW storage type qualifier field. The
generated code accesses this signal as Your_Package.Signal_Name.
- ImportedExternPointer: This is not permitted in Ada.
• RTW storage type qualifier : This is only used when specifying the package
specification to qualify fully the signal name for the Imported Extern option.
This field is ignored in all other cases.
These cases are useful if you want to link Real-Time Workshop Ada Coder
generated code to other Ada code (i.e., code that the Real-Time Workshop Ada
Coder did not generate).
16-17
16
Real-Time Workshop Ada Coder
Code Validation
After completing the build process, the stand-alone version of the
countersdemo model is ready for comparison with the Simulink model. The
data logging options selected with the Workspace I/O page of the Simulation
Parameters dialog box cause the program to save the control signal, enabled
counter, triggered counter, and simulation time. You can now use MATLAB to
produce plots of the same data that you see on the three Simulink scopes.
In both the Simulink and the stand-alone executable version of the
countersdemo model, the control input is simulated with a discrete-pulse
generator producing a 10 Hz, fifty percent duty cycle waveform.
Open the control signal, enabled counter, and triggered counter scopes.
Running the Simulink simulation from T=0 to T=2 produces these outputs.
Type who at the MATLAB prompt to view the variable names from Simulink
simulation.
who
Your variables are:
Enable_Signal
Triggered_Counter
Enabled_Counter
tout
Now run the stand-alone program from MATLAB.
!countersdemo
16-18
Code Validation
The “!” character passes the command that follows it to the operating system.
This command, therefore, runs the stand-alone version of countersdemo (not
the M-file).
To obtain the data from the stand-alone program, load the file
countersdemo.mat.
load countersdemo
Then look at the workspace variables.
who
Your variables are:
Enable_Signal
Enabled_Counter
Triggered_Counter
rt_Enable_Signal
rt_Enabled_Counter
rt_Triggered_Counter
rt_tout
tout
The stand-alone Ada program prepends rt_ to the logged variable names to
distinguish them from the variables Simulink logged.
You can now use MATLAB to plot the three workspace variables as a function
of time.
plot(rt_Enable_Signal(:,1),rt_Enable_Signal(:,2))
figure
plot(rt_Enabled_Counter(:,1),rt_Enabled_Counter(:,2))
figure
plot(rt_Triggered_Counter(:,1),rt_Triggered_Counter(:,2))
16-19
16
Real-Time Workshop Ada Coder
Analyzing Data with MATLAB
Points to consider when data logging:
• Ada95 code supports all data logging formats (matrix, structure, and
structure/time).
• Ada83 code does not support data logging.
• To Workspace blocks log data at the frequency of the driving block and do not
log time.
• Scope blocks log data at the frequency of the driving block and log time in the
first column of the matrix.
• Root Outport blocks are updated at the frequency of the driving block but are
logged at the base rate of the model.
16-20
Supported Blocks
Supported Blocks
The Real-Time Workshop Ada Coder supports the following Simulink blocks.
Discrete Blocks
Discrete-Time Integrator
Discrete Zero-Pole
Discrete Filter
Unit Delay
Discrete State-Space
Zero-Order Hold
Discrete Transfer Fcn
Functions & Tables
Direct Look-Up Table (n-D)
Look-Up Table (2-D)
Fcn
Look-Up Table (n-D)
Interpolation (n-D) Using
PreLook-Up Index Search
PreLook-Up Index Search
Look-Up Table
S-Function — Only Target
Language Compiler inlined
S-functions are supported
Math Blocks
Abs
MinMax
Bitwise Logical Operator
Product — matrix multiplication
and element-wise multiplication
and division are supported. Matrix
division is not supported.
Combinatorial Logic
Real-Imag to Complex
Complex to Magnitude-Angle
Relational Operator
Complex to Real-Imag
Rounding Function
16-21
16
Real-Time Workshop Ada Coder
Math Blocks (Continued)
Dot Product
Sign
Gain (inluding matrix/
element-wise)
Slider Gain
Logic Operator
Sum
Magnitude-Angle to Complex
Trigonometric Function
Math Function
Nonlinear Blocks
Backlash
Quantizer
Coulomb & Viscous Friction
Relay
DeadZone
Saturation
Manual Switch (must Break
Library Link and use discrete
sample time)
Switch
Multiport Switch
Signals & Systems Blocks
16-22
Bus Selector
Initial Condition (IC)
Configurable Subsystem
Inport
DataStore Memory
Matrix Concatenation
DataStore Read
Merge
DataStore Write
ModelInfo
Data Type Conversion
Outport
Demux
Probe
Supported Blocks
Signals & Systems Blocks (Continued)
Enable
Reshape
From
Selector
Goto Tag Visibility
Subsystem
Goto
Terminator
Ground
Trigger Width
Hit Crossing
Sinks
Display — no code is generated for
this block
To File
Scope
To Workspace
Stop Simulation
Sources
Band-Limited White Noise
Ramp — You must break the
library link and replace the clock
with a discrete clock and manually
set the sample time step to match
the discrete clock.
Chirp Signal — (you must break
the library link and use a discrete
clock)
Random Number
Constant
Sine Wave
16-23
16
Real-Time Workshop Ada Coder
Sources (Continued)
Digital Clock
Repeating Sequence — You must
break the library link and replace
the clock with a discrete clock and
manually set the sample time step
to match the discrete clock.
Discrete Pulse Generator
Step
From File
Uniform Random Number
Note All element-wise operation blocks are suported by the Real-Time
Workshop Ada Coder.
16-24
17
Targeting Real-Time
Systems
Introduction . . . . . . . . . . . . . . . . . . . . 17-2
Components of a Custom Target Configuration . . . . . 17-4
Tutorial: Creating a Custom Target Configuration . . . . 17-9
Customizing the Build Process
. . . . . . . . . . . 17-16
Creating Device Drivers . . . . . . . . . . . . . . 17-34
Interfacing Parameters and Signals . . . . . . . . . 17-65
Creating an External Mode Communication Channel
Combining Multiple Models
DSP Processor Support
. 17-73
. . . . . . . . . . . . 17-82
. . . . . . . . . . . . . . 17-86
17
Targeting Real-Time Systems
Introduction
The target configurations bundled with the Real-Time Workshop are suitable
for many different applications and development environments. Third-party
targets provide additional versatility. However, a number of users find that
they require a custom target configuration.You may want to implement a
custom target configuration for any of the following reasons:
• To support custom hardware and incorporate custom device driver blocks
into your models.
• To customize a bundled target configuration — such as the generic real-time
(GRT) or Real-Time Workshop Embedded Coder targets — to your needs.
• To configure the build process for a special compiler (such as a compiler for
an embedded microcontroller or DSP board).
As part of your custom target implementation, you may also need to:
• Interface generated model code with existing supervisory or supporting code
that calls the generated code.
• Interface signals and parameters within generated code to your own code.
• Combine code generated from multiple models into a single system.
• Implement external mode communication via your own low-level protocol
layer.
The following sections provide the information necessary to accomplish these
tasks:
• “Components of a Custom Target Configuration” on page 17-4 gives an
overview of the code and control files that make up a custom target
configuration.
• “Tutorial: Creating a Custom Target Configuration” on page 17–9 is a
hands-on exercise in building a custom rapid prototyping target.
• “Customizing the Build Process” on page 17–16 provides information on the
structure of system target files (“System Target File Structure” on page 17–
16) and template makefiles (“Template Makefiles” on page 17–25).
• “Adding a Custom Target to the System Target File Browser” on page 17–24
shows you how to make your custom target configuration available to users
via the System Target File Browser.
17-2
• “Creating Device Drivers” on page 17–34 discusses the implementation of
device drivers as S-Function blocks, covering both inlined and noninlined
drivers.
• “Interfacing Parameters and Signals” on page 17–65 contains guidelines for
use of the Real-Time Workshop signal monitoring and parameter tuning
APIs.
• “Creating an External Mode Communication Channel” on page 17–73
provides information you will need to support external mode on your custom
target, using your own low-level communications layer.
• “Combining Multiple Models” on page 17–82 discusses strategies for
combining several models (or several instances of the same model) into a
single executable.
17-3
17
Targeting Real-Time Systems
Components of a Custom Target Configuration
The components of a custom target configuration are:
• Code to supervise and support execution of generated model code
• Control files:
- A system target file to control the code generation process
- A template makefile to build the real-time executable
This section summarizes key concepts and terminology you will need to know
to begin developing each component. References to more detailed information
sources are provided, in case any of these topics are unfamiliar to you.
Code Components
A Real-Time Workshop 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
Run-Time Interface Components
A number of code modules and data structures, referred to collectively as the
run-time interface, are responsible for managing and supporting the execution
of the generated program. The run-time interface modules are not
automatically generated. To develop a custom target, you must implement
17-4
Components of a Custom Target Configuration
certain parts of the run-time interface. Table 17-1 summarizes the run-time
interface components.
Table 17-1: Run-Time Interface Components
User Provides:
Real-Time Workshop 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 and signal
monitoring user interface
Data logging, parameter tuning,
signal monitoring, and external mode
support
The components of the run-time interface vary, depending upon whether the
target is an embedded system or a rapid prototyping environment.
User-Written Run-Time Interface Code
Most of the run-time interface is provided by Real-Time Workshop. You must
implement 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 Real-Time Workshop supplied
function, rt_OneStep.
• The main program. Your main program initializes the blocks in the model,
installs the 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.
• Device drivers to communicate with your target hardware.
17-5
17
Targeting Real-Time Systems
Run-Time Interface for Rapid Prototyping
The run-time interface for a rapid prototyping target includes:
• Supervisory logic
- The main program
- Execution engine and integration solver
• Supporting logic
- I/O drivers
- Code to handle timing, and interrupts
• Monitoring, tuning, and debugging support
- Data logging code
- Signal monitoring
- Real-time parameter tuning
- External mode communications
The structure of the rapid prototyping run-time interface, and the execution of
rapid prototyping code, are detailed in Chapter 6, “Program Architecture” and
Chapter 7, “Models with Multiple Sample Rates.”
Development of a custom rapid prototyping target generally begins with
customization of one of the generic main programs, grt_main.c or
grt_malloc_main.c. As described in “User-Written Run-Time Interface Code”
above, you must modify the main program for real-time interrupt-driven
execution. You must also supply device drivers (optionally inlined).
Run-Time Interface for Embedded Targets
The run-time interface for an embedded (production) target includes:
• Supervisory logic
- The main program
- Execution engine and integration solver
• Supporting logic
- I/O drivers
- Code to handle timing, and interrupts
17-6
Components of a Custom Target Configuration
• Monitoring and debugging support
- Data logging code
- Access to tunable parameters and external signals
Development of a custom embedded target generally begins with customization
of the Real-Time Workshop Embedded Coder main program, ert_main.c.
Chapter 9, “Real-Time Workshop Embedded Coder” details the structure of the
Real-Time Workshop Embedded Coder run-time interface and the execution of
Real-Time Workshop Embedded Coder code, and provides guidelines for
customizing ert_main.c.
Control Files
System Target Files
The Target Language Compiler (TLC) generates target-specific C or Ada 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 output of this process is a
number of source files, which are fed to your development system’s make
utility.
The system target file controls the code generation process. You will need to
create a customized system target file to set code generation parameters for
your target. We recommend that you copy, rename, and modify one of the
standard system target files:
• The generic real-time (GRT) target file, matlabroot/rtw/c/grt/grt.tlc, for
rapid prototyping targets
• The Real-Time Workshop Embedded Coder target file, matlabroot/rtw/c/
ert/ert.tlc, for embedded (production) targets
Chapter 2, “Technical Overview”2 and Chapter 3, “Code Generation and the
Build Process” describe the role of the system target file in the code generation
and build process. Guidelines for creating a custom system target file are given
in “Customizing the Build Process” on page 17-16.
Template Makefiles
A template makefile (.tmf file) provides information about your model and
your development system. Real-Time Workshop uses this information to create
17-7
17
Targeting Real-Time Systems
an appropriate makefile (.mk file) to build an executable program. Real-Time
Workshop provides a large number of template makefiles suitable for different
types of targets and development systems. The standard template makefiles
are described in “Template Makefiles and Make Options” on page 3–102.
If one of the standard template makefiles meets your requirements, you can
simply copy and rename it in accordance with the conventions of your project.
If you need to make more extensive modifications, see “Template Makefiles” on
page 17-25 for a full description of the structure of template makefiles.
17-8
Tutorial: Creating a Custom Target Configuration
Tutorial: Creating a Custom Target Configuration
This tutorial walks through the task of creating a skeletal rapid prototyping
target. This exercise illustrates several tasks that are usually required when
creating a custom target:
• Incorporating a noninlined S-function into a model for use in simulation.
• Inlining the S-function in the generated code, using a corresponding TLC
file.
In a real-world application, you would incorporate inlined and noninlined
device driver S-functions into the model and the generated code. In this
tutorial, we inline a simple S-function that multiplies its input by two.
• Making minor modifications to a standard system target file and template
makefile.
• Generating code from the model by invoking your customized system target
file and template makefile.
You can use this process as a starting point for your own projects.
This example uses the LCC compiler under Windows. LCC is distributed with
Real-Time Workshop. If you use a different compiler, you can set up LCC
temporarily as your default compiler by typing the MATLAB command
mex -setup
A command prompt window will open; follow the prompts and select LCC.
Note On UNIX systems, make sure that you have a C compiler installed. You
can then do this exercise substituting appropriate UNIX directory syntax.
In this example, the code is generated from targetModel.mdl, a very simple
fixed-step model (see Figure 17-1). The resultant program behaves exactly as
if it had been built for the generic real-time target.
17-9
17
Targeting Real-Time Systems
Figure 17-1: targetModel.mdl
The S-Function block will use the source code from the timestwo example. See
the Writing S-Functions manual for a complete discussion of this S-function.
The Target Language Compiler Reference Guide discusses timestwo.tlc, the
inlined version of timestwo.
To create the skeletal target system:
1 Create a directory to store your C source files and .tlc and .tmf files. We
refer to this directory as d:/work/mytarget.
2 Add d:/work/mytarget to your MATLAB path.
addpath d:/work/mytarget
3 Make d:/work/mytarget your working directory. Real-Time Workshop
writes the output files of the code generation process into a build directory
within the working directory.
4 Copy the timestwo S-function C source code from matlabroot/toolbox/
rtw/rtwdemos/tlctutorial/timestwo/solutions/timestwo.c to
d:/work/mytarget.
5 Build the timestwo MEX-file in d:/work/mytarget.
mex timestwo.c
6 Create the model as illustrated in Figure 17-1. Use an S-Function block from
the Simulink Functions & Tables library in the Library Browser. Set the
solver options to fixed-step and ode4.
7 Double-click the S-Function block to open the Block Parameters dialog.
Enter the S-function name timestwo. The block is now bound to the
timestwo MEX-file. Click OK.
17-10
Tutorial: Creating a Custom Target Configuration
8 Open the Scope and run the simulation. Verify that the timestwo S-function
multiplies its input by 2.0.
9 In order to generate inlined code from the timestwo S-Function block, you
must have a corresponding TLC file in the working directory. If the Target
Language Compiler detects a C-code S-function and a TLC file with the
same name in the working directory, it generates inline code from the TLC
file. Otherwise, it generates a function call to the external S-function.
To ensure that the build process generates inlined code from the timestwo
block, copy the timestwo TLC source code from matlabroot/toolbox/rtw/
rtwdemos/tlctutorial/timestwo/solutions/timestwo.tlc to
d:/work/mytarget.
10 Make local copies of the main program and system target files. matlabroot/
rtw/c/grt contains the main program (grt_main.c) and the system target
file (grt.tlc) for the generic real-time target. Copy grt_main.c and grt.tlc
to d:/work/mytarget. Rename them to mytarget_main.c and
mytarget.tlc.
11 Remove the initial comment lines from mytarget.tlc. The lines to remove
are shown below.
%% SYSTLC: Generic Real-Time Target \
%%
TMF: grt_default_tmf MAKE: make_rtw EXTMODE: ext_comm
%% SYSTLC: Visual C/C++ Project Makefile only for the "grt" target \
%%
TMF: grt_msvc.tmf MAKE: make_rtw EXTMODE: ext_comm
The initial comment lines have significance only if you want to add
my_target to the System Target File Browser. For now you should remove
them.
17-11
17
Targeting Real-Time Systems
12 Real-Time Workshop creates a build directory in your working directory to
store files created during the code generation process. The build directory is
given the name of the model, followed by a suffix. This suffix is specified in
the rtwgensettings structure in the system target file.
To set the suffix to a more appropriate string, change the line
rtwgensettings.BuildDirSuffix = '_grt_rtw'
to
rtwgensettings.BuildDirSuffix = '_mytarget_rtw'
Your build directory will be named targetModel__mytarget_rtw.
13 Make a local copy of the template makefile. matlabroot/rtw/c/grt contains
several compiler-specific template makefiles for the generic real-time target.
The appropriate template makefile for the LCC compiler is grt_lcc.tmf.
Copy grt_lcc.tmf to d:/work/mytarget, and rename it to mytarget.tmf.
Note Some of the template makefile modifications described in the next step
are specific to the LCC template makefile. If you are using a different compiler
and template makefile, the rules for the source (REQ_SRCS) and object file
(%.obj :) lists may differ slightly.
17-12
Tutorial: Creating a Custom Target Configuration
14 Modify mytarget.tmf. The SYS_TARGET FILE parameter must be changed so
that the correct file reference is generated in the make file. Change the line
SYS_TARGET FILE = grt.tlc
to
SYS_TARGET FILE = mytarget.tlc
Also, change the source file list to include mytarget_main.c instead of
grt_main.c.
REQ_SRCS = $(MODEL).c $(MODULES) mytarget_main.c...
Finally, change the line
%.obj : $(MATLAB_ROOT)/rtw/c/grt/%.c
to
%.obj : d:/work/mytarget/%.c
15 This exercise requires no changes to mytarget_main.c. In an actual
application, you would modify mytarget_main.c to execute your model code
under the control of a timer interrupt, and make other changes.
17-13
17
Targeting Real-Time Systems
16 Open the Real-Time Workshop page in the Simulation Parameters dialog.
Select Target configuration from the Category menu. Enter the system
target file, template makefile, and Make command parameters as below.
17 Click the Apply button.
18 Click the Build button. If the build is successful, MATLAB will display the
message below.
### Created executable: targetModel.exe
### Successful completion of Real-Time Workshop build procedure
for model: targetModel
Your working directory will contain the targetModel.exe file and the build
directory, targetModel_mytarget_rtw.
17-14
Tutorial: Creating a Custom Target Configuration
19 Edit the generated file d:/work/mytarget/targetModel_mytarget_rtw/
targetModel.c and locate the MdlOutputs function. Observe the inlined
code.
/* S-Function Block: <Root>/S-Function (timestwo) */
rtB.S_Function = 2.0 * rtB.Sine_Wave;
Because the working directory contained a TLC file (timestwo.tlc) with
the same name as the timestwo S-Function block, the Target Language
Compiler generated inline code instead of a function call to the external Ccode S-function.
20 As an optional final step to this exercise, you may want to add your custom
target configuration to the System Target File Browser. See “Adding a
Custom Target to the System Target File Browser” on page 17-24 to learn
how to do this.
17-15
17
Targeting Real-Time Systems
Customizing the Build Process
The Real-Time Workshop build process proceeds in two stages. The first stage
is code generation. The system target file exerts overall control of the code
generation stage. In the second stage, the template makefile generates a .mk
file, which compiles and links code modules into an executable.
In developing your custom target, you may need to create a customized system
target file and/or template makefile. This section provides information on the
structure of these files, and guidelines for modifying them.
System Target File Structure
This section is a guide to the structure and contents of a system target file. You
may want to refer to the system target files provided with the Real-Time
Workshop while reading this section. Most of these files are stored in the
target-specific directories under matlabroot/rtw/c. Additional system target
files are stored in matlabroot/toolbox/rtw/targets/rtwin/rtwin and
matlabroot/toolbox/rtw/targets/xpc/xpc.
Before creating or modifying a system target file, you should acquire a working
knowledge of the Target Language Compiler. The Target Language Compiler
Reference Guide documents the features and syntax of the language.
Figure 17-2 shows the general structure of a system target file.
17-16
Customizing the Build Process
%% SYSTLC: Example Real-Time Target
%%
TMF: example.tmf MAKE: make_rtw EXTMODE: ext_comm
%% Inital comments contain directives for System Target File Browser.
%% Documentation, date, copyright, and other info may follow.
%%
%% TLC Configuration Variables Section -----------------------------%% Assign code format, language, target type.
%%
%assign CodeFormat = "Embedded-C"
%assign TargetType = "RT"
%assign Language
= "C"
%%
%% TLC Program Entry Point -----------------------------------------%% Call entry point function.
%include "codegenentry.tlc"
%%
%% 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 statements';
rtwoptions(6).type = 'Checkbox';
.
.
%% Define additional TLC variables here.
.
.
%% Define suffix string for naming build directory here.
%%
rtwgensettings.BuildDirSuffix = '_mytarget_rtw'
END_RTW_OPTIONS
%/
Browser
Comments
TLC Configuration
Variables
TLC Program Entry
Point
rtwoptions Array
and Other TLC
Variables
Build
Directory
Name
Figure 17-2: Structure of a System Target File
Browser Comments
This section is optional. You can place comment lines at the head of the file to
identify your system target file to the System Target File Browser. These lines
have significance to the browser only. During code generation, the Target
Language Compiler treats them as comments.
17-17
17
Targeting Real-Time Systems
Note that you must place the browser comments at the head of the file, before
any other comments or TLC statements.
The comments contain the following directives:
• SYSTLC: This string is a descriptor that appears in the browser.
• TMF: Name of the template makefile to use during build process. When the
target is selected, this filename is displayed in the Template makefile field
of the Target configuration section of the Real-Time Workshop page.
• MAKE: make command to use during build process. When the target is selected,
this command is displayed in the Make command field of the Target
configuration section of the Real-Time Workshop page.
• 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 browser information comments are from matlabroot/rtw/c/
grt/grt.tlc.
%% SYSTLC: Generic Real-Time Target
%%
TMF: grt_default_tmf MAKE: make_rtw EXTMODE: ext_comm
See “Adding a Custom Target to the System Target File Browser” on page
17-24 for further information.
Target Language Compiler Configuration Variables
This section assigns global TLC variables that affect the overall code
generation process. The following variables must be assigned:
• CodeFormat: The CodeFormat variable selects one of the available code
formats:
- RealTime: Designed for rapid prototyping, with static memory allocation.
- RealTimeMalloc: Similar to RealTime, but with dynamic memory
allocation.
- Embedded-C: Designed for production code, minimal memory usage,
simplified interface to generated code.
- S-Function: For use by S-function and Accelerator targets only.
17-18
Customizing the Build Process
- Ada: Designed for production code, minimal memory usage, simplified
interface to generated code.
The default CodeFormat value is RealTime.
Chapter 4, “Generated Code Formats” summarizes available code formats
and provides pointers to further details.
• Language: Selects code generation in one of the supported languages:
- C
- Ada
When Ada is selected, Real-Time Workshop generates Ada95 code by
default. To generate Ada83 code, set the variable AdaVersion as follows.
%assign AdaVersion = “83”
It is possible to generate code in a language other than C or Ada. To do this
would require considerable development effort, including reimplementation
of all block target files to generate the desired target language code. See the
Target Language Compiler Reference Guide for a discussion of the issues.
• TargetType: The Real-Time Workshop 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 Simulink Accelerator, generate code for use in non
real-time only. Such targets assign TargetType as follows.
%assign TargetType = "NRT"
See “Conditional Compilation for Simulink and Real-Time” on page 17–40
for further information on the use of these symbols.
Target Language Compiler Program Entry Point
The code generation process normally begins with codegenentry.tlc. The
system target file invokes codegenentry.tlc as follows.
%include "codegenentry.tlc"
17-19
17
Targeting Real-Time Systems
codegenentry.tlc in turn invokes other TLC files:
• genmap.tlc maps the 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.
To customize the code generation process, you can call the lower-level TLC files
explicitly and include your own TLC functions at each stage of the process. See
the Target Language Compiler Reference Guide for guidelines.
Note codegenentry.tlc and the lower-level TLC files assume that
CodeFormat, TargetType, and Language have been correctly assigned. Set
these variables before including codegenentry.tlc.
RTW_OPTIONS Section
The RTW_OPTIONS section (see Figure 17-2) is bounded by the directives:
%/
BEGIN_RTW_OPTIONS
.
.
END_RTW_OPTIONS
/%
The first part of the RTW_OPTIONS section defines an array of rtwoptions
structures. The rtwoptions structure is discussed in this section.
The second part of the RTW_OPTIONS section defines rtwgensettings, a
structure defining the build directory name and other settings for the code
generation process. See “Build Directory Name” on page 17-24 for information
about rtwgensettings.
The rtwoptions Structure. The fields of the rtwoptions structure define variables
and associated user interface elements to be displayed in the Real-Time
Workshop page. Using the rtwoptions structure array, you can customize the
Category menu in the Real-Time Workshop page, define the options displayed
in each category, and specify how these options are processed.
17-20
Customizing the Build Process
When the Real-Time Workshop page 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, pop-up menu, or
pushbutton), which displays the current option value.
The user interface elements can be in an enabled or disabled (grayed-out) state.
If the option is enabled, the user can change the option value.
The elements of the rtwoptions structure array are organized into groups that
correspond to items in the Category menu in the Real-Time Workshop page.
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 header is followed by options to be displayed on the Real-Time Workshop
page. The header in each category is followed by a maximum of seven elements.
Table 17-2 summarizes the fields of the rtwoptions structure.
The following example is excerpted from matlabroot/rtw/c/rtwsfcn/
rtwsfcn.tlc, the system target file 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 2, indicating the number of elements that follow the
header.
rtwoptions(1).prompt = 'RTW S-function code generation options';
rtwoptions(1).type = 'Category';
rtwoptions(1).enable = 'on';
rtwoptions(1).default = 2; % Number of items under this category
% excluding this one.
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 RTW 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 instead of variable name in generated block mask edit fields'];
17-21
17
Targeting Real-Time Systems
The first element adds the RTW S-function code generation options item to
the Category menu of the Real-Time Workshop page. The options defined in
rtwoptions(2) and rtwoptions(3) display as shown in Figure 17-3.
Figure 17-3: Code Generation Options for S-Function Target
If you want to define more than seven options, you can define multiple
Category menu items within a single system target file. For an example, see
the Tornado system target file, matlabroot/rtw/c/tornado/tornado.tlc.
For further examples of target-specific rtwoptions definitions, see the system
target files in the other target directories under matlabroot/rtw/c.
Note that to verify the syntax of your rtwoptions definitions, you can execute
the commands in MATLAB by copying and pasting them to the MATLAB
command window.
The following table lists the fields of the rtwoptions structure.
17-22
Customizing the Build Process
Table 17-2: rtwoptions Structure Fields Summary
Field Name
Description
callback
Name of M-code function to call when value of option
changes.
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.
makevariable
Template makefile token (if any) associated with
option. The makevariable will be expanded during
processing of the template makefile. See “Template
Makefile Tokens” on page 17-26.
opencallback
M-code to be executed when dialog opens. The purpose
of the code is to synchronize the displayed value of the
option with its previous setting. See matlabroot/rtw/
c/ert/ert.tlc for an example.
popupstrings
If type is Popup, popupstrings defines the items in the
pop-up menu. Items are delimited by the “|” (vertical
bar) character. The following example defines the items
of the Function management menu used by the GRT
and other targets:
['None|Function splitting|File ', ...
'splitting|Function and file splitting']
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, Popup, Pushbutton, or
Category.
17-23
17
Targeting Real-Time Systems
Additional Code Generation Options
“Target Language Compiler Variables and Options” on page 3-93 describes
additional code generation variables. For readability, it is recommended that
you assign these variables in the Configure RTW code generation settings
section of the system target file.
Alternatively, you can append statements of the form
-aVariable=val
to the System target filename field on the Real-Time Workshop page.
Build Directory Name
The final part of the system target file defines the BuildDirSuffix field of the
rtwgensettings structure. The build process appends the BuildDirSuffix
string to the model name to form the name of the build directory. For example,
if you define BuildDirSuffix as follows
rtwgensettings.BuildDirSuffix = '_mytarget_rtw'
the build directories are named model_mytarget_rtw.
See the Target Language Compiler Reference Manual for further information
on the rtwgensettings structure.
Adding a Custom Target to the System Target
File Browser
As a convenience to end users of your custom target configuration, you can add
a custom target configuration to the System Target File Browser. To do this:
1 Modify (or add) browser comments at the head of your custom system target
file. For example,
%% SYSTLC: John’s Real-Time Target \
%%
TMF: mytarget.tmf MAKE: make_rtw EXTMODE: no_ext_comm
2 Create a directory <targetname> (e.g., /mytarget). Move your custom system
target file, custom template makefile, and run-time interface files (such as
your main program and S-functions) into the <targetname> subdirectory.
3 Add your target directory to the MATLAB path.
17-24
Customizing the Build Process
addpath <targetname>
If you want <targetname> included in the MATLAB path each time
MATLAB starts up, include this addpath command in your startup.m file.
4 When the System Target File Browser opens, Real-Time Workshop detects
system target files that are on the MATLAB path, and displays the target
filenames and target description comments. Figure 17-4 shows how the
target file mytarget.tlc, which contains the browser comments above,
appears in the System Target File Browser.
Figure 17-4: Custom System Target File Displayed in Browser
Template Makefiles
To configure or customize template makefiles, you should be familiar with how
the make command works and how the make command processes makefiles. You
should also understand makefile build rules. For information of these topics,
please refer to the documentation provided with the make utility you use.
There are also several good books on the make utility.
17-25
17
Targeting Real-Time Systems
Template makefiles are made up of statements containing tokens. The
Real-Time Workshop build process expands tokens and creates a makefile,
model.mk. Template makefiles are designed to generate makefiles for specific
compilers on specific platforms. The generated model.mk file is specifically
tailored to compile and link code generated from your model, using commands
specific to your development system.
Template
Makefile
system.tmf
Makefile:
model.mk
Figure 17-5: Creation of model.mk
Template Makefile Tokens
The make_rtw M-file command (or a different command provided with some
targets) directs the process of generating model.mk. The make_rtw command
processes the template makefile specified on the Target configuration section
of the Real-Time Workshop page of the Simulation Parameters dialog.
make_rtw copies the template makefile, line by line, expanding each token
encountered. Table 17-3 lists the tokens and their expansions.
Table 17-3: Template Makefile Tokens Expanded by make_rtw
17-26
Token
Expansion
|>COMPUTER<|
Computer type. See the MATLAB
computer command.
|>MAKEFILE_NAME<|
model.mk — The name of the makefile
that was created from the template
makefile.
|>MATLAB_ROOT<|
Path to where MATLAB is installed.
|>MATLAB_BIN<|
Location of the MATLAB executable.
Customizing the Build Process
Table 17-3: Template Makefile Tokens Expanded by make_rtw (Continued)
Token
Expansion
|>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_NAME<|
Name of the Simulink block diagram
currently being built.
|>MODEL_MODULES<|
Any additional generated source (.c)
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 (.c)
modules.
|>MULTITASKING<|
True (1) if solver mode is multitasking,
otherwise False (0).
|>NUMST<|
Number of sample times in the model.
|>RELEASE_VERSION<|
The release version of MATLAB.
|>S_FUNCTIONS<|
List of noninlined S-function (.c)
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, e.g., ode3.c.
|>SOLVER_OBJ<|
Solver object (.obj) filename, e.g.,
ode3.obj.
17-27
17
Targeting Real-Time Systems
Table 17-3: Template Makefile Tokens Expanded by make_rtw (Continued)
Token
Expansion
|>TID01EQ<|
True (1) if sampling rates of the
continuous task and the first discrete
task are equal, otherwise False (0).
|>NCSTATES<|
Number of continuous states.
|>BUILDARGS<|
Options passed to make_rtw. This token
is provided so that the contents of your
model.mk file will change when you
change the build arguments, thus
forcing an update of all modules when
your build options change.
|>EXT_MODE<|
True (1) to enable generation of
external mode support code, otherwise
False (0).
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 template makefile statement
NUMST = |>NUMST<|
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 via the Target configuration section of the
Real-Time Workshop page of the Simulation Parameters dialog box.
• Structures in the RTW Options 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 M-file code that sets
up rtwoptions. The directive
17-28
Customizing the Build Process
rtwoptions(2).makevariable = 'EXT_MODE'
causes the |>EXT_MODE<| token to be expanded into 1 (on) or 0 (off),
depending on how you set the External mode option in the Code generation
options section of the Real-Time Workshop page.
The Make Command
After creating model.mk from your template makefile, the Real-Time Workshop
invokes a make command. To invoke make, the Real-Time Workshop issues this
command.
makecommand -f model.mk
makecommand is defined by the MAKE macro in your system’s template makefile
(see Figure 17-6 on page 17-31). You can specify additional options to make in
the Make command field of the Real-Time Workshop page. (see “Make
Command Field” on page 3-8 and “Template Makefiles and Make Options” on
page 3-102.)
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 template makefile specifies the available make
command options. If these options do not provide you with enough flexibility,
you can configure your own template makefile.
Make Utilities
The make utility lets you control nearly every aspect of building your real-time
program. There are several different versions of make available. The Real-Time
Workshop provides the Free Software Foundation’s GNU Make for both UNIX
and PC platforms in the platform-specific subdirectories below matlabroot/
rtw/bin.
It is possible to use other versions of make with the Real-Time Workshop,
although GNU Make is recommended. To ensure compatibility with the
Real-Time Workshop, make sure that your version of make supports the
following command format.
makecommand −f model.mk
17-29
17
Targeting Real-Time Systems
Structure of the Template Makefile
A template makefile has four sections:
• The first section contains initial comments that describe what this makefile
targets.
• The second section defines macros that tell make_rtw how to process the
template makefile. The macros are:
- MAKE — This is the command used to invoke the make utility. For example,
if MAKE = mymake, then the make command invoked is
mymake −f model.mk
- HOST — What platform this template makefile is targeted for. This can be
HOST=PC, UNIX, computer_name (see the MATLAB computer command), or
ANY.
- BUILD — This tells make_rtw whether or not (BUILD=yes or no) it should
invoke make from the Real-Time Workshop build procedure.
- SYS_TARGET_FILE — Name of the system target file. This is used for
consistency checking by make_rtw to verify that the correct system target
file was specified in the Target configuration section of the Real-Time
Workshop page of the Simulation Parameters dialog box.
- BUILD_SUCCESS — An optional macro that specifies the build success string
to be displayed on successful make completion on the PC. For example,
BUILD_SUCCESS = ### Successful creation of
- BUILD_ERROR — An optional macro that specifies the build error message
to be displayed when an error is encountered during the make procedure.
For example,
BUILD_ERROR = ['Error while building ', modelName]
The following DOWNLOAD options apply only to the Tornado target:
- 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 successful
download. For example,
DOWNLOAD_SUCCESS = ### Downloaded
17-30
Customizing the Build Process
- 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]
• The third section defines the tokens make_rtw expands (see Table 17-3).
• The fourth 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.
Figure 17-6 shows the general structure of a template makefile.
#-- Section 1: Comments ------------------------------------------------------#
# Description of target type and version of make for which
# this template makefile is intended.
# Also documents any optional build arguments.
#-- Section 2: Macros read by make_rtw ---------------------------------------#
# The following macros are read by the Real-Time Workshop build procedure:
#
# MAKE
- This is the command used to invoke the make utility.
# HOST
- Platform this template makefile is designed
#
(i.e., PC or UNIX)
# BUILD
- Invoke make from the Real-Time Workshop build procedure
#
(yes/no)?
# SYS_TARGET_FILE - Name of system target file.
Comments
make_rtw
macros
MAKE
= make
HOST
= UNIX
BUILD
= yes
SYS_TARGET_FILE = system.tlc
#-- Section 3: Tokens expanded by make_rtw -----------------------------------#
make_rtw
MODEL
MODULES
MAKEFILE
MATLAB_ROOT
...
COMPUTER
BUILDARGS
=
=
=
=
|>MODEL_NAME<|
|>MODEL_MODULES<|
|>MAKEFILE_NAME<|
|>MATLAB_ROOT<|
tokens
= |>COMPUTER<|
= |>BUILDARGS<|
#-- Section 4: Build rules ---------------------------------------------------#
# The build rules are specific to your target and version of make.
Build rules
Figure 17-6: Structure of aTemplate Makefile
17-31
17
Targeting Real-Time Systems
Customizing and Creating Template Makefiles
To customize or create a new template makefile, we recommend that you copy
an existing template makefile to your local working directory and modify it.
This section shows, through an example, how to use macros and
file-pattern-matching expressions in a template makefile 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 needed to build or rebuild 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
C 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
In this example, we assumed a UNIX environment. In a PC environment the
file extensions and compile and link commands will be 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
17-32
Customizing the Build Process
If file1.o doesn’t exist, or if file1.o is older than file1.c, make compiles
file1.c.
The format of Real-Time Workshop template makefiles follows the above
example. Our template makefiles use additional features of make such as
macros and file-pattern-matching expressions. In most versions of make, a
macro is defined via
MACRO_NAME = value
References to macros are made via $(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 GNU 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 $< above is a special macro that equates to the dependency file (i.e.,
file1.c or file2.c). Thus, using macros and the “%” pattern matching
character, the above example can be reduced to
SRCS = file1.c file2.c
OBJS = $(SRCS:.c=.o)
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 (.c) with the object file extension (.o). This example also
generalized the build rule for the program, test, to use the special “$@” macro.
17-33
17
Targeting Real-Time Systems
Creating Device Drivers
Device drivers that communicate with target hardware are essential to many
real-time development projects. This section describes how to integrate device
drivers into your target system. This includes incorporating drivers into your
Simulink model and into the code generated from that model.
Device drivers are implemented as Simulink device driver blocks. A device
driver block is an S-Function block that is bound to user-written driver code.
To implement device drivers, you should be familiar with the Simulink C MEX
S-function format and API. The following documents contain more information
about C MEX S-functions:
• Writing S-Functions describes S-functions, including how to write both
inlined and noninlined S-functions and how to access parameters from a
masked S-function. Writing S-Functions also describes how to use the special
mdlRTW function to parameterize an inlined S-function.
• “External Interfaces” in the MATLAB online documentation explains how to
write C and other programs that interact with MATLAB via the MEX API.
Simulink’s S-function API is built on top of this API. To pass parameters to
your device driver block from MATLAB/Simulink you must use the MEX
API. MATLAB Application Program Interface Reference Guide contains
reference descriptions for the required MATLAB mx* routines.
• Target Language Compiler Reference Guide describes the Target Language
Compiler. Knowledge of the Target Language Compiler is required in order
to inline S-functions. The Target Language Compiler Reference Guide also
describes the structure of the model.rtw file.
• “Using Masks to Customize Blocks” in Using Simulink describes how to
create a mask for an S-function.
Note Device driver blocks must be implemented as C MEX S-functions, not
as M-file S-functions. C MEX S-functions are limited to a subset of the
features available in M-file S-functions. See “Limitations of Device Driver
Blocks” on page 17-37 for information.
17-34
Creating Device Drivers
This section covers the following topics:
• Inlined and noninlined device drivers
• General requirements and limitations for device drivers
• Obtaining S-function parameter values from a dialog box
• Writing noninlined device drivers
• Writing inlined device drivers
• Building the device driver MEX-file
Inlined and Noninlined Drivers
In your target system, a device driver has a dual function. First, it functions as
a code module that you compile and link with other code generated from your
model by Real-Time Workshop. In addition, the driver must interact with
Simulink during simulation. To meet both these requirements, you must
incorporate your driver code into a Simulink device driver block.
You can build your driver S-function in several ways:
• As a MEX-file component, bound to an S-Function block, for use in a
Simulink model. In this case, the Simulink engine calls driver routines in the
MEX-file during execution of the model.
• As a module within a stand-alone real-time program that is generated from
a model by Real-Time Workshop. The driver routines are called from within
the application in essentially the same way that Simulink calls them.
In many cases, the code generated from driver blocks for real-time execution
must run differently from the code used by the blocks in simulation. For
example, an output driver may write to hard device addresses in real time;
but these write operations could cause errors in simulation.
Real-Time Workshop provides standard compilation conditionals and
include files to let you build the drivers for both cases. (See “Conditional
Compilation for Simulink and Real-Time” on page 17-40.)
• As inlined code. The Target Language Compiler enables you to generate the
explicit code from your routines (instead of calls to these routines) in the body
of the application. Inlined code eliminates calling overhead, and reduces
memory usage.
Inlining an S-function can improve its performance significantly. However,
there is a tradeoff in increased development and maintenance effort. To inline
17-35
17
Targeting Real-Time Systems
a device driver block, you must implement the block twice: first, as a C
MEX-file, and second, as a TLC program.
The C MEX-file version is for use in simulation. Since a simulation normally
does not have access to I/O boards or other target hardware, the C MEX-file
version often acts as a “dummy” block within a model. For example, a
digital-to-analog converter (DAC) device driver block is often implemented as
a stub for simulation.
Alternatively, the C MEX-file version can simulate the behavior of the
hardware. For example, an analog-to-digital converter (ADC) device driver
block might read sample values from a data file or from the MATLAB
workspace.
The TLC version generates actual working code that accesses the target
hardware in a production system.
Inlined device drivers are an appropriate design choice when:
• You are using the Real-Time Workshop Embedded Coder target. Inlined
S-functions are required when building code from the Real-Time Workshop
Embedded Coder target. S-functions for other targets can be either inlined
or noninlined.
• You need production code generated from the S-function to behave
differently than code used during simulation. For example, an output device
block may write to an actual hardware address in generated code, but
perform no output during simulation.
• You want to avoid overhead associated with calling the S-function API.
• You want to reduce memory usage. Note that each noninlined S-function
creates its own Simstruct. Each Simstruct uses over 1K of memory. Inlined
S-functions do not allocate any Simstruct. For optimal memory usage,
consider using inlined S-functions with the Real-Time Workshop Embedded
Coder target.
• You want to avoid making calls to routines that are required by Simulink,
but which are empty, in your generated code.
17-36
Creating Device Drivers
Device Driver Requirements and Limitations
In order to create a device driver block, the following components are required:
• Hardware-specific driver code, which handles communication between a
real-time program and an I/O device. See your I/O device documentation for
information on hardware requirements.
• S-function code, which implements the model initialization, output, and
other functions required by the S-function API. The S-function code calls
your driver code.
Your S-function code and the hardware-specific driver code are compiled and
linked into a component that is bound to an S-Function block in your
Simulink model. The MATLAB mex utility builds this component (a DLL
under Windows, or a shared library under UNIX).
We recommend that you use the S-function template provided by the
Real-Time Workshop as a starting point for developing your driver S-functions.
The template file is
matlabroot/simulink/src/sfuntmpl.c
An extensively commented version of the S-function template is also available.
See matlabroot/simulink/src/sfuntmpl.doc.
The following components are optional:
• A TLC file that generates inline code for the S-function.
• A mask for the device driver block to create a customized user interface.
Limitations of Device Driver Blocks
The following limitations apply to noninlined driver blocks:
• Only a subset of MATLAB API functions are supported. See the “Noninlined
S-functions” section of Chapter 4 of Writing S-Functions for a complete list
of supported calls.
• Parameters must be doubles or characters contained in scalars, vectors, or
2-D matrices.
The following applies to inlined driver blocks:
• If the driver does not have a mdlRTW function, parameter restrictions are the
same as for noninlined drivers.
• If the driver has a mdlRTW function, any parameter type is supported.
17-37
17
Targeting Real-Time Systems
Preemption
Consider preemption issues in the design of your drivers. In a typical real-time
program, a timer interrupt invokes rtOneStep, which in turn calls MdlOutputs,
which in turn calls your input (ADC) and /or output (DAC) drivers. In this
situation, your drivers are interruptible.
Parameterizing Your Driver
You can add a custom icon, dialog box, and initialization commands to an
S-Function block by masking it. This provides an easy-to-use graphical user
interface for your device driver in the Simulink environment.
You can parameterize your driver by letting the user enter hardware-related
variables. Figure 17-7 shows the dialog box of a masked device driver block for
an input (ADC) device. The Simulink user can enter the device address, the
number of channels, and other operational parameters.
Figure 17-7: Dialog Box for a Masked ADC Driver Block
A masked S-Function block obtains parameter data from its dialog box using
macros and functions provided for the purpose.
To obtain a parameter value from the dialog:
17-38
Creating Device Drivers
1 Access the parameter from the dialog box using the ssGetSFcnParam macro.
The arguments to ssGetSFcnParam are a pointer to the block’s Simstruct,
and the index (0-based) to the desired parameter. For example, use the
following call to access the Number of Channels parameter from the dialog
above.
ssGetSFcnParam(S,3); /* S points to block’s Simstruct */
2 Parameters are stored in arrays of type mxArray, even if there is only a
single value. Get a particular value from the input mxArray using the
mxGetPr function. The following code fragment extracts the first (and only)
element in the Number of Channels parameter.
#define NUM_CHANNELS_PARAM
(ssGetSFcnParam(S,3))
#define NUM_CHANNELS ((uint_T) mxGetPr(NUM_CHANNELS_PARAM)[0])
uint_T num_channels;
num_channels = NUM_CHANNELS;
It is typical for a device driver block to read and validate input parameters in
its mdlInitializeSizes function. See the listing “adc.c” on page 17-55 for an
example.
By default, S-function parameters are tunable. To make a parameter
nontunable, use the ssSetSFcParamNotTunable macro in the
mdlInitializeSizes routine. Nontunable S-function parameters become
constants in the generated code, improving performance.
For further information on creation and use of masked blocks, see the Using
Simulink and Writing S-Functions manuals.
Writing a Noninlined S-Function Device Driver
Overview
Device driver S-functions are relatively simple to implement because they
perform only a few operations. These operations include:
• Initializing the SimStruct.
• Initializing the I/O device.
• Calculating the block outputs. How this is done depends upon the type of
driver being implemented:
17-39
17
Targeting Real-Time Systems
- An input driver for a device such as an ADC reads values from an I/O
device and assigns these values to the block’s output vector y.
- An output driver for a device such as a DAC writes values from the block’s
input vector u to an I/O device.
• Terminating the program. This may require setting hardware to a “neutral”
state; for example, zeroing DAC outputs.
Your driver performs these operations by implementing certain specific
functions required by the S-function API.
Since these functions are private to the source file, you can incorporate
multiple instances of the same S-function into a model. Note that each such
noninlined S-function also instantiates a SimStruct.
Conditional Compilation for Simulink and Real-Time
Noninlined S-functions must function in both Simulink and in real-time
environments. The Real-Time Workshop defines the preprocessor symbols
MATLAB_MEX_FILE, RT, and NRT to distinguish simulation code from real-time
code. Use these symbols as follows:
• MATLAB_MEX_FILE
Conditionally include code that is intended only for use in simulation under
this symbol. When you build your S-function as a MEX-file via the mex
command, MATLAB_MEX_FILE is automatically defined.
• RT
Conditionally include code that is intended to run only in a real-time
program under this symbol. When you generate code via the Real-Time
Workshop build command, RT is automatically defined.
• NRT
Conditionally include code that is intended only for use with a variable-step
solver, in a non-real-time standalone simulation or in a MEX-file for use with
Simulink, under this symbol.
Real-Time Workshop provides these conditionals to help ensure that your
driver S-functions access hardware only when it is appropriate to do so. Since
your target I/O hardware is not present during simulation, writing to
addresses in the target environment can result in illegal memory references,
overwriting system memory, and other severe errors. Similarly, read
17-40
Creating Device Drivers
operations from nonexistent hardware registers can cause model execution
errors.
In the following code fragment, a hardware initialization call is compiled in
generated real-time code. During simulation, a message is printed to the
MATLAB command window.
#if defined(RT)
/* generated code calls function to initialize an A/D device */
INIT_AD();
#elif defined(MATLAB_MEX_FILE)
/* during simulation, just print a message */
if (ssGetSimMode(S) == SS_SIMMODE_NORMAL) {
mexPrintf("\n adc.c: Simulating initialization\n”);
}
#endif
The MATLAB_MEX_FILE and RT conditionals also control the use of certain
required include files. See “Required Defines and Include Files” below.
You may prefer to control execution of real-time and simulation code by some
other means. For an example, see the use of the variable ACCESS_HW in
matlabroot/rtw/c/dos/devices/das16ad.c
Required Defines and Include Files
Your driver S-function must begin with the following three statements, in the
following order:
1 #define S_FUNCTION_NAME name
This defines the name of the entry point for the S-function code. name must
be the name of the S-function source file, without the .c extension. For
example, if the S-function source file is das16ad.c:
#define S_FUNCTION_NAME das16ad
2 #define S_FUNCTION_LEVEL 2
This statement defines the file as a level 2 S-function. This allows you to
take advantage of the full feature set included with S-functions. Level-1
S-functions are currently used only to maintain backwards compatibility.
17-41
17
Targeting Real-Time Systems
3 #include “simstruc.h”
The file simstruc.h defines the SimStruct (the Simulink data structure)
and associated accessor macros. It also defines access methods for the mx*
functions from the MATLAB MEX API.
Depending upon whether you intend to build your S-function as a MEX file or
as real-time code, you must include one of the following files at the end of your
S-function:
• simulink.c provides required functions interfacing to Simulink.
• cg_sfun.h provides the required S-function entry point for generated code.
A noninlined S-function should conditionally include both these files, as in the
following code from sfuntmpl.c:
#ifdef MATLAB_MEX_FILE
/* File being compiled as a MEX-file? */
#include "simulink.c"
/* MEX-file interface mechanism */
#else
#include "cg_sfun.h" /* Code generation registration function */
#endif
Required Functions
The S-function API requires you to implement several functions in your driver:
• mdlInitializeSizes specifies the sizes of various parameters in the
SimStruct, such as the number of output ports for the block.
• mdlInitializeSampleTimes specifies the sample time(s) of the block.
If your device driver block is masked, your initialization functions can obtain
the sample time and other parameters entered by the user in the block’s
dialog box.
• mdlOutputs: for an input device, reads values from the hardware and sets
these values in the output vector y. For an output device, reads the input u
from the upstream block and outputs the value(s) to the hardware.
• mdlTerminate resets hardware devices to a desired state, if any. This
function may be implemented as a stub.
In addition to the above, you may want to implement the mdlStart function.
mdlStart, which is called once at the start of model execution, is useful for
operations such as setting I/O hardware to some desired initial state.
This following sections provide guidelines for implementing these functions.
17-42
Creating Device Drivers
mdlInitializeSizes
In this function you specify the sizes of various parameters in the SimStruct.
This information may depend upon the parameters passed to the S-function.
“Parameterizing Your Driver” on page 17-38 describes how to access parameter
values specified in S-function dialog boxes.
Initializing Sizes - Input Devices. The mdlInitializeSizes function sets size
information in the SimStruct. The following implementation of
mdlInitializeSizes initializes a typical ADC driver block.
static void mdlInitializeSizes(SimStruct *S)
{
uint_T num_channels;
ssSetNumSFcnParams(S, 3); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)){
/*Return if number of expected != number of actual params */
return;
}
num_channels = mxGetPr(NUM_CHANNELS_PARAM)[0];
ssSetNumInputPorts(S, 0);
ssSetNumOutputPorts(S, num_channels);
ssSetNumSampleTimes(S,1);
}
This routine first validates that the number of input parameters is equal to the
number of parameters in the block’s dialog box. Next, it obtains the Number of
Channels parameter from the dialog.
ssSetNumInputPorts sets the number of input ports to 0 because an ADC is a
source block, having only outputs.
ssSetNumOutputPorts sets the number of output ports equal to the number of
I/O channels obtained from the dialog box.
ssSetNumSampleTimes sets the number of sample times to 1. This would be the
case where all ADC channels run at the same rate. Note that the actual sample
period is set in mdlInitializeSampleTimes.
17-43
17
Targeting Real-Time Systems
Note that by default, the ADC block has no direct feedthrough. The ADC output
is calculated based on values read from hardware, not from data obtained from
another block.
Initializing Sizes - Output Devices. Initializing size information for an output
device, such as a DAC, differs in several important ways from initializing sizes
for an ADC:
• Since the DAC obtains its inputs from other blocks, the number of channels
is equal to the number of inputs.
• The DAC is a sink block. That is, it has input ports but no output ports. Its
output is written to a hardware device.
• The DAC block has direct feedthrough. The DAC block cannot execute until
the block feeding it updates its outputs.
The following example is an implementation of mdlInitializeSizes for a DAC
driver block.
static void mdlInitializeSizes(SimStruct *S)
{
uint_T num_channels;
ssSetNumSFcnParams(S, 3); /* Number of expected parameters */
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)){
/* Return if number of expected != number of actual params */
return;
}
num_channels = mxGetPr(NUM_CHANNELS_PARAM)[0];
ssSetNumInputPorts(S, num_channels);
/* Number of inputs is now the number of channels. */
ssSetNumOutputPorts(S, 0);
/* Set direct feedthrough for all ports */
{
uint_T i;
for(i=0, i < num_channels, i++) {
ssSetInputPortDirectFeedThrough(S,i,1);
}
}
ssSetNumSampleTimes(S, 1);
}
17-44
Creating Device Drivers
mdlInitializeSampleTimes
Device driver blocks are discrete blocks, requiring you to set a sample time. The
procedure for setting sample times is the same for both input and output device
drivers. Assuming that all channels of the device run at the same rate, the
S-function has only one sample time.
The following implementation of mdlInitializeSampleTimes reads the sample
time from a block’s dialog box. In this case, sample time is the fifth parameter
in the dialog box. The sample time offset is set to 0.
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, mxGetPr(ssGetSFcnParams(S,4))[0]);
ssSetOffsetTime(S, 0, 0.0);
}
mdlStart
mdlStart is an optional function. It is called once at the start of model
execution, and is often used to initialize hardware. Since it accesses hardware,
you should compile it conditionally for use in real-time code or simulation, as
in this example:
static void mdlStart(SimStruct *S)
{
#if defined(RT)
/* Generated code calls function to initialize an A/D device */
INIT_AD(); /* This call accesses hardware */
#elif defined(MATLAB_MEX_FILE)
/* During simulation, just print a message */
if (ssGetSimMode(S) == SS_SIMMODE_NORMAL) {
mexPrintf("\n adc.c: Simulating initialization\n");
}
#endif
}
mdlOutputs
The basic purpose of a device driver block is to allow your program to
communicate with I/O hardware. Typically, you accomplish this by using low
level hardware calls that are part of your compiler’s C library, or by using
C-callable functions provided with your I/O hardware.
17-45
17
Targeting Real-Time Systems
All S-functions implement a mdlOutputs function to calculate block outputs.
For a device driver block, mdlOutputs contains the code that reads from or
writes to the hardware.
mdlOutputs - Input Devices. In a driver for an input device (such as an ADC),
mdlOutputs must:
• Initiate a conversion for each channel.
• Read the board’s ADC output for each channel (and perhaps apply scaling to
the values read).
• Set these values in the output vector y for use by the model.
The following code is the mdlOutputs function from the ADC driver
matlabroot/rtw/c/dos/devices/das16ad.c. The function uses macros
defined in matlabroot/rtw/c/dos/devices/das16ad.h to perform low-level
hardware access. Note that the Boolean variable ACCESS_HW (rather than
conditional compilation) controls execution of simulation and real-time code.
The real-time code reads values from the hardware and stores them to the
output vector. The simulation code simply outputs 0 on all channels.
static void mdlOutputs(SimStruct *S, int_T tid)
{
real_T *y = ssGetOutputPortRealSignal(S,0);
uint_T i;
if (ACCESS_HW) {
/* Real-time code reads hardware*/
ADCInfo
*adcInfo
= ssGetUserData(S);
uint_T
baseAddr
= adcInfo->baseAddr;
real_T
offset
= adcInfo->offset;
real_T
resolution = adcInfo->resolution;
/* For each ADC channel initiate conversion,*/
/* then read channel value, scale and offset it and store */
/* it to output y */
for (i = 0; i < NUM_CHANNELS; i++) {
uint_T adcValue;
adcStartConversion(baseAddr);
for ( ; ; ){
if (!adcIsBusy(baseAddr)) break;
}
adcValue = adcGetValue(baseAddr);
17-46
Creating Device Drivers
y[i] = offset + resolution*adcValue;
}
}
else {
/* simulation code just zeroes the output for all channels*/
for (i = 0; i < NUM_CHANNELS; i++){
y[i] = 0.0;
}
}
}
mdlOutputs - Output Devices. In a driver for an output device (such as a DAC),
mdlOutputs must:
• Read the input u from the upstream block.
• Set the board’s DAC output for each channel (and apply scaling to the input
values if necessary).
• Initiate a conversion for each channel.
The following code is the mdlOutputs function from the DAC driver
matlabroot/rtw/c/dos/devices/das16da.c. The function uses macros
defined in matlabroot/rtw/c/dos/devices/das16ad.h to perform low-level
hardware access. This function iterates over all channels, obtaining and
scaling a block input value. It then range-checks and (if necessary) trims each
value. Finally it writes the value to the hardware.
In simulation, this function is a stub.
static void mdlOutputs(SimStruct *S, int_T tid)
{
if (ACCESS_HW) {
int_T
i;
DACInfo
*dacInfo
= ssGetUserData(S);
uint_T
baseAddr
= dacInfo->baseAddr;
real_T
resolution = dacInfo->resolution;
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
for (i = 0; i < NUM_CHANNELS; i++) {
uint_T codeValue;
/* Get and scale input for channel i. */
real_T value = (*uPtrs[i] - MIN_OUTPUT)*resolution;
/* Range check value */
17-47
17
Targeting Real-Time Systems
value = (value < DAC_MIN_OUTPUT) ? DAC_MIN_OUTPUT : value;
value = (value > DAC_MAX_OUTPUT) ? DAC_MAX_OUTPUT : value;
codeValue = (uint_T) value;
/* Output to hardware */
switch (i) {
case 0:
dac0SetValue(baseAddr, codeValue);
break;
case 1:
dac1SetValue(baseAddr, codeValue);
break; }
}
}
}
mdlTerminate
This final required function is typically needed only in DAC drivers. The
following routine sets the output of each DAC channel to zero:
static void mdlTerminate(SimStruct *S)
{
uint_T num_channels;
uint_T i;
num_channels = (uint_t)mxGetPr(ssGetSFcnParams(S,0)[0]);
for (i = 0; i < num_channels; i++){
ds1102_da(i + 1, 0.0); /* Hardware-specific DAC output */
}
}
ADC drivers usually implement mdlTerminate as an empty stub.
Writing an Inlined S-Function Device Driver
Overview
To inline a device driver, you must provide:
• driver.c: C MEX S-function source code, implementing the functions
required by the S-function API. These are the same functions required for
noninlined drivers, as described in “Required Functions” on page 17-42. For
17-48
Creating Device Drivers
these functions, only the code for simulation in Simulink simulation is
required.
It is important to ensure that driver.c does not attempt to read or write
memory locations that are intended to be used in the target hardware
environment. The real-time driver implementation, generated via a
driver.tlc file, should access the target hardware.
• Any hardware support files such as header files, macro definitions, or code
libraries that are provided with your I/O devices.
• Optionally, a mdlRTW function within driver.c. The sole purpose of this
function is to evaluate and format parameter data during code generation.
The parameter data is output to the model.rtw file. If your driver block does
not need to pass information to the code generation process, you do not need
to write a mdlRTW function. See “mdlRTW and Code Generation” on page
17-52 .
• driver.dll (PC) or driver (UNIX): MEX-file built from your C MEX
S-function source code. This component is used:
- In simulation: Simulink calls the simulation versions of the required
functions
- During code generation: if a mdlRTW function exists in the MEX-file, the
code generator executes it to write parameter data to the model.rtw file.
• driver.tlc: TLC functions that generate real-time implementations of the
functions required by the S-function API.
Example: An Inlined ADC Driver
As an aid to understanding the process of inlining a device driver, this section
describes an example driver block for an ADC device. “Source Code for Inlined
ADC Driver” on page 17-55 lists code for:
• adc.c, the C MEX S-function
• adc.tlc, the corresponding TLC file
• device.h, a hardware-specific header file included in both the simulation
and real-time generated code
The driver S-Function block is masked and has an icon. Figure 17-8 shows a
model using the driver S-Function block. Figure 17-9 shows the block’s dialog
box.
17-49
17
Targeting Real-Time Systems
Figure 17-8: ADC S-function Driver Block in a Model
The dialog box lets the user enter:
• The ADC base address
• An array defining its signal range
• Its gain factor
• The block’s sample time
17-50
Creating Device Drivers
Figure 17-9: ADC Driver Dialog Box
Simulation Code. adc.c consists almost entirely of functions to be executed
during simulation. (The sole exception is mdlRTW, which executes during code
generation.) Most of these functions are similar to the examples of
non-real-time code given in “Writing a Noninlined S-Function Device Driver”
on page 17-39. The S-function implements the following functions:
• mdlInitializeSizes validates input parameters (via mdlCheckParameters)
and declares all parameters nontunable. This function also initializes ports
and sets the number of sample times.
• mdlInitializeSampleTimes sets the sample time using the user-entered
value.
• mdlStart prints a message to the MATLAB command window.
• mdlOutputs outputs zero on all channels.
• mdlTerminate is a stub routine.
Since adc.c contains only simulation code, it uses a single test of
MATLAB_MEX_FILE to ensure that it is compiled as a C MEX-file.
#ifndef MATLAB_MEX_FILE
#error "Fatal Error: adc.c can only be used to create C-MEX S-Function"
#endif
For the same reason, adc.c unconditionally includes simulink.c.
17-51
17
Targeting Real-Time Systems
mdlRTW and Code Generation. mdlRTW is a mechanism by which an S-function can
generate and write data structures to the model.rtw file. The Target Language
Compiler, in turn, uses these data structures when generating code. Unlike the
other functions in the driver, mdlRTW executes at code generation time.
In this example, mdlRTW calls the ssWriteRTWParamSettings function to
generate a structure that contains both user-entered parameter values (base
address, hardware gain) and values computed from user-entered values
(resolution, offset).
static void mdlRTW(SimStruct *S)
{
boolean_T polarity
= adcIsUnipolar(MIN_SIGNAL_VALUE, MAX_SIGNAL_VALUE);
real_T
offset
= polarity ? 0.0 : MIN_SIGNAL_VALUE/HARDWARE_GAIN;
real_T
resolution = (((MAX_SIGNAL_VALUE-MIN_SIGNAL_VALUE)/HARDWARE_GAIN)/
ADC_NUM_LEVELS);
char_T
baseAddrStr[128];
if ( mxGetString(BASE_ADDRESS_PARAM, baseAddrStr, 128) ) {
ssSetErrorStatus(S, "Error reading Base Address parameter, "
"need to increase string buffer size.");
return;
}
if ( !ssWriteRTWParamSettings(S, 4,
SSWRITE_VALUE_QSTR,
SSWRITE_VALUE_NUM,
SSWRITE_VALUE_NUM,
SSWRITE_VALUE_NUM,
"BaseAddress",
"HardwareGain",
"Resolution",
"Offset",
baseAddrStr,
HARDWARE_GAIN,
resolution,
offset) ) {
return; /* An error occured, which will be reported by Simulink. */
}
} /* end: mdlRTW */
17-52
Creating Device Drivers
The structure defined in model.rtw is
SFcnParamSettings {
BaseAddress "0x300"
HardwareGain 1.0
Resolution 0.0048828125
Offset -10.0
}
(The actual values of SFcnParamSettings derive from data entered by the
user.)
Values stored in the SFcnParamSettings structure are referenced in
driver.tlc, as in the following assignment statement.
%assign baseAddr = SFcnParamSettings.BaseAddress
The Target Language Compiler uses variables such as baseAddr to generate
parameters in real-time code files such as model.c and model.h. This is
discussed in the next section.
The TLC File. adc.tlc contains three TLC functions. The BlockTypeSetup
function generates the statement
#include "device.h"
in the model.h file. The other two functions, Start and Outputs, generate code
within the MdlStart and MdlOutputs functions of model.c.
Statements in adc.tlc, and in the generated code, employ macros and symbols
defined in device.h, and parameter values in the SFcnParamSettings
structure. The following code uses the values from the SFcnParamSettings
structure above to generate code containing constant values:
%assign baseAddr = SFcnParamSettings.BaseAddress
%assign hwGain = SFcnParamSettings.HardwareGain
...
adcSetHardwareGain(%<baseAddr>, adcGetGainMask(%<hwGain>));
The TLC code above generates this statement in the MdlOutputs function of
model.c.
adcSetHardwareGain(0x300, adcGetGainMask(1.0));
17-53
17
Targeting Real-Time Systems
adcSetHardwareGain and adcGetGainMask are macros that expand to low-level
hardware calls.
S-Function Wrappers
Another technique for integrating driver code into your target system is to use
S-function wrappers. In this approach, you write:
• An S-function (the wrapper) that calls your driver code as an external
module
• A TLC file that generates a call to the same driver code that was called in the
wrapper
See Writing S-Functions for a full description of how to use wrapper
S-functions.
Building the MEX-File and the Driver Block
This section outlines how to build a MEX-file from your driver source code for
use in Simulink. For full details on how to use mex to compile the device driver
S-function into an executable MEX-file, see “External Interfaces” in the
MATLAB online documentation. For details on masking the device driver
block, see “Using Masks to Customize Blocks” in Using Simulink.
1 Your C S-function source code should be in your working directory. To build
a MEX-file from mydriver.c type
mex mydriver.c
mex builds mydriver.dll (PC) or mydriver (UNIX).
2 Add an S-Function block (from the Simulink Functions & Tables library in
the Library Browser) to your model.
3 Double-click the S-Function block to open the Block Parameters dialog.
Enter the S-function name mydriver. The block is now bound to the
mydriver MEX-file.
4 Create a mask for the block if you want to use a custom icon or dialog.
17-54
Creating Device Drivers
Source Code for Inlined ADC Driver
These files are described in “Example: An Inlined ADC Driver” on page 17-49.
adc.c
/*
* File
: adc.c
* Abstract:
* Example S-function device driver (analog to digital convertor) for use
* with Simulink and Real-Time Workshop.
* This S-function contains simulation code only (except mdlRTW, used
* only during code generation.) An error will be generated if
* this code is compiled without MATLAB_MEX_FILE defined. That
* is,it must be compiled via the MATLAB mex utility.
*
* DEPENDENCIES:
* (1) This S-function is intended for use in conjunction with adc.tlc,
* a Target Language Compiler program that generates inlined, real-time code that
* implements the real-time I/O functions required by mdlOutputs, etc.
*
* (2) device.h defines hardware-specific macros, etc. that implement
* actual I/O to the board
*
* (3) This file contains a mdlRTW function that writes parameters to
* the model.rtw file during code generation.
*
* Copyright (c) 1994-2000 by The MathWorks, Inc. All Rights Reserved.
*
*/
/*********************
* Required defines *
*********************/
#define S_FUNCTION_NAME adc
#define S_FUNCTION_LEVEL 2
/*********************
* Required includes *
*********************/
#include "simstruc.h"
/* The Simstruct API, definitions and macros */
/*
* Generate a fatal error if this file is (by mistake) used by Real-Time
* Workshop. There is a target file corresponding to this S-function: adc.tlc,
* which should be used to generate inlined code for this S-funciton.
*/
#ifndef MATLAB_MEX_FILE
# error "Fatal Error: adc.c can only be used to create C-MEX S-Function"
#endif
17-55
17
Targeting Real-Time Systems
/*
* Define the number of S-function parameters and set up convenient macros to
* access the parameter values.
*/
#define NUM_S_FUNCTION_PARAMS
(4)
#define N_CHANNELS (2) /* For this example, num. of channels is fixed */
/* 1. Base Address */
#define BASE_ADDRESS_PARAM
(ssGetSFcnParam(S,0))
/* 2. Analog Signal Range */
#define SIGNAL_RANGE_PARAM
#define MIN_SIGNAL_VALUE
#define MAX_SIGNAL_VALUE
(ssGetSFcnParam(S,1))
((real_T) (mxGetPr(SIGNAL_RANGE_PARAM)[0]))
((real_T) (mxGetPr(SIGNAL_RANGE_PARAM)[1]))
/* 3. Hardware Gain */
#define HARDWARE_GAIN_PARAM
#define HARDWARE_GAIN
(ssGetSFcnParam(S,2))
((real_T) (mxGetPr(HARDWARE_GAIN_PARAM)[0]))
/* 4. Sample Time */
#define SAMPLE_TIME_PARAM
#define SAMPLE_TIME
(ssGetSFcnParam(S,3))
((real_T) (mxGetPr(SAMPLE_TIME_PARAM)[0]))
/*
* Hardware specific information pertaining to the A/D board. This information
* should be provided with the documentation that comes with the board.
*/
#include "device.h"
/*====================*
* S-function methods *
*====================*/
/* Function: mdlCheckParameters ================================================
* Abstract:
*
Check that the parameters passed to this S-function are valid.
*/
#define MDL_CHECK_PARAMETERS
static void mdlCheckParameters(SimStruct *S)
{
static char_T errMsg[256];
boolean_T allParamsOK = 1;
/*
* Base I/O Address
*/
if (!mxIsChar(BASE_ADDRESS_PARAM)) {
sprintf(errMsg, "Base address parameter must be a string.\n");
allParamsOK = 0;
goto EXIT_POINT;
17-56
Creating Device Drivers
}
/*
* Signal Range
*/
if (mxGetNumberOfElements(SIGNAL_RANGE_PARAM) != 2) {
sprintf(errMsg,
"Signal Range must be a two element vector [minInp maxInp]\n");
allParamsOK = 0;
goto EXIT_POINT;
}
if ( !adcIsSignalRangeParamOK(MIN_SIGNAL_VALUE, MAX_SIGNAL_VALUE) ) {
sprintf(errMsg,
"The specified Signal Range is not supported by I/O board.\n");
allParamsOK = 0;
goto EXIT_POINT;
}
/*
* Hardware Gain
*/
if (mxGetNumberOfElements(HARDWARE_GAIN_PARAM) != 1) {
sprintf(errMsg, "Hardware Gain must be a scalar valued real number\n");
allParamsOK = 0;
goto EXIT_POINT;
}
if (!adcIsHardwareGainParamOK(HARDWARE_GAIN)) {
sprintf(errMsg, "The specified hardware gain is not supported.\n");
allParamsOK = 0;
goto EXIT_POINT;
}
/*
* Sample Time
*/
if (mxGetNumberOfElements(SAMPLE_TIME_PARAM) != 1) {
sprintf(errMsg, "Sample Time must be a positive scalar.\n");
allParamsOK = 0;
goto EXIT_POINT;
}
EXIT_POINT:
if ( !allParamsOK ) {
ssSetErrorStatus(S, errMsg);
}
} /* end: mdlCheckParameters */
/* Function: mdlInitializeSizes ================================================
* Abstract:
* Validate parameters,set number and width of ports.
*/
static void mdlInitializeSizes(SimStruct *S)
{
17-57
17
Targeting Real-Time Systems
/* Set the number of parameters expected. */
ssSetNumSFcnParams(S, NUM_S_FUNCTION_PARAMS);
if ( ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S) ) {
/*
* If the number of parameter passed in is equal to the number of
* parameters expected, then check that the specified parameters
* are valid.
*/
mdlCheckParameters(S);
if ( ssGetErrorStatus(S) != NULL ) {
return; /* Error was reported in mdlCheckParameters. */
}
} else {
return; /* Parameter mismatch. Error will be reported by Simulink. */
}
/*
* This S-functions's parameters cannot be changed in the middle of a
* simulation, hence set them to be nontunable.
*/
{
int_T i;
for (i=0; i < NUM_S_FUNCTION_PARAMS; i++) {
ssSetSFcnParamNotTunable(S, i);
}
}
/* Has no input ports */
if ( !ssSetNumInputPorts(S, 0) ) return;
/* Number of output ports = number of channels specified */
if ( !ssSetNumOutputPorts(S, N_CHANNELS) ) return;
/* Set the width of each output ports to be one. */
{
int_T oPort;
for (oPort = 0; oPort < ssGetNumOutputPorts(S); oPort++) {
ssSetOutputPortWidth(S, oPort, 1);
}
}
ssSetNumSampleTimes( S, 1);
} /* end: mdlInitializeSizes */
/* Function: mdlInitializeSampleTimes ==========================================
* Abstract:
*
Set the sample time of this block as specified via the sample time
*
parameter.
*/
static void mdlInitializeSampleTimes(SimStruct *S)
17-58
Creating Device Drivers
{
ssSetSampleTime(S, 0, SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
} /* end: mdlInitializeSampleTimes */
/* Function: mdlStart ==========================================================
* Abstract:
*
At the start of simulation in Simulink, print a message to the MATLAB
*
command window indicating that output of this block will be zero during
*
simulation.
*/
#define MDL_START
static void mdlStart(SimStruct *S)
{
if (ssGetSimMode(S) == SS_SIMMODE_NORMAL) {
mexPrintf("\n adc.c: The output of the A/D block '%s' will be set "
"to zero during simulation in Simulink.\n", ssGetPath(S));
}
} /* end: mdlStart */
/* Function: mdlOutputs ========================================================
* Abstract:
*
Set the output to zero.
*/
static void mdlOutputs(SimStruct *S, int_T tid)
{
int oPort;
for (oPort = 0; oPort < ssGetNumOutputPorts(S); oPort++) {
real_T *y = ssGetOutputPortRealSignal(S, oPort);
y[0] = 0.0;
}
} /* end: mdlOutputs */
/* Function: mdlTerminate ======================================================
* Abstract:
*
Required S-function method that gets called at the end of simulation
*
and code generation. Nothing to do in simulation.
*/
static void mdlTerminate(SimStruct *S)
{
} /* end: mdlTerminate */
/* Function: mdlRTW ============================================================
* Abstract:
*
Evaluate parameter data and write it to the model.rtw file.
17-59
17
Targeting Real-Time Systems
*/
#define MDL_RTW
static void mdlRTW(SimStruct *S)
{
boolean_T polarity
= adcIsUnipolar(MIN_SIGNAL_VALUE, MAX_SIGNAL_VALUE);
real_T
offset
= polarity ? 0.0 : MIN_SIGNAL_VALUE/HARDWARE_GAIN;
real_T
resolution = (((MAX_SIGNAL_VALUE-MIN_SIGNAL_VALUE)/HARDWARE_GAIN)/
ADC_NUM_LEVELS);
char_T
baseAddrStr[128];
if ( mxGetString(BASE_ADDRESS_PARAM, baseAddrStr, 128) ) {
ssSetErrorStatus(S, "Error reading Base Address parameter, "
"need to increase string buffer size.");
return;
}
if ( !ssWriteRTWParamSettings(S, 4,
SSWRITE_VALUE_QSTR,
SSWRITE_VALUE_NUM,
SSWRITE_VALUE_NUM,
SSWRITE_VALUE_NUM,
"BaseAddress",
"HardwareGain",
"Resolution",
"Offset",
baseAddrStr,
HARDWARE_GAIN,
resolution,
offset) ) {
return; /* An error occured, which will be reported by Simulink. */
}
} /* end: mdlRTW */
/*
* Required include for Simulink-MEX interface mechanism
*/
#include "simulink.c"
/* EOF: adc.c */
adc.tlc
%% File
: adc.tlc
%% Abstract:
%%
Target file for the C-Mex S-function adc.c
%%
%% Copyright (c) 1994-2000 by The MathWorks, Inc. All Rights Reserved.
%%
%implements "adc" "C"
%% Function: BlockTypeSetup ===========================================
%% Abstract:
%%
This function is called once for all instance of the S-function
%% "dac" in the model. Since this block requires hardware specific
%% information about the I/O board, we generate code to include
%% "device.h" in the generated model.h file.
%%
%function BlockTypeSetup(block, system) void
17-60
Creating Device Drivers
%%
%% Use the Target Language Ccompiler global variable INCLUDE_DEVICE_H to make sure that
%% the line "#include device.h" gets generated into the model.h
%%file only once.
%%
%if !EXISTS("INCLUDE_DEVICE_H")
%assign ::INCLUDE_DEVICE_H = 1
%openfile buffer
/* Include information about the I/O board */
#include "device.h"
%closefile buffer
%<LibCacheIncludes(buffer)>
%endif
%endfunction %% BlockTypeSetup
%% Function: Start ====================================================
%% Abstract:
%%
Generate code to set the number of channels and the hardware gain
%% mask in the start function.
%%
%function Start(block, system) Output
/* %<Type> Block: %<Name> (%<ParamSettings.FunctionName>) */
%%
%assign numChannels = block.NumDataOutputPorts
%assign baseAddr
= SFcnParamSettings.BaseAddress
%assign hwGain
= SFcnParamSettings.HardwareGain
%%
%% Initialize the Mux Scan Register to scan from 0 to NumChannels-1.
%% Also set the Gain Select Register to the appropriate value.
%%
adcSetLastChannel(%<baseAddr>, %<numChannels-1>);
adcSetHardwareGain(%<baseAddr>, adcGetGainMask(%<hwGain>));
%endfunction %% Start
%% Function: Outputs =================================================
%% Abstract:
%%
Generate inlined code to perform one A/D conversion on the enabled
%%
channels.
%%
%function Outputs(block, system) Output
%%
%assign offset
= SFcnParamSettings.Offset
%assign resolution = SFcnParamSettings.Resolution
%assign baseAddr
= SFcnParamSettings.BaseAddress
%%
/* %<Type> Block: %<Name> (%<ParamSettings.FunctionName>) */
{
int_T chIdx;
uint_T adcValues[%<NumDataOutputPorts>];
17-61
17
Targeting Real-Time Systems
for (chIdx = 0; chIdx < %<NumDataOutputPorts>; chIdx++) {
adcStartConversion(%<baseAddr>);
while (adcIsBusy(%<baseAddr>)) {
/* wait for conversion */
}
adcValues[chIdx] = adcGetValue(%<baseAddr>);
}
%foreach oPort = NumDataOutputPorts
%assign y = LibBlockOutputSignal(oPort, "", "", 0)
%<y> = %<offset> + %<resolution>*adcValues[%<oPort>];
%endforeach
}
%endfunction %% Outputs
%% EOF: adc.tlc
device.h
/*
* File
: device.h
*
* Copyright (c) 1994-2000 by The MathWorks, Inc. All Rights
* Reserved.
*
*/
/*
* Operating system utilities to read and write to hardware
* registers.
*/
#define ReadByte(addr)
inp(addr)
#define WriteByte(addr,val)
outp(addr,val)
/*=============================================================*
* Specification of the Analog Input Section of the I/O board
* (used in the ADC device driver S-function, adc.c and *adc.tlc)
*=======================================================*/
/*
* Define
* number
*/
#define
#define
#define
macros for the attributes of the A/D board, such as the
of A/D channels and bits per channel.
ADC_MAX_CHANNELS
(16)
ADC_BITS_PER_CHANNEL
(12)
ADC_NUM_LEVELS ((uint_T) (1 << ADC_BITS_PER_CHANNEL))
/*
* Macros to check if the specified parameters are valid.
* These macros are used by the C-Mex S-function, adc.c
17-62
Creating Device Drivers
*/
#define
#define
#define
#define
#define
#define
adcIsUnipolar(lo,hi)
adcIsBipolar(lo,hi)
adcIsSignalRangeParamOK(l,h)
(lo
== 0.0 && 0.0 < hi)
(lo + hi == 0.0 && 0.0 < hi)
(adcIsUnipolar(l,h) || adcIsBipolar(l,h))
adcGetGainMask(g) ( (g==1.0) ? 0x0 : \
( (g==10.0) ? 0x1 : \
( (g==100.0) ? 0x2 : \
( (g==500.0) ? 0x3 : 0x4 ) ) ) )
adcIsHardwareGainParamOK(g)
(adcGetGainMask(g) != 0x4)
adcIsNumChannelsParamOK(n)
(1 <= n && n <= ADC_MAX_CHANNELS)
/* Hardware registers used by the A/D section of the I/O board */
#define
#define
#define
#define
#define
#define
/*
* Macros
*/
#define
#define
#define
#define
#define
#define
#define
ADC_START_CONV_REG(bA)
ADC_LO_BYTE_REG(bA)
ADC_HI_BYTE_REG(bA)
ADC_MUX_SCAN_REG(bA)
ADC_STATUS_REG(bA)
ADC_GAIN_SELECT_REG(bA)
(bA)
(bA)
(bA +
(bA +
(bA +
(bA +
0x1)
0x2)
0x8)
0xB)
for the A/D section of the I/O board
adcSetLastChannel(bA,n) WriteByte(ADC_MUX_SCAN_REG(bA), n<<4)
adcSetHardwareGain(bA,gM) WriteByte(ADC_GAIN_SELECT_REG(bA), gM)
adcStartConversion(bA) WriteByte(ADC_START_CONV_REG(bA), 0x00)
adcIsBusy(bA) (ReadByte(ADC_STATUS_REG(bA)) & 0x80)
adcGetLoByte(bA) ReadByte(ADC_LO_BYTE_REG(bA))
adcGetHiByte(bA) ReadByte(ADC_HI_BYTE_REG(bA))
adcGetValue(bA) ((adcGetLoByte(bA)>>4) | (adcGetHiByte(bA)<<4))
/*============================================================*
* Specification of the Analog Output Section of the I/O board
* (used in the DAC device driver S-function, adc.c and adc.tlc)
*============================================================*/
#define
#define
#define
#define
#define
#define
DAC_BITS_PER_CHANNEL
DAC_UNIPOLAR_ZERO
DAC_BIPOLAR_ZERO
DAC_MIN_OUTPUT
DAC_MAX_OUTPUT
DAC_NUM_LEVELS
(12)
( 0)
(1 << (DAC_BITS_PER_CHANNEL-1))
(0.0)
((real_T) ((1 << DAC_BITS_PER_CHANNEL)-1))
((uint_T) (1 << DAC_BITS_PER_CHANNEL))
/*
* Macros to check if the specified parameters are valid.
* These macros are used by the C-Mex S-function,dac.c.
*/
#define dacIsUnipolar(lo,hi)
(lo
== 0.0 && 0.0 < hi)
#define dacIsBipolar(lo,hi)
(lo+hi == 0.0 && 0.0 < hi)
#define dacIsSignalRangeParamOK(l,h) (dacIsUnipolar(l,h) || dacIsBipolar(l,h))
/* Hardware registers */
17-63
17
Targeting Real-Time Systems
#define DAC_LO_BYTE_REG(bA)
#define DAC_HI_BYTE_REG(bA)
(bA + 0x4)
(bA + 0x5)
#define dacSetLoByte(bA,c) WriteByte(DAC_LO_BYTE_REG(bA),(c & 0x00f)<<4)
#define dacSetHiByte(bA,c) WriteByte(DAC_HI_BYTE_REG(bA),(c & 0xff0)>>4)
#define dacSetValue(bA,c) dacSetLoByte(bA,c); dacSetHiByte(bA,c)
/* EOF: device.h */
17-64
Interfacing Parameters and Signals
Interfacing Parameters and Signals
Simulink external mode (see Chapter 5, “External Mode”) offers a quick and
easy way to monitor signals and modify parameter values while generated
model code executes. However, external mode may not be appropriate for your
application. Some targets (such as the Real-Time Workshop Embedded Coder)
do not support external mode, due to optimizations. In other cases, you may
want existing code to access parameters and signals of a model directly, rather
than using the external mode mechanism.
The Real-Time Workshop supports several approaches to the task of
interfacing block parameters and signals to your hand-written code.
The Workspace Parameter Attributes dialog enables you to declare how to
the generated code allocates memory for variables used in your model. This
allows your supervisory software to read or write block parameter variables as
your model executes. Similarly, the Signal Properties dialog gives your code
access to selected signals within your model. Operation of these dialogs is
described in “Parameters: Storage, Interfacing, and Tuning” on page 3-51 and
“Signals: Storage, Optimization, and Interfacing” on page 3-65.
In addition, the MathWorks provides C and Target Language Compiler APIs
that give your code additional access to block outputs, and parameters that are
stored in global data structures created by the Real-Time Workshop. This
section is an overview of these APIs. This section also includes pointers to
additional detailed API documents shipped with the Real-Time Workshop.
Signal Monitoring via Block Outputs
All block output data is written to the block outputs structure with each time
step in the model code. To access the output of a given block in the block
outputs structure, your code must have the following information, per port:
• The address of the rtB structure where the data is stored
• The number of output ports of the block
• The width of each output
• The data type of the signal
This information is contained in the BlockIOSignals data structure. The TLC
code generation variable, BlockIOSignals, determines whether
BlockIOSignals data is generated. If BlockIOSignals is enabled, a file
17-65
17
Targeting Real-Time Systems
containing an array of BlockIOSignals structures is written during code
generation. This file is named model_bio.c.
BlockIOSignals is disabled by default. To enable generation of model_bio.c,
use a %assign statement in the Configure RTW code generation settings
section of your system target file:
%assign BlockIOSignals = 1
Alternatively, you can append the following command to the System target
file field on the Target configuration section of the Real-Time Workshop
page.
-aBlockIOSignals=1
Note that, depending on the size of your model, the BlockIOSignals array can
consume a considerable amount of memory.
BlockIOSignals and the Local Block Outputs Option
When the Local block outputs code generation option is selected, block
outputs are declared locally in functions instead of being declared globally in
the rtB structure (when possible). The BlockIOSignals array in model_bio.c
will not contain information about such locally declared signals. (Note that
even when all outputs in the system are declared locally, enabling
BlockIOSignals will generate model_bio.c. In such a case the
BlockIOSignals array will contain only a null entry.)
Signals that are designated as test points via the Signal Properties dialog are
declared globally in the rtB structure, even when the Local block outputs
option is selected. Information about test-pointed signals is therefore written
to the BlockIOSignals array in model_bio.c.
Therefore, you can interface your code to selected signals by test-pointing them
and enabling BlockIOSignals, without losing the benefits of the Local block
outputs optimization for the other signals in your model.
17-66
Interfacing Parameters and Signals
model_bio.c and the BlockIO Data Structure
The BlockIOSignals data structure is declared as follows.
typedef struct BlockIOSignals_tag {
char_T *blockName; /* Block's full pathname
(mangled by the Real-Time Workshop) */
char_T *signalName; /* Signal label (unmangled) */
uint_T portNumber; /* Block output port number (start at 0) */
uint_T signalWidth; /* Signal's width */
void *signalAddr;
/* Signal's address in the rtB vector */
char_T *dtName;
/* The C language data type name */
uint_T dtSize;
/* The size (# of bytes) for the data type*/
} BlockIOSignals;
The structure definition is in matlabroot/rtw/c/src/bio_sig.h. The
model_bio.c file includes bio_sig.h. Any source file that references the array
should also include bio_sig.h.
model_bio.c defines an array of BlockIOSignals structures. Each array
element, except the last, describes one output port for a block. The final
element is a sentinel, with all fields set to null values.
17-67
17
Targeting Real-Time Systems
The code fragment below is an example of an array of BlockIOSignals
structures from a model_bio.c file.
#include "bio_sig.h"
/* Block output signal information */
const BlockIOSignals rtBIOSignals[] =
{
/* blockName,
signalName, portNumber, signalWidth, signalAddr,
dtName, dtSize */
{
"simple/Constant",
NULL, 0, 1, &rtB.Constant,
"double", sizeof(real_T)
},
{
"simple/Constant1",
NULL, 0, 1, &rtB.Constant1,
"double", sizeof(real_T)
},
{
"simple/Gain",
"accel", 0, 2, &rtB.accel[0],
"double", sizeof(real_T)
},
{
NULL, NULL, 0, 0, 0, NULL, 0
}
};
Thus, a given block will have as many entries as it has output ports. In the
above example, the simple/Gain structure has a signal named accel on block
output port 0. The width of the signal is 2.
Using BlockIOSignals to Obtain Block Outputs
The model_bio.c array is accessed via the name rtBIOSignals. To avoid
overstepping array bounds, you can do either of the following:
17-68
Interfacing Parameters and Signals
• Use the SimStruct access macro ssGetNumBlockIO to determine the number
of elements in the array.
• Test for a null blockName to identify the last element.
You must then write code that iterates over the rtBIOSignals array and
chooses the signals to be monitored based on the blockName and signalName or
portNumber. How the signals are monitored is up to you. For example, you
could collect the signals at every time step. Alternatively, you could sample
signals asynchronously in a separate, lower priority task.
The following code example is drawn from the main program (rt_main.c) of the
Tornado target. The code illustrates how the StethoScope Graphical
Monitoring/Data Analysis Tool uses BlockIOSignals to collect signal
information in Tornado targets. The following function,
rtInstallRemoveSignals, selectively installs signals from the
BlockIOSignals array into the StethoScope Tool by calling
ScopeInstallSignal. The main simulation task then collects signals by calling
ScopeCollectSignals.
static int_T rtInstallRemoveSignals(SimStruct *S,
char_T *installStr, int_T fullNames, int_T install)
{
uint_T
i, w;
char_T
*blockName;
char_T
name[1024];
extern BlockIOSignals rtBIOSignals[];
int_T
ret = -1;
if (installStr == NULL) {
return -1;
}
i = 0;
while(rtBIOSignals[i].blockName != NULL) {
BlockIOSignals *blockInfo = &rtBIOSignals[i++];
if (fullNames) {
blockName = blockInfo->blockName;
} else {
blockName = strrchr(blockInfo->blockName, '/');
if (blockName == NULL) {
blockName = blockInfo->blockName;
} else {
blockName++;
}
}
if ((*installStr) == '*') {
17-69
17
Targeting Real-Time Systems
} else if (strcmp("[A-Z]*", installStr) == 0) {
if (!isupper(*blockName)) {
continue;
}
} else {
if (strncmp(blockName, installStr, strlen(installStr)) != 0) {
continue;
}
}
/*install/remove the signals*/
for (w = 0; w < blockInfo->signalWidth; w++) {
sprintf(name, "%s_%d_%s_%d", blockName, blockInfo->portNumber,
(blockInfo->signalName==NULL)?"":blockInfo->signalName, w);
if (install) { /*install*/
if (!ScopeInstallSignal(name, "units",
(void *)((int)blockInfo->signalAddr +
w*blockInfo->dtSize),
blockInfo->dtName, 0)) {
fprintf(stderr,"rtInstallRemoveSignals: ScopeInstallSignal "
"possible error: over 256 signals.\n");
return -1;
} else {
ret =0;
}
} else { /*remove*/
if (!ScopeRemoveSignal(name, 0)) {
ifprintf(stderr,"rtInstallRemoveSignals: ScopeRemoveSignal\n"
"%s not found.\n",name);
return -1;
} else {
ret =0;
}
}
}
}
return ret;
}
17-70
Interfacing Parameters and Signals
Below is an excerpt from an example routine that collects signals taken from
the main simulation loop.
/*******************************************
* Step the model for the base sample time *
*******************************************/
MdlOutputs(FIRST_TID);
#ifdef MAT_FILE
if (rt_UpdateTXYLogVars(S) != NULL) {
fprintf(stderr,"rt_UpdateTXYLogVars() failed\n");
return(1);
}
#endif
#ifdef STETHOSCOPE
ScopeCollectSignals(0);
#endif
MdlUpdate(FIRST_TID);
<code continues ...>
See Chapter 12, “Targeting Tornado for Real-Time Applications” for more
information on using StethoScope.
Parameter Tuning via model_pt.c
By enabling the TLC variable ParameterTuning, you can generate a file
containing data structures that enable a running program to access model
parameters without use of external mode. The file is named model_pt.c.
ParameterTuning is disabled by default. To enable generation of model_pt.c,
use a %assign statement in your system target file.
%assign ParameterTuning = 1
Alternatively, you can append the following command to the System target
file field on the Target configuration section of the Real-Time Workshop
page.
-aParameterTuning=1
17-71
17
Targeting Real-Time Systems
model_pt.c contains two parameter mapping structures containing
information required for parameter tuning:
• The BlockTuning structure contains all the modifiable block parameters by
block name and parameter name.
• The VariableTuning structure contains all the modifiable workspace
variables that were specified in a Simulink parameter dialog box.
The structure and content of the model_pt.c file are documented in
matlabroot/rtw/c/src/pt_readme.txt. For example source code using the
parameter tuning API, see matlabroot/rtw/c/src/pt_print.c.
Target Language Compiler API for
Signals and Parameters
The Real-Time Workshop 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 the Target Language
Compiler Reference Guide 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/globalmaplib.tlc. The
comments in the source code fully document the global data map structures
and the library functions.
Note The global data map structures and functions maybe modified and/or
enhanced in future releases.
17-72
Creating an External Mode Communication Channel
Creating an External Mode Communication Channel
This section provides information you will need in order to support external
mode on your custom target, using your own low-level communications layer.
This information includes:
• 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 rebuilding the
ext_comm MEX-file
This section assumes that you are familiar with the execution of Real-Time
Workshop programs, and with the basic operation of external mode. These
topics are described in Chapter 6, “Program Architecture” and Chapter 5,
“External Mode.”
The Design of External Mode
External mode communication between Simulink and a target system is based
on a client/server architecture. The client (Simulink) 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
Simulink 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.
This design makes it possible for different targets to use different transport
layers. For example, the grt, grt_malloc, and Tornado targets support host/
target communication via TCP/IP, whereas the xPC Target supports both
RS232 (serial) and TCP/IP communication.
The Real-Time Workshop provides full source code for both the client and
server-side external mode modules, as used by the grt, grt_malloc, and
Tornado targets. The main client-side module is ext_comm.c. The main
server-side module is ext_svr.c.
These two modules call the TCP/IP transport layer. ext_transport.c
implements the client-side transport functions. ext_svr_transport.c
17-73
17
Targeting Real-Time Systems
contains the corresponding server-side functions. You can modify these files to
support external mode via your own low-level communications layer.
You need only modify those parts of the code that implement low-level
communications. You need not be concerned with issues such as data
conversions between host and target, or with the formatting of messages. Code
provided by the Real-Time Workshop handles these functions.
On the client (Simulink) side, communications are handled by ext_comm, a C
MEX-file. This component is implemented as a DLL on Windows, or as a
shared library on UNIX.
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. These modules, called
from the main program and the model execution engine, are independent of the
generated model code.
To implement your own low-level protocol:
• On the client side, you must replace low-level TCP/IP calls in
ext_transport.c with your own communication calls, and rebuild ext_comm
using the mex command. You should then designate your custom ext_comm
component as the MEX-file for external interface in the Simulink External
Target Interface dialog.
• On the server side, you must replace low-level TCP/IP calls in
ext_svr_transport.c with your own communication calls. If you are writing
your own system target file and/or template makefile, make sure that the
EXT_MODE code generation option is defined. The generated makefile will then
link ext_svr_transport.c and other server code into your executable.
• Define symbols and functions common to both the client and server sides in
ext_transport_share.h.
Overview of External Mode Communications
This section gives a high-level overview of how a Real-Time Workshop
generated program communicates with Simulink in external mode. This
description is based on the TCP/IP version of external mode that ships with
Real-Time Workshop.
17-74
Creating an External Mode Communication Channel
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 Simulink must be executing. Note that this
does not mean that the model code in the server system must be executing.
The server may be waiting for Simulink to issue a command to start model
execution.
The client and server communicate via two sockets. Each socket supports a
distinct channel. The message channel is bidirectional; it carries commands,
responses, and parameter downloads. The unidirectional upload channel is for
uploading signal data to the client. The message channel is given higher
priority.
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, Simulink 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 upload channel. As the target computes model outputs, it also copies
signal values into data upload buffers. This occurs as part of the task
associated with each task identifier (tid). Therefore, data collection occurs in
17-75
17
Targeting Real-Time Systems
the foreground. Transmission of the collected data, however, occurs as a
background task. The background task sends the data in the collection buffers
to Simulink via the upload channel.
The host initiates most exchanges on the message channel. 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
• 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 both sockets. The host also shuts down its sockets,
and exits external mode.
External Mode Source Files
Host (ext_comm) Source Files
The source files for the ext_comm component are located in the directory
matlabroot/rtw/ext_mode:
• ext_comm.c
This file is the core of external mode communication. It acts as a relay station
between the target and Simulink. ext_comm.c communicates to Simulink via
a shared data structure, ExternalSim. It communicates to the target via calls
to the transport layer.
Tasks carried out by ext_comm include establishment of a connection with
the target, downloading of parameters, and termination of the connection
with the target.
• ext_transport.c
This file implements required transport layer functions. (Note that
ext_transport.c includes ext_transport_share.h, which contains
functions common to client and server sides.) The version of
17-76
Creating an External Mode Communication Channel
ext_transport.c shipped with the Real-Time Workshop uses TCP/IP
functions including recv(), send(), and socket().
• ext_main.c
This file is a MEX-file wrapper for external mode. ext_main interfaces to
Simulink via the standard mexFunction call. (See “External Interfaces” in
the MATLAB online documentation for information on mexFunction.)
ext_main contains a function dispatcher, esGetAction, that sends requests
from Simulink to ext_comm.
• ext_convert.c
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
Simulink (via function pointers).
Note You do not need to customize ext_convert in order to implement a
custom transport layer. However, it may be necessary to customize
ext_convert for the intended target. For example, if the target represents the
float data type in Texas Instruments (TI) format, ext_convert must be
modified to perform a TI to IEEE conversion.
• extsim.h
This file defines the ExternalSim data structure and access macros. This
structure is used for communication between Simulink and ext_comm.c.
• extutil.h
This file contains only conditionals for compilation of the assert macro.
Target (Server) Source Files
These files are part of the run-time interface and are linked into the model.exe
executable. They are located in the directory matlabroot/rtw/c/src.
• 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
17-77
17
Targeting Real-Time Systems
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.
The version of ext_svr.c shipped with the Real-Time Workshop uses TCP/
IP functions including recv(), send(), and socket().
• ext_svr_transport.c
This file implements required transport layer functions. (Note that
ext_svr_transport.c includes ext_transport_share.h, which contains
functions common to client and server sides.) The version of
ext_svr_transport.c shipped with the Real-Time Workshop uses TCP/IP
functions including recv(), send(), and socket().
• 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 (e.g., grt_main.c). It contains code that is
called via the background tasks of ext_svr.c as well as code that is called as
part of the higher priority model execution.
• dt_info.h and model.dt
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.
• updown_util.h
This file contains only conditionals for compilation of the assert macro.
Other Files
• ext_share.h
Contains message code definitions and other definitions required by both the
host and target modules.
17-78
Creating an External Mode Communication Channel
• ext_transport_share.h
Contains functions and data structures required by both the host and target
modules of the transport layer. The version of ext_transport_share.h
shipped with the Real-time Workshop is specific to TCP/IP communications.
Guidelines for Implementing the Transport Layer
Requirements
• ext_svr.c and updown.c use malloc to allocate buffers in target memory for
messages, data collection, and other purposes. If your target uses some other
memory allocation scheme, you must modify these modules appropriately.
• The target is assumed to support both int32_T and uint32_T data types.
Guidelines for Modifying ext_transport
The function prototypes in ext_transport.h define the calling interface for the
host (client) side transport layer functions. The implementation is in
ext_transport.c.
To implement the host side of your transport layer:
• Replace the functions in the “Visible Functions” section of ext_transport.c
with functions that call your low-level communications primitives. The
visible functions are called from other external mode modules such as
ext_comm.c. You must implement all the functions defined in
ext_transport.h. Your implementations must conform to the prototypes
defined in ext_transport.h.
• Supply a definition for the UserData structure in ext_transport.c. This
structure is required. If UserData is not necessary for your external mode
implementation, define a UserData structure with one dummy field.
• Replace the functions in ext_transport_share.h with functions that call
your low-level communications primitives, or remove these functions.
Functions defined in ext_transport_share.h are common to the host and
target, and are not part of the public interface to the transport layer.
• Rebuild the ext_comm MEX-file, using the MATLAB mex command. This
requires a compiler supported by the MATLAB API. See “External
Interfaces” in the MATLAB online documentation for more information on
17-79
17
Targeting Real-Time Systems
the mex command. The following table lists the form of the commands to
build the standard ext_comm module on PC and UNIX platforms.
Table 17-4: Commands to Rebuild ext_comm MEX-Files
Platform
Commands
PC
cd matlabroot\toolbox\rtw
mex matlabroot\rtw\ext_mode\ext_comm.c
matlabroot\rtw\ext_mode\ext_convert.c
matlabroot\rtw\ext_mode\ext_transport.c
–Imatlab\rtw\c\src –DWIN32
compiler_library_path\wsock32.lib
UNIX
cd matlabroot/toolbox/rtw
mex matlabroot/rtw/ext_mode/ext_comm.c
matlabroot/rtw/ext_mode/ext_convert.c
matlabroot/rtw/ext_mode/ext_transport.c
–Imatlab/rtw/c/src
The ext_transport and ext_transport_share source code modules are fully
commented. See these files for further details.
Guidelines for Modifying ext_svr_transport
The function prototypes in ext_svr_transport.h define the calling interface
for the target (server) side transport layer functions. The implementation is in
ext_svr_transport.c.
To implement the target side of your transport layer:
• Replace the functions in ext_svr_transport.c with functions that call your
low-level communications primitives. These are the functions called from
other target modules such as the main program. You must implement all the
functions defined in ext_svr_transport.h. Your implementations must
conform to the prototypes defined in ext_svr_transport.h.
• Supply a definition for the ExtUserData structure in ext_svr_transport.c.
This structure is required. If ExtUserData is not necessary for your external
mode implementation, define an ExtUserData structure with one dummy
field.
• Define the EXT_BLOCKING conditional in ext_svr_transport.c as needed:
17-80
Creating an External Mode Communication Channel
- Define EXT_BLOCKING as 0 to poll for a connection to the host (appropriate
for single-threaded applications).
- Define EXT_BLOCKING as 1 in multi-threaded applications where tasks are
able to block for a connection to the host without blocking the entire
program.
See also the comments on EXT_BLOCKING in ext_svr_transport.c.
The ext_svr_transport source code modules are fully commented. See these
files for further details.
17-81
17
Targeting Real-Time Systems
Combining Multiple Models
If you want to combine several models (or several instances of the same model)
into a single executable, the Real-Time Workshop offers several options.
One solution is to use the S-function target to combine the models into a single
model, and then generate an executable using either the grt or grt_malloc
targets. Simulink and Real-Time workshop implicitly handle connections
between models, sequencing of calls to the models, and multiple sample rates.
This is the simplest solution in many cases. See Chapter 10, “The S-Function
Target” for further information.
A second option, for embedded systems development, is to generate code from
your models using the Real-Time Workshop Embedded Coder target. You can
interface the model code to a common harness program by directly calling the
entry points to each model. The Real-Time Workshop Embedded Coder target
has certain restrictions that may not be appropriate for your application. For
more information, see “Requirements and Restrictions” in Chapter 9,
“Real-Time Workshop Embedded Coder.”
The grt_malloc target is a third solution. It is appropriate in situations where
you want do any or all of the following:
• 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.
This section discusses how to use the grt_malloc target to combine models into
a single program. Before reading this section, you should become familiar with
model execution in Real-Time Workshop programs. (See Chapter 6, “Program
Architecture” and Chapter 7, “Models with Multiple Sample Rates.”) It will be
helpful to refer to grt_malloc_main.c while reading these chapters.
The procedure for building a multiple-model executable is fairly
straightforward. The first step is to generate and compile code from each of the
models that are to be combined. Next, the makefiles for each of the models are
combined into one makefile for creating the final multimodel executable. The
next step is create a combined simulation engine by modifying
grt_malloc_main.c to initialize and call the models correctly. Finally, the
17-82
Combining Multiple Models
combination makefile links the object files from the models and the main
program into an executable. “Example Mutliple-Model Program” on page 17-83
discusses an example implementation.
Sharing Data Across Models
We recommend using 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
We recommend that you generate all the models you are combining with the
same solver mode (either all singletasking or all multitasking.) In addition, if
the models employ continuous states, the same solver should be used for all
models.
If all the models to be combined have the same sample rates and the same
number of rates, the models can share the same timing engine data structure.
(The TimingData structure is defined in matlabroot/rtw/c/src/mrt_sim.c).
Alternatively, the models can maintain separate timing engine data
structures, as in the example program discussed below.
If the models have the same base rate, but have different sub-rates, each model
should maintain a separate timing engine data structure. Each model should
use the same base rate timer interrupt.
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 is responsible for calling
each of the models at the appropriate time interval.
Data Logging and External Mode Support
A multiple-model program can log data to separate MAT-files for each model
(as in the example program discussed below.)
Only one of the models in a multiple-model program can use external mode.
Example Mutliple-Model Program
An example multiple-model program, distributed with Real-Time Workshop, is
located at matlabroot/rtw/c/grt_malloc/demos. This example combines two
17-83
17
Targeting Real-Time Systems
models, fuelsys1 and mcolon. Both models have the same base rate and the
same number of sample times. For simplicity, each model creates and
maintains a separate timing engine data structure (although it would be
possible for them to share a common structure.) Each model logs states,
outputs, and simulation time to a separate model.mat file.
The example files consist of:
• The models, fuelsys1.mdl and mcolon.mdl
• Run-time interface components: modified main program
(combine_malloc_main.c) and modified solver (ode5combine.c)
• Control files: modified model.bat and model.mk files
Runtime Interface Components. The main program, combine_malloc_main.c, is a
modified version of grt_malloc_main.c. combine_malloc_main employs two
#defines for the models. MODEL1() and MODEL2() are macros that return
pointers to the Simstructs for fuelsys1 and mcolon, respectively. The code
refers to the models through these pointers throughout, as in the following
extract.
SimStruct
SimStruct
...
*S1;
*S2;
S1 = MODEL1();
S2 = MODEL2();
...
sfcnInitializeSizes(S1);
sfcnInitializeSizes(S2);
sfcnInitializeSampleTimes(S1);
sfcnInitializeSampleTimes(S2);
...
combine_malloc_main.c calls initialization, execution, and cleanup functions
once for each model.
combine_malloc_main.c also uses the following #defines:
• NCSTATES1 and NCSTATES2 represent the number of continuous states in each
model.
• MATFILEA and MATFILEB represent the MAT-files logged by each model.
17-84
Combining Multiple Models
To see all modifications in the main program, compare grt_malloc_main.c to
combine_malloc_main.c.
The solver, ode5combine.c, is also modified to handle multiple models. The
UpdateContinuousStates function has been modified to obtain the number of
continuous states from each model’s Simstruct at runtime. Simstructs are
passed in by reference.
Control Files. combine.bat was created from the generated control files
fuelsys1.bat and mcolon.bat. These were modified to invoke the makefile,
combine.mk.
combine.mk combines parameters from the generated makefiles, fuelsys1.mk
and mcolon.mk. Note the following modifications:
• combine.mk contains the model-specific defines MODEL1, MODEL2, NCSTATES1,
and NCSTATES2. Note that these defines are included in the CPP_REQ_DEFINES
list.
• The SOLVER parameter specifies ode5combine.c.
• The REQ_SRCS list includes combine_malloc_main.c.
• Two rules have been added in order for make to locate source files in the build
subdirectories, fuelsys1_grt_malloc_rtw and mcolon_grt_malloc_rtw.
Building the Example Program. To try the example:
1 use the build command to generate code and compile object files for the
fuelsys1 and mcolon models.
2 Modify the MATLAB_ROOT and MATLAB_BIN path information in combine.mk as
appropriate for your installation.
3 At the command prompt, type
combine.bat (on PC)
or
make -f combine.mk (on UNIX)
to build the combine executable.
17-85
17
Targeting Real-Time Systems
DSP Processor Support
The Real-Time Workshop now supports target processors that have only one
register size (e.g., 32-bit). This makes data type emulation of 8 and 16 bits on
the TCI_C30/C40 DSP and similar processors possible.
To support these processors:
• Add the command
-DDSP32=1
to your template makefile.
• Add the statement
%assign DSP32=1
to your system target file.
17-86
A
Blocks That Depend on
Absolute Time
A
Blocks That Depend on Absolute Time
Some Simulink blocks use the value of absolute time (i.e., the time from the
beginning of the program to the present time) to calculate their outputs. If you
are designing a program that is intended to run indefinitely, then you cannot
use blocks that have a dependency on absolute time.
The problem arises when the value of time reaches the largest value that can
be represented by a double precision number. At that point, time is no longer
incremented and the output of the block is no longer correct.
Note In addition to the blocks listed below, logging Time (in the Workspace
I/O page of the Simulation Parameters dialog box) also requires absolute
time.
The following Simulink blocks depend on absolute time:
• Continuous Blocks
- Derivative
- Transport Delay
- Variable Transport Delay
• Discrete Blocks
- Discrete-Time Integrator (when used in triggered subsystems)
• Nonlinear Blocks
- Rate Limiter
• Sinks
- Scope
- To File
- To Workspace (only if logging to StructureWithTime format)
• Sources
- Chirp Signal
- Clock
- Digital Clock
- Discrete Pulse Generator
- From File
A-2
- From Workspace
- Pulse Generator
- Ramp
- Repeating Sequence
- Signal Generator
- SineWave
- Step
In addition to the Simulink block above:
• Blocks in other Blocksets may reference absolute time. Please refer to the
documentation for the Blocksets that you use.
• Stateflow charts that use time are dependent on absolute time.
A-3
A
Blocks That Depend on Absolute Time
A-4
B
Glossary
B
Glossary
Application Modules − With respect to Real-Time Workshop program
architecture, these are collections of programs that implement functions
carried out by the system dependent, system independent, and application
components.
Block Target File − A file that describes how a specific Simulink block is to be
transformed to a language such as C, based on the block’s description in the
Real-Time Workshop file (model.rtw). Typically, there is one block target file
for each Simulink block.
File Extensions − Below is a table that lists the file extensions associated with
Simulink, the Target Language Compiler, and the Real-Time Workshop.
Extension
Created by
Description
.c
Target Language
Compiler
The generated C code
.h
Target Language
Compiler
A C include header file used by the .c
program
.mdl
Simulink
Contains structures associated with
Simulink block diagrams
.mk
Real-Time
Workshop
A makefile specific to your model that
is derived from the template makefile
.rtw
Real-Time
Workshop
A translation of the .mdl file into an
intermediate file prior to generating C
code
.tlc
Target Language
Compiler
Script files that Real-Time Workshop
uses to translate
.tmf
Supplied with
Real-Time
Workshop
A template makefile
Generic Real-Time (GRT) target − A target configuration that generates
model code for a real-time system, with the resulting code executed on your
workstation. (Note that execution is not tied to a real-time clock.) You can use
GRT as a starting point for targeting custom hardware.
B-2
Host System − The computer system on which you create your real-time
application.
Inline − Generally, this means to place something directly in the generated
source code. You can inline parameters and S-functions using the Real-Time
Workshop.
Inlined Parameters (Target Language Compiler Boolean global variable:
InlineParameters) − The numerical values of the block parameters are hard
coded into the generated code. Advantages include faster execution and less
memory use, but you lose the ability to change the block parameter values at
run-time.
Inlined S-Function − An S-function can be inlined into the generated code by
implementing it as a .tlc file. The code for this S-function is placed in the
generated model code itself. In contrast, noninlined S-functions require a
function call to S-function residing in an external MEX-file.
Interrupt Service Routine (ISR) − A piece of code that your processor
executes when an external event, such as a timer, occurs.
Loop Rolling (Target Language Compiler global variable: RollThreshold) −
Depending on the block's operation and the width of the input/output ports, the
generated code uses a for statement (rolled code) instead of repeating identical
lines of code (flat code) over the block width.
Make − A utility to maintain, update, and regenerate related programs and
files. The commands to be executed are placed in a makefile.
Makefiles − Files that contain a collection of commands that allow groups of
programs, object files, libraries, etc. to interact. Makefiles are executed by your
development system’s make utility.
Multitasking − A process by which your microprocessor schedules the
handling of multiple tasks. The number of tasks is equal to the number of
sample times in your model.
Noninlined S-Function − In the context of the Real-Time Workshop, this is
any C MEX S-function that is not implemented using a customized .tlc file. If
you create an C MEX S-function as part of a Simulink model, it is by default
noninlined unless you write your own .tlc file that inlines it.
Non-Real-Time − A simulation environment of a block diagram provided for
high-speed simulation of your model. Execution is not tied to a real-time clock.
B-3
B
Glossary
Nonvirtual Block − Any block that performs some algorithm, such as a Gain
block.
Pseudomultitasking − In processors that do not offer multitasking support,
you can perform pseudomultitasking by scheduling events on a fixed
time-sharing basis.
Real-Time System – A system that uses actual hardware to implement
algorithms, for example, digital signal processing or control applications.
Run-time Interface − A wrapper around the generated code that can be built
into a stand-alone executable. The run-time interface consists of routines to
move the time forward, save logged variables at the appropriate time steps, etc.
The run-time interface is responsible for managing the execution of the
real-time program created from your Simulink block diagram.
S-Function − A customized Simulink block written in C or M-code. C-code
S-functions can be inlined in the Real-Time Workshop.
Singletasking − A mode in which a model runs in one task.
System Target File − The entry point to the Target Language Compiler
program, used to transform the Real-Time Workshop file into target specific
code.
Target Language Compiler − A compiler that compiles and executes system
and target files.
Target File − A file that is compiled and executed by the Target Language
Compiler. A combination of these files describes how to transform the
Real-Time Workshop file (model.rtw) into target-specific code.
Target System − The computer system on which you execute your real-time
application.
Targeting − The process of creating an executable for your target system.
Template Makefile − A line-for-line makefile used by a make utility. The
template makefile is converted to a makefile by copying the contents of the
template makefile (usually system.tmf) to a makefile (usually system.mk)
replacing tokens describing your model’s configuration.
Target Language Compiler Program − A set of TLC files that describe how
to convert a model.rtw file into generated code.
B-4
Task Identifier (tid) − Each sample time in your model is assigned a task
identifier (tid). The tid is passed to the model output and update routines to
decide which portion of your model should be executed at a given time.
Virtual Block − A connection or graphical block, for example, a Mux block.
B-5
B
Glossary
B-6
Index
A
Ada code format 17-18
Ada Coder
applications of 16-3
blocks supported by 16-21
code validation 16-18
compilers supported by 16-3
data logging 16-13
signal properties 16-16
targets supported by 16-3
application modules
application-specific components 6-34
definition of 6-24
system-independent components 6-30
atomic subsystem 3-41
automatic S-function generation 10-12
See also S-function target
B
Block reduction optimization 3-23
block target file 2-14
blocks
Asynchronous Buffer 15-16
Asynchronous Interrupt 15-5
depending on absolute time A-2
device driver 17-34
nonvirtual 2-18
Rate Transition 15-18
Scope 3-19
S-Function 10-4, 17-34
Task Synchronization 15-12
To File 3-20
To Workspace 3-19
Unit Delay 7-13
virtual 2-18
Zero-Order Hold 7-12
Build button 3-5
Build command 3-5
build directory
contents of 1-49, 3-98
naming convention 1-43, 3-98
build process
and code generation 3-2
overview 2-12
steps in 2-13
C
code format
Ada 17-18
choosing 4-3
definition of 1-37
embedded C 4-11
real-time 4-6
real-time malloc 4-8
S-function 4-10, 10-2
code generation 3-1
and simulation parameters 3-17
automatic 2-12
from nonvirtual subsystems 3-41
TLC variables for 17-18
tutorial 1-56
code generation options
advanced 3-22
Block reduction 3-23
Boolean logic signals 3-24
External mode 3-14
Force generation of parameter comments 3-13
general 3-9
Inline invariant signals 3-12
Inline parameters 3-22
Local block outputs
I-1
Index
See also Signal storage reuse
Loop rolling threshold 3-10
MAT-file variable name modifier 3-14
Retain .rtw file 3-15
Show eliminated statements 3-9
Signal storage reuse 3-28
See also Local block outputs
Solver page 3-17
target specific 3-13
TLC debugging 3-15
Verbose builds 3-11
Workspace I/O page 3-18
code tracing 3-28
code validation
in Ada Coder 16-18
tutorial 1-52
combining models
in RTW Embedded Coder target 17-82
via grt_malloc target 17-82
via S-function target 17-82
communication
external mode 5-2
external mode API for 17-73
continuous states, integration of 6-29
Custom Code library
Custom Subsystem Code sublibrary 14-9
overview 14-2
custom target configuration
components of 17-4
tutorial 17-9
D
data logging 3-18
in Ada Coder 16-13
in single- and multitasking models 3-20
to MAT-files 1-49, 3-18
I-2
tutorial 1-49
via Scope blocks 3-19
example 1-53
via To File blocks 3-20
via To Workspace blocks 3-19
data structures in generated code
block I/O 6-21
block parameters 6-21
block states 6-21
external inputs 6-21
external outputs 6-21
device driver blocks
building 17-54
creating custom 17-34
DOS 13-10
inlined 17-48
example 17-49
mdlRTW function in 17-52
requirements for 17-48
when to inline 17-36
limitations of 17-37
noninlined 17-39
conditional compilation of 17-40
required defines and includes 17-41
required functions 17-42
parameterizing 17-38
requirements for 17-37
S-function wrappers for 17-54
VxWorks 12-14
directories
build 1-42
used in build process 3-98
working 1-42
DOS
Analog Input (ADC) block parameters 13-12
Analog Output (DAC) block parameters 13-13
building programs 13-17
Index
communications overview 17-74
configuring to use sockets 12-7
control panel 5-9, 5-11
download mechanism 5-36
error conditions 5-44
ext_comm MEX-file 5-36, 5-40
optional arguments to 5-40
rebuilding 17-80
host and target systems in 5-2
limitations of 5-45
Signal Viewing Subsystems in 5-32
TCP implementation 5-38
tutorial 5-4
using with VxWorks 12-6
device driver blocks 13-7, 13-10, 13-11
adding to model 13-16
Digital Input block parameters 13-14
Digital Output block parameters 13-15
hardware requirements 13-6
implementation overview 13-4
interrupt service routine 7-3
Keithley Metrabyte board I/O driver 13-10
modifying program timing 13-8
program timing 13-7
sample rate limits 13-7
software requirements 13-6
system configuration 13-5
DOS Device Drivers library 13-2
doslib block library 13-10
F
E
Embedded Coder. See RTW Embedded Coder
target
embedded target. See RTW Embedded Coder
target
Euler integration algorithm 6-29
expressions
tunable 3-51
in masked subsystems 3-62
limitations on 3-61
ext_comm MEX-file 5-40
external mode 5-2, 17-73
API
host source files 17-76
implementing transport layer 17-79
target source files 17-77
architecture 5-37, 17-73
blocks compatible with 5-32
code generation option 17-28, 17-75
command line options for target program 5-42
files
generated See generated files
G
generated code
operations performed by 6-30
generated files 2-17
model (UNIX executable) 2-17
model.c 2-17
model.exe 2-17
model.exe (PC executable) 2-17
model.h 2-17
model.mdl 2-17
model.mk 2-17
model.rtw 2-17
model_export.h 2-17
generated s-functions
tunable parameters in 10-10
generic real-time (GRT) target 1-38
tutorial 1-42
I-3
Index
H
host
and target 1-37
in external mode 5-2
I
installation xxi
interrupt service routine
locking and unlocking 15-11
under DOS 7-3, 13-5
under VxWorks 7-3
Interrupt Templates library 15-5
L
libraries
DOS Device Drivers 13-2
Interrupt Templates 15-5
VxWorks support 12-3
Local block outputs option 3-12
M
make command 17-29
make utility 2-12
make_rtw 1-39, 2-12, 3-8
MAT-files
file naming convention 3-19
loading 1-55
logging data to 1-49, 3-18
variable names in 3-19
MATLAB 1-9
required for Real-Time Workshop xviii
mdlRTW function 17-52
I-4
model code
customizing 14-9
execution of 6-32
operations performed by 6-32
model execution
in real time 7-10
in Simulink 7-10
Simulink vs. real-time 7-9
Model Parameter Configuration dialog
tunable parameters and 3-51
using 3-57
model registration function 6-32
multitasking
building program for 7-8
enabling 7-8
task identifiers in 7-5
task priorities 7-5
versus singletasking 7-3
N
nonvirtual blocks 2-18
nonvirtual subsystems
atomic 3-41
categories of 3-41
conditionally executed 3-41
modularity of code generated from 3-48
O
operating system
tasking primitives 6-10, 6-11
VxWorks 12-2
Index
P
parameters
interfacing 3-51
storage declarations 3-51
tunable 3-51, 3-77
priority
of sample rates 7-5
of VxWorks tasks 12-10
program architecture
data logging functions 6-32
embedded 6-35
initialization functions 6-26, 6-32
main function 6-26
model execution 6-27, 6-28
model execution functions 6-32
program execution 6-14
program termination 6-27
program timing 6-13
rapid prototyping 6-25
real-time 6-25
termination functions 6-32
pseudomultitasking 7-5
R
rapid prototyping 2-2
for control systems 2-6
for digital signal processing 2-5
overview of process 2-2
rapid simulation target
batch simulations (Monte Carlo) 11-12
command line options 11-5
real time
executing models in 7-10
integrating continuous states in 6-29
real-time malloc target 4-8
combining models with 17-82
real-time object 9-4
See also RTW Embedded Coder target
Real-Time Workshop
open architecture of 2-8
user interface 3-4
Real-Time Workshop page
Category menu 3-4
opening 3-4
overview 3-4
Target configuration options 3-7
Browse button 3-7
Build button 3-5
Generate code only option 3-9
Make command field 3-8
System target file field 3-7
Template makefile field 3-8
rsim. See rapid simulation target
RTW Embedded Coder target
automatic S-function wrapper generation 9-17
code generation options 9-20, 9-27
code generation report for 9-23
code modules
generated 9-5
header files 9-6
main program 9-6
user-written 9-8
data structures
logging object 9-4
real-time object 9-4
inherent optimizations 9-2
interfacing multiple models 9-16
introduction to 9-2
model entry points
calling directly 9-16
modifying main program 9-10
modifying rt_OneStep 9-14
optimizing generated code 9-20
I-5
Index
program execution
main program 9-10
rt_OneStep 9-11
multirate operation 9-12
reentrancy 9-13
single-rate operation 9-11
servicing timer interrupts 9-9
requirements 9-29
restrictions 9-29
stack space allocation in 9-25
system target files 9-31
template makefiles 9-31
unsupported blocks 9-30
run-time interface modules 1-60
S
sample rate transitions 7-12
faster to slower
in real-time 7-14
in Simulink 7-13
slower to faster
in real-time 7-17
in Simulink 7-16
sample time overlaps 7-17
S-function target 4-10, 10-2
applications of 10-2
automatic S-function generation 10-12
generating reusable components with 10-4
intellectual property protection in 10-3
restrictions 10-15
tunable parameters in 10-10
unsupported blocks 10-16
I-6
S-functions
API 6-33
generating automatically
models containing 6-32
noninlined 6-32
signal properties 3-77
setting via Signal Properties dialog 3-77
Signal storage reuse option 3-28
Signal Viewing Subsystems 5-32
simstruc.h
contents of 6-30
SimStruct data structure
and global registration function 6-32
definition of 6-30
Simulation Parameters dialog
Advanced page 3-22
Diagnostics page 3-21
Real-Time Workshop page 3-4
Solver Options page 3-17
Workspace I/O page 3-18
Simulink 1-9
interactions with Real-Time Workshop 3-29
block execution order 3-32
data propagation 3-29
sample time propagation 3-31
required for Real-Time Workshop xviii
simulation parameters
and code generation 3-17
Simulink data objects 3-79
and ObjectProperties records 3-88
parameter objects 3-81
signal objects 3-85
singletasking 7-9
building program for 7-9
enabling 7-9
step size
of real-time continuous system 6-29
Index
StethoScope
See VxWorks
subsystem
nonvirtual 3-41
system records 2-18
system target file 1-37, 2-14
System Target File Browser 3-34, 3-36
T
target
available configurations 1-37
bundled 1-22
custom 1-23
table of 3-36
third-party 1-23
custom configuration 17-2
DOS 13-2
generic real-time See generic realtime (GRT)
target
rapid simulation See rapid simulation target
real-time malloc See real-time malloc target
RTW Embedded Coder target. See RTW Embedded Coder target
S-function See S-function target
Tornado See VxWorks
Target Language Compiler
code generation variables 17-18
debugging options 3-15
files
block target 1-38
system target 1-38
function library 2-14
generation of code by 2-14
task identifier (tid) 7-5, 9-12, 9-15
template makefile 1-39
compiler-specific 3-102
default 3-99, 3-102
defined 1-39
options
Borland 3-105
LCC 3-106
UNIX 3-103
Visual C/C++ 3-103, 3-104
Watcom 3-105
structure of 17-25
tokens 17-26
tid 9-12, 9-15
tokens 17-26
Tornado See VxWorks
tutorials
building generic real-time program 1-42
code generation 1-56
code validation 1-52
creating custom target configuration 17-9
data logging 1-49
external mode 5-4
V
virtual blocks 2-18
VxWorks 12-2
and external mode 12-6
application overview 12-5
configuring
for external mode (sockets) 12-6
makefile template 12-14
connecting target to Ethernet 12-5
downloading and running the executable interactively 12-19
external mode options 12-7
GNU tools for 12-15
implementation overview 12-12
program build options 12-15
I-7
Index
program execution 12-20
program monitoring 12-5
real-time operating system 12-2
runtime structure 12-8
StethoScope code generation option 12-18
support library 12-3
target
connecting to 12-19
downloading to 12-19
target CPU 12-5
tasks created by 12-10
template makefiles 12-14
W
working directory 1-42
I-8
Download PDF

advertising