1 /*
2  * Copyright (c) 2019 Intel corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _TRACE_BACKEND_H
8 #define _TRACE_BACKEND_H
9 
10 #include <string.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/sys/iterable_sections.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /**
19  * @brief Tracing backend
20  * @defgroup Tracing_backend Tracing backend
21  * @{
22  * @}
23  */
24 
25 struct tracing_backend;
26 
27 /**
28  * @brief Tracing backend API.
29  */
30 struct tracing_backend_api {
31 	void (*init)(void);
32 	void (*output)(const struct tracing_backend *backend,
33 		       uint8_t *data, uint32_t length);
34 };
35 
36 /**
37  * @brief Tracing backend structure.
38  */
39 struct tracing_backend {
40 	const char *name;
41 	const struct tracing_backend_api *api;
42 };
43 
44 /**
45  * @brief Create tracing_backend instance.
46  *
47  * @param _name Instance name.
48  * @param _api  Tracing backend API.
49  */
50 #define TRACING_BACKEND_DEFINE(_name, _api)                              \
51 	static const STRUCT_SECTION_ITERABLE(tracing_backend, _name) = { \
52 		.name = STRINGIFY(_name),                                \
53 		.api = &_api                                             \
54 	}
55 
56 /**
57  * @brief Initialize tracing backend.
58  *
59  * @param backend Pointer to tracing_backend instance.
60  */
tracing_backend_init(const struct tracing_backend * backend)61 static inline void tracing_backend_init(
62 		const struct tracing_backend *backend)
63 {
64 	if (backend && backend->api && backend->api->init) {
65 		backend->api->init();
66 	}
67 }
68 
69 /**
70  * @brief Output tracing packet with tracing backend.
71  *
72  * @param backend Pointer to tracing_backend instance.
73  * @param data    Address of outputting buffer.
74  * @param length  Length of outputting buffer.
75  */
tracing_backend_output(const struct tracing_backend * backend,uint8_t * data,uint32_t length)76 static inline void tracing_backend_output(
77 		const struct tracing_backend *backend,
78 		uint8_t *data, uint32_t length)
79 {
80 	if (backend && backend->api) {
81 		backend->api->output(backend, data, length);
82 	}
83 }
84 
85 /**
86  * @brief Get tracing backend based on the name of
87  *        tracing backend in tracing backend section.
88  *
89  * @param name Name of wanted tracing backend.
90  *
91  * @return Pointer of the wanted backend or NULL.
92  */
tracing_backend_get(char * name)93 static inline struct tracing_backend *tracing_backend_get(char *name)
94 {
95 	STRUCT_SECTION_FOREACH(tracing_backend, backend) {
96 		if (strcmp(backend->name, name) == 0) {
97 			return backend;
98 		}
99 	}
100 
101 	return NULL;
102 }
103 
104 #ifdef __cplusplus
105 }
106 #endif
107 
108 #endif
109