1 // Copyright 2020 The Pigweed Authors
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
7 // https://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
14 //==============================================================================
16 // This file describes Pigweed's public user-facing tracing API.
18 // THIS PUBLIC API IS NOT STABLE OR COMPLETE!
26 #include "pw_preprocessor/util.h"
27 #include "pw_trace/internal/trace_internal.h"
29 // Backend defines PW_TRACE in the form:
30 // #define PW_TRACE(event_type, flags, label, group_label, trace_id)
32 // trace_backend.h must ultimately resolve to a header that implements the
33 // macros required by the tracing facade, as described below.
35 // Inputs: Macros the downstream user provides to control the tracing system:
37 // PW_TRACE_MODULE_NAME
38 // - The module name the backend should use
40 // Outputs: Macros trace_backend.h is expected to provide:
42 // PW_TRACE(event_type, flags, label, group_label, trace_id)
43 // PW_TRACE_DATA(event_type, flags, label, group_label, trace_id,
44 // data_format_string, data, data_size)
45 // - Implementing PW_TRACE_DATA is optional. If not defined, all data
46 // traces will be removed.
48 // event_type will pass the macro value which is defined by the backend when
49 // enabling the trace type.
51 // Enabling traces: The backend can define these macros to enable the different
52 // trace types. If not defined those traces are removed.
54 // PW_TRACE_TYPE_INSTANT: Instant trace, with only a label.
55 // PW_TRACE_TYPE_INSTANT_GROUP: Instant trace, with a label and a group.
56 // PW_TRACE_TYPE_DURATION_START: Start trace, with only a label.
57 // PW_TRACE_TYPE_DURATION_END: End trace, with only a label.
58 // PW_TRACE_TYPE_DURATION_GROUP_START: Start trace, with a label and a group.
59 // PW_TRACE_TYPE_DURATION_GROUP_END: End trace, with a label and a group.
60 // PW_TRACE_TYPE_ASYNC_START: Start trace, with label, group, and trace_id.
61 // PW_TRACE_TYPE_ASYNC_INSTANT: Instant trace, with label, group, and trace_id
62 // PW_TRACE_TYPE_ASYNC_END: End trace, with label, group, and trace_id.
64 // Defaults: The backend can use the macros to change what the default value is
67 // PW_TRACE_FLAGS_DEFAULT: Default value if no flags are provided.
68 // PW_TRACE_TRACE_ID_DEFAULT: Default value if not trace_id provided.
69 // PW_TRACE_GROUP_LABEL_DEFAULT: Default value if not group_label provided.
71 #include "pw_trace_backend/trace_backend.h"
73 // Default: Module name
74 #ifndef PW_TRACE_MODULE_NAME
75 #define PW_TRACE_MODULE_NAME ""
76 #endif // PW_TRACE_MODULE_NAME
78 // Default: Flags values currently set if not provided
79 #ifndef PW_TRACE_FLAGS
80 #define PW_TRACE_FLAGS PW_TRACE_FLAGS_DEFAULT
81 #endif // PW_TRACE_FLAGS
83 // PW_TRACE_INSTANT(label)
84 // PW_TRACE_INSTANT(label, group)
85 // PW_TRACE_INSTANT(label, group, trace_id)
87 // Used to trace an instantaneous event in code.
90 // PW_TRACE_INSTANT("HERE");
93 // label: A string literal which desribes the trace
94 // group <optional>: A string literal which groups this trace with others in
95 // the same module and group.
96 // trace_id <optional>: A runtime uint32_t which groups this trace with
97 // others with the same module group and trace_id.
98 // Every trace with a trace_id must also have a group.
99 #define PW_TRACE_INSTANT(...) PW_TRACE_INSTANT_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
101 // PW_TRACE_INSTANT_FLAG(flag, label)
102 // PW_TRACE_INSTANT_FLAG(flag, label, group)
103 // PW_TRACE_INSTANT_FLAG(flag, label, group, trace_id)
105 // These macros mirror PW_TRACE_INSTANT but intruduce the flag argument to
106 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
107 // at the start, group and trace_id arguments are still optional.
108 #define PW_TRACE_INSTANT_FLAG(...) \
109 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_INSTANT_ARGS, __VA_ARGS__)
111 // PW_TRACE_INSTANT_DATA(label, data_format_string, data, size)
112 // PW_TRACE_INSTANT_DATA(label, group, data_format_string, data, size)
113 // PW_TRACE_INSTANT_DATA(label, group, trace_id, data_format_string, data, size)
115 // These macros mirror PW_TRACE_INSTANT but introduce arguments to specify a
116 // user-supplied data buffer to append to the trace event.
119 // data_format_string: A string which is used by the decoder to identify the
120 // data. This could for example be either be printf style
121 // tokens, python struct packed fmt string or a custom
122 // label recognized by the decoder.
123 // data: A pointer to a buffer of arbitrary caller-provided data (void*).
124 // size: The size of the data (size_t).
125 #define PW_TRACE_INSTANT_DATA(...) \
126 PW_TRACE_INSTANT_DATA_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
128 // PW_TRACE_INSTANT_DATA_FLAG(flag, label, data_format_string, data, size)
129 // PW_TRACE_INSTANT_DATA_FLAG(flag,
132 // data_format_string,
135 // PW_TRACE_INSTANT_DATA_FLAG(flag,
139 // data_format_string,
143 // These macros mirror PW_TRACE_INSTANT_DATA but intruduce the flag argument to
144 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
145 // at the start, group and trace_id arguments are still optional.
148 // data_format_string: A string which is used by the decoder to identify the
149 // data. This could for example be either be printf style
150 // tokens, python struct packed fmt string or a custom
151 // label recognized by the decoder.
152 // data: A pointer to a buffer of arbitrary caller-provided data (void*).
153 // size: The size of the data (size_t).
154 #define PW_TRACE_INSTANT_DATA_FLAG(...) \
155 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_INSTANT_DATA_ARGS, __VA_ARGS__)
157 // PW_TRACE_START(label)
158 // PW_TRACE_START(label, group)
159 // PW_TRACE_START(label, group, trace_id)
161 // Used to start tracing an event, should be paired with an PW_TRACE_END (or
162 // PW_TRACE_END_DATA) with the same module/label/group/trace_id.
165 // PW_TRACE_START("label");
166 // .. Do something ..
167 // PW_TRACE_END("label");
170 // label: A string literal which desribes the trace
171 // group <optional>: A string literal which groups this trace with others in
172 // the same module and group.
173 // trace_id <optional>: A runtime uint32_t which groups this trace with
174 // others with the same module group and trace_id.
175 // Every trace with a trace_id must also have a group.
176 #define PW_TRACE_START(...) PW_TRACE_START_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
178 // PW_TRACE_START_FLAG(flag, label)
179 // PW_TRACE_START_FLAG(flag, label, group)
180 // PW_TRACE_START_FLAG(flag, label, group, trace_id)
182 // These macros mirror PW_TRACE_START but intruduce the flag argument to
183 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
184 // at the start, group and trace_id arguments are still optional.
185 #define PW_TRACE_START_FLAG(...) \
186 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_START_ARGS, __VA_ARGS__)
188 // PW_TRACE_START_DATA(label, data_format_string, data, size)
189 // PW_TRACE_START_DATA(label, group, data_format_string, data, size)
190 // PW_TRACE_START_DATA(flag,
194 // data_format_string,
198 // These macros mirror PW_TRACE_START but introduce arguments to specify a
199 // user-supplied data buffer to append to the trace event.
201 // NOTE: A trace duration start/end can be combined with a duration data
202 // start/end, to include data at only one of the trace points and not the other.
205 // data_format_string: A string which is used by the decoder to identify the
206 // data. This could for example be either be printf style
207 // tokens, python struct packed fmt string or a custom
208 // label recognized by the decoder.
209 // data: A pointer to a buffer of arbitrary caller-provided data (void*).
210 // size: The size of the data (size_t).
211 #define PW_TRACE_START_DATA(...) \
212 PW_TRACE_START_DATA_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
214 // PW_TRACE_START_DATA_FLAG(flag, label, data_format_string, data, size)
215 // PW_TRACE_START_DATA_FLAG(flag, label, group, data_format_string, data, size)
216 // PW_TRACE_START_DATA_FLAG(flag,
220 // data_format_string,
224 // These macros mirror PW_TRACE_START_DATA but intruduce the flag argument to
225 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
226 // at the start, group and trace_id arguments are still optional.
229 // data_format_string: A string which is used by the decoder to identify the
230 // data. This could for example be either be printf style
231 // tokens, python struct packed fmt string or a custom
232 // label recognized by the decoder.
233 // data: A pointer to a buffer of arbitrary caller-provided data (void*).
234 // size: The size of the data (size_t).
235 #define PW_TRACE_START_DATA_FLAG(...) \
236 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_START_DATA_ARGS, __VA_ARGS__)
238 // PW_TRACE_END(label)
239 // PW_TRACE_END(label, group)
240 // PW_TRACE_END(label, group, trace_id)
242 // Used to start tracing an event, should be paired with an PW_TRACE_START (or
243 // PW_TRACE_START_DATA) with the same module/label/group/trace_id.
246 // PW_TRACE_START("label");
247 // .. Do something ..
248 // PW_TRACE_END("label");
251 // label: A string literal which desribes the trace
252 // group <optional>: A string literal which groups this trace with others in
253 // the same module and group.
254 // trace_id <optional>: A runtime uint32_t which groups this trace with
255 // others with the same module group and trace_id.
256 // Every trace with a trace_id must also have a group.
257 #define PW_TRACE_END(...) PW_TRACE_END_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
259 // PW_TRACE_END_FLAG(flag, label)
260 // PW_TRACE_END_FLAG(flag, label, group)
261 // PW_TRACE_END_FLAG(flag, label, group, trace_id)
263 // Is the same as PW_TRACE_END but uses the provided flag value instead of
264 // PW_TRACE_FLAGS. The flag goes at the start, group and trace_id are still
266 #define PW_TRACE_END_FLAG(...) \
267 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_END_ARGS, __VA_ARGS__)
269 // PW_TRACE_END_DATA(label, data_format_string, data, size)
270 // PW_TRACE_END_DATA(label, group, data_format_string, data, size)
271 // PW_TRACE_END_DATA(label, group, trace_id, data_format_string, data, size)
273 // These macros mirror PW_TRACE_END but introduce arguments to specify a
274 // user-supplied data buffer to append to the trace event.
276 // NOTE: A trace duration start/end can be combined with a duration data
277 // start/end, to include data at only one of the trace points and not the other.
280 // data_format_string: A string which is used by the decoder to identify the
281 // data. This could for example be either be printf style
282 // tokens, python struct packed fmt string or a custom
283 // label recognized by the decoder.
284 // data: A pointer to a buffer of arbitrary caller-provided data (void*).
285 // size: The size of the data (size_t).
286 #define PW_TRACE_END_DATA(...) \
287 PW_TRACE_END_DATA_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
289 // PW_TRACE_END_DATA_FLAG(flag, label, data_format_string, data, size)
290 // PW_TRACE_END_DATA_FLAG(flag, label, group, data_format_string, data, size)
291 // PW_TRACE_END_DATA_FLAG(flag,
295 // data_format_string,
299 // These macros mirror PW_TRACE_END_DATA but intruduce the flag argument to
300 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
301 // at the start, group and trace_id arguments are still optional.
304 // data_format_string: A string which is used by the decoder to identify the
305 // data. This could for example be either be printf style
306 // tokens, python struct packed fmt string or a custom
307 // label recognized by the decoder.
308 // data: A pointer to a buffer of arbitrary caller-provided data (void*).
309 // size: The size of the data (size_t).
310 #define PW_TRACE_END_DATA_FLAG(...) \
311 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_END_DATA_ARGS, __VA_ARGS__)
315 // PW_TRACE_SCOPE(label)
316 // PW_TRACE_SCOPE(label, group)
317 // PW_TRACE_SCOPE(label, group, trace_id)
319 // C++ Scope API measures durations until the object loses scope.
320 // This can for example, provide a convenient method of tracing
321 // functions or loops.
324 // label: A string literal which desribes the trace
325 // group <optional>: A string literal which groups this trace with others in
326 // the same module and group.
327 // trace_id <optional>: A runtime uint32_t which groups this trace with
328 // others with the same module group and trace_id.
329 // Every trace with a trace_id must also have a group.
332 // PW_TRACE_SCOPE("Bar");
337 // PW_TRACE_SCOPE("Group", "Foo");
339 // PW_TRACE_SCOPE("Group", "SubFoo");
345 // Which can be visualized as
346 // Bar: [----------------Bar----------------]
347 // Group: [----------------Foo----------------]
348 // [------SubFoo-------]
349 #ifndef PW_TRACE_SCOPE
350 #define PW_TRACE_SCOPE(...) PW_TRACE_SCOPE_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
351 #endif // PW_TRACE_SCOPE
352 // PW_TRACE_SCOPE_FLAG(flag, label)
353 // PW_TRACE_SCOPE_FLAG(flag, label, group)
354 // PW_TRACE_SCOPE_FLAG(flag, label, group, trace_id)
356 // These macros mirror PW_TRACE_SCOPE but intruduce the flag argument to
357 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
358 // at the start, group and trace_id arguments are still optional.
359 #ifndef PW_TRACE_SCOPE_FLAG
360 #define PW_TRACE_SCOPE_FLAG(...) \
361 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_SCOPE_ARGS, __VA_ARGS__)
362 #endif // PW_TRACE_SCOPE_FLAG
364 // PW_TRACE_FUNCTION()
365 // PW_TRACE_FUNCTION(group)
366 // PW_TRACE_FUNCTION(group, trace_id)
368 // C++ Function API measures durations until the function returns.
369 // This is the same as PW_TRACE_SCOPE, but uses the function name as the label.
372 // group <optional>: A string literal which groups this trace with others in
373 // the same module and group.
374 // trace_id <optional>: A runtime uint32_t which groups this trace with
375 // others with the same module group and trace_id.
376 // Every trace with a trace_id must also have a group.
379 // PW_TRACE_FUNCTION();
384 // PW_TRACE_FUNCTION("Group");
389 // PW_TRACE_FUNCTION("Group");
394 // Which can be visualized as
395 // Bar: [----------------Bar----------------]
396 // Group: [----------------Parent----------------]
397 // [------Child-------]
398 #ifndef PW_TRACE_FUNCTION
399 #define PW_TRACE_FUNCTION(...) \
400 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_FUNCTION_ARGS, __VA_ARGS__)
401 // PW_TRACE_FUNCTION_FLAG(PW_TRACE_FLAGS, __VA_ARGS__)
402 #endif // PW_TRACE_FUNCTION
404 // PW_TRACE_FUNCTION_FLAG(flag)
405 // PW_TRACE_FUNCTION_FLAG(flag, group)
406 // PW_TRACE_FUNCTION_FLAG(flag, group, trace_id)
408 // These macros mirror PW_TRACE_FUNCTION but intruduce the flag argument to
409 // specify a flag value which is used instead of PW_TRACE_FLAGS. The flag goes
410 // at the start, group and trace_id arguments are still optional.
411 #ifndef PW_TRACE_FUNCTION_FLAG
412 #define PW_TRACE_FUNCTION_FLAG(...) \
413 PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_FUNCTION_FLAGS_ARGS, __VA_ARGS__)
414 #endif // PW_TRACE_FUNCTION_FLAG
416 #endif // __cplusplus