1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_
7 #define ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_
8 
9 #include <zephyr/types.h>
10 #include <zephyr/sys/iterable_sections.h>
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 /** @brief Constant data associated with the source of log messages. */
17 struct log_source_const_data {
18 	const char *name;
19 	uint8_t level;
20 #ifdef CONFIG_NIOS2
21 	/* Workaround alert! Dummy data to ensure that structure is >8 bytes.
22 	 * Nios2 uses global pointer register for structures <=8 bytes and
23 	 * apparently does not handle well variables placed in custom sections.
24 	 */
25 	uint32_t dummy;
26 #endif
27 };
28 
29 /** @brief Dynamic data associated with the source of log messages. */
30 struct log_source_dynamic_data {
31 	uint32_t filters;
32 #ifdef CONFIG_NIOS2
33 	/* Workaround alert! Dummy data to ensure that structure is >8 bytes.
34 	 * Nios2 uses global pointer register for structures <=8 bytes and
35 	 * apparently does not handle well variables placed in custom sections.
36 	 */
37 	uint32_t dummy[2];
38 #endif
39 #if defined(CONFIG_RISCV) && defined(CONFIG_64BIT)
40 	/* Workaround: RV64 needs to ensure that structure is just 8 bytes. */
41 	uint32_t dummy;
42 #endif
43 };
44 
45 /** @internal
46  *
47  * Creates name of variable and section for constant log data.
48  *
49  *  @param _name Name.
50  */
51 #define Z_LOG_ITEM_CONST_DATA(_name) UTIL_CAT(log_const_, _name)
52 
53 /** @internal
54  *
55  * Create static logging instance in read only memory.
56  *
57  * @param _name name of the module. With added prefix forms name of variable and
58  * memory section.
59  *
60  * @param _str_name Name of the module that will be used when message is formatted.
61  *
62  * @param _level Messages up to this level are compiled in.
63  */
64 #define Z_LOG_CONST_ITEM_REGISTER(_name, _str_name, _level)		       \
65 	const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const,		       \
66 		log_source_const_data,					       \
67 		Z_LOG_ITEM_CONST_DATA(_name)) =				       \
68 	{								       \
69 		.name = _str_name,					       \
70 		.level  = (_level),					       \
71 	}
72 
73 /** @brief Initialize pointer to logger instance with explicitly provided object.
74  *
75  * Macro can be used to initialized a pointer with object that is not unique to
76  * the given instance, thus not created with @ref LOG_INSTANCE_REGISTER.
77  *
78  * @param _name Name of the structure element for holding logging object.
79  * @param _object Pointer to a logging instance object.
80  */
81 #define LOG_OBJECT_PTR_INIT(_name, _object) \
82 	IF_ENABLED(CONFIG_LOG, (._name = _object,))
83 
84 /** @internal
85  *
86  * Create a name for which contains module and instance names.
87  */
88 #define Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name) \
89 	UTIL_CAT(_module_name, UTIL_CAT(_, _inst_name))
90 
91 /** @internal
92  *
93  * Returns a pointer associated with given logging instance. When runtime filtering
94  * is enabled then dynamic instance is returned.
95  *
96  * @param _name Name of the instance.
97  *
98  * @return Pointer to the instance object (static or dynamic).
99  */
100 #define Z_LOG_OBJECT_PTR(_name) \
101 		COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, \
102 			(&LOG_ITEM_DYNAMIC_DATA(_name)), \
103 			(&Z_LOG_ITEM_CONST_DATA(_name))) \
104 
105 /** @brief Get pointer to a logging instance.
106  *
107  * Instance is identified by @p _module_name and @p _inst_name.
108  *
109  * @param _module_name Module name.
110  * @param _inst_name Instance name.
111  *
112  * @return Pointer to a logging instance.
113  */
114 #define LOG_INSTANCE_PTR(_module_name, _inst_name) \
115 	Z_LOG_OBJECT_PTR(Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name))
116 
117 /** @brief Macro for initializing a pointer to the logger instance.
118  *
119  * @p _module_name and @p _inst_name are concatenated to form a name of the object.
120  *
121  * Macro is intended to be used in user structure initializer to initialize a field
122  * in the structure that holds pointer to the logging instance. Structure field
123  * should be declared using @p LOG_INSTANCE_PTR_DECLARE.
124  *
125  * @param _name Name of a structure element that have a pointer to logging instance object.
126  * @param _module_name Module name.
127  * @param _inst_name Instance name.
128  */
129 #define LOG_INSTANCE_PTR_INIT(_name, _module_name, _inst_name)	   \
130 	LOG_OBJECT_PTR_INIT(_name, LOG_INSTANCE_PTR(_module_name, _inst_name))
131 
132 #define Z_LOG_INSTANCE_STRUCT \
133 	COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, \
134 		    (struct log_source_dynamic_data), \
135 		    (const struct log_source_const_data))
136 
137 /**
138  * @brief Declare a logger instance pointer in the module structure.
139  *
140  * @param _name Name of a structure element that will have a pointer to logging
141  * instance object.
142  */
143 #define LOG_INSTANCE_PTR_DECLARE(_name)	\
144 	IF_ENABLED(CONFIG_LOG, (Z_LOG_INSTANCE_STRUCT * _name))
145 
146 #define Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name) \
147 	STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \
148 			LOG_INSTANCE_DYNAMIC_DATA(_module_name, _inst_name))
149 
150 #define Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \
151 	Z_LOG_CONST_ITEM_REGISTER( \
152 		Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name), \
153 		STRINGIFY(_module_name._inst_name), \
154 		_level); \
155 	IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \
156 		   (Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name)))
157 
158 /**
159  * @brief Macro for registering instance for logging with independent filtering.
160  *
161  * Module instance provides filtering of logs on instance level instead of
162  * module level. Instance create using this macro can later on be used with
163  * @ref LOG_INSTANCE_PTR_INIT or referenced by @ref LOG_INSTANCE_PTR.
164  *
165  * @param _module_name Module name.
166  * @param _inst_name Instance name.
167  * @param _level Initial static filtering.
168  */
169 #define LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \
170 	IF_ENABLED(CONFIG_LOG, (Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level)))
171 
172 #ifdef __cplusplus
173 }
174 #endif
175 
176 #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_ */
177