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 };
21 
22 /** @brief Dynamic data associated with the source of log messages. */
23 struct log_source_dynamic_data {
24 	uint32_t filters;
25 #if defined(CONFIG_64BIT)
26 	/* Workaround: Ensure that structure size is a multiple of 8 bytes. */
27 	uint32_t dummy_64;
28 #endif
29 };
30 
31 /** @internal
32  *
33  * Creates name of variable and section for constant log data.
34  *
35  *  @param _name Name.
36  */
37 #define Z_LOG_ITEM_CONST_DATA(_name) UTIL_CAT(log_const_, _name)
38 
39 /** @internal
40  *
41  * Create static logging instance in read only memory.
42  *
43  * @param _name name of the module. With added prefix forms name of variable and
44  * memory section.
45  *
46  * @param _str_name Name of the module that will be used when message is formatted.
47  *
48  * @param _level Messages up to this level are compiled in.
49  */
50 #define Z_LOG_CONST_ITEM_REGISTER(_name, _str_name, _level)		       \
51 	const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const,		       \
52 		log_source_const_data,					       \
53 		Z_LOG_ITEM_CONST_DATA(_name)) =				       \
54 	{								       \
55 		.name = _str_name,					       \
56 		.level  = (_level),					       \
57 	}
58 
59 /** @brief Initialize pointer to logger instance with explicitly provided object.
60  *
61  * Macro can be used to initialized a pointer with object that is not unique to
62  * the given instance, thus not created with @ref LOG_INSTANCE_REGISTER.
63  *
64  * @param _name Name of the structure element for holding logging object.
65  * @param _object Pointer to a logging instance object.
66  */
67 #define LOG_OBJECT_PTR_INIT(_name, _object) \
68 	IF_ENABLED(CONFIG_LOG, (._name = _object,))
69 
70 /** @internal
71  *
72  * Create a name for which contains module and instance names.
73  */
74 #define Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name) \
75 	UTIL_CAT(_module_name, UTIL_CAT(_, _inst_name))
76 
77 /** @internal
78  *
79  * Returns a pointer associated with given logging instance. When runtime filtering
80  * is enabled then dynamic instance is returned.
81  *
82  * @param _name Name of the instance.
83  *
84  * @return Pointer to the instance object (static or dynamic).
85  */
86 #define Z_LOG_OBJECT_PTR(_name) \
87 		COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, \
88 			(&LOG_ITEM_DYNAMIC_DATA(_name)), \
89 			(&Z_LOG_ITEM_CONST_DATA(_name))) \
90 
91 /** @brief Get pointer to a logging instance.
92  *
93  * Instance is identified by @p _module_name and @p _inst_name.
94  *
95  * @param _module_name Module name.
96  * @param _inst_name Instance name.
97  *
98  * @return Pointer to a logging instance.
99  */
100 #define LOG_INSTANCE_PTR(_module_name, _inst_name) \
101 	Z_LOG_OBJECT_PTR(Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name))
102 
103 /** @brief Macro for initializing a pointer to the logger instance.
104  *
105  * @p _module_name and @p _inst_name are concatenated to form a name of the object.
106  *
107  * Macro is intended to be used in user structure initializer to initialize a field
108  * in the structure that holds pointer to the logging instance. Structure field
109  * should be declared using @p LOG_INSTANCE_PTR_DECLARE.
110  *
111  * @param _name Name of a structure element that have a pointer to logging instance object.
112  * @param _module_name Module name.
113  * @param _inst_name Instance name.
114  */
115 #define LOG_INSTANCE_PTR_INIT(_name, _module_name, _inst_name)	   \
116 	LOG_OBJECT_PTR_INIT(_name, LOG_INSTANCE_PTR(_module_name, _inst_name))
117 
118 #define Z_LOG_INSTANCE_STRUCT \
119 	COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, \
120 		    (struct log_source_dynamic_data), \
121 		    (const struct log_source_const_data))
122 
123 /**
124  * @brief Declare a logger instance pointer in the module structure.
125  *
126  * If logging is disabled then element in the structure is still declared to avoid
127  * compilation issues. If compiler supports zero length arrays then it is utilized
128  * to not use any space, else a byte array is created.
129  *
130  * @param _name Name of a structure element that will have a pointer to logging
131  * instance object.
132  */
133 #define LOG_INSTANCE_PTR_DECLARE(_name)	\
134 	COND_CODE_1(CONFIG_LOG, (Z_LOG_INSTANCE_STRUCT * _name), \
135 				(int _name[TOOLCHAIN_HAS_ZLA ? 0 : 1]))
136 
137 #define Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name) \
138 	STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \
139 			LOG_INSTANCE_DYNAMIC_DATA(_module_name, _inst_name))
140 
141 #define Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \
142 	Z_LOG_CONST_ITEM_REGISTER( \
143 		Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name), \
144 		STRINGIFY(_module_name._inst_name), \
145 		_level); \
146 	IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \
147 		   (Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name)))
148 
149 /**
150  * @brief Macro for registering instance for logging with independent filtering.
151  *
152  * Module instance provides filtering of logs on instance level instead of
153  * module level. Instance create using this macro can later on be used with
154  * @ref LOG_INSTANCE_PTR_INIT or referenced by @ref LOG_INSTANCE_PTR.
155  *
156  * @param _module_name Module name.
157  * @param _inst_name Instance name.
158  * @param _level Initial static filtering.
159  */
160 #define LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \
161 	IF_ENABLED(CONFIG_LOG, (Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level)))
162 
163 #ifdef __cplusplus
164 }
165 #endif
166 
167 #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_ */
168