1 /*
2  * Copyright (c) 2020 - 2023, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice, this
11  *    list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
18  *    contributors may be used to endorse or promote products derived from this
19  *    software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  */
34 
35 /**
36  * @file
37  * @defgroup nrf_802154_sl_debug_logging Debug logging service
38  * @{
39  * @ingroup nrf_802154
40  * @brief Execution backtrace and internal events logging service.
41  *
42  * To obtain unambiguous output of debug logs, it is required to use a unique identifier
43  * in each @c .c module. See the following distribution of IDs for debug logs in component libraries:
44  * - ranges for .c modules:
45  *   - [  1 .. 31 ] for 802.15.4 Driver modules (NRF_802154_DRV_MODULE_ID_..)
46  *   - [ 32 .. 39 ] for 802.15.4 MPSL modules (NRF_802154_MPSL_MODULE_ID_..)
47  *   - [ 40 .. 63 ] for 802.15.4 SL modules (NRF_802154_SL_MODULE_ID_..)
48  * - ranges for global events (NRF_802154_LOG_GLOBAL_EVENT_ID_..) :
49  *   - [  1 .. 31 ] for global events in 802.15.4 Driver
50  *   - [ 32 .. 39 ] for global events in 802.15.4 MPSL
51  *   - [ 40 .. 63 ] for global events in 802.15.4 SL
52  *
53  */
54 
55 #ifndef NRF_802154_SL_LOG_H__
56 #define NRF_802154_SL_LOG_H__
57 
58 #include <stdint.h>
59 
60 /**@def NRF_802154_SL_DEBUG_LOG_BUFFER_LEN
61  * @brief Configures capacity of debug log buffer.
62  *
63  * The value of this macro determines how many entries can be stored in the log buffer.
64  * If the buffer capacity is exceeded, the oldest entries are overwritten.
65  *
66  * @note This value must be power of 2.
67  */
68 #ifndef NRF_802154_SL_DEBUG_LOG_BUFFER_LEN
69 #define NRF_802154_SL_DEBUG_LOG_BUFFER_LEN 1024U
70 #endif
71 
72 /**@def NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS
73  * @brief Configures if writing to log buffer is performed with interrupts disabled.
74  *
75  * Setting this macro to 1 has following consequences:
76  * - Interrupts are automatically disabled during write to log buffer. This ensures
77  *   thread-safety and always coherent log.
78  * - Higher priority interrupts may be delayed, so logging has impact on timing.
79  *
80  * Setting this macro to 0 has following consequences:
81  * - Interrupts are NOT disabled during write to log buffer. This may lead to missing
82  *   logs if higher priority interrupt preempts current write log operation.
83  * - Logging does not introduce delay to execution of higher priority interrupts.
84  */
85 #ifndef NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS
86 #define NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS 0
87 #endif
88 
89 /**@def NRF_802154_SL_LOG_VERBOSITY
90  * @brief Defines the verbosity level of generated logs.
91  *
92  * Define this macro in your @c .c file before inclusion of @c nrf_802154_debug_log.h to
93  * set verbosity level per-module basis.
94  */
95 #ifndef NRF_802154_SL_LOG_VERBOSITY
96 #define NRF_802154_SL_LOG_VERBOSITY   NRF_802154_LOG_VERBOSITY_LOW
97 #endif
98 
99 #define NRF_802154_LOG_VERBOSITY_NONE 0
100 #define NRF_802154_LOG_VERBOSITY_LOW  1
101 #define NRF_802154_LOG_VERBOSITY_HIGH 2
102 
103 #if (NRF_802154_SL_DEBUG_LOG_BLOCKS_INTERRUPTS)
104 
105 #include "nrf_802154_sl_utils.h"
106 
107 /**@brief Declares a variable for storing interrupts state before disabling interrupts. */
108 #define nrf_802154_sl_debug_log_saved_interrupt_st_variable(var_name) \
109     nrf_802154_sl_mcu_critical_state_t var_name
110 
111 #define nrf_802154_sl_debug_log_disable_interrupts(var_name) \
112     nrf_802154_sl_mcu_critical_enter(var_name)               \
113 
114 #define nrf_802154_sl_debug_log_restore_interrupts(var_name) \
115     nrf_802154_sl_mcu_critical_exit(var_name)                \
116 
117 #else
118 
119 #define nrf_802154_sl_debug_log_saved_interrupt_st_variable(var_name) /* empty macro */
120 
121 #define nrf_802154_sl_debug_log_disable_interrupts(var_name) \
122     do                                                       \
123     {                                                        \
124     }                                                        \
125     while (0)
126 
127 #define nrf_802154_sl_debug_log_restore_interrupts(var_name) \
128     do                                                       \
129     {                                                        \
130     }                                                        \
131     while (0)
132 
133 #endif
134 
135 /**@brief Checks if the provided @p verbosity parameter has a value that allows the module to record a log. */
136 #define nrf_802154_sl_log_verbosity_allows(verbosity) \
137     (((verbosity) > 0) && ((verbosity) <= NRF_802154_SL_LOG_VERBOSITY))
138 
139 #if !defined(CU_TEST) && (NRF_802154_SL_ENABLE_DEBUG_LOG)
140 
141 extern volatile uint32_t g_nrf_802154_sl_log_buffer[NRF_802154_SL_DEBUG_LOG_BUFFER_LEN];
142 extern volatile uint32_t gp_nrf_802154_sl_log_ptr;
143 
144 /**@brief Writes one word into debug log buffer. */
145 #define nrf_802154_sl_debug_log_write_raw(value)                                                \
146     do                                                                                          \
147     {                                                                                           \
148         uint32_t nrf_802154_sl_debug_log_wr_raw_value = (value);                                \
149                                                                                                 \
150         nrf_802154_sl_debug_log_saved_interrupt_st_variable(nrf_802154_sl_debug_log_wr_raw_sv); \
151         nrf_802154_sl_debug_log_disable_interrupts(nrf_802154_sl_debug_log_wr_raw_sv);          \
152                                                                                                 \
153         uint32_t nrf_802154_sl_debug_log_write_raw_ptr = gp_nrf_802154_sl_log_ptr;              \
154                                                                                                 \
155         g_nrf_802154_sl_log_buffer[nrf_802154_sl_debug_log_write_raw_ptr] =                     \
156             nrf_802154_sl_debug_log_wr_raw_value;                                               \
157         nrf_802154_sl_debug_log_write_raw_ptr += 1U;                                            \
158         nrf_802154_sl_debug_log_write_raw_ptr &= (NRF_802154_SL_DEBUG_LOG_BUFFER_LEN - 1U);     \
159         gp_nrf_802154_sl_log_ptr               = nrf_802154_sl_debug_log_write_raw_ptr;         \
160                                                                                                 \
161         nrf_802154_sl_debug_log_restore_interrupts(nrf_802154_sl_debug_log_wr_raw_sv);          \
162     }                                                                                           \
163     while (0)
164 
165 #else // !defined(CU_TEST) && (NRF_802154_SL_ENABLE_DEBUG_LOG)
166 
167 #define nrf_802154_sl_debug_log_write_raw(value) \
168     do                                           \
169     {                                            \
170     }                                            \
171     while (0)
172 
173 #endif // !defined(CU_TEST) && (NRF_802154_SL_ENABLE_DEBUG_LOG)
174 
175 /**@name nrf_802154_sl_debug_log_entry_types
176  * @brief Types of log entries.
177  *
178  * Value 0 is reserved and can't be used (reserved for empty log entry).
179  * Allowed values are in range [ 1 .. 15 ].
180  *
181  * @{
182  */
183 #define NRF_802154_LOG_TYPE_FUNCTION_ENTER 1U
184 #define NRF_802154_LOG_TYPE_FUNCTION_EXIT  2U
185 #define NRF_802154_LOG_TYPE_LOCAL_EVENT    3U
186 #define NRF_802154_LOG_TYPE_GLOBAL_EVENT   4U
187 /**
188  *@}
189  **/
190 
191 /**@brief Bit shift of field "log type" in log word. */
192 #define NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS      28
193 
194 /**@brief Bit shift of field "module id" in log word. */
195 #define NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS 22
196 
197 /**@brief Bit shift of field "event id" in log word. */
198 #define NRF_802154_SL_DEBUG_LOG_EVENT_ID_BITPOS  16
199 
200 /**@brief Records log about entry to a function.
201  *
202  * @param[in] verbosity     Verbosity level required to emit log.
203  */
204 #define nrf_802154_sl_log_function_enter(verbosity)                                             \
205     do                                                                                          \
206     {                                                                                           \
207         if (nrf_802154_sl_log_verbosity_allows(verbosity))                                      \
208         {                                                                                       \
209             nrf_802154_sl_debug_log_write_raw(                                                  \
210                 ((NRF_802154_LOG_TYPE_FUNCTION_ENTER) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \
211                 ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) |          \
212                 ((uint32_t)((uintptr_t)(__func__) & 0x000FFFFFUL) << 0));                       \
213         }                                                                                       \
214     }                                                                                           \
215     while (0)
216 
217 /**@brief Records log about exit from a function.
218  *
219  * @param[in] verbosity     Verbosity level required to emit log.
220  */
221 #define nrf_802154_sl_log_function_exit(verbosity)                                             \
222     do                                                                                         \
223     {                                                                                          \
224         if (nrf_802154_sl_log_verbosity_allows(verbosity))                                     \
225         {                                                                                      \
226             nrf_802154_sl_debug_log_write_raw(                                                 \
227                 ((NRF_802154_LOG_TYPE_FUNCTION_EXIT) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \
228                 ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) |         \
229                 ((uint32_t)((uintptr_t)(__func__) & 0x000FFFFFUL) << 0));                      \
230         }                                                                                      \
231     }                                                                                          \
232     while (0)
233 
234 /**@brief Records log about event (with parameter) related to current module.
235  *
236  * @param[in] verbosity         Verbosity level required to emit log.
237  * @param[in] local_event_id    Event identifier whose meaning is defined within the scope
238  *                              of the module. Possible values: [ 0 .. 63 ].
239  * @param[in] param_u16         Additional parameter to be logged with event. Meaning
240  *                              of the parameter is defined by the module in which
241  *                              the log is recorded and @p local_event_id.
242  */
243 #define nrf_802154_sl_log_local_event(verbosity, local_event_id, param_u16)                  \
244     do                                                                                       \
245     {                                                                                        \
246         if (nrf_802154_sl_log_verbosity_allows(verbosity))                                   \
247         {                                                                                    \
248             nrf_802154_sl_debug_log_write_raw(                                               \
249                 ((NRF_802154_LOG_TYPE_LOCAL_EVENT) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \
250                 ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) |       \
251                 (((uint32_t)(local_event_id)) << NRF_802154_SL_DEBUG_LOG_EVENT_ID_BITPOS) |  \
252                 ((uint16_t)(param_u16) << 0));                                               \
253         }                                                                                    \
254     }                                                                                        \
255     while (0)
256 
257 /**@brief Records log about event (with parameter) related to global resource.
258  *
259  * @param[in] verbosity     Verbosity level required to emit log.
260  * @param[in] event_id      Event identifier whose meaning is defined globally. Possible values: [ 0 .. 63 ].
261  * @param[in] param_u16     Additional parameter to be logged with event. Meaning
262  *                          of the parameter is defined by value of @p global_event_id.
263  */
264 #define nrf_802154_sl_log_global_event(verbosity, global_event_id, param_u16)                 \
265     do                                                                                        \
266     {                                                                                         \
267         if (nrf_802154_sl_log_verbosity_allows(verbosity))                                    \
268         {                                                                                     \
269             nrf_802154_sl_debug_log_write_raw(                                                \
270                 ((NRF_802154_LOG_TYPE_GLOBAL_EVENT) << NRF_802154_SL_DEBUG_LOG_TYPE_BITPOS) | \
271                 ((NRF_802154_MODULE_ID) << NRF_802154_SL_DEBUG_LOG_MODULE_ID_BITPOS) |        \
272                 (((uint32_t)(global_event_id)) << NRF_802154_SL_DEBUG_LOG_EVENT_ID_BITPOS) |  \
273                 ((uint16_t)(param_u16) << 0));                                                \
274         }                                                                                     \
275     }                                                                                         \
276     while (0)
277 
278 /**@brief Helper macro for defining one element of the list of local events.
279  *
280  * @param[in] module_lbl    name of module
281  * @param[in] event_lbl     name of local event
282  * @param[in] event_id      numeric id of local event (unique in module @c module_lbl)
283  * @param[in] event_enum    enum that defines the set of possible values of parameter
284                             for event @c event_lbl
285  */
286 #define NRF_802154_LOG_L_EVENT_DEFINE(module_lbl, event_lbl, event_id, event_enum) \
287     NRF_802154_LOG_LOCAL_EVENT_ID_ ## module_lbl ## __ ## event_lbl = event_id,    \
288     NRF_802154_LOG_LE ## event_id ## _PARAM_ENUM_ ## event_enum     = event_id,
289 
290 /**
291  * @brief Initializes the Debug Logs module.
292  *
293  */
294 void nrf_802154_sl_log_init(void);
295 
296 /**
297  *@}
298  **/
299 
300 #endif // NRF_802154_SL_LOG_H__
301