主要内容

Collect Test and Code Profiling Results from Target Using Self-Managed Builds

R2026b

When running xUnit tests with code profiling on a target using self-managed builds, the method for collecting both results depends on the mode you use. This topic describes how to obtain both test results (.pstestr) and code profiling results (.psprof) from a target.

Overview

You can collect both test and code profiling results from the target using one of two modes:

 Monitor ModeManual Conversion Mode
Number of executionsSingle execution produces both test results (.pstestr) and code profiling results (.psprof).Two separate executions required — one for test results, one for code profiling data — each with its own configuration.
Number of configurationsSingle pstest_config.h with PST_MONITOR_MODE_WITH_PROFILING 1.Two separate pstest_config.h files — one for test output, one for profiling data.
Result conversionAutomatic — polyspace-test -monitor retrieves and converts results during execution.Manual — convert test output with polyspace-test -convert and profiling output with polyspace-code-profiler -convert.
Communication requirementRequires a live communication channel (serial port, TCP) between host and target during execution.No live connection required — collect outputs after each execution completes.

If you can stream data from your target through a serial or TCP/IP port, the monitor mode is recommended as it produces both results from a single execution. If your port is not supported for the monitor mode, use the manual conversion mode.

Monitor Mode

In monitor mode, a single execution produces both test results and code profiling results. Configure the test executable with PST_MONITOR_MODE_WITH_PROFILING 1 in your pstest_config.h. This macro enables both monitor-mode test output and managed profiling output through the same communication channel.

For the complete workflow including instrumentation, configuration, build, and run steps, see Monitor Mode.

Manual Conversion Mode

In manual conversion mode, you cannot collect both test results and code profiling data from a single execution. You must perform two separate executions, each with its own configuration, build, and conversion step.

Set Up Separate Configurations

Create two directories, each containing a pstest_config.h with different macros:

Test configuration — create a directory (for example, config_test/) containing a pstest_config.h that enables embedded-mode test output:

#ifndef PSTEST_CONFIG_H
#define PSTEST_CONFIG_H

#define PST_EMBEDDED_MODE 1
#define PST_ENABLE_EXECUTION_TIME 0

extern void pst_write(const char * str, unsigned long len);
#define PST_WRITE(str, len) pst_write(str, len)

#endif

Profiling configuration — create a separate directory (for example, config_prof/) containing a pstest_config.h that enables user-defined profiling data sending:

#ifndef PSTEST_CONFIG_H
#define PSTEST_CONFIG_H

#define PST_ENABLE_EXECUTION_TIME 0
#define PSPROFILE_SENDING_TYPE PSPROFILE_USER_DEFINED

extern int psprofile_send_data(const char *pData, unsigned int numData);
extern int psprofile_send_end(void);

#define PSPROFILE_SENDING_DATA_ASYNC(ptrData, numData) psprofile_send_data(ptrData, numData)
#define PSPROFILE_SENDING_END() psprofile_send_end()

#endif

Each configuration also requires a corresponding source file implementing the declared functions. The test configuration source implements pst_write() to store or transmit test output. The profiling configuration source implements psprofile_send_data() and psprofile_send_end() to store or transmit profiling data.

Set Up Main Functions

Each execution requires its own main() function. The test execution main registers and runs the tests. The profiling execution main additionally calls psprofile_stream() to flush profiling data after the tests complete.

Test Main.  The test main registers the test functions and calls PST_MAIN:

#include <pstunit.h>

int main(int argc, char *argv[]) {
    PST_REGFCN_CALL(register_tests);
    return PST_MAIN(argc, argv);
}

Profiling Main.  The profiling main registers the test functions, calls PST_MAIN, and then calls psprofile_stream() to transmit the profiling data:

#include <pstunit.h>
#include <psprofile.h>

int main(int argc, char *argv[]) {
    PST_REGFCN_CALL(register_tests);
    int result = PST_MAIN(argc, argv);
    psprofile_stream();
    return result;
}

Execution 1: Collect Test Results

Build and run the test executable using the test configuration. Use the -I flag to point to the directory containing the test pstest_config.h:

# Build with test configuration
<COMPILER> -c src.c tests.c config_test.c main_test.c <PSTEST_SOURCE> \
    -I <PSTEST_INCLUDE> -I config_test -D PST_USER_CONFIG

# Link
<COMPILER> -o testrunner_test.elf src.o tests.o config_test.o main_test.o pstest.o

Run the executable on the target and collect the output as an .mrf file. Convert the test results:

polyspace-test -convert -results-dir <RESULTS_DIR> out_test.mrf
This produces a .pstestr file in <RESULTS_DIR>.

For the complete test-only workflow, see Manual Conversion Mode.

Execution 2: Collect Code Profiling Results

Instrument your source code, build, and run using the profiling configuration. Use the -I flag to point to the directory containing the profiling pstest_config.h:

# Instrument and compile with profiling configuration
polyspace-code-profiler -instrument -instrum-dir <INSTRUM_DIR> \
    -limit-instrumentation-to <SRC_DIR> -ignore-file config_prof.c \
    -- <COMPILER> -c src.c tests.c config_prof.c main_prof.c <PSTEST_SOURCE> \
       -I <PSTEST_INCLUDE> -I <PSPROFILE_INCLUDE> -I config_prof -D PST_USER_CONFIG

# Link
<COMPILER> -o testrunner_prof.elf src.o tests.o config_prof.o main_prof.o pstest.o

Run the executable on the target and collect the profiling output as a .bin file. Convert the profiling results:

polyspace-code-profiler -convert -instrum-dir <INSTRUM_DIR> -results-dir <RESULTS_DIR> out_prof.bin
This produces a .psprof file in <RESULTS_DIR>.

For the complete profiling-only workflow, see Manual Conversion Mode.

See Also

|

Topics