Hauptinhalt

Create Library for Code Profiling Using Self-Managed Builds

R2026b

You can perform C/C++ code profiling in Polyspace® Test™ using a self-managed approach, which allows you to use any toolchain already configured for your builds. To facilitate the self-managed builds, Polyspace Test provides precompiled code profiling libraries for certain compilers. If the precompiled libraries are not compatible with your compiler, you can create the libraries from sources included with your installation. This topic shows how to create the code profiling libraries from scratch.

Usage of Code Profiling Library

In a typical code profiling workflow, you instrument your sources using the polyspace-code-profiler -instrument command. Next, you link the instrumented sources with a precompiled library containing definition of the macros used during code instrumentation. This process creates a final executable that enables code profiling.

For example, you can perform these steps using a GCC compiler as follows:

polyspace-code-profiler -instrument -instrum-dir instrums  -- gcc -c src.c
gcc src.o <PSTEST_LIB>
Here, <PSTEST_LIB> is the version of the library precompiled for use with GCC.

In the next sections, you will see how to create this library for your own compiler in cases where the precompiled library is not compatible.

Create Code Profiling Library for Profiling on Host

To create a code profiling library for profiling on host, you need the following files and folders:

  • Test source file <polyspaceroot>\polyspace\pstest\pstunit\src\pstest.c. In the examples below, this file is referred to as <PSTEST_SOURCE>.

    Here, <polyspaceroot> is the Polyspace installation folder, for example, C:\Program Files\Polyspace\R2026b.

  • Profiling include folder <polyspaceroot>\polyspace\psprofile\include. In the examples below, this file is referred to as <PSPROFILE_INCLUDE>.

  • A configuration header file pstest_test_config.h. You can adapt the example configuration file in the folder <polyspaceroot>\polyspace\examples\doc_pstest\profiling_configs\host.

    In the examples below, the folder containing this header is referred to as <PSTEST_CONFIG_INCLUDE>. For more information on the macros used in the configuration file, see Configuration Macros for Code Profiling.

To create the library, compile the required files in a single compilation command. To make sure that the configuration file is used, define the macro PST_USER_CONFIG during compilation. For example, if you are using the GCC compiler, compile the sources and includes as follows:

gcc -c <PSTEST_SOURCE> -I <PSPROFILE_INCLUDE> -I <PSTEST_CONFIG_INCLUDE> -D PST_USER_CONFIG -o psTestLib

You can then use the library at link time just as you would use the precompiled libraries provided with Polyspace Test. For example, with the GCC compiler, your source code instrumentation and linking steps might look like this:

polyspace-code-profiler -instrument -instrum-dir instrums  -- gcc -c src.c
gcc src.o pstestLib.o
This step creates an executable that you can use with polyspace-code-profiler -run to collect coverage data. For a complete example of the workflow, see Calculate C/C++ Code Coverage Using Self-Managed Builds.

Create Code Profiling Library for Profiling on Target

To create a code profiling library for profiling on a target, you need the same files and folders as for profiling on host. However, your configuration file is different from before. In addition, for targets without a file system, you must define functions to initialize the target and stream data from the target back to the host.

To create a code profiling library for profiling on target, you need the following files and folders:

  • Test source file <polyspaceroot>\polyspace\pstest\pstunit\src\pstest.c. In the examples below, this file is referred to as <PSTEST_SOURCE>.

    Here, <polyspaceroot> is the Polyspace installation folder, for example, C:\Program Files\Polyspace\R2026b.

  • Profiling include folder <polyspaceroot>\polyspace\psprofile\include. In the examples below, this file is referred to as <PSPROFILE_INCLUDE>.

  • A configuration file pstest_config.h.

    • For targets with a file system, you can adapt the example configuration file in the folder <polyspaceroot>\polyspace\examples\doc_pstest\profiling_configs\host.

    • For targets without a file system, you can adapt the example configuration file in the folder <polyspaceroot>\polyspace\examples\doc_pstest\profiling_configs\targets_no_filesystem.

    In the examples below, the folder containing this header is referred to as <PSTEST_CONFIG_INCLUDE>. For more information on the macros used in the configuration file, see Configuration Macros for Code Profiling.

  • A file pstest_config.c that defines the implementation of the target initialization and data sending functions declared in pstest_config.h (required only for targets without a file system).

    For instance, if you define macros PSPROFILE_SENDING_INIT() and PSPROFILE_SENDING_DATA_ASYNC() as shown above, your file pstest_config.c can contain the definitions of the functions mapped to these macros:

    int psprofile_sending_init(void) {
       // Function body
    }
    
    int psprofile_sending_data_async(const char* ptrData, uint32_T numData) {
    ...// Function body
    }
    In the examples below, this file is referred to as <PSTEST_CONFIG_SOURCE>.

To create the libraries, compile the profiling source file and the profiling configuration source file in separate compilation commands. To make sure that the configuration file is used, define the macro PST_USER_CONFIG during compilation of the profiling source file. For example, if you are using the GCC compiler, compile the sources and includes as follows:

