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