/* * Copyright (c) 2018 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_ #define ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_ #include #include #ifdef __cplusplus extern "C" { #endif /** @brief Constant data associated with the source of log messages. */ struct log_source_const_data { const char *name; uint8_t level; #ifdef CONFIG_NIOS2 /* Workaround alert! Dummy data to ensure that structure is >8 bytes. * Nios2 uses global pointer register for structures <=8 bytes and * apparently does not handle well variables placed in custom sections. */ uint32_t dummy; #endif }; /** @brief Dynamic data associated with the source of log messages. */ struct log_source_dynamic_data { uint32_t filters; #ifdef CONFIG_NIOS2 /* Workaround alert! Dummy data to ensure that structure is >8 bytes. * Nios2 uses global pointer register for structures <=8 bytes and * apparently does not handle well variables placed in custom sections. */ uint32_t dummy[2]; #endif #if defined(CONFIG_64BIT) /* Workaround: Ensure that structure size is a multiple of 8 bytes. */ uint32_t dummy_64; #endif }; /** @internal * * Creates name of variable and section for constant log data. * * @param _name Name. */ #define Z_LOG_ITEM_CONST_DATA(_name) UTIL_CAT(log_const_, _name) /** @internal * * Create static logging instance in read only memory. * * @param _name name of the module. With added prefix forms name of variable and * memory section. * * @param _str_name Name of the module that will be used when message is formatted. * * @param _level Messages up to this level are compiled in. */ #define Z_LOG_CONST_ITEM_REGISTER(_name, _str_name, _level) \ const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const, \ log_source_const_data, \ Z_LOG_ITEM_CONST_DATA(_name)) = \ { \ .name = _str_name, \ .level = (_level), \ } /** @brief Initialize pointer to logger instance with explicitly provided object. * * Macro can be used to initialized a pointer with object that is not unique to * the given instance, thus not created with @ref LOG_INSTANCE_REGISTER. * * @param _name Name of the structure element for holding logging object. * @param _object Pointer to a logging instance object. */ #define LOG_OBJECT_PTR_INIT(_name, _object) \ IF_ENABLED(CONFIG_LOG, (._name = _object,)) /** @internal * * Create a name for which contains module and instance names. */ #define Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name) \ UTIL_CAT(_module_name, UTIL_CAT(_, _inst_name)) /** @internal * * Returns a pointer associated with given logging instance. When runtime filtering * is enabled then dynamic instance is returned. * * @param _name Name of the instance. * * @return Pointer to the instance object (static or dynamic). */ #define Z_LOG_OBJECT_PTR(_name) \ COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, \ (&LOG_ITEM_DYNAMIC_DATA(_name)), \ (&Z_LOG_ITEM_CONST_DATA(_name))) \ /** @brief Get pointer to a logging instance. * * Instance is identified by @p _module_name and @p _inst_name. * * @param _module_name Module name. * @param _inst_name Instance name. * * @return Pointer to a logging instance. */ #define LOG_INSTANCE_PTR(_module_name, _inst_name) \ Z_LOG_OBJECT_PTR(Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name)) /** @brief Macro for initializing a pointer to the logger instance. * * @p _module_name and @p _inst_name are concatenated to form a name of the object. * * Macro is intended to be used in user structure initializer to initialize a field * in the structure that holds pointer to the logging instance. Structure field * should be declared using @p LOG_INSTANCE_PTR_DECLARE. * * @param _name Name of a structure element that have a pointer to logging instance object. * @param _module_name Module name. * @param _inst_name Instance name. */ #define LOG_INSTANCE_PTR_INIT(_name, _module_name, _inst_name) \ LOG_OBJECT_PTR_INIT(_name, LOG_INSTANCE_PTR(_module_name, _inst_name)) #define Z_LOG_INSTANCE_STRUCT \ COND_CODE_1(CONFIG_LOG_RUNTIME_FILTERING, \ (struct log_source_dynamic_data), \ (const struct log_source_const_data)) /** * @brief Declare a logger instance pointer in the module structure. * * If logging is disabled then element in the structure is still declared to avoid * compilation issues. If compiler supports zero length arrays then it is utilized * to not use any space, else a byte array is created. * * @param _name Name of a structure element that will have a pointer to logging * instance object. */ #define LOG_INSTANCE_PTR_DECLARE(_name) \ COND_CODE_1(CONFIG_LOG, (Z_LOG_INSTANCE_STRUCT * _name), \ (int _name[TOOLCHAIN_HAS_ZLA ? 0 : 1])) #define Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name) \ STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \ LOG_INSTANCE_DYNAMIC_DATA(_module_name, _inst_name)) #define Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \ Z_LOG_CONST_ITEM_REGISTER( \ Z_LOG_INSTANCE_FULL_NAME(_module_name, _inst_name), \ STRINGIFY(_module_name._inst_name), \ _level); \ IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \ (Z_LOG_RUNTIME_INSTANCE_REGISTER(_module_name, _inst_name))) /** * @brief Macro for registering instance for logging with independent filtering. * * Module instance provides filtering of logs on instance level instead of * module level. Instance create using this macro can later on be used with * @ref LOG_INSTANCE_PTR_INIT or referenced by @ref LOG_INSTANCE_PTR. * * @param _module_name Module name. * @param _inst_name Instance name. * @param _level Initial static filtering. */ #define LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level) \ IF_ENABLED(CONFIG_LOG, (Z_LOG_INSTANCE_REGISTER(_module_name, _inst_name, _level))) #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_INSTANCE_H_ */