- Extract 28 non-empty RVS PDFs from src/scov/RVS/ to docs-extracted/ - Preserve full source tree structure under docs-extracted/src/scov/RVS/ - Regenerate docs-extracted/index.md to include all 65 extracted documents - List 21 empty PDFs that could not be extracted
146 KiB
| title | source | category | pages | extracted |
|---|---|---|---|---|
| Integration Guide | ./src/scov/RVS/doc/Integration_Guide.pdf | src/scov/RVS/doc | 74 | 2026-07-06T23:13:31.570561 |
Integration Guide
Extracted from
./src/scov/RVS/doc/Integration_Guide.pdf(74 pages). Figures, diagrams, and tables may not render accurately in plain text.
Integration Guide Version WF20190404 Disclaimer The information, text, and graphics contained within this document are provided for information purposes only by Rapita Systems Ltd. Rapita Systems Ltd. does not warrant the accuracy or completeness of the information, text, and other items contained in this document.
Copyright and Trademarks All rights reserved. Information and images contained within this doc- ument are copyright and the property of Rapita Systems Ltd. All trade- marks are hereby acknowledged to be the properties of their respective owners.
Acknowledgments Rapita Systems' tools are built using AdaCore's GNAT Pro compiler.
Rapita Systems Ltd. Registered in the UK, number 5011090. Registered address: Atlas House Link Business Park Osbaldwick Link Road York YO10 3JB UK Phone: +44 (0) 1904 413 945 http://www.rapitasystems.com/ This document copyright © 2011-2019, Rapita Systems Ltd.
Document build 118520
ID: DOC/12003 Table of Contents
1. About this guide ............................................................... 5
1.1. Who should read this guide? ................................................... 5
1.2. Structure of this guide ........................................................... 5
1.3. RVS tutorials ....................................................................... 6
1.4. Notation ............................................................................ 6
1.5. RVS documentation map ........................................................ 7
1.6. Support ............................................................................. 9
2. What is an RVS integration? ............................................ 11
2.1. RVS integrations ................................................................. 11
2.2. Running an integration ......................................................... 12
3. Getting started ................................................................ 15
3.1. Next steps ........................................................................ 17
4. Integrating with a build system ....................................... 19
4.1. Selecting an integration strategy .............................................. 20
4.2. Compiler wrappers .............................................................. 21
4.3. Clone integrations ............................................................... 28
4.4. Custom integrations ............................................................ 31
4.5. Using clonehelper to clone source files ...................................... 31
4.6. Using ihelper to link RVS files ................................................. 32
4.7. Checklist .......................................................................... 35
5. Integrating with a target .................................................. 37
5.1. Selecting a data collection strategy .......................................... 37
RVS Integration Guide vWF20190404 3 Table of Contents
5.2. Implementing a data collection strategy ..................................... 40
5.3. Checklist .......................................................................... 41
6. Converting data .............................................................. 43
6.1. Conversion strategies ........................................................... 43
6.2. Data converters .................................................................. 43
6.3. Specifying data files and converters ......................................... 44
6.4. Checklist .......................................................................... 46
7. Integrating with extended programming languages ......... 47
7.1. Adding a compiler extension to your project ................................ 47
8. Using the command-line ................................................. 49
9. Customizing integrations ................................................. 51
9.1. Custom recipes .................................................................. 51
9.2. Editing RVS integration scripts ................................................ 53
10. Integration resources .................................................... 55
A. Appendix ........................................................................ 57
A.1. Integrating RVS with Ada projects ............................................ 57
A.2. Using different integration strategies in a single RVS integration ......... 62
A.3. Working with limited resources: RapiTime and RapiTask .................. 63
4 RVS Integration Guide vWF20190404 1 About this guide The RVS Integration Guide describes how to integrate the Rapita Verification Suite (RVS) to work in a development environment.
1.1 Who should read this guide? This document is intended for users wanting to integrate RVS into a development environment. The development environment comprises the source files, build sys- tem and target architecture used to build and run software. The reader should have a good understanding of this environment before reading this guide.
This document assumes that the reader can already build and run software on their
target architecture. It further assumes that the reader is familiar with the general
process of using RVS, and understands RVS terminology. For more information
on this, see the RVS User Guide.
1.2 Structure of this guide This document includes the following chapters:
Chapter 1: About this guide
Describes the purpose and layout of the RVS Integration Guide and the notation
used throughout the document.
Chapter 2: What is an RVS integration?
Describes what RVS integrations are, and how they can be used to run RVS.
Chapter 3: Getting started
Describes an example RVS integration, showing how simple projects can be con-
figured entirely through the RVS Project Manager.
Chapter 4: Integrating with a build system
Describes what must be done to integrate RVS alongside an existing a build sys-
tem.
Chapter 5: Integrating with a target
Describes what must be done to integrate RVS to collect data from different target
architectures.
Chapter 6: Converting data
Describes what must be done to convert output data into a format usable by RVS.
RVS Integration Guide vWF20190404 5 RVS tutorials About this guide
Chapter 7: Integrating with extended programming languages
Describes how to extend RVS integrations to support analysis of code written with
language extensions over common standards.
Chapter 8: Using the command-line
Describes how to run RVS integrations from the command-line.
Chapter 9: Customizing integrations
Describes how to customize RVS integrations.
Chapter 10: Integration resources
Describes resources that are helpful while integrating RVS into a development
environment, including reference documentation.
Appendix A: Appendix
Describes important factors when using RVS with Ada projects, how to use mul-
tiple integration strategies in a single project and considerations when using
RapiTime or RapiTask on targets with limited resources.
1.2.1 Integration Annexes Information on how to integrate RVS with specific build systems and targets can be found in the Integration Annexes distributed with an RVS installation in RVS_install_path/integration_resources/integration_annexes. These annexes describe how to use RVS with specific compilers, processors, data collection methods and operating systems.
For further information about integrating RVS with a specific target, or if there is no
Integration Annex for your target, contact the Rapita Systems support team.
1.3 RVS tutorials RVS comes with a set of tutorials that explain and demonstrate how to use RVS through a series of practical exercises.
You can access the RVS tutorials from the RVS Project Manager Welcome page
or Help menu.
Tutorial
Many sections of this guide include a Tutorial box.
Each box highlights an RVS tutorial demonstrating the contents of the sec-
tion.
1.4 Notation This document uses the following notation:
6 RVS Integration Guide vWF20190404 About this guide RVS documentation map
• References to other documents and to other chapters or sections in this doc-
ument are written in italics, for example Chapter 1: About this guide. When
reading an electronic copy of this document, you can click on a reference to
navigate to the location of the referenced element.
• Names of RVS applications are formatted in bold italics, for example RVS
Project Manager.
• References to areas or elements in user interfaces are formatted in italics, for
example the Report Navigator.
• Menus, menu choices and button labels are formatted in bold, for example
File » Print or OK. Where buttons have icons, these are shown before their
Label in in-line text, for example Save.
• Names of RVS tools are formatted in bold, for example rvsdriver.
• References to HTML links appear as underlined text, for example
www.rapitasystems.com.
• Folder and file names are formatted in a monospaced font.
• Command-line tools and their commands, annotations and examples are for-
matted in a monospaced font. These are either written in-line with text
or as separate text blocks. When written in-line with text, they are formatted
like the following: rvsdriver, default_instrument, rvs_instr.h.
When written as a separate text block, they are formatted like the examples
below:
rvsdriver --project rvs.rvsprj --all
#pragma RVS instrument( "function_name", "FALSE" )
• When referencing Ada code, the term functions refers to both functions and
procedures.
1.5 RVS documentation map This document is part of the Rapita Verification Suite (RVS) document set, which contains the following documents:
RVS Installation and Licensing Guide
Describes how to install RVS tools, and licensing options for them.
RVS Integration Guide
Describes how to integrate RVS tools into build and target environments.
RVS User Guide
Describes how to set up and run RVS projects, analyze data and export verification
results.
RapiTest User Guide
Describes how to use RapiTest to manage test projects.
RVS Integration Guide vWF20190404 7 RVS documentation map About this guide
Spreadsheet Test Format User Guide
Describes how to write tests for RapiTest in the Spreadsheet Test Format.
RapiCover User Guide
Describes how to use RapiCover to measure code coverage and address cover-
age holes.
RapiTime User Guide
Describes how to use RapiTime to measure timing metrics including worst-case
execution time, and how to use these metrics to identify the best optimization
candidates.
RapiTask User Guide
Describes how to use RapiTask to measure system level task timing information,
visualize traces and gain insight into runtime behavior.
RTBx 2xxx User Guide
Describes how to use the RTBx data logger.
RVS Integration Library Implementation Guide
Describes how to implement RVS integration libraries. This document is for use by
readers with a thorough understanding of the implementation of RVS.
RVS Files Reference Guide
Describes RVS-specific files including input, intermediate and output files.
RVS Filters Guide
Describes RVS filters, which are used to convert raw trace data into a format that
RVS can analyze, and how to write them.
RVS Command Line Tools Reference Guide
Describes the command-line tools used by RVS, including a list of available com-
mand options.
RVS Annotations Reference Guide
Describes the annotations you can use to control instrumentation and analysis
with RVS.
RVS Troubleshooting Guide
Describes the error and warning messages you may encounter when using RVS
tools, and how to address them.
RVS Migration Guide
Describes how to migrate between using different versions of RVS.
8 RVS Integration Guide vWF20190404 About this guide Support
1.6 Support For support issues, please contact Rapita Systems Ltd. by any of the following means:
Email
support@rapitasystems.com
Telephone
+44 (0) 1904 413 945
Website
www.rapitasystems.com
To register for support, visit www.rapitasystems.com/register. More than one user
can register per license.
RVS Integration Guide vWF20190404 9 This page intentionally left blank What is an RVS 2 integration? To understand RVS integrations, it is helpful to first understand how RVS works. This is summarized in Figure 2.1.
Figure 2.1: How RVS works
In its standard workflow, RVS takes a copy of input source code and injects addi-
tional code into it so that RVS can collect verification data. The code is compiled
and linked into an executable that is run on the target hardware, host system or
simulator. While the executable is run, verification data is generated. This data is
collected either while the executable is run or after it finishes execution. Finally,
verification data is written to an output report.
2.1 RVS integrations An RVS integration extends your existing development environment so verification data can be produced while running test executables – these may be run by RVS or otherwise. After a robust RVS integration has been achieved, using RVS to produce results requires minimal effort. Three major steps are involved in setting up an RVS integration: 1. Integrating RVS with your build system. 2. Selecting and implementing a method to collect data from your target. 3. Converting raw verification data into a format that RVS can understand.
RVS Integration Guide vWF20190404 11 Running an integration What is an RVS integration?
These fit into your existing build system as shown in Figure 2.2.
Figure 2.2: Steps in an RVS integration
In the first step, you must integrate RVS with the existing build system. There are
many strategies to do this, such as using compiler wrappers, creating a copy of
source files, or manually editing the build system to insert calls to RVS tools. In
many cases there is a quick and simple way to integrate RVS with a build system.
In the next step, you must select and implement an appropriate data collection
strategy. You will likely only have to do this if you want to use RVS to collect verifi-
cation data from an embedded target. This involves creating an integration library
containing the functionality needed to collect data from your target. This is often
the most complex step in integrating RVS. RVS comes packaged with templates
that you can use to develop your own library if necessary.
In the final step, you may need to configure a strategy to convert raw data into a
format that RVS can understand. In some cases, this is not necessary as output
data can already be recognized by RVS.
This guide assumes that you achieve these steps one after the other, in the order
above. To do this, you will set up an RVS project file in the RVS Project Manager
that contains an Integration you can use to collect data from your embedded
target.
2.2 Running an integration After you have configured an RVS Integration suitable for use in your develop- ment environment, you can run this using either the RVS Project Manager or a
12 RVS Integration Guide vWF20190404 What is an RVS integration? Running an integration
command-line terminal. When you use the RVS Project Manager to run an RVS
integration, it sends commands to a command-line tool called rvsdriver. This tool
manages other command-line tools that perform specific tasks such as parsing
coverage data (covparser) or combining reports (rvdutils).
For more information on rvsdriver and other RVS command-line tools, see Chap-
ter 8 in the RVS User Guide and the RVS Command Line Tools Reference Guide,
respectively.
Standard RVS integrations follow one of the two workflows shown in Figure 2.3.
Figure 2.3: RVS workflows
The dual-pass integration mode is the default and recommended mode to use
RVS. In this mode, static and dynamic analyses are made during separate builds
of the source code. This means that you need only run static analysis once during
your project, saving computational effort. In the single-pass integration mode, you
must carry out static and dynamic analyses at the same time. This guide describes
how to set up dual-pass integrations.
RVS Integration Guide vWF20190404 13 Running an integration What is an RVS integration?
Note
Single-pass and dual-pass integration modes are not functionally equiva-
lent, and using a dual-pass integration mode makes it easier to use some
RVS features. For more information on single-pass integrations, contact
support@rapitasystems.com.
Figure 2.3 shows the stages of RVS integrations. Some or all of these stages are
carried out when you run RVS, depending on which options rvsdriver is called
with, see Chapter 8: Using the command-line. The actions carried out in each RVS
stage are described below:
• Deploy – the folders and integration library needed to run an integration are
created.
• Clean – intermediate files are deleted from integration folders.
• Prepare – source code files are statically analyzed and have instrumentation
applied to them.
• Build – source code files are statically analyzed, instrumented, and compiled
and linked into executable files that will work on target.
• Run – instrumented executable files from the build stage are run on target.
• Report – verification data obtained from running executable code on target is
written into a report file that can be viewed in the RVS Project Manager.
• Export – verification data obtained from running executable code on target is
written to an output file.
You can invoke these stages from the RVS Project Manager, or by calling rvs-
driver directly from the command-line. When you invoke a stage, rvsdriver runs
a script that calls the RVS command-line tools needed to execute the stage.
Each RVS integration stage includes three hooks:
• An optional Prehook that, when present, performs operations necessary to run
before the Action hook.
• A mandatory Action hook that performs the main operations necessary in the
integration stage.
• An optional Posthook that, when present, performs operations necessary to
run after the Action hook.
RVS integrations based on standard templates usually only include an Action
hook. Standard integrations can be customized in various ways to produce differ-
ent functionality, see Chapter 9: Customizing integrations.
14 RVS Integration Guide vWF20190404 3 Getting started This chapter describes how to create an RVS project that includes relevant com- mands and settings needed to execute a build system and run analysis using one of the RVS tools.
Depending on your development environment, more steps may be needed to in-
tegrate RVS into it. These are discussed in subsequent chapters in this guide.
To begin, you must have RVS installed on your system and have an appropriate
license configured. For more information, see the RVS Installation and Licensing
Guide.
Next, create an RVS project suitable for your needs using the RVS Project Man-
ager application. Open this application on Windows systems from the Start menu
(Start » RVS » RVS Project Manager).
When the RVS Project Manager opens for the first time, it opens on the Welcome
page, see Figure 3.1. From this page, create a new project by clicking Create
a new project in the Get started section.
Figure 3.1: RVS Project Manager Welcome page
Tip
If the Welcome page is not open, create a New RVS Project from the
File menu.
RVS Integration Guide vWF20190404 15 Getting started
The New RVS Project Wizard opens, which guides you through project creation.
To create a project suitable for your needs, follow the instructions below as you
work through the wizard:
1. On the Project Settings page, give your project a name and select the main
language used in your source code.
2. On the Analysis Settings page, provide a name for your analysis and select
settings depending on the type(s) of RVS analysis you want to apply. For
more information, see the RVS User Guide.
3. On the Target Settings page, provide a name for the target you'll be running
your test executable on. Optionally, provide the commands to run during RVS
integration stages (see Section 2.2: Running an integration) and the folder
to run them in. These should be the same commands you normally use to
invoke various stages of your build system.
Note
RVS uses the system's default shell to invoke commands. For your integra-
tion to succeed, the commands you enter on the Target Settings page must
be valid for this shell.
On Windows systems, the default shell is cmd.exe.
4. On the Integration Settings page, provide a name for your integration and
select an Integration Strategy. For more information on integration strategies,
see Chapter 4: Integrating with a build system. If you have RapiTest installed,
select either the Managed or Unmanaged or Testing Mode, to either use
RapiTest to create a test harness or not.
5. On the Export Settings page, optionally provide settings for an export to add
to your integration. RVS exports let you export data into formats other than
the RVS report format, which you can only view in the RVS Project Manager.
For more information, see the RVS User Guide.
6. On the Summary page, review your settings to ensure that they are correct.
After you click Finish, RVS creates a folder containing the files it needs to run,
including the project file.
Before you can use an RVS project to analyze source code, you must deploy an
RVS integration library. This includes definitions for RVS functions that tell RVS how
to instrument code and collect data from an executable when it runs.
RVS copies files from a template folder to create an integration library during the
Deploy stage of an integration. To deploy an integration library for an integration
using the RVS Project Manager, click Deploy in the Actions section of the project
overview page that is open, and confirm by clicking OK. For more information on
deploying RVS integrations, see Section 4.3 in the RVS User Guide.
16 RVS Integration Guide vWF20190404 Getting started Next steps
This deploys an integration library from a standard template based on your project
settings. While template libraries for on-host integrations can often be used out-
of-the-box, you may need to manually edit libraries for on-target integrations.
3.1 Next steps For some on-host integrations, you may now be able to use RVS to produce re- sults. For more complex integrations such as ones using the clone strategy or where the test executable is run on an embedded target, more steps must be carried out first.
To check if your integration works, click Prepare in the Actions section of the
project overview page (see Figure 3.2), then click OK in the dialog that opens.
Figure 3.2: Preparing your integration
If the console reports an error, you may need to perform more steps to integrate
RVS with your build system. To learn how to do this, follow Chapter 4: Integrating
with a build system.
If the console eventually displays that rvsdriver completed successfully, you
may be able to run RVS to produce results and analyze them, if you are running
an on-host integration. To learn how to do so, follow the RVS User Guide.
If you want to use RVS to collect data from tests run on an embedded target,
continue to Chapter 5: Integrating with a target to further the integration process.
RVS Integration Guide vWF20190404 17 This page intentionally left blank Integrating with a build 4 system This chapter assumes that you have created an RVS project suitable for the pro- gramming language of your source code. If you have not done this, we recom- mend that you learn how to by reading Chapter 3: Getting started.
Important
This chapter describes the options available for integrating RVS with vari-
ous build systems, and factors that may be important when deciding which
strategy to use.
RVS is flexible and there are many options for integration, which are not all
described herein. Further, the number of factors involved mean that, while
some strategies may be more efficient in certain cases, no one strategy is
universally appropriate.
We can provide expert assistance with integrating RVS with your build sys-
tem. For more information, contact support@rapitasystems.com.
For RVS to collect verification data, it must be integrated with the build system
used to produce and run an executable. When it is, you can run your build system
using the RVS Project Manager.
RVS build system integrations must allow RVS to do the following:
1. Collect information on all source files in a project during the Prepare stage
of an integration – to know which files need to be analyzed, and collect static
information on the source code, RVS must be able to observe, collect and
store information on all source files in the project.
2. Inject code into preprocessed files to apply RVS analysis during the Build
stage of an integration – to apply RVS analysis, RVS tools inject code into
preprocessed source code. This injected code may apply RVS instrumenta-
tion (for coverage or timing analysis with RapiCover or RapiTime, for exam-
ple) or create a test harness for functional testing (RapiTest).
3. Add RVS integration libraries to preprocessed code during the Build stage of
an integration – for RVS to collect results, an RVS integration library must be
included in the binary produced by the build system. RVS integration libraries
contain the functions needed to collect data such as results from functional
tests, coverage or timing results from the target system. For more information
on RVS integration libraries, see Section 5.2: Implementing a data collection
strategy.
For more information on the stages of RVS integrations, see Section 2.2: Running
an integration.
RVS Integration Guide vWF20190404 19 Selecting an integration strategy Integrating with a build system
4.1 Selecting an integration strategy There are multiple ways to integrate RVS with build systems. These include: • Using compiler wrappers – a wrapper intercepts calls made to your compiler so RVS can observe and instrument source code automatically. This strategy is described in Section 4.2: Compiler wrappers. • Using a clone strategy – a copy is made of all the files needed to run the build system, and source files are replaced with instrumented versions. This strategy is described in Section 4.3: Clone integrations. • Using a custom strategy – custom strategies are the most flexible strategies to implement, but also the most complex. These strategies may involve adding calls to RVS tools directly to your build system, using RVS compiler wrappers, and using parts of the typical clone integration strategy. This strategy is de- scribed in Section 4.4: Custom integrations.
The language of your source code is important when determining which integration
strategy to use. If your project includes Ada code, special considerations must be
taken when selecting an integration strategy. These are described in Section A.1:
Integrating RVS with Ada projects, and it is strongly recommended that you read
through them before continuing.
Note
You can use different integration strategies for the Prepare and Build
stages of RVS integrations. For example, you could use a clone strategy for
the Prepare stage and a compiler wrapper strategy for the Build stage. To
learn how to do this, see Section A.2: Using different integration strategies in
a single RVS integration.
When selecting an integration strategy, you should consider how much effort the
strategy will take to implement. The compiler wrapper strategy usually requires
the least effort to apply and maintain, and is the preferred option when it can be
used. Among other reasons, this is because this strategy often requires the fewest
modifications to be made to your build system.
20 RVS Integration Guide vWF20190404 Integrating with a build system Compiler wrappers
4.2 Compiler wrappers A compiler wrapper is an executable that offers an efficient way of integrating RVS with your build system by intercepting calls made to your compiler, see Figure 4.1. The use of compiler wrappers is often the preferred integration strategy as it re- quires the least modification to the build system and automates more stages of the integration that other strategies.
Figure 4.1: Compiler wrappers
Compiler wrappers intercept calls to the compiler they wrap. They ensure that RVS
tasks such as source code instrumentation happen before the call to the original
compiler happens. They do the following during an RVS integration:
• During the Prepare stage, they automatically store information on all source
files in the system.
• During the Build stage, they automatically inject RVS code into preprocessed
versions of source files from the project and add RVS integration libraries to
the system.
We include wrappers for a number of commonly-used compilers in your RVS in-
stallation. If you have a compiler that we don't have a wrapper for, contact us at
support@rapitasystems.com for support options.
RVS Integration Guide vWF20190404 21 Compiler wrappers Integrating with a build system
4.2.1 Using compiler wrappers To select a compiler wrapper integration strategy, select Compiler Wrapper as the Integration Strategy when creating an RVS project, see Chapter 3: Getting started.
There are three ways to integrate RVS with a build system using a compiler wrap-
per:
• Wrapping in-place
• Calling a wrapper from the PATH
• Calling a wrapper from your build system
The most efficient strategy to take depends on your development environment and
how much access you have to it. This may be influenced by your IT policy.
The build system is often the most complicated part of the development environ-
ment, and integration strategies that do not modify it are generally more reliable
and incur lower maintenance costs. Figure 4.2 shows how to select the most effi-
cient strategy assuming that compilers are stored in an accessible location and
you want to avoid making changes to the build system as much as possible.
Figure 4.2: Selecting a compiler wrapper integration strategy
Note
GNAT compilers, which must be used during the Prepare stage of Ada inte-
grations, must be wrapped in-place.
22 RVS Integration Guide vWF20190404 Integrating with a build system Compiler wrappers
Note
Visual Studio compilers from versions up to Visual Studio 2008 must be
wrapped in-place. Compilers from Visual Studio 2010 and above, however,
can be wrapped either in-place or through other methods.
For more information on integrating RVS with Visual Studio, including how to
wrap Visual Studio compilers, see the Visual Studio Integration Annex.
To learn more about each integration method, and how to apply it, see the following
sections.
4.2.2 Wrapping in-place The simplest strategy to integrate RVS with your build system using compiler wrap- pers is often to wrap the compiler in-place. For some compilers, such as GNAT, this is the only wrapper strategy that can be used.
Wrapping a compiler in-place involves renaming the compiler in its directory and
putting the compiler wrapper in its place. For example, to wrap the GCC compiler,
gcc is renamed to gcc_orig in its directory, and the wrapper (called gcc) is
added to the same directory. As such, this strategy can only be used if you have
access to the directory containing the compiler.
To wrap a compiler in-place on Windows, use the RVS Compiler Wrapper config-
uration utility as follows:
1. Launch the RVS Project Manager.
2. From the Help menu, select Compiler Wrapper Installer to launch the RVS
Compiler Wrapper configuration utility.
3. On the Compiler Selection screen, select the compiler you want to wrap.
4. On the Compiler Location screen, provide the file path to your compiler.
5. On the Task Selection screen, select Wrap the compiler. If your compiler has
already been wrapped, this option is replaced with Re-wrap the compiler.
To wrap a compiler in-place on Linux:
1. Open a terminal and navigate to the root of your RVS installation.
2. Run the following command to check the compilers supported and what
their codes are i.e. for GNAT use 'GNAT': ./auxd/python/bin/python3 ./
integration_resources/compiler_wrappers/setup.py --help
3. Run the following command to wrap the compiler ./auxd/python/bin/
python3 ./integration_resources/compiler_wrappers/setup.py --mode
install --compiler <COMPILER> --dir /path/to/compiler
e.g. to wrap GNAT under /usr/local/pkg/gnat run ./auxd/python/
bin/python3 ./integration_resources/compiler_wrappers/setup.py --
mode install --compiler GNAT --dir /usr/local/pkg/gnat
RVS Integration Guide vWF20190404 23 Compiler wrappers Integrating with a build system
Note
RVS is shipped with a pre-wrapped version of GNAT GPL 2014, which is lo-
cated in the RVS/auxd/x86/gnat-gpl-wrapped folder.
If you are integrating RVS with an Ada project, you may want to use this
compiler to build your source code during the Prepare stage of your in-
tegration, see Section A.2: Using different integration strategies in a single
RVS integration.
Assuming you have followed this guide so far, you should now be able to use RVS
to produce verification data; continue to Section 4.7: Checklist.
4.2.3 Calling a wrapper from the PATH One strategy to run RVS using a compiler wrapper is to change the PATH set by RVS when invoking your build system to point to the wrapper instead of your com- piler. When using this strategy, you should ensure that the compiler is only called from the PATH in the build system. If it is not, you should also change the build system as described in Section 4.2.4: Calling a wrapper from your build system.
This strategy involves adding a wrapper with the same name as your compiler to
your file system and editing the PATH RVS uses so that it calls the wrapper rather
than the compiler.
The compiler wrappers included in RVS are located in the
rvs/integration_resources/compiler_wrappers directory. Wrap-
per executable names end with _wrap to distinguish them from the compilers
they wrap, for example gcc_wrap.
To use this strategy, copy the wrapper for your compiler somewhere outside the
read-only RVS directory, and rename it to have the same name as your compiler
(gcc, for example).
Next, edit the path RVS uses by doing the following:
1. Open your project in the RVS Project Manager.
2. Click Configure in the Actions section of the project overview page to
open the configuration options page.
3. Open the Environment page from the sidebar, which is nested under
Project.
4. Type the path to the wrapper before $((PATH)) in the Path Variable section.
5. Save and Close your configuration using the buttons at the top-left
of the window.
24 RVS Integration Guide vWF20190404 Integrating with a build system Compiler wrappers
Figure 4.3: Calling a wrapper from the PATH
Assuming that you have followed this guide so far, you should now be able to use
RVS to produce verification data; continue to Section 4.7: Checklist.
4.2.4 Calling a wrapper from your build system One strategy to run RVS using a compiler wrapper is to change your build scripts so they call the compiler wrapper instead of your compiler. Build scripts are often the most complicated part of a build system, and other compiler wrapper integra- tion strategies are recommended where applicable.
RVS compiler wrappers are located in the
rvs/integration_resources/compiler_wrappers directory. Wrap-
per executable names end _wrap to distinguish them from the compilers they
wrap, for example gcc_wrap.
To use these wrappers, you must edit your build scripts to call the wrapper rather
than your compiler. You must replace all calls to your compiler in the build script to
call the wrapper instead – this may mean simply changing an environment variable
in your build scripts, or changing the script in multiple places.
After editing your build scripts to call the compiler wrapper, you must also configure
the wrapper in the RVS Project Manager by doing the following:
1. Open your project in the RVS Project Manager.
2. Click Configure in the Actions section of the project overview page to
open the configuration options page.
3. On the sidebar, expand your target and open the Compiler Wrapper
page.
4. Click Add to add a compiler wrapper.
5. Beside the Wrapper path field, click Browse and select the wrapper you are
using.
6. Beside the Compiler path field, click Browse and select the compiler you are
using from your file system.
RVS Integration Guide vWF20190404 25 Compiler wrappers Integrating with a build system
7. Save and Close your configuration using the buttons at the top-left
of the window.
Figure 4.4: Calling a wrapper from your build system
Assuming you have followed this guide so far, you should now be able to use RVS
to produce verification data; continue to Section 4.7: Checklist.
4.2.5 Modifying compiler wrapper integrations In many cases, little or no modification of an integration is needed for compiler wrapper strategies to work efficiently. You may, however, need to, or want to, make some changes, as described in the following sections.
Including RVS libraries
By default, compiler wrappers add RVS integration libraries to source code by
linking the libraries together with your other source files during the Build stage
of the integration. For this strategy to work, you may need to configure RVS with
additional information about your linking strategy.
If your build system links files in multiple stages, you must instruct RVS during
which linker invocation you want RVS to link libraries by specifying link triggers. To
do so, do the following:
1. Open your project in the RVS Project Manager.
2. Click Configure in the Actions section of the project overview page.
3. Click Advanced Configuration in the sidebar to the left of the window.
4. Select the Rvslib Link Trigger[+] entry, which is nested under Target List. You
can use the filter function to find this more easily.
26 RVS Integration Guide vWF20190404 Integrating with a build system Compiler wrappers
5. In the New Item field, click Add.
6. In the Rvslib Link Trigger[<number>] entry that appears, configure settings
so that RVS knows when to link libraries:
• In the Trigger Option Type entry, you can select the type of options to be
matched against; any, file, flag or tool specific options.
• In the Argument Pattern and Value Pattern entries, specify glob patterns
to match against option arguments and values that identify a linker invo-
cation, respectively.
• In the Match State entry, specify a Value of true to configure RVS to link
libraries when elements are matched according to the entries above, or
a Value of false to configure RVS not to do so.
7. If you need to specify more link triggers, add more from the Rvslib Link Trig-
ger[+] entry and configure them as appropriate. If you have added multiple
link triggers, RVS determines when to link libraries by applying a Boolean
operation on those triggers (and by default). If you need to change this be-
havior, change the Value field in the Rvslib Link Condition State entry.
8. Click the Save and Close buttons to save your changes and return to
the RVS Project Manager.
Figure 4.5 shows an example in which RVS has been configured to link RVS li-
braries when the -o main.elf flag is observed.
Figure 4.5: Specifying link triggers
RVS Integration Guide vWF20190404 27 Clone integrations Integrating with a build system
4.3 Clone integrations One way to integrate RVS to work within your development environment is to use a clone strategy. Using this strategy, RVS creates a copy (clone) of your source files and the files needed to build your code, injects RVS code and instrumentation into the copied code for RVS analysis, then compiles and links files, including an RVS library, to produce an executable from which verification results are collected, see Figure 4.6.
Figure 4.6: Clone integration workflow
28 RVS Integration Guide vWF20190404 Integrating with a build system Clone integrations
When using a clone strategy, RVS must be able to:
1. Observe and clone all preprocessed source files in the project during the
Prepare stage of the integration. To learn how to configure an RVS clone in-
tegration to do this, see Section 4.3.2: Observing preprocessed source files.
2. Inject RVS code into the cloned versions of preprocessed source files and
compile and link these during the Build stage of the integration. To learn how
to configure an RVS clone integration to do this, see Section 4.3.3: Injecting
RVS code into cloned preprocessed files.
3. Add RVS integration libraries to cloned source files and compile and link
these during the Build stage of the integration. To learn how to configure an
RVS clone integration to do this, see Section 4.3.4: Adding RVS integration
libraries.
To select a clone integration strategy, select Clone as the Integration Strategy when
creating an RVS project, see Chapter 3: Getting started.
4.3.1 Editing clone integration settings You can configure many of the clone settings applied in your project from the Clone page of the RVS Config Editor, see Figure 4.7. To access this page, open your project in the RVS Project Manager, click Configure on the project overview page, and click Clone, which is nested under Targets.
Figure 4.7: Clone settings page
RVS Integration Guide vWF20190404 29 Clone integrations Integrating with a build system
4.3.2 Observing preprocessed source files
Important
To observe preprocessed source files from your project, these files must be
preserved by your build system. Preprocessed files can be preserved by
using compiler flags; when using the gcc compiler, for example, you can
save preprocessed files by using the -save-temps flag.
For more information, contact support@rapitasystems.com
The first requirement when implementing an RVS clone integration strategy is that
RVS can observe all of the preprocessed source files in a project. There are mul-
tiple ways in which RVS can do this:
• It can scan the file system for files matching specific file extensions within and
under a specified folder after the build system has been run. This is the sim-
plest and default method and is described in the section called “Scanning the
file system for preprocessed files” on p. 30.
• You can configure your build system to store information on source files in your
project by using the RVS clonehelper tool. This is described in the section
called “Storing source file information with clonehelper” on p. 31.
You can use both methods above in a single integration.
Important
If you use multiple methods to instruct RVS which preprocessed source files
are present in your project, you must ensure that each file is only provided
to RVS once. Otherwise, unexpected behavior may occur.
Scanning the file system for preprocessed files
By default, during clone integrations, RVS scans the Root Source Folder and all
folders under it for files with a specific Pproc File Pattern, depending on the project
language(s). It then clones each such file and stores information associated with
the source and cloned files in order to apply subsequent processing.
You can edit these settings from the Clone page in your RVS project (see Sec-
tion 4.3.1: Editing clone integration settings):
• To edit the directories that RVS scans for preprocessed files, change the Root
Source Folder setting.
• To edit the file extensions that RVS treats as preprocessed files, change the
respective Pproc File Pattern settings.
• To disable automatic scanning for preprocessed files, set Auto-scan For Pre-
processed Files to False.
30 RVS Integration Guide vWF20190404 Integrating with a build system Custom integrations
Storing source file information with clonehelper
You can configure your build system to store information on source files in your
project by adding calls to the RVS clonehelper tool directly to your build system.
To learn how to do so, see Section 4.5: Using clonehelper to clone source files.
4.3.3 Injecting RVS code into cloned preprocessed files The second requirement when implementing an RVS clone integration strategy is that RVS can inject RVS code into cloned preprocessed files and compile and link these files during the Build stage of the integration. To do this, during the Build stage of an integration, RVS automatically overlays the original source files to be compiled with preprocessed versions of them, which were collected during the Prepare stage of the integration.
4.3.4 Adding RVS integration libraries The final requirement when implementing an RVS clone integration strategy is that RVS integration libraries are added when source files are compiled and linked dur- ing the Build stage of the integration. To configure RVS to add integration libraries, you must modify your build system.
You can use the RVS ihelper tool to help you do this, see Section 4.6.2: Injecting
RVS integration libraries using ihelper.
4.4 Custom integrations Custom integrations are flexible, giving you a blank slate from which to configure an integration. This involves making changes to your build system.
As with all RVS integrations, in custom integrations, RVS must be able to:
• Collect information on all source files in your project during the Prepare stage
of an integration – to configure this, you can use clonehelper as described in
Section 4.5: Using clonehelper to clone source files.
• Inject code into preprocessed source files from your project during the Build
stage of an integration – to configure this, you can use ihelper as described
in Section 4.6.1: Overlaying source files using ihelper.
• Add RVS integration libraries to preprocessed code during the Build stage of
an integration – to configure this, you can use ihelper as described in Sec-
tion 4.6.2: Injecting RVS integration libraries using ihelper.
To select a clone integration strategy, select Custom as the Integration Strategy
when creating an RVS project, see Chapter 3: Getting started.
4.5 Using clonehelper to clone source files The RVS tool clonehelper is designed to help you clone source files so they can be instrumented by RVS.
RVS Integration Guide vWF20190404 31 Using ihelper to link RVS files Integrating with a build system
Example 4.1 shows an example of a clonehelper call in a build system that uses
gcc to build C code using Make.
Example 4.1: Storing source file information with clonehelper
1 GCCEXE?=gcc
2 SRCS_C=$(shell ls src/*.c)
3 OBJS=$(SRCS_C:.c=.o)
4
5 ifeq ($(RVS_BUILD_STAGE),prepare)
6 RVS_CFLAGS:=-save-temps=obj -DRVS
7 endif
8
9 all: build run
10 @echo ========== Complete ==========
11
12 build : $(OBJS)
13 @echo ========== Build ==========
14 $(GCCEXE) -o all.exe $(OBJS)
15
16 %.o : %.c
17 $(GCCEXE) -c -o $@ $(RVS_CFLAGS) $<
18 clonehelper $<
The conditional RVS_BUILD_STAGE segment beginning on line 5 configures
RVS to apply the -save-temps=obj compiler flag when running the Prepare stage
of an RVS integration to ensure that preprocessed files are preserved during com-
pilation.
The RVS_BUILD_STAGE variable is set by the master RVS tool, rvsdriver, which
will be called when you run your RVS integration. When running the Prepare stage
of an integration, rvsdriver sets the value of this variable to prepare.
Thus, by including the conditional RVS_CFLAGS variable in the %.o rule that gen-
erates object files (line 17), we instruct the compiler to save preprocessed files
when we Prepare the integration and invoke the build systems with rvsdriver.
For more information on rvsdriver, see Chapter 12 in the RVS Command Line Tools
Reference Guide.
The clonehelper $< command on line 18 calls clonehelper for each com-
piled .c file. This stores information RVS needs to instrument each file and, by
default, moves preserved preprocessed files to the intermediates folder in
the RVS project.
For more information on clonehelper, see Chapter 5 in the RVS Command Line
Tools Reference Guide.
4.6 Using ihelper to link RVS files The RVS tool ihelper is designed to help you modify build systems to achieve RVS integrations with them. ihelper can perform a variety of actions including the following:
32 RVS Integration Guide vWF20190404 Integrating with a build system Using ihelper to link RVS files
• Overlaying source files with instrumented versions of them, see Section 4.6.1:
Overlaying source files using ihelper.
• Injecting RVS library files into a project, see Section 4.6.2: Injecting RVS inte-
gration libraries using ihelper.
For more information on ihelper, see Chapter 9 in the RVS Command Line Tools
Reference Guide.
4.6.1 Overlaying source files using ihelper You can use ihelper to overlay instrumented RVS files over the source files your build system would compile normally. This is typically done by adding calls to ihelper manually to a build system.
Example 4.2 shows an example of an ihelper overlay call in a build system that
uses gcc to build C code using Make. This example builds on the one shown in
Section 4.5: Using clonehelper to clone source files.
Example 4.2: Overlaying source files with ihelper
1 GCCEXE?=gcc
2 SRCS_C=$(shell ls src/*.c)
3 OBJS=$(SRCS_C:.c=.o)
4
5 ifeq ($(RVS_BUILD_STAGE),prepare)
6 RVS_CFLAGS:=-save-temps=obj -DRVS
7 endif
8
9 all: build run
9 @echo ========== Complete ==========
10
11 build : $(OBJS)
12 @echo ========== Build ==========
13 $(GCCEXE) -o all.exe $(OBJS)
14
15 %.o : %.c
16 $(GCCEXE) -c -o $@ $(RVS_CFLAGS) $(shell ihelper --overlay $<)
17 clonehelper $<
The $(shell ihelper --overlay $<) command on line 16 calls ihelper
to overlay the input .c file with the version of the same file instrumented by RVS.
For more information on ihelper and the --overlay option, see Chapter 9 in the
RVS Command Line Tools Reference Guide.
4.6.2 Injecting RVS integration libraries using ihelper You can use ihelper to configure the injection of RVS integration libraries when you link files during your project. This is typically done by adding calls to ihelper manually to a build system.
Example 4.3 shows an example, where ihelper calls are used to inject RVS in-
tegration libraries in a build system that uses gcc to build C code using Make.
RVS Integration Guide vWF20190404 33 Using ihelper to link RVS files Integrating with a build system
This example builds on the ones shown in Section 4.5: Using clonehelper to clone
source files and Section 4.6.1: Overlaying source files using ihelper.
Example 4.3: Adding integration libraries with ihelper
1 GCCEXE?=gcc
2 SRCS_C=$(shell ls src/*.c)
3 OBJS=$(SRCS_C:.c=.o)
4
5 ifeq ($(RVS_BUILD_STAGE),prepare)
6 RVS_CFLAGS:=-save-temps=obj -DRVS
7 endif
8 RVS_CFLAGS+=$(shell ihelper --prearg -I --libinc)
9
10 all: build run
11 @echo ========== Complete ==========
12
13 build : $(OBJS) $(shell ihelper --fmt-make --libobjs)
14 @echo ========== Build ==========
15 $(GCCEXE) -o all.exe $(OBJS) $(shell ihelper --libobjs)
16
17 %.o : %.c
18 $(GCCEXE) -c -o $@ $(RVS_CFLAGS) $(shell ihelper --overlay $<)
19 clonehelper $<
The ihelper call added to the RVS_CFLAGS variable on line 8 configures ihelper
to prepend each compiler call made during the %.o rule with a command to add
RVS include paths so the build system can find RVS header files.
The commands in the build rule instruct the build system to include RVS libraries
when building code. The $(shell ihelper --fmt-make --libobjs)
command on line 13 instructs make to build the RVS libraries along with other
objects. The $(shell ihelper --libobjs) command on line 15 instructs
gcc to link RVS libraries along with other objects in the system.
For more information on ihelper and the options used in the example above, see
Chapter 9 in the RVS Command Line Tools Reference Guide.
34 RVS Integration Guide vWF20190404 Integrating with a build system Checklist
4.7 Checklist When you have selected and implemented an appropriate strategy to apply during both the Prepare and Build stages of an integration, you should be able to run an integration to produce verification data if you are running your test executable on a host system. To learn how to do so, see Chapter 4 in the RVS User Guide.
If you want to learn how to use RVS to collect verification data from an embedded
target, continue to Chapter 5: Integrating with a target.
RVS Integration Guide vWF20190404 35 This page intentionally left blank 5 Integrating with a target This chapter assumes that you have created an RVS project suitable for the pro- gramming language of your source code and use with your build system. If you have not done this, we recommend that you learn how to by reading Chapter 3: Getting started and Chapter 4: Integrating with a build system.
If you want to use RVS to collect verification data from an embedded target, you
must select and implement an appropriate data collection strategy. When this has
been done, you can use the RVS Project Manager to invoke your build system and
collect verification data from your target. This involves two stages: selecting a data
collection strategy, and creating an integration library suitable for that strategy.
5.1 Selecting a data collection strategy This section describes various strategies that can be used to integrate RVS to collect data from an embedded target. With an appropriate strategy, RVS can be integrated with almost any target. When selecting a strategy, you should consider your target hardware, the analyses you want to perform and any auxiliary hardware you have available.
When selecting a strategy, the following factors are important:
• Execution time overhead – RVS calls take time to execute, but should not
cause your system to violate timing restraints such as watchdog timers. Be-
cause of this, lightweight instrumentation points are preferred.
• Memory – it may be beneficial to store temporary RVS data in a buffer. If not
enough memory is available for this, the data can be streamed to an external
device for storage, such as on an RTBx.
• Code size – each instrumentation point requires space when compiled into
object code. This can be a limiting factor when determining a collection strat-
egy due to the limited space available on many embedded targets.
• Bandwidth – if RVS data is stored externally, the speed at which data can be
transferred to external storage is important.
• Off-target data processing time – if RVS data needs to be filtered and this is
not done as it is created, it must be filtered afterwards. For programs compiled
from large code bases, this can take a long time.
The most appropriate strategy to use depends on the analysis you want to per-
form with RVS. If you want to use RVS to run unit tests (with RapiTest) or analyze
structural code coverage (with RapiCover), the best strategy differs to that if you
want to use it to run timing (RapiTime) or tasking (RapiTask) analysis. If you want
to use RVS to analyze timing or tasking behavior, this will have a large influence
RVS Integration Guide vWF20190404 37 Selecting a data collection strategy Integrating with a target
on your data collection strategy due to the large volume of data involved and the
need to preserve the original execution time behavior as much as possible.
The next sections describe how to select a strategy to collect data for:
• RapiCover and RapiTest
• RapiTime and RapiTask
5.1.1 RapiCover and RapiTest strategies Most often, the best way to collect data for RapiTest or RapiCover is to use a map. A map stores RVS data in memory on the target while the program executes. The same memory location can be overwritten, for example if a function is instrumented for coverage analysis and is observed more than once. After the program finishes, RVS data is extracted. A map incurs low execution time and memory overheads and is easy to implement.
If your target has limited memory, you can use a LiveMap to transfer RVS data
onto external memory as the program executes. While this has very low on-target
overheads, your system must have enough bandwidth to support streaming the
trace as it is produced.
If your system's bandwidth is a limiting factor, you can use a DiffMap to collect RVS
data from it. Using this method, a standard map is created on your target. Every
time unique RVS data is stored to this map, it is transferred off-target. Because
only unique data is transferred, the off-target data processing time needed is lower
than for a LiveMap. This method requires the same amount of memory available
on your target as needed for a standard map.
A summary of the strategies discussed above is shown in Table 5.1.
Table 5.1 RapiCover and RapiTest data collection strategies
Collection Hardware required Execution Memory Code size Bandwidth
method time overhead overhead overhead
overhead
Map Any target data link, Medium Low Low – None
e.g. debugger, eth- medium
ernet.
LiveMap RTBx or a logic ana- Low Negligible Low High
lyzer. Access to I/O
pins.
DiffMap RTBx or a logic ana- Medium Low Medium Low
lyzer. Access to I/O
pins.
5.1.2 RapiTime and RapiTask strategies To collect data that can be used for analysis with RapiTime or RapiTask, you must use a trace. Traces collect both an identifier (ID) and timestamp for each instru- mentation point (ipoint) encountered in the executable.
38 RVS Integration Guide vWF20190404 Integrating with a target Selecting a data collection strategy
There are multiple types of trace and the most appropriate strategy to use depends
on the hardware you have available, see below:
• Memory trace – a trace is stored in memory. Timestamps are provided by the
target hardware, which writes each ipoint ID and timestamp to a buffer. The
in-memory trace may be extracted, for example, while the executable runs by
using an ethernet connection or debugger.
• File trace – this works like a memory trace, but data is written to a file instead of
memory. To use this strategy, it must be possible to write to permanent storage
such as a hard disk.
• I/O trace – ipoint IDs are written to an output port (for example GPIO pins)
connected to a RTBx or logic analyzer. The external hardware timestamps the
ID and stores trace data.
• Address trace – an address or range of addresses is reserved to encode each
ipoint ID. An RTBx, logic analyzer or trace-enabled debugger monitors each
address and timestamps data when data is written to the address.
A summary of these strategies is shown in Table 5.2.
Table 5.2 Trace collection methods
Collection Hardware required Execution Memory Code size
method time overhead overhead
overhead
Memory trace Any target data link, e.g. Medium – High Medium
debugger, ethernet. high
File trace Data storage device. Medium – Low Medium
high
I/O trace An RTBx or logic analyz- Low Very low Medium
er.
Access to I/O pins.
Address trace An RTBx or logic analyz- Low Very low Low
er.
Connectivity to address
bus.
All trace collection techniques involve collecting a large amount of trace da-
ta. This incurs a large off-target data processing time overhead. To reduce this
overhead, you may want to consider using the RTBx, which filters timestamped
verification data produced at high rates on-the-fly. For more information, con-
tact enquiries@rapitasystems.com or visit https://www.rapitasystems.com/prod-
ucts/rtbx.
Note
More information on using RapiTime or RapiTask on hardware with limited
resources is available in Section A.3.
RVS Integration Guide vWF20190404 39 Implementing a data collection strategy Integrating with a target
5.2 Implementing a data collection strategy When you have selected an appropriate data collection strategy, you must imple- ment it. This involves developing an integration library that instructs your build sys- tem how to collect data from your target.
If you have reached this point in the integration, RVS should already have deployed
a template integration library for your project. If you have not yet created an RVS
project, follow Chapter 3: Getting started.
RVS automatically deploys a template integration library based on the options you
have configured in your RVS project after you create it using the New RVS Project
Wizard. To locate this, open the Project menu in the RVS Project Manager and
select Open project folder. In this folder, open the folder prefixed rvs and
then the folder prefixed with rvslib. The files in this folder comprise a template
integration library, which must be configured to work with your target hardware.
Developing an integration library for a specific target requires a good understand-
ing of how to configure data input and output to and from an embedded target, and
of the RVS API. The following calls are included in most RVS integration libraries:
• RVS_Init (RVS.Init for Ada) – this instructs RVS to set up the environ-
ment it needs to begin data collection. It is usually the first RVS function called
during an integration.
• RVS_Build_Id (RVS.Build_Id for Ada) – this optional call sets a build
version identifier based on, for example, the source code revision used in the
integration.
• RVS_Begin_Test (RVS.Begin_Test for Ada) – this instructs RVS to start
a new test that can be referenced with a test identifier. It is optional, but can
be used to assign unique identifiers to each test for easier processing later.
• RVS_Ipoint (RVS.Ipoint for Ada) – this instructs RVS to register that a
point in the program has been hit during its execution. Examples of how this is
achieved include setting a bit on an I/O port or writing an ipoint identifier to a
file. If data is timestamped, this function may also configure how this is done.
This function is not normally referenced directly, but expanded from macros
such as RVS_I or inline functions in the source code.
• RVS_End_Test (RVS.End_Test for Ada) – this instructs RVS to end a test.
• RVS_Output (RVS.Output for Ada) – this instructs RVS to output data,
often at the end of a test run. For example, it may instruct RVS how to upload
data stored in memory at the end of a test.
The RVS Integration Library Implementation Guide describes how to implement
RVS integration libraries including more detailed information about the API calls
above, and which you need to implement depending on your analysis settings
and data collection method. This is aimed for use by readers with a thorough
understanding of how RVS works.
40 RVS Integration Guide vWF20190404 Integrating with a target Checklist
For more information on how to integrate RVS to work with specific com-
pilers, data collection methods or hardware, you can read the Integra-
tion Annexes included in your RVS installation. To locate these, open the
RVS/integration_resources/integration_annexes folder.
We offer support integrating RVS to work with your embedded target. The main
outcome of this is a robust integration library that lets you use RVS to collect data
from your target. For more information, contact support@rapitasystems.com.
5.2.1 Configuring RVS to use an integration library For RVS to be able to collect data from your embedded target, a library must be deployed for the integration. By default, RVS deploys a template library, which is selected depending on your project settings, for example the language of your source code and your data collection strategy. If we have provided you with a custom library, or you have developed one yourself, you will have to configure RVS to deploy this library instead.
To configure RVS to use an integration library, open your project in the RVS Project
Manager. On the main project page, click Configure. Click on the page for your
integration (if this is not shown, click the arrow next to Integrations to show it). In
the Integration Library field, click Browse, locate and select the integration library
on your file system, and click OK. Finally, Save and Close your changes
using the buttons at the top of the window. The library you selected will be used
for your integration from now on.
5.3 Checklist If you have followed this guide so far, you should now be able to run your inte- gration to produce verification data from your target. To learn how to do so, see Chapter 4 in the RVS User Guide.
You may need to convert your raw data into an output format that RVS understands.
To learn how to do this, continue to Chapter 6: Converting data.
RVS Integration Guide vWF20190404 41 This page intentionally left blank 6 Converting data This chapter assumes that you have created an RVS project suitable for the pro- gramming language of your source code and use with your build system and tar- get. If you have not done this, we recommend that you learn how to by reading Chapter 3: Getting started, Chapter 4: Integrating with a build system and Chap- ter 5: Integrating with a target.
Verification data that RVS analyzes may be stored in different formats. To allow
RVS to analyze your data, you may need to configure a strategy to convert raw
data into a suitable output format.
6.1 Conversion strategies To convert data into a suitable output format, one or more data converters should be configured to apply a transform to the raw data. Data conversion could range from a simple procedure such as removing spurious ipoints from the beginning of a single trace file to a complex one involving sequential chains of converters operating on multiple input files.
6.2 Data converters Each converter takes one or more input files and converts them into one or more output files by using RVS filters or running external tools. Common operations performed by converters include the following: • Translating data from raw formats into formats suitable for RVS analysis • Splitting raw data into multiple files or merging multiple input files into a single output file • Removing specific ipoints or sequences of them • Replacing specific patterns of ipoints with others
Figure 6.1 shows a simple example conversion strategy.
RVS Integration Guide vWF20190404 43 Specifying data files and converters Converting data
Figure 6.1: Example conversion
The input file in Figure 6.1 is a memory dump. The first and only conversion stage
uses a read filter to extract only RVS ipoint data from the memory dump. At this
point, the trace file can be used by RVS.
We provide support for using RVS filters to convert your data. For more information
on RVS filters, see the RVS Filters Guide. If you want us to write filters to convert
the raw data collected from your target, contact support@rapitasystems.com.
6.3 Specifying data files and converters Before you can convert data to a suitable output format, you must first specify the data files that you need to convert. To do this, follow the steps below: 1. Open the project and select the Integration you want to specify data files for in the RVS Project Manager. To change the active integration, use the Active integration drop-down menu on the project overview page. 2. Click Configure in the Actions section of the project overview page. 3. Click Data Files on the sidebar to show a list of data files in the integration. 4. When you first create an integration, RVS sets up a default data file. This is set up based on the options you select when creating the integration. While the default can be used for most on-host integrations, you may need to specify different data files for on-target integrations. To do so, you can Edit the de- fault data file, and Add new ones if necessary.
44 RVS Integration Guide vWF20190404 Converting data Specifying data files and converters
5. For each data file you specify, provide the path and name of the file on your
file system and the file format (see Chapter 5: Integrating with a target). In
most cases, you can leave the Target Metrics section as auto.
6. Make sure to Save your changes.
Figure 6.2: Specifying data files
After you have specified the data files created during your project, add converters
to apply to them by doing the following:
1. On the page for the data file (nested under Data Files in your Integration),
click Add beside the Converters section.
2. In the wizard that opens, type a Name for the converter, see Figure 6.3. If you
have already set up a converter and want to reuse it, select it from the drop-
down menu. This fills in the other fields on this page using the converter's
existing settings.
3. If you are using an RVS filter to convert your data, select it from your file
system by using the Add button in the Filter File section. You can specify
multiple filters to use for each converter. In this case, filters are called in the
order shown in the Filter File list.
4. If you are using an external tool to convert your data, provide the com-
mand-line arguments to run it in the External Command Lines section.
5. Click Finish to add the new converter.
6. Make sure you Save your changes before you Close the window.
RVS Integration Guide vWF20190404 45 Checklist Converting data
Figure 6.3: Setting up converters
Note
We recommend that you do not enter settings for both RVS filters and ex-
ternal tools for a single converter. If your conversion strategy uses both of
these, we recommend that you set up multiple converters to implement it.
6.4 Checklist If you have followed this guide so far, you should now be able to run your integra- tion to produce and view verification data from your target. To do this, open your RVS project in the RVS Project Manager and click Run in the Actions section of the project overview page.
46 RVS Integration Guide vWF20190404 Integrating with extended 7 programming languages RVS can analyze code written in various standards of C and C++ programming languages by default. For more information on the standards supported, see the Rapita Systems Ltd. website.
If your code is extended beyond common standards to include additional key-
words or functionality, RVS must be instructed how to analyze any non-standard
language features you may be using when parsing and instrumenting code. RVS
supports this through the use of compiler extensions, which you can add to your
project.
7.1 Adding a compiler extension to your project Note
If you are using compiler wrappers to integrate RVS with your build sys-
tem, and are using a language extension for which support is already avail-
able, you do not need to add a compiler extension to your project – the RVS
compiler wrapper automatically adds any extensions needed based on your
compiler.
RVS installations include compiler extensions for many common compilers in the
RVS/integration_resources/compiler_extensions folder.
To add a compiler extension to your project, do the following:
• Open your project in the RVS Project Manager.
• Click Configure in the Actions section of the project overview page.
• Click Advanced Configuration in the sidebar to the left of the window.
• Select the C Extensions or C++ Extensions entry. You can use the filter function
to find these more easily.
• Add the extension you need in the Value field. To add an ex-
tension, type the filename of the extension as it appears in
your RVS/integration_resources/compiler_extensions fold-
er, without the file extensions, e.g. ANSI, see Figure 7.1.
To specify multiple compiler extensions, enter the extensions as a space-sep-
arated list.
• Save and Close your configuration using the buttons at the top-left of
the window.
RVS Integration Guide vWF20190404 47 Integrating with extended programming lan- Adding a compiler extension to your project guages
Figure 7.1: Adding compiler extensions
If you need us to develop support for the language features you're using, we'd be
happy to help you. Contact support@rapitasystems.com for more information.
Important
We recommend that you do not modify compiler extension files. If you do
so and you are qualifying RVS to use for producing certification evidence,
your qualification may be invalidated.
48 RVS Integration Guide vWF20190404 8 Using the command-line You can run RVS integrations from the command-line, for example by using the RVS Shell command-line application included in RVS installations. You can access this application on Windows systems from the Start menu (Start » RVS » RVS Shell).
Even when you run an RVS integration through the RVS Project Manager, it is run
using rvsdriver, which manages all of the back-end tools involved in RVS integra-
tions, see Section 2.2: Running an integration.
For more information on using rvsdriver, see Chapter 12 in the RVS Command
Line Tools Reference Guide.
RVS Integration Guide vWF20190404 49 This page intentionally left blank 9 Customizing integrations RVS integrations are typically based on a standard workflow, as described in Sec- tion 2.2: Running an integration This chapter describes how to customize RVS in- tegrations to produce different functionality.
You can customize RVS integrations in two main ways:
• Using custom recipes to run RVS integration stages in a different workflow.
• Editing the scripts called when RVS integration stages are invoked to cus-
tomize what happens during each RVS integration stage.
These approaches to customizing integrations are described in the following sec-
tions.
9.1 Custom recipes You can specify custom recipes that use existing RVS integration stages but apply these in a different workflow.
Custom recipes support automation when using RVS. For example, you may spec-
ify a custom recipe that runs the RVS Build, Run and Report stages multiple times
to support integrations that collect data from multiple builds. You can run custom
recipes through both the RVS Project Manager and the command-line.
9.1.1 Writing custom recipes Custom recipes are script files that can be written in a variety of formats.
This guide will not describe how to write these files. If you want assistance pro-
ducing custom recipes, contact support@rapitasystems.com.
9.1.2 Adding custom recipes to RVS projects To add a custom recipe to an existing RVS project, do the following: 1. Open your project in the RVS Project Manager. 2. Click Configure in the Actions section of the project overview page. 3. Click Advanced Configuration in the sidebar to the left of the window. 4. Select the Integration Recipe[+] entry, which is nested under Project. You can use the filter function to find this more easily. 5. In the New Item field, provide a name for the recipe you want to add, then click Add. 6. In the Recipe stages entry for the recipe you just added, provide the names of the RVS integration stages that you may want to use the recipe in in the
RVS Integration Guide vWF20190404 51 Custom recipes Customizing integrations
Value field, for example Prepare, Build or Report, see Section 2.2: Running
an integration. Setting Recipe stages is optional, but this will let you run the
recipe easily through the RVS Project Manager, see Section : Running cus-
tom recipes through the RVS Project Manager.
7. In the Integration script entry, click Browse and select the script file you want
to use from your file system.
8. Click Save and Close to save your changes and return to the RVS
Project Manager.
9.1.3 Running custom recipes You can run custom recipes through both the RVS Project Manager and the com- mand-line (by using rvsdriver).
Running custom recipes through the RVS Project Manager
You can run custom recipes from the project overview page in the RVS Project
Manager if you have set valid Recipe stages for the custom recipe, see Sec-
tion 9.1.2: Adding custom recipes to RVS projects.
When you have set a Recipe stage, it appears as an advanced option in the Actions
section of the project overview page, which you can access by clicking the
button.
In Figure 9.1, for example, we have specified a recipe for the Run stage, MyCus-
tomRecipe.
Figure 9.1: Running custom recipes through the RVS Project Manager
To run a custom recipe, click the button beside the action it is assigned to and
click the name of the recipe.
Running custom recipes through the command-line
To run a custom recipe through the command-line, call rvsdriver with the
--recipe <recipe_name> option, as in the following example:
52 RVS Integration Guide vWF20190404 Customizing integrations Editing RVS integration scripts
rvsdriver --project MyRVSProject.rvsprj --recipe MyCustomRecipe
9.2 Editing RVS integration scripts By default, when an RVS stage is invoked (see Section 2.2: Running an integration), a script is called, see Section 2.2: Running an integration. These scripts determine what occurs during that stage of an integration. The default scripts are written in JavaScript, but scripts can be written in a variety of formats. The default integra- tion scripts are located in the RVS/integration_resources/rvsdriver folder, and have the same filename as the RVS integration stage during which they are called, for example run.js.
By default, run.js determines what occurs during the run hook of an inte-
gration. If you have a good understanding of JavaScript and the RVS integra-
tion workflow, you can write an alternative to use in place of this file. Alternative-
ly, you can write a script in another suitable scripting language to replace this
one. You can also add up to two additional scripts; one that runs before the
main script, and one that runs after. The js_builtins.html document in the
RVS/integration_resources/reference folder contains a reference of
built-in JavaScript functions that may be useful when setting up JavaScript files.
Warning
We recommend that you do not modify any of the default scripts included in
your integration library.
To change the file that RVS uses during the run hook of an integration, do the
following:
1. Open the project in the RVS Project Manager.
2. On the project overview page, click Configure.
3. Click Advanced Configuration.
4. Scroll down in the table until you find the Run Script field and select it.
5. Click Browse beside the Value field, locate and select the JavaScript file you
want to use, and click Open.
6. Save and Close your changes using the buttons at the top of the
window.
In the same way, you can add a file to run before or after the run hook by changing
the Run Prehook or Run Posthook settings. You can also change the Working folder
where the script executes commands; this defaults to the project's working folder.
Just like you can for the run stage, you can customize what occurs during other
RVS stages such as clean and prepare by modifying the scripts run during them.
RVS Integration Guide vWF20190404 53 This page intentionally left blank 10 Integration resources RVS comes with many resources that are available to help inte- grate RVS into a development environment. These are stored in the RVS/integration_resources folder, which contains the following subfold- ers: • clone_scripts – scripts for the clone integration strategy, see Section 4.2: Compiler wrappers. • code_generators – scripts used to generate unit test code for RapiTest. • compiler_extensions – scripts needed to use RVS to analyze code that is built using compilers with specific extensions. • compiler_wrappers – tools for the compiler wrapper integration strategy, see Section 4.3: Clone integrations. • map_templates – integration library templates for implementation of the RVS map API on various platforms. • plugins – plugins for running RVS with third-party tools. • quoting_codecs – scripts needed to integrate RVS with various third-party tools that use specific quoting mechanisms. • reference – additional documentation about the integration workflow for use by integrators (see below). • scripts – scripts used by default for the various stages of RVS integrations. • taskparser_os – resources for running RapiTask in OS-only mode. • templates – scripts used by default for the various stages of RVS integra- tions. • test_converters – scripts used for converting RapiTest tests between different formats.
RVS Integration Guide vWF20190404 55 Integration resources
Integration reference documentation is stored in the
RVS/integration_resources/reference folder. This folder contains
subfolders and documents including the following:
• integration_annexes – this folder contains additional documentation
for integrations involving specific platforms.
• cext.html – this contains reference documentation for using RVS compiler
extensions.
• js_builtins.html – this contains a reference of built-in JavaScript func-
tions that may be useful when setting up integration scripts for use with RVS,
see Chapter 9: Customizing integrations.
• riclib_doc.html – this contains a reference of settings for RIClib, the
RVS integration API. Access to these settings is available via the RVS Config
Editor, particularly on the Advanced Configuration tab (see Section 4.11 in the
RVS User Guide).
• rvs_integrations.html – this contains a knowledge map that con-
tains information about integration concepts, terminology and the integration
process and includes examples and links to other documentation where ap-
propriate.
• rvsdriver_vars.html – this contains information about the variables
passed from rvsdriver to integration scripts.
• rvsdriver_workflow.png – this figure shows the rvsdriver integration
stages in more detail than the figure shown in Figure 2.3.
• tool_roles.html – this describes the purpose of some of the RVS com-
mand-line tools, in which hooks of an RVS integration they are used. For more
information on the RVS command-line tools, see the RVS Command Line Tools
Reference Guide.
56 RVS Integration Guide vWF20190404 A Appendix A.1 Integrating RVS with Ada projects RVS must observe all of the source files in a project during the Prepare stage of an integration. When integrating with Ada projects, RVS uses a common strategy to observe these files, which is to read ADT files generated by a supported GNAT compiler. These contain a tree-based representation of the source code structure, which can be used for later analysis. If you are using a non-GNAT Ada compiler, you will need to generate ADT files using a GNAT compiler during the Prepare stage of your integrations.
Note
You only need to use a GNAT compiler during the Prepare stage of RVS in-
tegrations, you can use your normal compiler during the Build stage.
Not all versions of GNAT can produce ADT files that can be read by RVS, as the
ADT file format changes between compiler versions. The versions of GNAT sup-
ported by RVS are:
• GNAT Pro 7.2
• GNAT Pro 7.3
• GNAT Pro 7.4
• GNAT Pro 17
• GNAT Pro 18
• GNAT Pro 19
• GNAT GPL 2014
• GNAT GPL 2015
• GNAT GPL 2016
The preferred versions to use with RVS are GNAT Pro 19 and GNAT GPL 2016,
as these contain some bugfixes to ADT generation not present in earlier versions.
However, if you are working with an older codebase, you may find earlier versions
of GNAT more compatible with your source code.
RVS has limited support for the following legacy versions of GNAT:
• GNAT Pro 6.1
• GNAT Pro 6.4
• GNAT Pro 7.1
RVS Integration Guide vWF20190404 57 Integrating RVS with Ada projects Appendix
As described in Chapter 4: Integrating with a build system, two main strategies can
be used to integrate RVS with your build system: compiler wrapper and clone
strategies.
RVS is shipped with the GNAT GPL 2014 compiler and a wrapper for this compiler.
If you can use this compiler with your system, or you already use a GNAT compiler
that has a compiler wrapper available, you can use the compiler wrapper strategy,
see Section 4.2: Compiler wrappers. This is preferable as it requires less modifi-
cation to your build system. If no wrapper is available for your compiler, but you
want us to add support for it, contact support@rapitasystems.com.
If you cannot use a compiler wrapper strategy, you can use a clone strategy to
copy your source files and then process these using a GNAT compiler during
the Prepare stage of your integrations. This requires more extensive modifica-
tion to your build system than using a compiler wrapper strategy. For more in-
formation on the clone strategy, see Section 4.3: Clone integrations or contact
support@rapitasystems.com.
The rest of this section describes some factors that should be considered when
generating ADT files with GNAT, depending on your existing build system:
• Section A.1.1 explains important factors when generating ADT files if your cur-
rent compiler is a GNAT compiler supported by RVS.
• Section A.1.2 explains important factors when generating ADT files if your cur-
rent compiler is a GNAT compiler that is not supported by RVS.
• Section A.1.3 explains important factors when generating ADT files if your cur-
rent compiler is not a GNAT compiler.
A.1.1 Generating ADT files when the project is built using a supported GNAT compiler If your software is built using a supported GNAT compiler, the build process must be changed so that it produces ADT files during the Prepare stage of an RVS integration. These files are not normally produced during compilation.
When gnatmake is used to invoke the build, ADT files can be generated by in-
cluding the -gnatt option on the gnatmake commandline:
Example A.1: Call to gnatmake including -gnatt option
gnatmake -gnatt ... sourcefile.adb
This is handled automatically by compiler wrappers but must be configured man-
ually when using a clone integration strategy.
A.1.2 Generating ADT files when the project is built using an unsupported GNAT compiler If your software is built using a version of GNAT that is not supported by RVS, you will need to use a supported GNAT compiler to generate ADT files. The build
58 RVS Integration Guide vWF20190404 Appendix Integrating RVS with Ada projects
process must also be changed so that it uses this compiler to generate ADT files
during the Prepare stage of an RVS integration.
The following sections describe factors that should be considered when switching
from an unsupported GNAT compiler to a supported one:
• Calling the GNAT compiler
• Modifying the GNAT search path
Calling the GNAT compiler
The build system must be modified so that it includes a call to the GNAT compiler
used to generate ADT files. This call should include the -gnatc option, which
stops the build process after the compilation stage.
When gnatmake is used to invoke the build, add an additional call to the ADT
compiler's gnatmake with the -gnatt option to generate ADT files:
Example A.2: Additional call to ADT gnatmake
# Extra call to ADT gnatmake to generate ADT files
/path/to/supported/gnatmake -gnatt -gnatc sourcefile.adb
# Original call to target gnatmake
gnatmake ... sourcefile.adb
This is handled automatically by compiler wrappers, but must be configured man-
ually when using a clone integration strategy.
Modifying the GNAT search path
If your source code requires a particular runtime or access to libraries that are not
supplied with the regular x86 version of GNAT, you may need to add the directo-
ries containing the appropriate package specification files to the ADT compiler's
search path.
A.1.3 Generating ADT files when the project is built using a non- GNAT compiler If your software is built using a non-GNAT compiler, you will need to use a support- ed GNAT compiler to generate ADT files. The build process must also be changed so that it uses this compiler to generate ADT files during the Prepare stage of an RVS integration.
RVS is shipped with the GNAT GPL 2014 compiler, which you may be able to use
to generate ADT files. Alternatively, if you have access to it, we recommend that
you use GNAT Pro 17, or GNAT GPL 2016 if you do not have access to GNAT Pro.
The following sections describe factors that should be considered when switching
to a GNAT compiler from a non-GNAT one:
RVS Integration Guide vWF20190404 59 Integrating RVS with Ada projects Appendix
• Dealing with file names
• Calling a GNAT compiler
• Modifying the GNAT search path
Dealing with file names
GNAT compilers follow strict rules for defining the file names used for package
specifications, package bodies and separately-defined subprograms. GNAT as-
sumes that specifications are in files with .ads extensions, bodies and separates
are in files with .adb extensions, and that files are named based on the name of
the package or subprogram they contain.
If your source code does not follow these naming conventions, you will need to
supply configuration pragmas to the GNAT compiler so that it can identify your
source files. These pragmas are passed to the compiler via a text file named
gnat.adc, which must be located in the current working directory.
Configuration pragmas let you specify a systematic naming convention for file
names that correspond to specifications, bodies and subunits. For example, if your
codebase uses .ada files and discriminates between specifications and bodies
by prefixes _s and _b at the end of the file name, you can use the following
pragmas to allow GNAT to correctly identify your source files:
Example A.3: Using configuration pragmas to read files
pragma Source_File_Name (Spec_File_Name => "*_s.ada");
pragma Source_File_name (Body_File_Name => "*_b.ada");
If your codebase does not use a systematic naming convention, you will need
to supply a configuration pragma for each unit, indicating which source files con-
tain the relevant specification and body code, for example by using the following
pragmas:
Example A.4: Using configuration pragmas to read files: extended
pragma Source_File_Name (My_Units.Stacks, Spec_File_Name =>
"myunitst_a.ada");
pragma Source_File_name (My_Units.Stacks, Body_File_Name =>
"myunitst.ada");
Alternatively, you can use the gnatchop tool to automatically produce input files
with file names that can be understood by GNAT, without overwriting the original
files. If your code is structured with package specification and body in the same
file, you will need to use gnatchop to create input files that can be understood
by GNAT.
For more information on GNAT configuration pragmas and to learn how to use
gnatchop, see the GNAT User Guide. If you need help generating GNAT-compat-
ible file names for use with RVS, contact support@rapitasystems.com.
60 RVS Integration Guide vWF20190404 Appendix Integrating RVS with Ada projects
Calling a GNAT compiler
The build system must be modified so that it includes a call to the GNAT compiler
used to generate ADT files. This call should include the -gnatc option, which
stops the build process after the compilation stage.
When gnatmake is used to invoke the build, add an additional call to the ADT
compiler's gnatmake with the -gnatt option to generate ADT files:
Example A.5: Additional call to ADT gnatmake
# Extra call to ADT gnatmake to generate ADT files
/path/to/supported/gnatmake -gnatt -gnatc sourcefile.adb
# Original call to target gnatmake
gnatmake ... sourcefile.adb
This is handled automatically by compiler wrappers, but must be configured man-
ually when using a clone integration strategy.
Modifying the GNAT search path
If your source code requires a particular runtime or access to libraries that are not
supplied with the regular x86 version of GNAT, you may need to add the directo-
ries containing the appropriate package specification files to the ADT compiler's
search path.
RVS Integration Guide vWF20190404 61 Using different integration strategies in a single Appendix RVS integration
A.2 Using different integration strategies in a single RVS integration Sometimes, you may need to use different integration strategies in the Prepare and Build stages of an RVS integration.
By default, RVS uses the Integration Strategy specified when creating an RVS
project using the New RVS Project Wizard for both the Prepare and Build stages.
You can specify a different strategy to use for the Prepare stage by doing the
following:
1. Open the project in the RVS Project Manager.
2. Click Configure in the Actions section of the project overview page.
3. Click Advanced Configuration in the sidebar to the left of the window.
4. Using the search bar in the middle of the page, search for Prepara-
tion strategy.
5. Select the Preparation strategy for the integration you want to modify and
change the contents of the Value field to either wrapper or clone.
62 RVS Integration Guide vWF20190404 Working with limited resources: RapiTime and Appendix RapiTask
A.3 Working with limited resources: RapiTime and RapiTask If your target hardware has resource constraints, you may need to make special considerations when using RapiTime or RapiTask to collect data from it. This chap- ter describes how you can work around various resource constraints that your tar- get hardware may have: • Section A.3.1: Working with limited data memory describes considerations when using RapiTime or RapiTask on targets with limited available data mem- ory. • Section A.3.2: Working with limited code memory describes considerations when using RapiTime or RapiTask on targets with limited available code mem- ory. • Section A.3.3: Working with limited CPU time describes considerations when using RapiTime or RapiTask on targets with limited available CPU time. • Section A.3.4: Working with limited data collection bandwidth describes con- siderations when using RapiTime or RapiTask on targets with limited available bandwidth for data collection.
A.3.1 Working with limited data memory If you are using an in-memory trace, sufficient data memory must be available to store the trace. The amount of memory needed depends on how much code you are analyzing (the size of the analysis scope) and the instrumentation applied to your code.
If you do not have enough data memory available to store a trace, you can do
the following:
• Reduce the size of your analysis scope and/or the depth of instrumentation –
To learn how to do so, see Section 9.2 in the RapiTime User Guide. This will
reduce the number of instrumentation points executed during the test so less
data memory is required.
• Generate timing data incrementally by instrumenting parts of the software at
once, rather than the entire application, and merging results into a final report
later. See Section 9.10 in the RapiTime User Guide to learn how to do this.
• Use an IO trace or address trace to collect data rather than an in-memory trace
(if supported by the target platform). These data collection mechanisms does
not require data memory to be available. For more information on RapiTime
and RapiTask data collection strategies, see RapiTime and RapiTask.
• Use an in-memory trace of a fixed size which is periodically dumped to an IO
port, allowing a smaller buffer to be used. It will be necessary to consider the
execution time overheads of dumping the trace, and how frequently the trace
needs to be dumped, to understand the impact of this approach.
RVS Integration Guide vWF20190404 63 Working with limited resources: RapiTime and Appendix RapiTask
A.3.2 Working with limited code memory Each instrumentation point added by RapiTime or RapiTask incurs a code memory overhead. If the amount of code memory available is insufficient, you can do the following:
• Reduce the level of instrumentation. If it is acceptable to the specific situation,
selecting a lower level of instrumentation will reduce the number of instrumen-
tation points generated.
• Generate timing data incrementally by instrumenting parts of the software at
once, rather than the entire application, and merging results into a final report
later. See Section 9.10 in the RapiTime User Guide to learn how to do this.
• Call, rather than in-line, instrumentation points. Normally it is recommended
that instrumentation points are inlined functions or macros, as this helps to
maximize performance. However, if the number of machine instructions in the
instrumentation point is larger than the number of instructions to call a function,
the amount of code memory required can be reduced by calling the function
instead.
• Optimize the instrumentation point functions to minimize the number of ma-
chine instructions they use. Depending on the system, it may be possible to
reduce the size of the code required for instrumentation points by making use
of inline assembly code.
• Use an IO trace or an address trace if supported by the target platform, see
RapiTime and RapiTask. This means that instrumentation points can normally
be implemented using a small number of instructions (possibly one), to write
a constant value to a known address/IO port.
A.3.3 Working with limited CPU time If the application is time-constrained (for example, if it must complete within one frame of a partitioned RTOS, or if it must respond before a watchdog times out) the additional execution time introduced by instrumentation may cause timing prob- lems. If timing problems are encountered, the following actions can be taken:
• Reduce the level of instrumentation. If it is acceptable to the specific situation,
selecting a lower level of instrumentation will reduce the number of instrumen-
tation points generated, and therefore reduce the number of times the instru-
mentation point function must be executed.
• Generate timing data incrementally by instrumenting parts of the software at
once, rather than the entire application, and merging results into a final report
later. See Section 9.10 in the RapiTime User Guide to learn how to do this.
• Avoid instrumenting commonly-called functions. This avoids the problem
where a single function is called many times (and consequently the execution
time of a test case includes many instances of this function’s instrumentation).
• Ensure instrumentation points are in-lined rather than called.
64 RVS Integration Guide vWF20190404 Working with limited resources: RapiTime and Appendix RapiTask
• Optimize the instrumentation point functions to minimize the number of ma-
chine instructions they use. Depending on the system, it may be possible to
reduce the size of the code required for instrumentation points by making use
of inline assembly code.
• Use an IO trace or an address trace if supported by the target platform, see
RapiTime and RapiTask. This means that instrumentation points are normally
implemented using a small number of instructions (possibly one), to write a
constant value to a known address/IO port.
A.3.4 Working with limited data collection bandwidth An important part of RapiTime or RapiTask's integration with a target is the col- lection of data from the target to the host. There are a number of circumstances where the bandwidth of the connection between the host and the target can have an impact on the data collection process:
• The IO trace uses a port with a limited number of pins. In some cases, the
number of IO pins that can to be used for tracing purposes are limited. In this
situation, you can use the IdPack feature to reduce the number of bits needed
for instrumentation, see Section .
• The IO trace uses a slow port. If the IO trace is connected to a port that is
running much slower than the processor, it is possible that several instrumen-
tation points close to each other may cause problems. In this case, it may
be necessary to remove some of the instrumentation to increase the time be-
tween the execution of consecutive instrumentation points.
• The communications channel used to download blocks of data is slow. In this
situation, it may be possible to compress the blocks of data on target before
transmitting them back to the host. RVS uses a proprietary data compression
algorithm (which generates .rpz files). If you require a target-specific library
to carry out this compression, please contact support@rapitasystems.com.
Reducing the number of bits required for instrumentation
Sometimes, target hardware has a limited number of output pins that can be used
for tracing purposes. To ensure that the instrumentation can be reported via these
pins, there are three approaches that can be taken. In order of increasing com-
plexity, these are:
• Reducing the instrumentation identifier space via the --nbits option for the
instrumenter.
• Automatically reallocating the instrumentation identifier space with IdPack
rewriting or remapping.
• Manually reallocating the instrumentation identifier space with IdPack config-
uration.
The following sections describe these approaches.
RVS Integration Guide vWF20190404 65 Working with limited resources: RapiTime and Appendix RapiTask
Reducing instrumentation identifier space with --nbits
When code is instrumented, the RVS instrumentation tools must allocate an iden-
tifier to each inserted instrumentation point. The policy used for the allocation of
ipoint IDs depends on whether the instrumentation requires that ipoint IDs are
unique across the entire system, or whether they can be reused across different
functions. The use of unique ipoint IDs is specified with the -u option to the in-
strumenter.
In general, the use of a coverage map requires unique ipoint IDs, whereas with
trace data the execution of specific functions can be inferred from the ordering of
ipoints within the trace. Table A.1 shows the ipoint allocation policy where unique
ipoints are required, and Table A.2 shows the policy for non-unique ipoints.
Table A.1 Ipoint allocation (unique ipoints specified)
Value Purpose
0 Unused
1-9 Reserved for special purposes in manual instrumentation.
n
10 to 2 -1 Master ipoints. Unique IDs allocated to all instrumentation points.
Table A.2 Ipoint allocation (non-unique ipoints)
Value Purpose
0 Unused
1-9 Reserved for special purposes in manual instrumentation.
10 to X Non-master ipoints. Allocated to instrumentation points within
functions and re-used between different functions (starting at 10
and working upwards to X).
n
Y to 2 -1 Master ipoints. Unique IDs allocated to function entry and exit
n
points (starting at 2 -1 and working downwards to Y).
Where non-unique ipoint IDs are used, the value of X (as shown in Table A.2) is
the number of ipoints required to instrument the most complex function. Where
the instrumentation policy for the entire application is FUNCTIONS, X will be 10
(i.e. there are no non-master ipoints). The value of Y depends on the number of
function entries and exits. In order for the instrumentation to succeed, the range
of master ipoints and the range of non-master ipoints must not overlap, i.e. the
value of X must be less than the value of Y.
The upper limit on the value of ipoint IDs can be set by the --nbits option,
passed to the instrumenter (cins, cppins or adains). The value of the --nbits
option should be set to the number of output pins available on the target. Providing
the ipoint ranges do not overlap, the instrumentation will be successful. Should an
overlap occur, RVS will return an error message. The default value of the --nbits
option is 16.
66 RVS Integration Guide vWF20190404 Working with limited resources: RapiTime and Appendix RapiTask
Automatic ipoint reallocation with IdPack
RVS provides the IdPack feature to reduce the number of IDs required for a specific
application. It does this by removing the distinction between master ipoints and
non-master ipoints.
There are two stages to automatically reallocate ipoint IDs with IdPack:
1. Allocate unique ipoint identifiers to the application, using the -u and
--nbits options during instrumentation (Example A.6).
2. Reallocate the identifiers, either by rewriting the instrumented source code
(Example A.7), or by means of a mapping file (Example A.8).
Example A.6: Allocating unique ipoint IDs for IdPack
cins --exf build.exf -c rvs_instr.h -d build -u --nbits 31 -l
files.txt
After the instrumenter has generated unique ipoint identifiers, these are reallocated
into the reduced identifier space by xstutils. There are two methods for reallocating
identifiers:
• Rewriting. The parameters of the ipoint calls in the instrumented source code
are rewritten into the IdPacked range of values. This approach is recommend-
ed, as it results in fewer files being recompiled when changes occur.
• Remapping. The reallocation of instrumentation identifiers is done in a sepa-
rate file, which must be included by all instrumented source files.
In both cases, the number of output pins (i.e. the number of bits available) is
passed to xstutils via the --idpack-nbits option. By default, IdPack observes
the reserved range of identifiers (0 to 9). This can be overridden to add additional
values to the range of permitted identifiers using the --idpack-start option.
To create the .rvd using the rewriting approach, a list of instrumented files needs
to be created which is then passed to xstutils using to the --ipoint-rewrite
option (Example A.7).
Example A.7: Rewriting ipoint IDs with IdPack
xstutils -r my_root *.xsc -o my_root.rvd --ipoint-rewrite
instr_files.txt --idpack-nbits 7
Using the remapping approach, the rvs_ipoint.h header file needs to include
a remap file, which is produced by xstutils using the command shown in Exam-
ple A.8
Example A.8: Generating an ipoint remapping file with IdPack
xstutils -r my_root *.xsc -o my_root.rvd --ipoint-remap remap.h --
idpack-nbits 7
RVS Integration Guide vWF20190404 67 Working with limited resources: RapiTime and Appendix RapiTask
Where ipoint IDs are modified by either rewriting or remapping, the instrumented
source code must be compiled after the xstutils command has been executed.
Using IdPack on multiple roots
When it is necessary to analyze multiple root functions but also use IdPack func-
tionality, all the required root functions must be specified on the initial run of xs-
tutils to avoid recompilation. This is because the mapping between the original
ipoint IDs and the IdPacked ones is only valid for the specified root functions; all
ipoints that cannot be reached by the root functions are removed. Thus, if it is later
necessary to analyze a new root function (not originally specified on the xstutils
command line), a new IdPack remapping must be generated using xstutils and
the instrumented code then recompiled.
When xstutils is executed with the IdPack options and with more than one -r
option it:
1. Generates an IdPack mapping suitable for all root functions.
2. Generates one .rvd file per root. The names of the rvd files follow the
format<output_name>.<root_name>.rvd.
Note
Since there are several .rvd files, one for each root, processing of the
trace data file must either be done:
• By running timeparser with the trace data file on each individual.rvd.
• By first splitting the trace data file into a number of files (using traceuti-
ls) and then processing each (spawned) trace data file with the relevant
.rvd file using timeparser.
Advanced IdPack usage
Sometimes the number of bits available to write ipoint IDs is not sufficient to in-
strument the entire source code. In these cases, use the --idpack-cfg option
to xstutils, which inserts calls to a tailored ipoint routine depending on the number
of bits required to output the ipoint ID. The ipoint routine can be tailored to output
ipoint IDs to a fast or slow output port, or to initiate multiple writes to allow larger
ipoint IDs to be built up from a sequence of smaller values.
For example, assume that you plan to record the trace data using an output port
and that you need 1000 different ipoint IDs to instrument the source code, but only
7 bits are available on the output port. The way to record 1000 different values
from a 7-bit output port is to do multiple writes to the output port.
To do this, you should define two ipoint routines: a short type (RVS_I_Short) for
values 1 to 127 (which can be coded in 7 bits), and a long type (RVS_I_Long) for
values 128 - 1000. Whenever it is executed, RVS_I_Short results in one write
of 3 bits (for example RVS_I_Short(4) = write 0x4). And when RVS_I_Long
68 RVS Integration Guide vWF20190404 Working with limited resources: RapiTime and Appendix RapiTask
is executed it results in two writes: a zero followed by a 3-bit value(for example
RVS_I_Long(9) = write 0x0 then 0x2). With the correct configuration to xstutils,
the source code is instrumented using RVS_I_Short as often as possible to
keep the number of multiple writes low.
The --idpack-cfg option allows you to control the IdPack feature via an IdPack
configuration file, which instructs xstutils to produce several types of ipoint and to
use them in a priority ordering (i.e. try to use the short ones most often).
In the IdPack configuration file, you specify groups of ipoints, and you associate
with each group a range of permissible ipoint IDs together with a name which is
appended to the ipoint routine in the source code (to distinguish this group from
the others).
The IdPack configuration file is a text file that must comply with the following gram-
mar:
FILE: UNCHANGED? GROUP+
UNCHANGED: '[' 'unchanged' ']' RANGEID NAME?
GROUP: '[' 'group' ID ']' RANGEID NAME? UNIQIDS?
RANGEID: 'range' '=' RANGEDEF
NAME: 'name' '=' STRING
UNIQIDS: 'uniq_ids' '=' BOOL
BOOL: 'TRUE'
| 'FALSE'
STRING: '"' [a-zA-Z_]+ '"'
ID: [a-zA-Z_][a-zA-Z_0-9]*
RANGEDEF: SET
| RANGE
| '(' RANGEDEF ')'
| RANGEDEF '-' RANGEDEF
| RANGEDEF '+' RANGEDEF
SET: '{' NUM {',' NUM}* '}'
RANGE: '[' NUM '..' NUM ']'
NUM: DIGIT DIGIT*
DIGIT: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
where:
• Each non-terminal symbol appears in upper case. For example, FILE and SET
are both non-terminals. Repetitive non-terminal symbols are enclosed in brace
brackets {}.
• Each terminal symbol is enclosed between single quotes. For example, '+'
represents the character literal +.
• * matches the preceding element zero or more times. + matches the preced-
ing element one or more times. ? matches the preceding element zero or one
time.
• Character classes are enclosed between square brackets []. For example, [a-
z] specifies a range which matches any lower-case character from 'a' to 'z'.
The grammar permits an optional group of ipoints to be specified as unchanged,
indicating that xstutils will not remap any ipoint IDs in the specified range. Typically,
this is needed when particular ipoints are used to instrument interrupts or the OS.
RVS Integration Guide vWF20190404 69 Working with limited resources: RapiTime and Appendix RapiTask
Warning
Unchanged ipoints must be placed manually in the source code before
cins runs.
xstutils uses the order that the (other) groups appear in the IdPack configuration
file as the priority it should employ when searching for a remapped ipoint ID. For
example, if it cannot find a suitable remapped ipoint ID from the range specified
by the first group then it continues onto the second group, and so on.
The grammar also permits a group of ipoints to have unique remapped IDs (indi-
cated by uniq_ids = TRUE), which is needed for black-boxed functions and
master ipoints of root functions. At least one group must be selected for unique
IDs (it is possible to select several groups). As the number of unique IDs required
is usually low, the group selected for unique IDs is usually the most expensive one.
Note that the ipoint IDs of all groups should be disjointed. If an ID is present in
multiple groups, a warning will be issued and the ID will be assigned to the first
group in the file in which it appears.
Example use of --idpack-cfg option
Assume that you have the following requirements on remapped ipoint IDs:
• Ipoint IDs between 500 and 510, except 505 and 506, are reserved for instru-
mentation of interrupts and the OS. This is the first group of ipoint IDs.
• Availability of a 3-bit output port to which ipoint IDs are written. Therefore, val-
ues in the range 1 to 7 can be written in a single write (0 is a reserved ipoint
ID and cannot be used) and should be used as often as possible. This is the
second group of ipoint IDs.
• When ipoint IDs from the second group are not sufficient for the remapping,
two writes can be used (a 0 followed by a value from 1 to 7), allowing values
between 8 and 14. This is the third group of ipoint IDs.
• When ipoints IDs from any other group are not sufficient for the remapping,
use values between 1 and 511, except for those used by the other groups.
This requires 5 writes (two 0 and then three values from 1 to 7). This is the
fourth group of ipoint IDs.
Also use values from this group whenever a unique ipoint ID is needed (this is
indicated by the line uniq_ids = TRUE).
These requirements are met using the configuration file shown in Example A.9
70 RVS Integration Guide vWF20190404 Working with limited resources: RapiTime and Appendix RapiTask
Example A.9: Example IdPack configuration file
# 1/ Unchanged ipoints
[unchanged]
range = [500..510] - {505, 506}
name = "OS"
# 2/ Short ipoints (One 3-bit write)
[group short]
range = [1..7]
name = "Short"
# 3/ Long ipoints (Two 3-bit writes)
[group long]
range = [8..14]
name="Long"
# 4/ Very_Long ipoints (Five 3-bit writes)
[group very_long]
range = (([1..511] - [1..14]) - [500..510]) + {505, 506}
name="Very_Long"
uniq_ids = TRUE
Note that, during the remapping performed by xstutils, the ipoint routine in the
source code is appended with the name specified by the group. For example,
if the remapped ID of an ipoint is taken from the fourth group, then the ipoint
routine appears as RVS_I_Very_Long in the source code once xstutils has
completed.
The command line for xstutils that uses this configuration file is shown in Exam-
ple A.10.
Example A.10: Using xstutils with an IdPack configuration file
xstutils -r my_root *.xsc -o my_root.rvd--ipoint-rewrite
files_instr3bits.txt --idpack-cfg my_idpack.cfg
Example A.11 shows a source code section to which this remapping has been
applied:
RVS Integration Guide vWF20190404 71 Working with limited resources: RapiTime and Appendix RapiTask
Example A.11: Source file instrumented using --idpack-cfg
...
int
my_fun(unsigned int x)
{RVS_I_Very_Long(511) ;{
int choice, r;
if (x>6) {RVS_I_Long(13) ;{
choice = 6;
}} else {RVS_I_Short(1) ;{
choice = x;
}}
switch (choice) {
case 0 :RVS_I_Short(6) ; r = 5;
case 1 :RVS_I_Short(7) ; r = 6;
case 2 :RVS_I_Long(11) ; r = 7;
case 3 :RVS_I_Long(9) ; r = 15;
case 4 :RVS_I_Short(2) ; r = 16;
case 5 :RVS_I_Short(4) ; r = 17;
case 6 :RVS_I_Short(3) ; r = 50;
break;
default : RVS_I_Short(5) ;}
if (buffer_full ()) {{
/* Manual Ipoint added by user with ID 500 */
RVS_I_OS(500) ;
}}else {RVS_I_Short(7) ;}
{RVS_I_Very_Long(506) ;return r;}
}}
...
In this instrumented source code, all ipoint groups are used. ipoints 511 and 506
are from the 'Very_Long' group because they must be unique (entry/exit of the root
function), which was specified in the configuration file. Ipoints 1 to 7 ('Short') were
not sufficient to instrument the source code, therefore 'Long' ipoints have been
used as well. Finally, ipoint 500 (which was manually added) is allocated to the
'OS' group and its value is left unchanged.
IdPack Caveats
After using the IdPack options, master ipoint IDs will no longer be unique. With
fewer bits, the same ID is typically repeated many times in an .rvd file. This makes
it difficult to manually follow the source code path represented by an execution
trace. However, timeparser is able to easily follow the path represented by the
trace data. In case of a parsing error being detected by timeparser, the error
message displayed identifies ipoints using their IDs (which are not unique) and
their position in the source code (file name and line number, which is unique).
Since the master Ipoints are no longer unique, you can no longer use the
--discover-fptr option with timeparser. Instead, you must provide explic-
it call_to annotations to resolve function pointers. See Section 8.1 in the RVS
Annotations Reference Guide for details on how to use these annotations.
72 RVS Integration Guide vWF20190404 Working with limited resources: RapiTime and Appendix RapiTask
Note
Debugging unresolved function pointer destinations is significantly more
difficult when an integration uses IdPack. It is strongly recommended that
you resolve all function pointer destinations and provide appropriate anno-
tations before enabling IdPack.
The IdPack options ensure that some special ipoints still have a unique ID. These
special ipoints are: the entries and exits of the root function(s) and the ipoints
added by the black_box annotation (see Section 7.2 in the RVS Annotations
Reference Guide). The unique IDs used for these ipoints start at 10 by default (this
can be changed using the --idpack-start option).
RVS Integration Guide vWF20190404 73 This page intentionally left blank