Create Polyspace Test Target Registration Package for TRACE32 Debugging on Physical Hardware
R2026bTRACE32 is a hardware and software toolset from Lauterbach that lets you load programs onto target hardware, run them, and inspect what they are doing. It works through a hardware debug probe that plugs into your target on one end and your computer on the other.
The TRACE32 toolset supports various ways of communicating with the target hardware. One of the supported ways is the Fast Data Exchange or FDX protocol. In this protocol, the test code reads and writes designated memory locations on the target, and the debug probe continuously moves that data between the target and your computer. No extra software licenses are needed beyond TRACE32 itself.
This topic shows how to create a Polyspace® Test™ target registration package for FDX communication with a physical target through the TRACE32 debug probe. The example uses a NXP S32K344 board (Cortex-M7) with a Lauterbach CombiProbe connected via USB.
Prerequisites
Before you begin, you need:
TRACE32 PowerView installed on your machine. Download from the Lauterbach Portal. This example uses
<T32Install>as the TRACE32 software installation folder. For instance:FDX source files from your TRACE32 installation,
t32fdx.candt32fdx.h, are located under<T32Install>\demo\arm\fdx\.To open the PowerView software, you can double-click the appropriate executable in
<T32Install>\bin.
NXP S32 Design Studio installed on your machine. It provides both the cross-compiler (GCC for ARM) and the SDK files (Real-Time Drivers, startup code, and peripheral headers) used in this example.
A Lauterbach debug probe (such as CombiProbe or PowerDebug) connected to your target board via USB.
Package Overview
Your target registration package for FDX communication contains the following files:
NXP_S32K3X4EVB_Q257_Package/ ├── pstestPreferences.json ├── NXP_S32K3X4EVB_Q257_Preferences.m ├── NXP_S32K3X4EVB_Q257_PackageRegister.m ├── NXP_S32K3X4EVB_Q257_PackageUnregister.m ├── NXP_S32K3X4EVB_Q257_DebugIOTool.m ├── NXP_S32K3X4EVB_Q257_BoardDefinition.m ├── NXP_S32K3X4EVB_Q257_ToolchainDefinition.m ├── S32K344_Trace32_config.t32 ├── s32k344evb-q257.cmm ├── src/ │ ├── rtiostream_fdx.c │ ├── rtiostream_fdx.h │ ├── NXP_S32K3X4EVB_Q257_board.c │ ├── NXP_S32K3X4EVB_Q257_board.h │ └── ... (SDK/driver files for your board)
.t32 file and the .cmm file control how TRACE32 connects to the target and sets up FDX communication. Sample versions of these files are provided with a TRACE32 installation but the key parts of the files are highlighted below. This example also walks through authoring the remainder of the files.Create TRACE32 Files
The .t32 file and the .cmm files control how TRACE32 connects to the specific hardware board. The key parts of the files are outlined below. For more information on the syntaxes, see TRACE32 documentation.
Create TRACE32 Config File
Create a .t32 configuration file for your debug probe. The key settings for physical hardware with FDX are:
; USB debugger with auto-reconnect PBI=USB CONNECTIONMODE=AUTOCONNECT ; System paths OS= ID=TRACE32 ; Remote API (used internally by the framework) IC=NETASSIST PORT=20000 PACKLEN=1024
The file has three sections:
Probe connection — The
PBI=block specifies how TRACE32 connects to the debug hardware.USBselects a USB-attached probe.CONNECTIONMODE=AUTOCONNECTforces the connection even if a previous session did not release the probe cleanly — without it, subsequent runs fail with "TRACE32 device already used by other GUI."System paths —
OS=andID=TRACE32identify the TRACE32 instance. SetSYS=to your TRACE32 installation directory if it is not in the default location.Remote API — The
IC=NETASSISTblock opens a UDP port (here20000) that the framework uses to send control commands to TRACE32.
Create Startup Script
Create a PRACTICE script (.cmm) that configures the CPU, programs the flash, sets up FDX channels, and starts execution. The script receives four arguments from the framework: the ELF file path, pipe names for input and output, and a debug flag.
ENTRY &ELF_FILE &pipeIn &pipeOut &isDebug
IF (!OS.FILE(&ELF_FILE))
(
PRINT %ERROR "The target binary location must be passed to the script."
ENDDO
)
; CPU and debug port configuration (adapt to your target)
SYStem.CPU S32K344-M7
SYStem.CONFIG.DEBUGPORTTYPE SWD
IF COMBIPROBE()||UTRACE()
(
SYStem.CONFIG.CONNECTOR MIPI20T
)
SYStem.Option DUALPORT ON
SYStem.MemAccess DAP
SYStem.JtagClock 10MHz
Trace.DISable
SYStem.Up
; Flash programming (adapt to your target)
DO ~~/demo/arm/flash/s32k3.cmm PREPAREONLY
FLASH.ReProgram ALL
Data.LOAD.Elf "&ELF_FILE"
FLASH.ReProgram OFF
; FDX configuration
FDX.RESet
SYStem.MemAccess DAP
FDX.METHOD BUFFERE
FDX.OutChannel FdxSendBuffer
FDX.InChannel FdxReceiveBuffer
FDX.PipeWRITE FdxSendBuffer "&pipeOut"
FDX.PipeREAD FdxReceiveBuffer "&pipeIn"
FDX.ENableChannel
; Optional: breakpoint for debug mode
if "&isDebug"=="1"
(
Break.Set pst_run_test_case_function
)
Break.Set rtIOStreamClose /OnChip
Go
ENDDOThe script proceeds in four phases:
CPU and debug port setup — Selects the CPU type, configures the debug interface (SWD, JTAG clock speed), and brings the debug session up with
SYStem.Up.Flash programming — Erases and programs the target flash with the compiled test binary. The
FLASH.ReProgramcommands handle sector-level erase-before-write automatically.FDX channel configuration —
FDX.METHOD BUFFEREselects the ring buffer transfer method.FDX.OutChannelandFDX.InChannelbind FDX channels to symbols in target memory (FdxSendBufferandFdxReceiveBuffer, defined inrtiostream_fdx.c).FDX.PipeWRITEandFDX.PipeREADexpose those channels as Windows named pipes whose names are provided by the framework.Execution —
Break.Set rtIOStreamClose /OnChipplaces a hardware breakpoint that halts the CPU when the test completes.Gostarts execution and the script exits withENDDO. From this point, the framework exchanges test data through the named pipes while the target runs.
Create Preferences Files
You can abstract away details specific to your target board and TRACE32 installation in a JSON file.
Create Preferences JSON
Create a pstestPreferences.json file with paths to your cross-compiler, TRACE32 files, and FDX source files:
{
"GnuARMPath": "C:/path/to/your/gcc-arm-compiler",
"SDK_Base_Path": "C:/path/to/your/sdk/base",
"SDK_Platform_Path": "C:/path/to/your/sdk/platform",
"T32Config": "C:/path/to/your/S32K344_Trace32_config.t32",
"T32StartupScript": "C:/path/to/your/s32k344evb-q257.cmm",
"T32Executable": "C:/T32/bin/windows64/t32marm.exe",
"T32FdxFiles" : ["C:/T32/demo/arm/fdx/t32fdx.c",
"C:/T32/demo/arm/fdx/t32fdx.h"]
}The JSON contains two groups of settings:
TRACE32 and FDX (required for all FDX setups) —
T32ConfigandT32StartupScriptpoint to the.t32and.cmmfiles described in the previous sections.T32Executableis the path to the TRACE32 PowerView executable for your target architecture (for example,t32marm.exefor ARM).T32FdxFileslists thet32fdx.candt32fdx.hfiles from the TRACE32 installation. The framework compiles these into the target binary alongside yourrtiostream_fdx.c.Board-specific paths (vary by target) —
GnuARMPathpoints to the cross-compiler.SDK_Base_PathandSDK_Platform_Pathare specific to the NXP S32K3 RTD package and provide the headers and drivers for this board. Other boards would have different keys here depending on their SDK structure.For instance, the following are example paths from an NXP Design Studio installation:
"GnuARMPath": "C:/NXP/S32DS.3.6.8/S32DS/build_tools/gcc_v11.4/gcc-11.4-arm32-eabi", "SDK_Base_Path": "C:/NXP/SW32K3_RTD_4.4_R21-11_3.0.0/eclipse/plugins/BaseNXP_TS_T40D34M30I0R0", "SDK_Platform_Path": "C:/NXP/SW32K3_RTD_4.4_R21-11_3.0.0/eclipse/plugins/Platform_TS_T40D34M30I0R0"
Create Preferences Class to Read JSON
Create a preferences class NXP_S32K3X4EVB_Q257_Preferences that inherits from pstest.target.Trace32.TargetPreferences:
classdef NXP_S32K3X4EVB_Q257_Preferences < pstest.target.Trace32.TargetPreferences properties(Constant) ToolChainName = "GCC ARM Cortex M | NXP_S32K3X4EVB-Q257" BoardName = "NXP_S32K3X4EVB_Q257 TRACE32" end methods(Access=public) function this = NXP_S32K3X4EVB_Q257_Preferences(jsonName) arguments jsonName (1,1) string = "pstestPreferences.json" end jsonFullPath = fullfile(fileparts(which(mfilename)), jsonName); this@pstest.target.Trace32.TargetPreferences(jsonFullPath); end end end
ToolchainName and BoardName), and implicitly adds some properties to enable a gateway for communication between Polyspace
Test and the target hardware.Instantiate Preferences Class From Package Registration File
In your packageRegister.m, instantiate the NXP_S32K3X4EVB_Q257_Preferences class you just created.
addpath(fileparts(mfilename('fullpath'))); prefs = NXP_S32K3X4EVB_Q257_Preferences(); if savepath warning('Error while saving path!'); end rehash toolboxcache;
prefs as a MATLAB® structure whose fields are the properties in the JSON file.Implement Target-Side Data Transfer
Create a file rtiostream_fdx.c that implements the rtIOStream API using FDX. This file runs on the target and is responsible for exchanging data with the host through memory locations that the debug probe monitors.
The FDX API is provided by t32fdx.c and t32fdx.h
from your TRACE32 installation (listed in T32FdxFiles in the JSON
preferences).
#include <stddef.h>
#include "t32fdx.h"
#include "rtiostream_fdx.h"
#define RTIOSTREAM_NO_ERROR (0)
#define RTIOSTREAM_ERROR (-1)
/* FDX channel buffers (4096 bytes each) */
T32_Fdx_DefineChannel(FdxSendBuffer, 4096); /* target -> host */
T32_Fdx_DefineChannel(FdxReceiveBuffer, 4096); /* host -> target */
void initFDX(void) {
T32_Fdx_InitChannel(FdxSendBuffer);
T32_Fdx_InitChannel(FdxReceiveBuffer);
T32_Fdx_EnableChannel(FdxSendBuffer);
T32_Fdx_EnableChannel(FdxReceiveBuffer);
}
int rtIOStreamOpen(int argc, void *argv[])
{
(void)argc;
(void)argv;
initFDX();
return RTIOSTREAM_NO_ERROR;
}
int rtIOStreamClose(int streamID)
{
(void)streamID;
T32_Fdx_DisableChannel(FdxSendBuffer);
T32_Fdx_DisableChannel(FdxReceiveBuffer);
return RTIOSTREAM_NO_ERROR;
}
int rtIOStreamSend(int streamID, const void *src, size_t size, size_t *sizeSent)
{
(void)streamID;
int sent = T32_Fdx_Send(&FdxSendBuffer, (void *)src, (int)size);
if (sent > 0) {
*sizeSent = (size_t)sent;
return RTIOSTREAM_NO_ERROR;
}
*sizeSent = 0;
return RTIOSTREAM_ERROR;
}
int rtIOStreamRecv(int streamID, void *dst, size_t size, size_t *sizeRecvd)
{
(void)streamID;
int recvd = T32_Fdx_Receive(&FdxReceiveBuffer, dst, (int)size);
*sizeRecvd = (size_t)(recvd > 0 ? recvd : 0);
return RTIOSTREAM_NO_ERROR;
}The implementation has three layers:
Channel declaration —
T32_Fdx_DefineChannelreserves a block of target memory (here 4096 bytes) as a data buffer. The symbol names (FdxSendBuffer,FdxReceiveBuffer) must match the names used in the.cmmscript so TRACE32 knows where to read and write.Initialization —
rtIOStreamOpencallsinitFDX(), which initializes and enables both channels. This runs once at the start of the test.Data transfer —
rtIOStreamSendwrites test data into the send buffer;rtIOStreamRecvreads incoming data from the receive buffer. The debug probe continuously moves data between these memory regions and the host.rtIOStreamClosedisables both channels when the test finishes.
Create Execution Tool
Create a class NXP_S32K3X4EVB_Q257_DebugIOTool that inherits from pstest.target.Trace32.DebugIOTool:
classdef NXP_S32K3X4EVB_Q257_DebugIOTool < pstest.target.Trace32.DebugIOTool methods function this = NXP_S32K3X4EVB_Q257_DebugIOTool this@pstest.target.Trace32.DebugIOTool(NXP_S32K3X4EVB_Q257_Preferences()); end end end
This class is a thin wrapper. The parent class pstest.target.Trace32.DebugIOTool handles the full lifecycle: launching TRACE32, running the startup script, managing the gateway process, and shutting everything down after the test. All it needs from you is the preferences object so it knows which executable, config file, and script to use.
Register Board and Communication
Create a board definition file NXP_S32K3X4EVB_Q257_BoardDefinition.m that registers the board, its processor, source files, execution service, and communication settings. The file has five sections:
Board and processor — Creates the board and processor objects with the appropriate language implementation:
prefs = NXP_S32K3X4EVB_Q257_Preferences(); board = target.create("Board", "Name", prefs.BoardName); processor = target.create("Processor", "Name", "NXP_S32K3X4EVB_Q257", ... "Manufacturer", "NXP"); langImpl = target.create("LanguageImplementation", ... "Name", "ARM Cortex-M Compatible", "Copy", "GNU GCC ARM 32-bit"); processor.LanguageImplementations = langImpl; board.Processors = processor;
Source files and includes — Lists the board support files (startup code, drivers, SDK files) and the
rtiostream_fdx.cimplementation. The FDX files from the JSON preferences are also added here:baseSoftDir = [strrep(fileparts(mfilename('fullpath')), '\','/') '/src']; mainFunction = target.create("MainFunction", "Name", prefs.BoardName + " - Test Main"); mainFunction.IncludeFiles = {'NXP_S32K3X4EVB_Q257_board.h'}; mainFunction.InitializationCode = sprintf('init_NXP_S32K3X4EVB_Q257();\n'); board.MainFunctions = mainFunction; mainFunction.BuildDependencies.SourceFiles = { ... [baseSoftDir, '/NXP_S32K3X4EVB_Q257_board.c'] ... [baseSoftDir, '/rtiostream_fdx.c'] ... ... % NXP SDK driver files (Clock_Ip, startup, nvic, etc.) }; mainFunction.BuildDependencies.IncludePaths = { ... baseSoftDir, ... [baseSoftDir, '/NXP'], ... [prefs.SDK_Base_Path, '/include'], ... [prefs.SDK_Base_Path, '/header'], ... [prefs.SDK_Platform_Path, '/startup/include'] ... }; % Add FDX files from TRACE32 installation for ii = 1:numel(prefs.T32FdxFiles) [folder, ~, ext] = fileparts(prefs.T32FdxFiles{ii}); if strcmp(ext, '.h') mainFunction.BuildDependencies.IncludePaths{end+1} = folder; else mainFunction.BuildDependencies.SourceFiles{end+1} = prefs.T32FdxFiles{ii}; end end
Execution service — Registers the
DebugIOToolclass as the execution tool for this board:className = 'NXP_S32K3X4EVB_Q257_DebugIOTool'; customExecutionService = target.create("APIImplementation", ... "Name", prefs.BoardName + " - Execution Service implementation", ... "API", target.get("API", "ExecutionTool"), ... "BuildDependencies", target.create("MATLABDependencies", "Classes", className)); executionTool = target.create("ExecutionService", ... "Name", prefs.BoardName + " - Target process execution", ... "APIImplementation", customExecutionService); board.Tools.ExecutionTools = executionTool;
Communication — Sets up the protocol stack and TCP connection to the gateway process. The gateway translates between TCP and the FDX named pipes:
% Internal protocol (polls for breakpoint hits) pilProtocol = target.internal.create("PILDebugIOProtocol", ... "Name", prefs.BoardName + " - PIL DebugIOProtocol"); pilProtocol.BreakpointPollingWaitTime = 10000; board.Inner.CommunicationProtocolStacks = pilProtocol; % External protocol (timeouts for receive and open) pilProtocolExt = target.create("PILProtocol", ... "Name", prefs.BoardName + " - PIL Protocol"); pilProtocolExt.ReceiveTimeout = 10000; pilProtocolExt.OpenTimeout = 30000; board.CommunicationProtocolStacks = pilProtocolExt; % TCP connection to gateway connection = target.create("TargetConnection", "Name", prefs.BoardName); connection.CommunicationChannel = target.create("TCPChannel", ... "Name", prefs.BoardName + " - TCPChannel"); connection.CommunicationChannel.IPAddress = "localhost"; gatewayArgs = prefs.getGatewayArgs(); connection.CommunicationChannel.Port = num2str(gatewayArgs.Port); connection.Target = board; target.add(connection, "UserInstall", true, "SuppressOutput", false);
Define Toolchain
Create a toolchain definition file NXP_S32K3X4EVB_Q257_ToolchainDefinition.m that registers the cross-compiler, linker, assembler, and archiver with the appropriate flags for your target processor.
The toolchain definition is not specific to TRACE32 or FDX — it defines how to compile, link, and produce an ELF binary for your target architecture. For a detailed walkthrough of creating a toolchain definition, see the toolchain section in Create Target Registration Packages for C/C++ Test Execution on Targets.
Bring It All Together in Package Registration
The package registration file NXP_S32K3X4EVB_Q257_PackageRegister.m is the entry point that ties all the pieces together. When you register the package, this file runs and calls the board definition and toolchain definition:
addpath(fileparts(mfilename('fullpath'))); if savepath warning('Error while saving path!'); end rehash toolboxcache; prefs = NXP_S32K3X4EVB_Q257_Preferences(); NXP_S32K3X4EVB_Q257_BoardDefinition(); NXP_S32K3X4EVB_Q257_ToolchainDefinition();
This file:
Adds the package folder to the MATLAB path so the framework can find your classes.
Saves the path and refreshes the toolbox cache so the registration persists across Polyspace Test sessions.
Calls
NXP_S32K3X4EVB_Q257_BoardDefinition()to register the board, processor, source files, execution tool, and communication settings.Calls
NXP_S32K3X4EVB_Q257_ToolchainDefinition()to register the cross-compiler and build tools.
Register and Run
To register and use the target:
Open a project configuration in the Polyspace Platform user interface. Select Manage Boards and register your package using the
packageRegister.mfile.On the Build tab, select your board name for the option
Target board name (Testing).Build and run your tests. TRACE32 PowerView opens automatically, programs the flash, configures FDX channels, and starts execution. Test results are transferred through FDX pipes and displayed in the user interface.
Troubleshooting
| Symptom | Likely Cause |
|---|---|
| "FATAL ERROR from PBI-driver. TRACE32 device already used by other GUI." | Add CONNECTIONMODE=AUTOCONNECT to the .t32 config file after the USB line. This forces the connection to the probe even if a previous session did not release it cleanly. |
| No data transfer or test hangs | Verify that initFDX() is called in rtIOStreamOpen. Open the FDX channel window in TRACE32 PowerView and check that channels show "EnableChannel" selected and pipes are connected. |
| Flash programming error | Power-cycle both the debug probe and the target board to reset the hardware state. |
Comparison with Instruction Set Simulator Workflow
TRACE32 also supports a software-only mode called the Instruction Set Simulator (ISS), which simulates CPU execution without physical hardware. For the ISS workflow, see Adapt Polyspace Test Target Package for TRACE32 Instruction Set Simulator.
The key differences between the two workflows are:
| Aspect | FDX (this topic) | ISS |
|---|---|---|
| Hardware | Physical board and debug probe required | No hardware required (software simulation) |
| T32XIL Toolbox | Not required | Required |
| Data transfer | FDX named pipes (debug probe reads target memory) | TCP port via RCL=NETTCP |
| Target-side code | Custom rtiostream_fdx.c using FDX API | Provided by T32XIL Toolbox (t32xil_rtiostream.c) |
| Startup script | Configures FDX channels, programs flash, issues Go | Loads ELF only (T32XIL Toolbox manages execution) |
| Execution control | Script starts the CPU; breakpoint halts it at test end | T32XIL Toolbox starts and stops the CPU |
Choose the FDX workflow when you need to run tests on real hardware — for example, to verify timing behavior, peripheral interaction, or flash-resident code. Choose the ISS workflow for fast iteration without hardware dependencies.