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