universalisos/docs-extracted/src/scov/RVS/doc/Integration_Guide.md
Fábio Coutada ebcfde0f5e feat(docs): extract RVS PDF manuals and regenerate index
- 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
2026-07-06 23:16:33 +01:00

146 KiB
Raw Blame History

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 functions 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