Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions tools/ctrace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The [architecture description](docs/architecture.md) documents the supported fea
ctrace <trace-dir> [options]

-t, --target <name> Process one solution set; otherwise process all
-c, --channel <name> Select one input channel; repeat to select several
--csv Generate CSV output
--ctf Generate CTF and Trace Compass XML output
-a, --all Generate all output formats
Expand All @@ -25,6 +26,10 @@ If the directory follows them, terminate option parsing explicitly, for example
`ctrace --type itm dwt -- .trace`. With no output option, `ctrace` validates and decodes the capture without writing
output files. Run `ctrace --help` for the current option details.

`--channel` selects exact, case-sensitive names (`SWO`, `TB`, `TB_<name>`). Repeat it for multiple channels,
e.g. `ctrace .trace --all -c SWO -c TB_ETB_0`; duplicates are ignored. Default: all supported channels.
`TB` selects only the unnamed buffer; `--type` and `--stream` filter events within the selected inputs.

Normal CLI diagnostics use the same compact trace messages as CSV. Add `--verbose` (or `-v`) to include detailed
reasons, raw positions with bounded inspection windows, native decoder codes, packet previews and technical run
information on stderr. This option does not change CSV or CTF output, event selection or the exit status.
Expand All @@ -50,9 +55,9 @@ For `ctrace .trace --target Board --all`, the supported input produces:
Board.traceanalysis.xml # graphical views from eligible completed CTF bundles
```

Discovery processes every existing `Board.SWO.raw`, `Board.TB.raw`, and `Board.TB_<name>.raw` input independently,
one after another. `--target Board` selects the solution set and all its supported inputs. Each input gets its own
CSV and CTF bundle, using `<solution-set>.<channel>` as their common base name. CTF uses
Discovery processes selected `Board.SWO.raw`, `Board.TB.raw`, and `Board.TB_<name>.raw` inputs independently,
one after another. `--target Board` selects the solution set; `--channel` further restricts its inputs. Each input gets
its own CSV and CTF bundle, using `<solution-set>.<channel>` as their common base name. CTF uses
this channel-qualified name even for a single input; older `Board.ctf` bundles are neither reused nor removed.
The [CTF profile](docs/ctf-format.md#files-and-common-structure) records the required specification alignment.

Expand All @@ -65,6 +70,10 @@ remains valid CTF but is omitted from the XML with a warning. Independent single
their clock UUIDs keep sources separate without synchronizing or rebasing their timestamps. No old per-channel XML
files are migrated or deleted. An XML failure leaves completed CSV and CTF outputs intact.

With `--channel`, sets without matches are skipped and their outputs preserved. Each requested channel must exist
in at least one selected set; otherwise ctrace returns `1` after processing available matches. Excluded CSV/CTF
files remain untouched and are omitted from regenerated XML.

Without a format declaration, each SWO input defaults to unformatted ITM and each TB or named-TB input defaults to
formatted CoreSight. Missing or null `trace-format` uses these channel-based defaults; an explicit value overrides
the format for every supported input in that trace-run:
Expand All @@ -81,8 +90,9 @@ memory-aligned CoreSight frames; there is no public `trace-framing` field yet. S
[constraints](docs/constraints.md) for the full discovery, routing, and
compatibility contract.

Event Recorder (`Board.ER.raw`) remains unsupported and is skipped with a warning. A solution set without a supported
input reports an error. A failure in one input leaves the remaining inputs and solution sets available for processing;
Event Recorder (`Board.ER.raw`) remains unsupported: unfiltered discovery skips it with a warning, and `--channel ER`
is rejected. Without a channel filter, a solution set without a supported input reports an error.
A failure in one input leaves the remaining inputs and solution sets available for processing;
the command returns non-zero if any input fails. This also applies when validating without output options.

## Incomplete captures
Expand Down
10 changes: 5 additions & 5 deletions tools/ctrace/docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Backend-specific representations are documented in the [CTF profile](ctf-format.
PC sampling accepts a four-byte PC or the one-byte status markers `0x00` (`CPU Sleeping`) and Armv8-M `0xff`
(`Trace prohibited`). Status markers preserve route, timestamp, and sample quality without a PC address.

Every matching SWO, TB, and named-TB raw input is processed independently and sequentially for each selected trace-run
Every selected SWO, TB, and named-TB raw input is processed independently and sequentially for each selected trace-run
configuration. Formatted input distributes bytes to configured ITM routes by Trace Bus ID; unformatted input uses
one synthetic route. Other protocols require explicit decoder integration, not guesses based on observed IDs.
Deferred inputs and decoders are tracked in the [TODO list](todo.md).
Expand All @@ -30,7 +30,7 @@ formats independent of OpenCSD and allows another raw trace channel to reuse the

## How it works at a glance

`ctrace` processes one solution set at a time and runs a separate file job for each supported raw input in that set.
`ctrace` processes one solution set at a time and runs a separate file job for each selected raw input in that set.
The [README](../README.md#trace-directory) describes how configuration, raw inputs, and generated outputs are grouped
by solution-set and channel names. The following path runs once per input, with fresh decoder and output state.

Expand Down Expand Up @@ -86,8 +86,9 @@ there is deliberately no common base class for all decode stages.

Input selection and route binding belong to `tracerun` and complete before each input's decoder and output backends
are constructed. Target-level XML preparation precedes these per-input jobs.
With `--channel`, `TraceDirectoryJob` skips sets without matching inputs before YAML parsing and output preparation.
The provisional, ctrace-private `trace-format` declaration describes effective capture bytes rather than target
capability or file identity. Discovery collects every matching SWO, TB, and named-TB input, independently of whether
capability or file identity. Discovery selects matching SWO, TB, and named-TB inputs independently of whether
the format is declared. Each input is preflighted and normalized separately. An explicit format applies to every input;
otherwise SWO defaults to `unformatted` and TB or named-TB to `formatted`. The format is resolved before
`CtraceRunMeta` normalizes that input's routes, so the decoder and route model use the same effective format. This
Expand Down Expand Up @@ -219,8 +220,7 @@ byte. Packet rollback remains separate from the fatal-input output policy descri

1. Start at [`CtraceMain.cpp`](../src/CtraceMain.cpp) for command-line handling and top-level error policy.
2. Follow [`TraceDirectoryJob.cpp`](../src/control/TraceDirectoryJob.cpp) and
[`TraceRunDiscovery.cpp`](../src/tracerun/TraceRunDiscovery.cpp) to see how a solution set and YAML select all
matching SWO/TB inputs, each with its own preflighted descriptor and file job.
[`TraceRunDiscovery.cpp`](../src/tracerun/TraceRunDiscovery.cpp) for target/channel selection and input preflight.
3. Read [`FileDecodeJob.cpp`](../src/control/FileDecodeJob.cpp) for output preflight, chunked input, pipeline
construction, and finalization.
4. Continue through [`DecodePipeline.cpp`](../src/decode/DecodePipeline.cpp),
Expand Down
22 changes: 14 additions & 8 deletions tools/ctrace/docs/constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,23 @@ configuration with trace communication, separate from trace-source setup.
channel-based default. Missing or null selects `unformatted` for SWO and `formatted` for TB or named-TB without an
Error. Discovery resolves this effective format separately for each input before route normalization. An explicit
override applies to every supported input associated with that trace-run configuration.
- Every existing `<set>.SWO.raw`, `<set>.TB.raw`, and `<set>.TB_<name>.raw` is processed independently and sequentially.
`--target` selects a solution set, including all its supported inputs. A set without an eligible input reports an error.
- Selected `<set>.SWO.raw`, `<set>.TB.raw`, and `<set>.TB_<name>.raw` inputs are processed independently and sequentially.
`--target` selects a solution set. Without `--channel`, all its supported inputs are selected and a set without an
eligible input reports an error.
Each input must be a regular, readable file and is opened during its own preflight, before that input's decoder and
output backends are constructed. Target XML preparation precedes these per-input jobs. Event Recorder input remains
diagnosed and excluded from processing.
output backends are constructed. Target XML preparation precedes these per-input jobs.
- `--channel` / `-c` accepts exact, case-sensitive names: `SWO`, `TB`, or `TB_<name>` with suffix `[A-Za-z0-9_-]+`.
Repeated options form a union without duplicates; `TB` excludes named buffers. `ER` is unsupported:
the CLI rejects it, while unfiltered discovery warns and skips it.
- With a channel filter, sets without matches are skipped before YAML parsing. Each requested channel must match
a filename within the selected target scope; missing channels cause exit status `1` after processing the matches.
Matched inputs report YAML/preflight failures without a missing-channel error. `--type` and `--stream` filter
events within selected inputs.
- Input preflight, route normalization, decoding, and output failures do not prevent processing the remaining inputs
or solution sets. Each input has independent decoder and output state; any failing input contributes to a non-zero
command exit status. A configuration read failure prevents processing that set but does not stop later sets.
- The standardized `trace-buffer` selection belongs to solution/build-run producer configuration, not to the
`*.ctrace-run.yml` file consumed by ctrace. The caller-facing selection and format/framing contract remains
follow-up work; this does not imply adding fields to `*.ctrace-run.yml`. Current discovery processes all supported
matching files and applies the channel-based defaults above.
`*.ctrace-run.yml` file consumed by ctrace. The caller-facing format/framing contract remains follow-up work.
- Formatted input globally uses 16-byte memory-aligned CoreSight frames. Its length must be a multiple of 16, and it
contains neither FSYNC nor HSYNC framing. Ctrace does not parse or emit a `trace-framing` YAML field; supporting
another framing mode requires a public trace contract first.
Expand Down Expand Up @@ -199,8 +204,9 @@ configuration with trace communication, separate from trace-source setup.
only CTF metadata successfully finalized in that invocation, never stale bundles discovered on disk. Recoverable
decoder errors do not exclude an otherwise completed bundle. An XML failure does not remove completed CTF or CSV;
an input failure does not remove other inputs' contributions. No per-channel XML is generated or cleaned up.
Excluded inputs retain their CSV/CTF files. Sets without selected inputs retain all outputs, including XML.
- CTF timestamps never regress, and a global timestamp does not by itself establish local timestamp quality.
- Validation-only mode creates no output. Unsupported trace channels are diagnosed and skipped.
- Validation-only mode creates no output.
- Apart from the explicitly retained CSV after a fatal decode abort, cleanup of incomplete output artifacts is
attempted after failure, and cleanup failures are reported. Incompatible existing output filesystem types are
rejected before replacement. CTF bundles and target XML use distinct sibling paths derived from the trace-run
Expand Down
8 changes: 2 additions & 6 deletions tools/ctrace/docs/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@

## Inputs and time correlation

- [ ] Align caller-facing raw-input/channel selection and transport format/framing with the outcome of
- [ ] Align caller-facing transport format/framing with the outcome of
[cmsis-toolbox #699](https://github.com/Open-CMSIS-Pack/cmsis-toolbox/pull/699), also tracked by
[vscode-cmsis-debugger #1150](https://github.com/Open-CMSIS-Pack/vscode-cmsis-debugger/issues/1150).
TB input/CSV naming support tracked by
[devtools #2573](https://github.com/Open-CMSIS-Pack/devtools/issues/2573) is complete and that issue is closed;
public channel selection and format/framing remain separate follow-up work. Keep trace communication separate
from trace-source setup and decide how to replace the temporary `trace-format` override without assuming its
standardization.
Replace the provisional `trace-format` override while keeping trace communication separate from trace-source setup.
- [ ] Align the published CTF bundle path with ctrace's `<solution-set>.<channel>.ctf` naming, including single-input runs.
- [ ] Support FSYNC and FSYNC+HSYNC formatted input after a public framing contract is specified.
- [ ] Define cross-stream clock correlation and offsets once a common producer time reference is available.
Expand Down
2 changes: 2 additions & 0 deletions tools/ctrace/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ set(CTRACE_MODEL_HEADER_FILES
model/MessageCatalog.inc
model/Messages.h
model/TraceEvent.h
model/TraceInputChannel.h
model/TraceMessages.h
model/TraceRoute.h
model/TraceSelection.h
Expand Down Expand Up @@ -86,6 +87,7 @@ source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}"
add_library(ctrace-model STATIC
model/DiagnosticMessages.cpp
model/Messages.cpp
model/TraceInputChannel.cpp
model/TraceMessages.cpp
model/TraceSelection.cpp
${CTRACE_MODEL_HEADER_FILES}
Expand Down
2 changes: 2 additions & 0 deletions tools/ctrace/src/cli/CliOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <optional>
#include <string>
#include <vector>

/** @brief Selects the trace output formats requested on the command line. */
enum class OutputFormat {
Expand All @@ -25,6 +26,7 @@ enum class OutputFormat {
struct CliOptions {
std::optional<std::string> traceDir;
std::optional<std::string> targetName;
std::vector<std::string> channels;
OutputFormat outputFormat = OutputFormat::None;
TraceSelection selection;
bool help = false;
Expand Down
40 changes: 32 additions & 8 deletions tools/ctrace/src/cli/CliParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "DiagnosticMessages.h"
#include "CliOptions.h"
#include "ProductInfo.h"
#include "TraceInputChannel.h"
#include "TraceSelection.h"
#include "TraceStreamId.h"

Expand Down Expand Up @@ -136,14 +137,23 @@ static void configureCliParser(cxxopts::Options& parser)
parser.custom_help("<trace-dir> [options]");
parser.set_width(100U);
parser.allow_unrecognised_options();
parser.add_options()("csv", "Generate only CSV output")("ctf", "Generate only CTF / Trace Compass XML output")(
"a,all", "Generate CSV and CTF / XML output")("type", "Filter output for specific packet types (default: all)",
cxxopts::value<SelectionValues>(), "sel [...]")(
"stream", "Filter output for specific streams (default: all)", cxxopts::value<SelectionValues>(),
"sel [...]")("t,target", "Specify a trace solution-set (default: all)",
cxxopts::value<std::string>())("V,version", "Print version")(
"v,verbose", "Show detailed diagnostics and processing information");
parser.add_options("Hidden")("h,help", "Print help");
parser.add_options()
("csv", "Generate only CSV output")
("ctf", "Generate only CTF / Trace Compass XML output")
("a,all", "Generate CSV and CTF / XML output")
("type", "Filter output for specific packet types (default: all)",
cxxopts::value<SelectionValues>(), "sel [...]")
("stream", "Filter output for specific streams (default: all)",
cxxopts::value<SelectionValues>(), "sel [...]")
("t,target", "Specify a trace solution-set (default: all)",
cxxopts::value<std::string>())
("c,channel", "Select an input channel (repeatable; default: all)",
cxxopts::value<std::string>(), "name")
("V,version", "Print version")
("v,verbose", "Show detailed diagnostics and processing information");

parser.add_options("Hidden")
("h,help", "Print help");
}

/** @brief Parses normalized command-line arguments into ctrace options. */
Expand Down Expand Up @@ -175,6 +185,15 @@ static CliOptions parseCliArgs(const std::vector<std::string>& arguments)
if (parsed.count("target") != 0U) {
options.targetName = parsed["target"].as<std::string>();
}
// Read repeated scalars without cxxopts' comma splitting.
for (const auto& argument : parsed.arguments()) {
if (argument.key() == "channel") {
if (argument.value().empty() || startsWithDash(argument.value())) {
throw std::runtime_error(missingArgumentValueMessage("--channel"));
}
options.channels.push_back(argument.value());
}
}
if (parsed.count("type") != 0U) {
for (const auto& type : parsed["type"].as<std::vector<std::string>>()) {
options.selection.types.push_back(type);
Expand All @@ -201,6 +220,11 @@ static void validateCliOptions(const CliOptions& options)
if (options.help) {
return;
}
for (const auto& channel : options.channels) {
if (!isSupportedTraceChannel(channel)) {
throw std::runtime_error(channelArgumentMessage(channel));
}
}
for (const auto& type : options.selection.types) {
if (!parseTraceEventType(type).has_value()) {
throw std::runtime_error(typeArgumentMessage(type, traceEventTypeList(", ")));
Expand Down
Loading
Loading