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 * If logging is disabled then element in the structure is still declared to avoid 141 * compilation issues. If compiler supports zero length arrays then it is utilized 142 * to not use any space, else a byte array is created. 143 * 144 * @param _name Name of a structure element that will have a pointer to logging 145 * instance object. 146 */ 147 #define LOG_INSTANCE_PTR_DECLARE(_name) \ 148 COND_CODE_1(CONFIG_LOG, (Z_LOG_INSTANCE_STRUCT * _name), \ 149 (int _name[TOOLCHAIN_HAS_ZLA ? 0 : 1])) 150 151 #define Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name) \ 152 STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \ 153 LOG_INSTANCE_DYNAMIC_DATA(_module_name, _inst_name)) 154 155 #define Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \ 156 Z_LOG_CONST_ITEM_REGISTER( \ 157 Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name), \ 158 STRINGIFY(_module_name._inst_name), \ 159 _level); \ 160 IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \ 161 (Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name))) 162 163 /** 164 * @brief Macro for registering instance for logging with independent filtering. 165 * 166 * Module instance provides filtering of logs on instance level instead of 167 * module level. Instance create using this macro can later on be used with 168 * @ref LOG_INSTANCE_PTR_INIT or referenced by @ref LOG_INSTANCE_PTR. 169 * 170 * @param _module_name Module name. 171 * @param _inst_name Instance name. 172 * @param _level Initial static filtering. 173 */ 174 #define LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \ 175 IF_ENABLED(CONFIG_LOG, (Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level))) 176 177 #ifdef __cplusplus 178 } 179 #endif 180 181 #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_ */ 182