• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Pigweed Authors
2 //
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
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
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
13 // the License.
14 //==============================================================================
15 //
16 // This file describes Pigweed's public user-facing tracing API.
17 //
18 // THIS PUBLIC API IS NOT STABLE OR COMPLETE!
19 //
20 
21 #pragma once
22 
23 #include <stdbool.h>
24 #include <stdint.h>
25 
26 #include "pw_preprocessor/util.h"
27 #include "pw_trace/internal/trace_internal.h"
28 
29 // Backend defines PW_TRACE in the form:
30 // #define PW_TRACE(event_type, flags, label, group_label, trace_id)
31 
32 // trace_backend.h must ultimately resolve to a header that implements the
33 // macros required by the tracing facade, as described below.
34 //
35 // Inputs: Macros the downstream user provides to control the tracing system:
36 //
37 //   PW_TRACE_MODULE_NAME
38 //     - The module name the backend should use
39 //
40 // Outputs: Macros trace_backend.h is expected to provide:
41 //
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.
47 //
48 //   event_type will pass the macro value which is defined by the backend when
49 //   enabling the trace type.
50 //
51 // Enabling traces: The backend can define these macros to enable the different
52 //                  trace types. If not defined those traces are removed.
53 //
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.
63 //
64 // Defaults: The backend can use the macros to change what the default value is
65 //           if not provided.
66 //
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.
70 
71 #include "pw_trace_backend/trace_backend.h"
72 
73 // Default: Module name
74 #ifndef PW_TRACE_MODULE_NAME
75 #define PW_TRACE_MODULE_NAME ""
76 #endif  // PW_TRACE_MODULE_NAME
77 
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
82 
83 // PW_TRACE_INSTANT(label)
84 // PW_TRACE_INSTANT(label, group)
85 // PW_TRACE_INSTANT(label, group, trace_id)
86 //
87 // Used to trace an instantaneous event in code.
88 //
89 // Example usage:
90 //     PW_TRACE_INSTANT("HERE");
91 //
92 // Arguments:
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__)
100 
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)
104 //
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__)
110 
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)
114 //
115 // These macros mirror PW_TRACE_INSTANT but introduce arguments to specify a
116 // user-supplied data buffer to append to the trace event.
117 //
118 // Arguments:
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__)
127 
128 // PW_TRACE_INSTANT_DATA_FLAG(flag, label, data_format_string, data, size)
129 // PW_TRACE_INSTANT_DATA_FLAG(flag,
130 //                            label,
131 //                            group,
132 //                            data_format_string,
133 //                            data,
134 //                            size)
135 // PW_TRACE_INSTANT_DATA_FLAG(flag,
136 //                            label,
137 //                            group,
138 //                            trace_id,
139 //                            data_format_string,
140 //                            data,
141 //                            size)
142 //
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.
146 //
147 // Arguments:
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__)
156 
157 // PW_TRACE_START(label)
158 // PW_TRACE_START(label, group)
159 // PW_TRACE_START(label, group, trace_id)
160 //
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.
163 //
164 // Example usage:
165 //    PW_TRACE_START("label");
166 //    .. Do something ..
167 //    PW_TRACE_END("label");
168 //
169 // Arguments:
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__)
177 
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)
181 //
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__)
187 
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,
191 //                     label,
192 //                     group,
193 //                     trace_id,
194 //                     data_format_string,
195 //                     data,
196 //                     size)
197 //
198 // These macros mirror PW_TRACE_START but introduce arguments to specify a
199 // user-supplied data buffer to append to the trace event.
200 //
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.
203 //
204 // Arguments:
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__)
213 
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,
217 //                          label,
218 //                          group,
219 //                          trace_id,
220 //                          data_format_string,
221 //                          data,
222 //                          size)
223 //
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.
227 //
228 // Arguments:
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__)
237 
238 // PW_TRACE_END(label)
239 // PW_TRACE_END(label, group)
240 // PW_TRACE_END(label, group, trace_id)
241 //
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.
244 //
245 // Example usage:
246 //    PW_TRACE_START("label");
247 //    .. Do something ..
248 //    PW_TRACE_END("label");
249 //
250 // Arguments:
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__)
258 
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)
262 //
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
265 // optional.
266 #define PW_TRACE_END_FLAG(...) \
267   PW_DELEGATE_BY_ARG_COUNT(_PW_TRACE_END_ARGS, __VA_ARGS__)
268 
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)
272 //
273 // These macros mirror PW_TRACE_END but introduce arguments to specify a
274 // user-supplied data buffer to append to the trace event.
275 //
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.
278 //
279 // Arguments:
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__)
288 
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,
292 //                        label,
293 //                        group,
294 //                        trace_id,
295 //                        data_format_string,
296 //                        data,
297 //                        size)
298 //
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.
302 //
303 // Arguments:
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__)
312 
313 #ifdef __cplusplus
314 
315 // PW_TRACE_SCOPE(label)
316 // PW_TRACE_SCOPE(label, group)
317 // PW_TRACE_SCOPE(label, group, trace_id)
318 //
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.
322 //
323 // Arguments:
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.
330 // Example:
331 //   {
332 //      PW_TRACE_SCOPE("Bar");
333 //      // Do some stuff
334 //   }
335 //
336 //   {
337 //      PW_TRACE_SCOPE("Group", "Foo");
338 //      {
339 //         PW_TRACE_SCOPE("Group", "SubFoo");
340 //         // Do some stuff
341 //      }
342 //      // Do some stuff
343 //   }
344 //
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)
355 //
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
363 
364 // PW_TRACE_FUNCTION()
365 // PW_TRACE_FUNCTION(group)
366 // PW_TRACE_FUNCTION(group, trace_id)
367 //
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.
370 //
371 // Arguments:
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.
377 // Example:
378 //   void Bar() {
379 //      PW_TRACE_FUNCTION();
380 //      // Do some stuff
381 //   }
382 //
383 //   void Child() {
384 //      PW_TRACE_FUNCTION("Group");
385 //      // Do some stuff
386 //   }
387 //
388 //   void Parent() {
389 //      PW_TRACE_FUNCTION("Group");
390 //      // Do some stuff
391 //      Child();
392 //   }
393 //
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
403 
404 // PW_TRACE_FUNCTION_FLAG(flag)
405 // PW_TRACE_FUNCTION_FLAG(flag, group)
406 // PW_TRACE_FUNCTION_FLAG(flag, group, trace_id)
407 //
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
415 
416 #endif  // __cplusplus
417