gcc -c <PSTEST_SOURCE> -I <PSPROFILE_INCLUDE> -I <PSTEST_CONFIG_INCLUDE> -D PST_USER_CONFIG -o psTestLib
gcc -c <PSTEST_CONFIG_SOURCE> -I <PSTEST_CONFIG_INCLUDE> -o psProfileConfigsLib

You can then use the library at link time just as you would use the precompiled libraries provided with Polyspace Test. For example, with the GCC compiler, your source code instrumentation and linking steps might look like this:

polyspace-code-profiler -instrument -instrum-dir instrums  -- gcc -c src.c
gcc src.o psTestLib.o psProfileConfigsLib.o
This step creates an executable that you can use with polyspace-code-profiler -run to collect coverage data. For a complete example of the workflow, see Manual Conversion Mode for Code Profiling on Targets.

Configuration Macros for Code Profiling

This table provides a list of configuration macros that you can use to adapt code profiling for specific targets.

MacroDescriptionExample
PSPROFILE_HOST_EXECUTIONSpecifies whether to build for test execution on host or target.

For execution on host, set this macro to 1:

#define PSPROFILE_HOST_EXECUTION 1

For execution on target, set this macro to 0:

#define PSPROFILE_HOST_EXECUTION 0

PSPROFILE_SENDING_TYPESpecifies whether tests will executed on a target with a file system or not.

For execution on host or targets with a file system, set this macro to PSPROFILE_SENDING_FILE:

#define PSPROFILE_SENDING_TYPE PSPROFILE_SENDING_FILE

For targets without a file system, set this macro to PSPROFILE_USER_DEFINED:

#define PSPROFILE_SENDING_TYPE PSPROFILE_USER_DEFINED

PSPROFILE_WORKING_BUFFER_SIZESpecifies the size of the working buffer.

Set a working buffer size of 512 bytes as follows:

#define SPROFILE_WORKING_BUFFER_SIZE 512
The minimum buffer size required is 128 bytes. Set an appropriate buffer size consistent with the memory available on your target.

PSPROFILE_SANITIZERSpecifies whether the build should support code sanitizer profiling.

Enable code sanitizer profiling as follows:

#define PSPROFILE_SANITIZER 1

PSPROFILE_PROFILING_COUNTER_WIDTHSpecifies whether to use a 32-bit or 64-bit counter for code profiling.

Specify a 32-bit counter as follows:

#define PSPROFILE_PROFILING_COUNTER_WIDTH 32

PSPROFILE_EXECPROF_AVAILABLESpecifies whether the build should support code execution profiling.

Enable execution profiling as follows:

#define PSPROFILE_EXECPROF_AVAILABLE 1

PSPROFILE_STACKPROF_AVAILABLESpecifies whether the build should support code memory use profiling.

Enable memory use profiling as follows:

#define PSPROFILE_EXECPROF_AVAILABLE 1

PSPROFILE_SENDING_DATA_ASYNC(Mandatory) Specifies a streaming function to send data from target to host. This is the only macro that is strictly required when PSPROFILE_SENDING_TYPE is set to PSPROFILE_USER_DEFINED.

For instance, you can specify a function send_data():

#define PSPROFILE_SENDING_DATA_ASYNC(ptr, num) send_data(ptr, num)
The function can have the prototype:
int send_data(const char* ptr, unsigned int num);
The first argument points to the data being streamed and the second argument is the number of bytes. The function returns PSPROFILE_SUCCESS on success.

For an example implementation, see Manual Conversion Mode for Code Profiling on Targets.

PSPROFILE_SENDING_INIT(Optional) Specifies an initialization function called before the first write. If not defined, defaults to returning PSPROFILE_SUCCESS.

For instance, you can specify a function init():

#define PSPROFILE_SENDING_INIT() init()
The function can have the prototype:
int init(void);
The function returns PSPROFILE_SUCCESS on successful initialization.

For an example implementation, see Manual Conversion Mode for Code Profiling on Targets.

PSPROFILE_SENDING_END(Optional) Specifies a teardown function called after all profiling data has been written. If not defined, defaults to returning PSPROFILE_SUCCESS.

For instance, you can specify a function stream_end():

#define PSPROFILE_SENDING_END() stream_end()
The function can have the prototype:
int stream_end(void);
Use this macro to transmit a buffer or release hardware resources after all profiling data is flushed.

PSPROFILE_SENDING_FLUSH(Optional) Specifies a flush function called to drain buffered data without closing the stream. If not defined, defaults to returning PSPROFILE_SUCCESS.

For instance, you can specify a function flush():

#define PSPROFILE_SENDING_FLUSH() flush()
The function can have the prototype:
int flush(void);
Use this macro to force buffered data through the transport (for example, drain a UART TX FIFO) without tearing down the channel.

See Also

Topics