logging: Remove logging v1 from the logging

Remove v1 implementation from log_core and all references in the tree.
Remove modules used by v1: log_list and log_msg.
Remove Kconfig v1 specific options.
Remove Kconfig flags used for distinction between v1 and v2.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2022-06-15 07:46:35 +02:00 committed by Anas Nashif
commit c5f2cdef09
59 changed files with 108 additions and 3606 deletions

View file

@ -123,9 +123,6 @@ allocated.
:kconfig:option:`CONFIG_LOG_PRINTK`: Redirect printk calls to the logging.
:kconfig:option:`CONFIG_LOG_PRINTK_MAX_STRING_LENGTH`: Maximal string length that can
be processed by printk. Longer strings are trimmed.
:kconfig:option:`CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD`: When number of buffered log
messages reaches the threshold dedicated thread (see :c:func:`log_thread_set`)
is waken up. If :kconfig:option:`CONFIG_LOG_PROCESS_THREAD` is enabled then this
@ -140,20 +137,11 @@ after which logging thread is started.
:kconfig:option:`CONFIG_LOG_BUFFER_SIZE`: Number of bytes dedicated for the circular
packet buffer.
:kconfig:option:`CONFIG_LOG_DETECT_MISSED_STRDUP`: Enable detection of missed transient
strings handling.
:kconfig:option:`CONFIG_LOG_STRDUP_MAX_STRING`: Longest string that can be duplicated
using log_strdup().
:kconfig:option:`CONFIG_LOG_STRDUP_BUF_COUNT`: Number of buffers in the pool used by
log_strdup().
:kconfig:option:`CONFIG_LOG_DOMAIN_ID`: Domain ID. Valid in multi-domain systems.
:kconfig:option`CONFIG_LOG_FRONTEND`: Direct logs to a custom frontend.
:kconfig:option:`CONFIG_LOG_FRONTEND`: Direct logs to a custom frontend.
:kconfig:option`CONFIG_LOG_FRONTEND_ONLY`: No backends are used when messages goes to frontend.
:kconfig:option:`CONFIG_LOG_FRONTEND_ONLY`: No backends are used when messages goes to frontend.
:kconfig:option:`CONFIG_LOG_TIMESTAMP_64BIT`: 64 bit timestamp.

View file

@ -259,41 +259,17 @@ extern "C" {
* printk functionality.
*
* It is less efficient compared to standard logging because static packaging
* cannot be used. When CONFIG_LOG1 is used string formatting is performed in the
* call context and not deferred to the log processing context (@ref log_process).
* cannot be used.
*
* @param fmt Formatted string to output.
* @param ap Variable parameters.
*/
void z_log_vprintk(const char *fmt, va_list ap);
/** @brief Copy transient string to a buffer from internal, logger pool.
*
* Function should be used when transient string is intended to be logged.
* Logger allocates a buffer and copies input string returning a pointer to the
* copy. Logger ensures that buffer is freed when logger message is freed.
*
* Depending on configuration, this function may do nothing and just pass
* along the supplied string pointer. Do not rely on this function to always
* make a copy!
*
* @param str Transient string.
*
* @return Copy of the string or default string if buffer could not be
* allocated. String may be truncated if input string does not fit in
* a buffer from the pool (see CONFIG_LOG_STRDUP_MAX_STRING). In
* some configurations, the original string pointer is returned.
*/
char *z_log_strdup(const char *str);
/** @brief Deprecated. */
static inline char *log_strdup(const char *str)
{
if (IS_ENABLED(CONFIG_LOG_MODE_MINIMAL) ||
IS_ENABLED(CONFIG_LOG_FRONTEND) ||
IS_ENABLED(CONFIG_LOG2)) {
return (char *)str;
}
return z_log_strdup(str);
return (char *)str;
}
#ifdef __cplusplus

View file

@ -6,7 +6,6 @@
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_BACKEND_H_
#define ZEPHYR_INCLUDE_LOGGING_LOG_BACKEND_H_
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_msg2.h>
#include <stdarg.h>
#include <zephyr/sys/__assert.h>
@ -31,21 +30,9 @@ struct log_backend;
* @brief Logger backend API.
*/
struct log_backend_api {
/* Logging v2 function. */
void (*process)(const struct log_backend *const backend,
union log_msg2_generic *msg);
/* DEPRECATED! Functions used for logging v1. */
void (*put)(const struct log_backend *const backend,
struct log_msg *msg);
void (*put_sync_string)(const struct log_backend *const backend,
struct log_msg_ids src_level, uint32_t timestamp,
const char *fmt, va_list ap);
void (*put_sync_hexdump)(const struct log_backend *const backend,
struct log_msg_ids src_level, uint32_t timestamp,
const char *metadata, const uint8_t *data, uint32_t len);
/* Functions used by v1 and v2 */
void (*dropped)(const struct log_backend *const backend, uint32_t cnt);
void (*panic)(const struct log_backend *const backend);
void (*init)(const struct log_backend *const backend);
@ -141,22 +128,6 @@ static inline int log_backend_is_ready(const struct log_backend *const backend)
return 0;
}
/**
* @brief Put message with log entry to the backend.
*
* @warning DEPRECATED. Use logging v2.
*
* @param[in] backend Pointer to the backend instance.
* @param[in] msg Pointer to message with log entry.
*/
static inline void log_backend_put(const struct log_backend *const backend,
struct log_msg *msg)
{
__ASSERT_NO_MSG(backend != NULL);
__ASSERT_NO_MSG(msg != NULL);
backend->api->put(backend, msg);
}
/**
* @brief Process message.
*
@ -175,58 +146,6 @@ static inline void log_backend_msg2_process(
backend->api->process(backend, msg);
}
/**
* @brief Synchronously process log message.
*
* @warning DEPRECATED. Use logging v2.
*
* @param[in] backend Pointer to the backend instance.
* @param[in] src_level Message details.
* @param[in] timestamp Timestamp.
* @param[in] fmt Log string.
* @param[in] ap Log string arguments.
*/
static inline void log_backend_put_sync_string(
const struct log_backend *const backend,
struct log_msg_ids src_level,
uint32_t timestamp, const char *fmt,
va_list ap)
{
__ASSERT_NO_MSG(backend != NULL);
if (backend->api->put_sync_string) {
backend->api->put_sync_string(backend, src_level,
timestamp, fmt, ap);
}
}
/**
* @brief Synchronously process log hexdump_message.
*
* @warning DEPRECATED. Use logging v2.
*
* @param[in] backend Pointer to the backend instance.
* @param[in] src_level Message details.
* @param[in] timestamp Timestamp.
* @param[in] metadata Raw string associated with the data.
* @param[in] data Data.
* @param[in] len Data length.
*/
static inline void log_backend_put_sync_hexdump(
const struct log_backend *const backend,
struct log_msg_ids src_level,
uint32_t timestamp, const char *metadata,
const uint8_t *data, uint32_t len)
{
__ASSERT_NO_MSG(backend != NULL);
if (backend->api->put_sync_hexdump) {
backend->api->put_sync_hexdump(backend, src_level, timestamp,
metadata, data, len);
}
}
/**
* @brief Notify backend about dropped log messages.
*
@ -347,7 +266,6 @@ static inline bool log_backend_is_active(
return backend->cb->active;
}
#ifndef CONFIG_LOG1
/** @brief Set logging format.
*
* @param backend Pointer to the backend instance.
@ -379,7 +297,6 @@ static inline int log_backend_format_set(const struct log_backend *backend, uint
return backend->api->format_set(backend, log_type);
}
#endif
/**
* @}

View file

@ -6,7 +6,7 @@
#ifndef ZEPHYR_LOG_BACKEND_STD_H_
#define ZEPHYR_LOG_BACKEND_STD_H_
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_msg2.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/kernel.h>
@ -36,25 +36,6 @@ static inline uint32_t log_backend_std_get_flags(void)
return flags;
}
/** @brief Put log message to a standard logger backend.
*
* @param output Log output instance.
* @param flags Formatting flags.
* @param msg Log message.
*/
static inline void
log_backend_std_put(const struct log_output *const output, uint32_t flags,
struct log_msg *msg)
{
log_msg_get(msg);
flags |= log_backend_std_get_flags();
log_output_msg_process(output, msg, flags);
log_msg_put(msg);
}
/** @brief Put a standard logger backend into panic mode.
*
* @param output Log output instance.
@ -76,87 +57,6 @@ log_backend_std_dropped(const struct log_output *const output, uint32_t cnt)
log_output_dropped_process(output, cnt);
}
/** @brief Synchronously process log message by a standard logger backend.
*
* @param output Log output instance.
* @param flags Formatting flags.
* @param src_level Log message source and level.
* @param timestamp Timestamp.
* @param fmt Log string.
* @param ap Log string arguments.
*/
static inline void
log_backend_std_sync_string(const struct log_output *const output,
uint32_t flags, struct log_msg_ids src_level,
uint32_t timestamp, const char *fmt, va_list ap)
{
int key;
flags |= LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP;
if (IS_ENABLED(CONFIG_LOG_BACKEND_SHOW_COLOR)) {
flags |= LOG_OUTPUT_FLAG_COLORS;
}
if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) {
flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
}
if (IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
/* In order to ensure that one log processing is not interrupted
* by another one, lock context for whole log processing.
*/
key = irq_lock();
}
log_output_string(output, src_level, timestamp, fmt, ap, flags);
if (IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
irq_unlock(key);
}
}
/** @brief Synchronously process hexdump message by a standard logger backend.
*
* @param output Log output instance.
* @param flags Formatting flags.
* @param src_level Log message source and level.
* @param timestamp Timestamp.
* @param metadata String associated with a hexdump.
* @param data Buffer to dump.
* @param length Length of the buffer.
*/
static inline void
log_backend_std_sync_hexdump(const struct log_output *const output,
uint32_t flags, struct log_msg_ids src_level,
uint32_t timestamp, const char *metadata,
const uint8_t *data, uint32_t length)
{
int key;
flags |= LOG_OUTPUT_FLAG_LEVEL | LOG_OUTPUT_FLAG_TIMESTAMP;
if (IS_ENABLED(CONFIG_LOG_BACKEND_SHOW_COLOR)) {
flags |= LOG_OUTPUT_FLAG_COLORS;
}
if (IS_ENABLED(CONFIG_LOG_BACKEND_FORMAT_TIMESTAMP)) {
flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
}
if (IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
/* In order to ensure that one log processing is not interrupted
* by another one, lock context for whole log processing.
*/
key = irq_lock();
}
log_output_hexdump(output, src_level, timestamp,
metadata, data, length, flags);
if (IS_ENABLED(CONFIG_LOG_IMMEDIATE_CLEAN_OUTPUT)) {
irq_unlock(key);
}
}
/**
* @}
*/

View file

@ -6,13 +6,11 @@
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_CORE_H_
#define ZEPHYR_INCLUDE_LOGGING_LOG_CORE_H_
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_msg2.h>
#include <zephyr/logging/log_instance.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdarg.h>
#include <zephyr/syscall.h>
#include <zephyr/sys/util.h>
/* This header file keeps all macros and functions needed for creating logging
@ -96,22 +94,6 @@ extern "C" {
#define _LOG_ZZZZ4 _LOG_YYYY,
#define _LOG_ZZZZ4U _LOG_YYYY,
/** @brief Macro for getting log level for given module.
*
* It is evaluated to LOG_LEVEL if defined. Otherwise CONFIG_LOG_DEFAULT_LEVEL
* is used.
*/
#define _LOG_LEVEL() Z_LOG_RESOLVED_LEVEL(LOG_LEVEL, CONFIG_LOG_DEFAULT_LEVEL)
/**
* @def LOG_CONST_ID_GET
* @brief Macro for getting ID of the element of the section.
*
* @param _addr Address of the element.
*/
#define LOG_CONST_ID_GET(_addr) \
COND_CODE_1(CONFIG_LOG, ((__log_level ? log_const_source_id(_addr) : 0)), (0))
/**
* @def LOG_CURRENT_MODULE_ID
* @brief Macro for getting ID of current module.
@ -119,20 +101,6 @@ extern "C" {
#define LOG_CURRENT_MODULE_ID() (__log_level != 0 ? \
log_const_source_id(__log_current_const_data) : 0U)
/**
* @def LOG_CURRENT_DYNAMIC_DATA_ADDR
* @brief Macro for getting address of dynamic structure of current module.
*/
#define LOG_CURRENT_DYNAMIC_DATA_ADDR() (__log_level ? \
__log_current_dynamic_data : (struct log_source_dynamic_data *)0U)
/** @brief Macro for getting ID of the element of the section.
*
* @param _addr Address of the element.
*/
#define LOG_DYNAMIC_ID_GET(_addr) \
COND_CODE_1(CONFIG_LOG, ((__log_level ? log_dynamic_source_id(_addr) : 0)), (0))
/* Set of defines that are set to 1 if function name prefix is enabled for given level. */
#define Z_LOG_FUNC_PREFIX_0U 0
#define Z_LOG_FUNC_PREFIX_1U COND_CODE_1(CONFIG_LOG_FUNC_NAME_PREFIX_ERR, (1), (0))
@ -173,80 +141,6 @@ extern "C" {
COND_CODE_1(UTIL_CAT(Z_LOG_FUNC_PREFIX_##_level), \
(Z_LOG_STR_WITH_PREFIX(__VA_ARGS__)), (__VA_ARGS__))
/******************************************************************************/
/****************** Internal macros for log frontend **************************/
/******************************************************************************/
/**@brief Second stage for Z_LOG_NARGS_POSTFIX */
#define Z_LOG_NARGS_POSTFIX_IMPL( \
_ignored, \
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, \
_22, _23, _24, _25, _26, _27, _28, _29, _30, _31, N, ...) N
/**@brief Macro to get the postfix for further log message processing.
*
* Logs with more than 3 arguments are processed in a generic way.
*
* param[in] ... List of arguments
*
* @retval Postfix, number of arguments or _LONG when more than 3 arguments.
*/
#define Z_LOG_NARGS_POSTFIX(...) \
Z_LOG_NARGS_POSTFIX_IMPL(__VA_ARGS__, LONG, LONG, LONG, LONG, LONG, \
LONG, LONG, LONG, LONG, LONG, LONG, LONG, LONG, LONG, \
LONG, LONG, LONG, LONG, LONG, LONG, LONG, LONG, LONG, \
LONG, LONG, LONG, LONG, LONG, LONG, 3, 2, 1, 0, ~)
#define Z_LOG_INTERNAL_X(N, ...) UTIL_CAT(_LOG_INTERNAL_, N)(__VA_ARGS__)
#define Z_LOG_INTERNAL2(is_user_context, _src_level, ...) do { \
if (is_user_context) { \
if (!IS_ENABLED(CONFIG_LOG_FRONTEND)) { \
log_from_user(_src_level, __VA_ARGS__); \
} \
} else if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) { \
log_string_sync(_src_level, __VA_ARGS__); \
} else { \
Z_LOG_INTERNAL_X(Z_LOG_NARGS_POSTFIX(__VA_ARGS__), \
_src_level, __VA_ARGS__); \
} \
} while (false)
#define Z_LOG_INTERNAL(is_user_context, _level, _source, _dsource, ...) do { \
uint16_t src_id = \
IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
LOG_DYNAMIC_ID_GET(_dsource) : LOG_CONST_ID_GET(_source); \
struct log_msg_ids src_level = { \
.level = _level, \
.domain_id = CONFIG_LOG_DOMAIN_ID, \
.source_id = src_id \
}; \
Z_LOG_INTERNAL2(is_user_context, src_level, \
Z_LOG_STR(_level, __VA_ARGS__)); \
} while (0)
#define _LOG_INTERNAL_0(_src_level, _str) \
log_0(_str, _src_level)
#define _LOG_INTERNAL_1(_src_level, _str, _arg0) \
log_1(_str, (log_arg_t)(_arg0), _src_level)
#define _LOG_INTERNAL_2(_src_level, _str, _arg0, _arg1) \
log_2(_str, (log_arg_t)(_arg0), (log_arg_t)(_arg1), _src_level)
#define _LOG_INTERNAL_3(_src_level, _str, _arg0, _arg1, _arg2) \
log_3(_str, (log_arg_t)(_arg0), (log_arg_t)(_arg1), (log_arg_t)(_arg2), _src_level)
#define __LOG_ARG_CAST(_x) (log_arg_t)(_x)
#define __LOG_ARGUMENTS(...) FOR_EACH(__LOG_ARG_CAST, (,), __VA_ARGS__)
#define _LOG_INTERNAL_LONG(_src_level, _str, ...) \
do { \
log_arg_t args[] = {__LOG_ARGUMENTS(__VA_ARGS__)};\
log_n(_str, args, ARRAY_SIZE(args), _src_level); \
} while (false)
#define Z_LOG_LEVEL_CHECK(_level, _check_level, _default_level) \
(_level <= Z_LOG_RESOLVED_LEVEL(_check_level, _default_level))
@ -340,17 +234,12 @@ static inline char z_log_minimal_level_to_char(int level)
!is_user_context && _level > Z_LOG_RUNTIME_FILTER(filters)) { \
break; \
} \
if (IS_ENABLED(CONFIG_LOG2)) { \
int _mode; \
void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
(void *)_dsource : (void *)_source; \
Z_LOG_MSG2_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), _mode, \
CONFIG_LOG_DOMAIN_ID, _src, _level, NULL,\
0, __VA_ARGS__); \
} else { \
Z_LOG_INTERNAL(is_user_context, _level, \
_source, _dsource, __VA_ARGS__);\
} \
int _mode; \
void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
(void *)_dsource : (void *)_source; \
Z_LOG_MSG2_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), _mode, \
CONFIG_LOG_DOMAIN_ID, _src, _level, NULL,\
0, __VA_ARGS__); \
if (false) { \
/* Arguments checker present but never evaluated.*/ \
/* Placed here to ensure that __VA_ARGS__ are*/ \
@ -420,36 +309,16 @@ static inline char z_log_minimal_level_to_char(int level)
!is_user_context && _level > Z_LOG_RUNTIME_FILTER(filters)) { \
break; \
} \
if (IS_ENABLED(CONFIG_LOG2)) { \
int mode; \
void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
(void *)_dsource : (void *)_source; \
Z_LOG_MSG2_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), mode, \
CONFIG_LOG_DOMAIN_ID, _src, _level, \
_data, _len, \
COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
(), \
(COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
("%s", __VA_ARGS__), (__VA_ARGS__)))));\
break; \
} \
uint16_t src_id = \
IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
LOG_DYNAMIC_ID_GET(_dsource) : LOG_CONST_ID_GET(_source);\
struct log_msg_ids src_level = { \
.level = _level, \
.domain_id = CONFIG_LOG_DOMAIN_ID, \
.source_id = src_id, \
}; \
if (is_user_context) { \
if (!IS_ENABLED(CONFIG_LOG_FRONTEND)) { \
log_hexdump_from_user(src_level, _str, (const char *)_data, _len); \
} \
} else if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) { \
log_hexdump_sync(src_level, _str, (const char *)_data, _len); \
} else { \
log_hexdump(_str, (const char *)_data, _len, src_level); \
} \
int mode; \
void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
(void *)_dsource : (void *)_source; \
Z_LOG_MSG2_CREATE(UTIL_NOT(IS_ENABLED(CONFIG_USERSPACE)), mode, \
CONFIG_LOG_DOMAIN_ID, _src, _level, \
_data, _len, \
COND_CODE_0(NUM_VA_ARGS_LESS_1(_, ##__VA_ARGS__), \
(), \
(COND_CODE_0(NUM_VA_ARGS_LESS_1(__VA_ARGS__), \
("%s", __VA_ARGS__), (__VA_ARGS__)))));\
} while (false)
#define Z_LOG_HEXDUMP(_level, _data, _length, ...) \
@ -521,15 +390,8 @@ static inline char z_log_minimal_level_to_char(int level)
extern struct log_source_const_data __log_const_start[];
extern struct log_source_const_data __log_const_end[];
/** @brief Enum with possible actions for strdup operation. */
enum log_strdup_action {
LOG_STRDUP_SKIP, /**< None RAM string duplication. */
LOG_STRDUP_EXEC, /**< Always duplicate RAM strings. */
LOG_STRDUP_CHECK_EXEC/**< Duplicate RAM strings, if not dupl. before.*/
};
#define Z_LOG_PRINTK(...) do { \
if (IS_ENABLED(CONFIG_LOG_MODE_MINIMAL) || !IS_ENABLED(CONFIG_LOG2)) { \
if (IS_ENABLED(CONFIG_LOG_MODE_MINIMAL)) { \
z_log_minimal_printk(__VA_ARGS__); \
break; \
} \
@ -588,102 +450,6 @@ void z_log_printf_arg_checker(const char *fmt, ...)
ARG_UNUSED(fmt);
}
/** @brief Standard log with no arguments.
*
* @param str String.
* @param src_level Log identification.
*/
void log_0(const char *str, struct log_msg_ids src_level);
/** @brief Standard log with one argument.
*
* @param str String.
* @param arg1 First argument.
* @param src_level Log identification.
*/
void log_1(const char *str,
log_arg_t arg1,
struct log_msg_ids src_level);
/** @brief Standard log with two arguments.
*
* @param str String.
* @param arg1 First argument.
* @param arg2 Second argument.
* @param src_level Log identification.
*/
void log_2(const char *str,
log_arg_t arg1,
log_arg_t arg2,
struct log_msg_ids src_level);
/** @brief Standard log with three arguments.
*
* @param str String.
* @param arg1 First argument.
* @param arg2 Second argument.
* @param arg3 Third argument.
* @param src_level Log identification.
*/
void log_3(const char *str,
log_arg_t arg1,
log_arg_t arg2,
log_arg_t arg3,
struct log_msg_ids src_level);
/** @brief Standard log with arguments list.
*
* @param str String.
* @param args Array with arguments.
* @param narg Number of arguments in the array.
* @param src_level Log identification.
*/
void log_n(const char *str,
log_arg_t *args,
uint32_t narg,
struct log_msg_ids src_level);
/** @brief Hexdump log.
*
* @param str String.
* @param data Data.
* @param length Data length.
* @param src_level Log identification.
*/
void log_hexdump(const char *str, const void *data, uint32_t length,
struct log_msg_ids src_level);
/** @brief Process log message synchronously.
*
* @param src_level Log message details.
* @param fmt String to format.
* @param ... Variable list of arguments.
*/
void log_string_sync(struct log_msg_ids src_level, const char *fmt, ...);
/** @brief Process log hexdump message synchronously.
*
* @param src_level Log message details.
* @param metadata Raw string associated with the data.
* @param data Data.
* @param len Data length.
*/
void log_hexdump_sync(struct log_msg_ids src_level, const char *metadata,
const void *data, uint32_t len);
/**
* @brief Writes a generic log message to the log.
*
* @note This function is intended to be used when porting other log systems.
*
* @param src_level Log identification.
* @param fmt String to format.
* @param ap Pointer to arguments list.
* @param strdup_action Manages strdup activity.
*/
void log_generic(struct log_msg_ids src_level, const char *fmt, va_list ap,
enum log_strdup_action strdup_action);
/**
* @brief Writes a generic log message to the logging v2.
*
@ -699,207 +465,6 @@ static inline void log2_generic(uint8_t level, const char *fmt, va_list ap)
NULL, 0, 0, fmt, ap);
}
/**
* @brief Returns number of arguments visible from format string.
*
* @note This function is intended to be used when porting other log systems.
*
* @param fmt Format string.
*
* @return Number of arguments.
*/
uint32_t log_count_args(const char *fmt);
/**
* @brief Writes a generic log message to the log from user mode.
*
* @note This function is intended to be used internally
* by the logging subsystem.
*/
void log_generic_from_user(struct log_msg_ids src_level,
const char *fmt, va_list ap);
/** @brief Check if address belongs to the memory pool used for transient.
*
* @param buf Buffer.
*
* @return True if address within the pool, false otherwise.
*/
bool log_is_strdup(const void *buf);
/** @brief Log a message from user mode context.
*
* @note This function is intended to be used internally
* by the logging subsystem.
*
* @param src_level Log identification.
* @param fmt String to format.
* @param ... Variable list of arguments.
*/
void __printf_like(2, 3) log_from_user(struct log_msg_ids src_level,
const char *fmt, ...);
/* Internal function used by log_from_user(). */
__syscall void z_log_string_from_user(uint32_t src_level_val, const char *str);
/**
* @brief Create mask with occurrences of a string format specifiers (%s).
*
* Result is stored as the mask (argument n is n'th bit). Bit is set if string
* format specifier was found.
*
* @param str String.
* @param nargs Number of arguments in the string.
*
* @return Mask with %s format specifiers found.
*/
uint32_t z_log_get_s_mask(const char *str, uint32_t nargs);
/** @brief Log binary data (displayed as hexdump) from user mode context.
*
* @note This function is intended to be used internally
* by the logging subsystem.
*
* @param src_level Log identification.
* @param metadata Raw string associated with the data.
* @param data Data.
* @param len Data length.
*/
void log_hexdump_from_user(struct log_msg_ids src_level, const char *metadata,
const void *data, uint32_t len);
/* Internal function used by log_hexdump_from_user(). */
__syscall void z_log_hexdump_from_user(uint32_t src_level_val,
const char *metadata,
const uint8_t *data, uint32_t len);
/******************************************************************************/
/********** Macros _VA operate on var-args parameters. ***************/
/********* Intended to be used when porting other log systems. ***************/
/********* Shall be used in the log entry interface function. ***************/
/********* Speed optimized for up to three arguments number. ***************/
/******************************************************************************/
#define Z_LOG_VA(_level, _str, _valist, _argnum, _strdup_action)\
__LOG_VA(_level, \
__log_current_const_data, \
__log_current_dynamic_data, \
_str, _valist, _argnum, _strdup_action)
#define __LOG_VA(_level, _source, _dsource, _str, _valist, _argnum, _strdup_action) do { \
if (!Z_LOG_CONST_LEVEL_CHECK(_level)) { \
break; \
} \
if (IS_ENABLED(CONFIG_LOG_MODE_MINIMAL)) { \
Z_LOG_TO_VPRINTK(_level, _str, _valist); \
break; \
} \
\
bool is_user_context = k_is_user_context(); \
uint32_t filters = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
_dsource->filters : 0;\
if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && !is_user_context && \
_level > Z_LOG_RUNTIME_FILTER(filters)) { \
break; \
} \
if (IS_ENABLED(CONFIG_LOG2)) { \
void *_src = IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
(void *)_dsource : (void *)_source; \
z_log_msg2_runtime_vcreate(CONFIG_LOG_DOMAIN_ID, _src, \
_level, NULL, 0, 0, _str, _valist); \
break; \
} \
uint16_t _id = \
IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) ? \
LOG_DYNAMIC_ID_GET(_dsource) : LOG_CONST_ID_GET(_source);\
struct log_msg_ids src_level = { \
.level = _level, \
.domain_id = CONFIG_LOG_DOMAIN_ID, \
.source_id = _id \
}; \
__LOG_INTERNAL_VA(is_user_context, \
src_level, \
_str, _valist, _argnum, \
_strdup_action); \
} while (false)
/**
* @brief Inline function to perform strdup, used in __LOG_INTERNAL_VA macro
*
* @note This function is intended to be used when porting other log systems.
*
* @param msk Bitmask marking all %s arguments.
* @param idx Index of actually processed argument.
* @param param Value of actually processed argument.
* @param action Action for strdup operation.
*
* @return Duplicated string or not changed param.
*/
static inline log_arg_t z_log_do_strdup(uint32_t msk, uint32_t idx,
log_arg_t param,
enum log_strdup_action action)
{
#ifndef CONFIG_LOG_MODE_MINIMAL
char *z_log_strdup(const char *str);
if (msk & (1 << idx)) {
const char *str = (const char *)param;
/* is_rodata(str) is not checked,
* because log_strdup does it.
* Hence, we will do only optional check
* if already not duplicated.
*/
if (action == LOG_STRDUP_EXEC || !log_is_strdup(str)) {
param = (log_arg_t)z_log_strdup(str);
}
}
#else
ARG_UNUSED(msk);
ARG_UNUSED(idx);
ARG_UNUSED(action);
#endif
return param;
}
#define __LOG_INTERNAL_VA(is_user_context, _src_level, _str, _valist, \
_argnum, _strdup_action) \
do { \
if (is_user_context) { \
log_generic_from_user(_src_level, _str, _valist); \
} else if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) { \
log_generic(_src_level, _str, _valist, _strdup_action); \
} else if (_argnum == 0) { \
_LOG_INTERNAL_0(_src_level, _str); \
} else { \
uint32_t mask = (_strdup_action != LOG_STRDUP_SKIP) ? \
z_log_get_s_mask(_str, _argnum) \
: 0; \
\
if (_argnum == 1) { \
_LOG_INTERNAL_1(_src_level, _str, \
z_log_do_strdup(mask, 0, \
va_arg(_valist, log_arg_t), _strdup_action));\
} else if (_argnum == 2) { \
_LOG_INTERNAL_2(_src_level, _str, \
z_log_do_strdup(mask, 0, \
va_arg(_valist, log_arg_t), _strdup_action), \
z_log_do_strdup(mask, 1, \
va_arg(_valist, log_arg_t), _strdup_action));\
} else if (_argnum == 3) { \
_LOG_INTERNAL_3(_src_level, _str, \
z_log_do_strdup(mask, 0, \
va_arg(_valist, log_arg_t), _strdup_action), \
z_log_do_strdup(mask, 1, \
va_arg(_valist, log_arg_t), _strdup_action), \
z_log_do_strdup(mask, 2, \
va_arg(_valist, log_arg_t), _strdup_action));\
} else { \
log_generic(_src_level, _str, _valist, _strdup_action);\
} \
} \
} while (false)
#include <syscalls/log_core.h>
#ifdef __cplusplus
}
#endif

View file

@ -8,7 +8,7 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_msg2.h>
#include <zephyr/logging/log_internal.h>
#ifdef __cplusplus
@ -82,12 +82,10 @@ __syscall void log_panic(void);
/**
* @brief Process one pending log message.
*
* @param bypass If true message is released without being processed.
*
* @retval true There is more messages pending to be processed.
* @retval false No messages pending.
*/
__syscall bool log_process(bool bypass);
__syscall bool log_process(void);
/**
* @brief Return number of buffered log messages.
@ -218,12 +216,7 @@ uint32_t log_get_strdup_longest_string(void);
*/
static inline bool log_data_pending(void)
{
if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED)) {
return IS_ENABLED(CONFIG_LOG2) ?
z_log_msg2_pending() : (log_msg_mem_get_used() > 0);
}
return false;
return IS_ENABLED(CONFIG_LOG_MODE_DEFERRED) ? z_log_msg2_pending() : false;
}
/**
@ -271,7 +264,7 @@ int log_mem_get_max_usage(uint32_t *max);
#define LOG_PROCESS() false
#else /* !CONFIG_LOG_FRONTEND_ONLY */
#define LOG_INIT() log_init()
#define LOG_PROCESS() log_process(false)
#define LOG_PROCESS() log_process()
#endif /* !CONFIG_LOG_FRONTEND_ONLY */
#else
#define LOG_CORE_INIT() do { } while (false)

View file

@ -12,73 +12,6 @@
*/
void log_frontend_init(void);
/** @brief Standard log with no arguments.
*
* @param str String.
* @param src_level Log identification.
*/
void log_frontend_0(const char *str, struct log_msg_ids src_level);
/** @brief Standard log with one argument.
*
* @param str String.
* @param arg0 First argument.
* @param src_level Log identification.
*/
void log_frontend_1(const char *str,
log_arg_t arg0,
struct log_msg_ids src_level);
/** @brief Standard log with two arguments.
*
* @param str String.
* @param arg0 First argument.
* @param arg1 Second argument.
* @param src_level Log identification.
*/
void log_frontend_2(const char *str,
log_arg_t arg0,
log_arg_t arg1,
struct log_msg_ids src_level);
/** @brief Standard log with three arguments.
*
* @param str String.
* @param arg0 First argument.
* @param arg1 Second argument.
* @param arg2 Third argument.
* @param src_level Log identification.
*/
void log_frontend_3(const char *str,
log_arg_t arg0,
log_arg_t arg1,
log_arg_t arg2,
struct log_msg_ids src_level);
/** @brief Standard log with arguments list.
*
* @param str String.
* @param args Array with arguments.
* @param narg Number of arguments in the array.
* @param src_level Log identification.
*/
void log_frontend_n(const char *str,
log_arg_t *args,
uint32_t narg,
struct log_msg_ids src_level);
/** @brief Hexdump log.
*
* @param str String.
* @param data Data.
* @param length Data length.
* @param src_level Log identification.
*/
void log_frontend_hexdump(const char *str,
const uint8_t *data,
uint32_t length,
struct log_msg_ids src_level);
/** @brief Log message.
*
* Message details does not contain timestamp. Since function is called in the

View file

@ -1,499 +0,0 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_MSG_H_
#define ZEPHYR_INCLUDE_LOGGING_LOG_MSG_H_
#include <zephyr/sys/atomic.h>
#include <zephyr/sys/util.h>
#include <string.h>
#include <zephyr/logging/log_msg2.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Log message API
* @defgroup log_msg Log message API
* @ingroup logger
* @{
*/
/** @brief Log argument type.
*
* Should preferably be equivalent to a native word size.
*/
typedef unsigned long log_arg_t;
/** @brief Maximum number of arguments in the standard log entry.
*
* It is limited by 4 bit nargs field in the log message.
*/
#define LOG_MAX_NARGS 15
/** @brief Number of arguments in the log entry which fits in one chunk.*/
#ifdef CONFIG_64BIT
#define LOG_MSG_NARGS_SINGLE_CHUNK 4U
#else
#define LOG_MSG_NARGS_SINGLE_CHUNK 3U
#endif
/** @brief Number of arguments in the head of extended standard log message..*/
#define LOG_MSG_NARGS_HEAD_CHUNK \
(LOG_MSG_NARGS_SINGLE_CHUNK - (sizeof(void *)/sizeof(log_arg_t)))
/** @brief Maximal amount of bytes in the hexdump entry which fits in one chunk.
*/
#define LOG_MSG_HEXDUMP_BYTES_SINGLE_CHUNK \
(LOG_MSG_NARGS_SINGLE_CHUNK * sizeof(log_arg_t))
/** @brief Number of bytes in the first chunk of hexdump message if message
* consists of more than one chunk.
*/
#define LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK \
(LOG_MSG_HEXDUMP_BYTES_SINGLE_CHUNK - sizeof(void *))
/** @brief Number of bytes that can be stored in chunks following head chunk
* in hexdump log message.
*/
#define HEXDUMP_BYTES_CONT_MSG \
(sizeof(struct log_msg) - sizeof(void *))
#define ARGS_CONT_MSG (HEXDUMP_BYTES_CONT_MSG / sizeof(log_arg_t))
/** @brief Flag indicating standard log message. */
#define LOG_MSG_TYPE_STD 0U
/** @brief Flag indicating hexdump log message. */
#define LOG_MSG_TYPE_HEXDUMP 1
/** @brief Common part of log message header. */
#define COMMON_PARAM_HDR() \
uint16_t type : 1; \
uint16_t ext : 1
/** @brief Number of bits used for storing length of hexdump log message. */
#define LOG_MSG_HEXDUMP_LENGTH_BITS 14
/** @brief Maximum length of log hexdump message. */
#define LOG_MSG_HEXDUMP_MAX_LENGTH (BIT(LOG_MSG_HEXDUMP_LENGTH_BITS) - 1)
/** @brief Part of log message header identifying source and level. */
struct log_msg_ids {
uint16_t level : 3; /*!< Severity. */
uint16_t domain_id : 3; /*!< Originating domain. */
uint16_t source_id : 10; /*!< Source ID. */
};
/** Part of log message header common to standard and hexdump log message. */
struct log_msg_generic_hdr {
COMMON_PARAM_HDR();
uint16_t reserved : 14;
};
/** Part of log message header specific to standard log message. */
struct log_msg_std_hdr {
COMMON_PARAM_HDR();
uint16_t reserved : 10;
uint16_t nargs : 4;
};
/** Part of log message header specific to hexdump log message. */
struct log_msg_hexdump_hdr {
COMMON_PARAM_HDR();
uint16_t length : LOG_MSG_HEXDUMP_LENGTH_BITS;
};
/** Log message header structure */
struct log_msg_hdr {
atomic_t ref_cnt; /*!< Reference counter for tracking message users. */
union log_msg_hdr_params {
struct log_msg_generic_hdr generic;
struct log_msg_std_hdr std;
struct log_msg_hexdump_hdr hexdump;
uint16_t raw;
} params;
struct log_msg_ids ids; /*!< Identification part of the message.*/
uint32_t timestamp; /*!< Timestamp. */
};
/** @brief Data part of log message. */
union log_msg_head_data {
log_arg_t args[LOG_MSG_NARGS_SINGLE_CHUNK];
uint8_t bytes[LOG_MSG_HEXDUMP_BYTES_SINGLE_CHUNK];
};
/** @brief Data part of extended log message. */
struct log_msg_ext_head_data {
struct log_msg_cont *next;
union log_msg_ext_head_data_data {
log_arg_t args[LOG_MSG_NARGS_HEAD_CHUNK];
uint8_t bytes[LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK];
} data;
};
/** @brief Log message structure. */
struct log_msg {
struct log_msg *next; /*!< Used by logger core list.*/
struct log_msg_hdr hdr; /*!< Message header. */
const char *str;
union log_msg_data {
union log_msg_head_data single;
struct log_msg_ext_head_data ext;
} payload; /*!< Message data. */
};
/** @brief Chunks following message head when message is extended. */
struct log_msg_cont {
struct log_msg_cont *next; /*!< Pointer to the next chunk. */
union log_msg_cont_data {
log_arg_t args[ARGS_CONT_MSG];
uint8_t bytes[HEXDUMP_BYTES_CONT_MSG];
} payload;
};
/** @brief Log message */
union log_msg_chunk {
struct log_msg head;
struct log_msg_cont cont;
};
/** @brief Function for initialization of the log message pool. */
void log_msg_pool_init(void);
/** @brief Function for indicating that message is in use.
*
* @details Message can be used (read) by multiple users. Internal reference
* counter is atomically increased. See @ref log_msg_put.
*
* @param msg Message.
*/
void log_msg_get(struct log_msg *msg);
/** @brief Function for indicating that message is no longer in use.
*
* @details Internal reference counter is atomically decreased. If reference
* counter equals 0 message is freed.
*
* @param msg Message.
*/
void log_msg_put(struct log_msg *msg);
/** @brief Get domain ID of the message.
*
* @param msg Message
*
* @return Domain ID.
*/
static inline uint32_t log_msg_domain_id_get(struct log_msg *msg)
{
return msg->hdr.ids.domain_id;
}
/** @brief Get source ID (module or instance) of the message.
*
* @param msg Message
*
* @return Source ID.
*/
static inline uint32_t log_msg_source_id_get(struct log_msg *msg)
{
return msg->hdr.ids.source_id;
}
/** @brief Get severity level of the message.
*
* @param msg Message
*
* @return Severity message.
*/
static inline uint32_t log_msg_level_get(struct log_msg *msg)
{
return msg->hdr.ids.level;
}
/** @brief Get timestamp of the message.
*
* @param msg Message
*
* @return Timestamp value.
*/
static inline uint32_t log_msg_timestamp_get(struct log_msg *msg)
{
return msg->hdr.timestamp;
}
/** @brief Check if message is of standard type.
*
* @param msg Message
*
* @retval true Standard message.
* @retval false Hexdump message.
*/
static inline bool log_msg_is_std(struct log_msg *msg)
{
return (msg->hdr.params.generic.type == LOG_MSG_TYPE_STD);
}
/** @brief Returns number of arguments in standard log message.
*
* @param msg Standard log message.
*
* @return Number of arguments.
*/
uint32_t log_msg_nargs_get(struct log_msg *msg);
/** @brief Gets argument from standard log message.
*
* @param msg Standard log message.
* @param arg_idx Argument index.
*
* @return Argument value or 0 if arg_idx exceeds number of arguments in the
* message.
*/
log_arg_t log_msg_arg_get(struct log_msg *msg, uint32_t arg_idx);
/** @brief Gets pointer to the unformatted string from standard log message.
*
* @param msg Standard log message.
*
* @return Pointer to the string.
*/
const char *log_msg_str_get(struct log_msg *msg);
/** @brief Allocates chunks for hexdump message and copies the data.
*
* @details Function resets header and sets following fields:
* - message type
* - length
*
* @note Allocation and partial filling is combined for performance reasons.
*
* @param str String.
* @param data Data.
* @param length Data length.
*
* @return Pointer to allocated head of the message or NULL
*/
struct log_msg *log_msg_hexdump_create(const char *str,
const uint8_t *data,
uint32_t length);
/** @brief Put data into hexdump log message.
*
* @param[in] msg Message.
* @param[in] data Data to be copied.
* @param[in, out] length Input: requested amount. Output: actual amount.
* @param[in] offset Offset.
*/
void log_msg_hexdump_data_put(struct log_msg *msg,
uint8_t *data,
size_t *length,
size_t offset);
/** @brief Get data from hexdump log message.
*
* @param[in] msg Message.
* @param[in] data Buffer for data.
* @param[in, out] length Input: requested amount. Output: actual amount.
* @param[in] offset Offset.
*/
void log_msg_hexdump_data_get(struct log_msg *msg,
uint8_t *data,
size_t *length,
size_t offset);
union log_msg_chunk *log_msg_no_space_handle(void);
/** @brief Allocate single chunk from the pool.
*
* @return Pointer to the allocated chunk or NULL if failed to allocate.
*/
union log_msg_chunk *log_msg_chunk_alloc(void);
/** @brief Allocate chunk for standard log message.
*
* @return Allocated chunk of NULL.
*/
static inline struct log_msg *z_log_msg_std_alloc(void)
{
struct log_msg *msg = (struct log_msg *)log_msg_chunk_alloc();
if (msg != NULL) {
/* all fields reset to 0, reference counter to 1 */
msg->hdr.ref_cnt = 1;
msg->hdr.params.raw = 0U;
msg->hdr.params.std.type = LOG_MSG_TYPE_STD;
if (IS_ENABLED(CONFIG_USERSPACE)) {
/* it may be used in msg_free() function. */
msg->hdr.ids.level = 0;
msg->hdr.ids.domain_id = 0;
msg->hdr.ids.source_id = 0;
}
}
return msg;
}
/** @brief Create standard log message with no arguments.
*
* @details Function resets header and sets following fields:
* - message type
* - string pointer
*
* @return Pointer to allocated head of the message or NULL.
*/
static inline struct log_msg *log_msg_create_0(const char *str)
{
struct log_msg *msg = z_log_msg_std_alloc();
if (msg != NULL) {
msg->str = str;
}
return msg;
}
/** @brief Create standard log message with one argument.
*
* @details Function resets header and sets following fields:
* - message type
* - string pointer
* - number of arguments
* - argument
*
* @param str String.
* @param arg1 Argument.
*
* @return Pointer to allocated head of the message or NULL.
*/
static inline struct log_msg *log_msg_create_1(const char *str,
log_arg_t arg1)
{
struct log_msg *msg = z_log_msg_std_alloc();
if (msg != NULL) {
msg->str = str;
msg->hdr.params.std.nargs = 1U;
msg->payload.single.args[0] = arg1;
}
return msg;
}
/** @brief Create standard log message with two arguments.
*
* @details Function resets header and sets following fields:
* - message type
* - string pointer
* - number of arguments
* - arguments
*
* @param str String.
* @param arg1 Argument 1.
* @param arg2 Argument 2.
*
* @return Pointer to allocated head of the message or NULL.
*/
static inline struct log_msg *log_msg_create_2(const char *str,
log_arg_t arg1,
log_arg_t arg2)
{
struct log_msg *msg = z_log_msg_std_alloc();
if (msg != NULL) {
msg->str = str;
msg->hdr.params.std.nargs = 2U;
msg->payload.single.args[0] = arg1;
msg->payload.single.args[1] = arg2;
}
return msg;
}
/** @brief Create standard log message with three arguments.
*
* @details Function resets header and sets following fields:
* - message type
* - string pointer
* - number of arguments
* - arguments
*
* @param str String.
* @param arg1 Argument 1.
* @param arg2 Argument 2.
* @param arg3 Argument 3.
*
* @return Pointer to allocated head of the message or NULL.
*/
static inline struct log_msg *log_msg_create_3(const char *str,
log_arg_t arg1,
log_arg_t arg2,
log_arg_t arg3)
{
struct log_msg *msg = z_log_msg_std_alloc();
if (msg != NULL) {
msg->str = str;
msg->hdr.params.std.nargs = 3U;
msg->payload.single.args[0] = arg1;
msg->payload.single.args[1] = arg2;
msg->payload.single.args[2] = arg3;
}
return msg;
}
/** @brief Create standard log message with variable number of arguments.
*
* @details Function resets header and sets following fields:
* - message type
* - string pointer
* - number of arguments
* - arguments
*
* @param str String.
* @param args Array with arguments.
* @param nargs Number of arguments.
*
* @return Pointer to allocated head of the message or NULL.
*/
struct log_msg *log_msg_create_n(const char *str,
log_arg_t *args,
uint32_t nargs);
/**
* @brief Get number of free blocks from the log mem pool
*/
uint32_t log_msg_mem_get_free(void);
/**
* @brief Get number of used blocks from the log mem pool
*/
uint32_t log_msg_mem_get_used(void);
/**
* @brief Get max used blocks from the log mem pool
*/
uint32_t log_msg_mem_get_max_used(void);
/**
* @brief Get slab size
*
* @return Size of a slab used in slab pool for log messages.
*/
size_t log_msg_get_slab_size(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_MSG_H_ */

View file

@ -37,7 +37,7 @@ typedef uint32_t log_timestamp_t;
/**
* @brief Log message API
* @defgroup log_msg2 Log message v2 API
* @defgroup log_msg Log message API
* @ingroup logger
* @{
*/

View file

@ -6,7 +6,7 @@
#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_H_
#define ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_H_
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_msg2.h>
#include <zephyr/sys/util.h>
#include <stdarg.h>
#include <zephyr/sys/atomic.h>
@ -46,11 +46,6 @@ extern "C" {
*/
#define LOG_OUTPUT_FLAG_FORMAT_SYSLOG BIT(6)
/** @brief Flag forcing syslog format specified in mipi sys-t.
* This flag is deprecated and can only be used when CONFIG_LOG1 is enabled.
*/
#define LOG_OUTPUT_FLAG_FORMAT_SYST BIT(7)
/** @brief Supported backend logging format types for use
* with log_format_set() API to switch log format at runtime.
*/
@ -123,19 +118,6 @@ log_format_func_t log_format_func_t_get(uint32_t log_type);
.size = _size, \
}
/** @brief Process log messages to readable strings.
*
* Function is using provided context with the buffer and output function to
* process formatted string and output the data.
*
* @param output Pointer to the log output instance.
* @param msg Log message.
* @param flags Optional flags.
*/
void log_output_msg_process(const struct log_output *output,
struct log_msg *msg,
uint32_t flags);
/** @brief Process log messages v2 to readable strings.
*
* Function is using provided context with the buffer and output function to
@ -160,42 +142,6 @@ void log_output_msg2_process(const struct log_output *log_output,
void log_output_msg2_syst_process(const struct log_output *log_output,
struct log_msg2 *msg, uint32_t flag);
/** @brief Process log string
*
* Function is formatting provided string adding optional prefixes and
* postfixes.
*
* @param output Pointer to log_output instance.
* @param src_level Log source and level structure.
* @param timestamp Timestamp.
* @param fmt String.
* @param ap String arguments.
* @param flags Optional flags.
*
*/
void log_output_string(const struct log_output *output,
struct log_msg_ids src_level, uint32_t timestamp,
const char *fmt, va_list ap, uint32_t flags);
/** @brief Process log hexdump
*
* Function is formatting provided hexdump adding optional prefixes and
* postfixes.
*
* @param output Pointer to log_output instance.
* @param src_level Log source and level structure.
* @param timestamp Timestamp.
* @param metadata String.
* @param data Data.
* @param length Data length.
* @param flags Optional flags.
*
*/
void log_output_hexdump(const struct log_output *output,
struct log_msg_ids src_level, uint32_t timestamp,
const char *metadata, const uint8_t *data,
uint32_t length, uint32_t flags);
/** @brief Process dropped messages indication.
*
* Function prints error message indicating lost log messages.

View file

@ -17,6 +17,5 @@ CONFIG_USE_SEGGER_RTT=y
CONFIG_SEGGER_RTT_BUFFER_SIZE_UP=4096
CONFIG_LOG_BACKEND_SHOW_COLOR=n
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1024
CONFIG_LOG_STRDUP_BUF_COUNT=20
CONFIG_LOG_DEFAULT_LEVEL=3

View file

@ -33,7 +33,6 @@ CONFIG_IDLE_STACK_SIZE=1024
# logging:
CONFIG_LOG=y
# CONFIG_NET_LOG=y
# CONFIG_LOG_STRDUP_MAX_STRING=256
# Do not include mbedtls via this option as civetweb does not
# work properly with mbedtls.

View file

@ -34,7 +34,6 @@ CONFIG_HTTP_CLIENT=y
# Network debug config
CONFIG_LOG=y
CONFIG_LOG_STRDUP_BUF_COUNT=20
CONFIG_NET_LOG=y
CONFIG_NET_SOCKETS_LOG_LEVEL_DBG=n
CONFIG_NET_HTTP_LOG_LEVEL_DBG=n

View file

@ -25,7 +25,6 @@ CONFIG_NET_CONNECTION_MANAGER=y
CONFIG_LOG=y
CONFIG_NET_LOG=y
#CONFIG_LOG_BUFFER_SIZE=16384
#CONFIG_LOG_STRDUP_BUF_COUNT=200
#CONFIG_MODEM_LOG_LEVEL_DBG=y
#CONFIG_NET_PPP_LOG_LEVEL_DBG=y
#CONFIG_NET_L2_PPP_LOG_LEVEL_DBG=y

View file

@ -1,6 +1,5 @@
CONFIG_NETWORKING=y
CONFIG_LOG=y
CONFIG_LOG_STRDUP_BUF_COUNT=10
CONFIG_LWM2M_LOG_LEVEL_DBG=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NET_IPV6=y

View file

@ -3,7 +3,6 @@ CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_LOG_BACKEND_SHOW_COLOR=n
CONFIG_LOG_BUFFER_SIZE=1024
CONFIG_LOG_STRDUP_BUF_COUNT=2048
CONFIG_NET_LOG=y

View file

@ -3,7 +3,6 @@ CONFIG_LOG_MODE_IMMEDIATE=y
CONFIG_LOG_BACKEND_SHOW_COLOR=n
CONFIG_LOG_BUFFER_SIZE=1024
CONFIG_LOG_STRDUP_BUF_COUNT=2048
CONFIG_NET_LOG=y

View file

@ -1,2 +0,0 @@
# To avoid flood of missing log_strdup messages
CONFIG_LOG_DETECT_MISSED_STRDUP=n

View file

@ -44,12 +44,6 @@ or
Building and Running
********************
.. note::
When deferred logging is enabled you will likely need to increase
:kconfig:option:`CONFIG_LOG_STRDUP_BUF_COUNT` and/or
:kconfig:option:`CONFIG_LOG_STRDUP_MAX_STRING` to make sure no messages are lost or
truncated.
Example building for :ref:`nrf52840dk_nrf52840`:
.. zephyr-app-commands::

View file

@ -210,12 +210,13 @@ static void performance_showcase(void)
{
/* Arbitrary limit when LOG_MODE_IMMEDIATE is enabled. */
#define LOG_IMMEDIATE_TEST_MESSAGES_LIMIT 50
#define MSG_SIZE (sizeof(struct log_msg2) + 2 * sizeof(void *) + sizeof(int))
volatile uint32_t current_timestamp;
volatile uint32_t start_timestamp;
uint32_t limit = COND_CODE_1(CONFIG_LOG_MODE_IMMEDIATE,
(LOG_IMMEDIATE_TEST_MESSAGES_LIMIT),
(CONFIG_LOG_BUFFER_SIZE / sizeof(struct log_msg)));
(CONFIG_LOG_BUFFER_SIZE / MSG_SIZE));
uint32_t per_sec;
uint32_t cnt = 0U;
uint32_t window = 2U;

View file

@ -4,7 +4,6 @@ CONFIG_LOG_BUFFER_SIZE=1024
CONFIG_LOG_PROCESS_THREAD=y
CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100
CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=2
CONFIG_LOG_PRINTK_MAX_STRING_LENGTH=256
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=4096
CONFIG_LOG_BLOCK_IN_THREAD=y
CONFIG_LOG_BACKEND_UART=y

View file

@ -44,7 +44,3 @@ CONFIG_LOG_BUFFER_SIZE=4096
#Generate HEX output
CONFIG_BUILD_OUTPUT_HEX=y
#LOG Maximum string define
CONFIG_LOG_STRDUP_MAX_STRING=100
CONFIG_LOG_STRDUP_BUF_COUNT=20

View file

@ -26,5 +26,4 @@ CONFIG_NET_SHELL=y
# Debug helpers
CONFIG_LOG=y
CONFIG_LOG_STRDUP_BUF_COUNT=20
#CONFIG_UPDATEHUB_LOG_LEVEL_DBG=y

View file

@ -104,7 +104,7 @@ psa_status_t al_psa_status(psa_status_t status, const char *func_name)
void al_dump_log(void)
{
while (log_process(false)) {
while (log_process()) {
}
}

View file

@ -48,7 +48,4 @@ config ATOMIC_OPERATIONS_C
config MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE
default n
config LOG_DETECT_MISSED_STRDUP
default n
endif

View file

@ -42,9 +42,6 @@ endif
config MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE
default n
config LOG_DETECT_MISSED_STRDUP
default n
if GDBSTUB
# ESP32 GDB expects 420 bytes G-packet.

View file

@ -46,7 +46,4 @@ config MP_NUM_CPUS
config MINIMAL_LIBC_OPTIMIZE_STRING_FOR_SIZE
default n
config LOG_DETECT_MISSED_STRDUP
default n
endif

View file

@ -3,16 +3,10 @@
if(NOT CONFIG_LOG_MODE_MINIMAL)
zephyr_sources_ifdef(
CONFIG_LOG
log_list.c
log_core.c
log_mgmt.c
log_msg.c
log_output.c
)
zephyr_sources_ifdef(
CONFIG_LOG2
log_msg2.c
log_output.c
)
# Determine if __auto_type is supported. If not then runtime approach must always
@ -112,15 +106,3 @@ if(NOT CONFIG_LOG_MODE_MINIMAL)
else()
zephyr_sources(log_minimal.c)
endif()
if(CONFIG_LOG2_MODE_IMMEDIATE OR CONFIG_LOG2_MODE_DEFERRED)
message(WARNING "CONFIG_LOG2_MODE_{IMMEDIATE,DEFERRED} is deprecated. Please \
use CONFIG_LOG_MODE_{IMMEDIATE,DEFERRED} which defaults to v2"
)
endif()
if(CONFIG_LOG1)
message(WARNING "Logging v1 has been deprecated. Use v2 instead and adapt \
custom backend to the new backend API"
)
endif()

View file

@ -6,7 +6,6 @@ menu "Backends"
config LOG_BACKEND_UART
bool "UART backend"
depends on UART_CONSOLE
depends on !LOG1
default y if !SHELL_BACKEND_SERIAL
help
When enabled backend is using UART to output logs.
@ -55,7 +54,6 @@ endif # LOG_BACKEND_UART
config LOG_BACKEND_SWO
bool "Serial Wire Output (SWO) backend"
depends on HAS_SWO
depends on !LOG1
help
When enabled, backend will use SWO for logging.
@ -85,7 +83,6 @@ endif # LOG_BACKEND_SWO
config LOG_BACKEND_RTT
bool "Segger J-Link RTT backend"
depends on USE_SEGGER_RTT
depends on !LOG1
default y if !SHELL_BACKEND_RTT
select SEGGER_RTT_CUSTOM_LOCKING
help
@ -191,7 +188,6 @@ endif # LOG_BACKEND_RTT
config LOG_BACKEND_SPINEL
bool "OpenThread dedicated Spinel protocol backend"
depends on !LOG_BACKEND_UART
depends on !LOG1
depends on NET_L2_OPENTHREAD
help
When enabled, backend will use OpenThread dedicated SPINEL protocol for logging.
@ -216,7 +212,6 @@ endif # LOG_BACKEND_SPINEL
config LOG_BACKEND_NATIVE_POSIX
bool "Native backend"
depends on ARCH_POSIX
depends on !LOG1
default y if !SERIAL
help
Enable backend in native_posix
@ -232,7 +227,6 @@ endif # LOG_BACKEND_NATIVE_POSIX
config LOG_BACKEND_XTENSA_SIM
bool "Xtensa simulator backend"
depends on SOC_XTENSA_SAMPLE_CONTROLLER || SOC_FAMILY_INTEL_ADSP
depends on !LOG1
default y if SOC_XTENSA_SAMPLE_CONTROLLER
help
Enable backend in xtensa simulator
@ -258,7 +252,6 @@ endif # LOG_BACKEND_XTENSA_SIM
config LOG_BACKEND_NET
bool "Networking backend"
depends on NETWORKING && NET_UDP && !LOG_MODE_IMMEDIATE
depends on !LOG1
select NET_CONTEXT_NET_PKT_POOL
help
Send syslog messages to network server.
@ -320,7 +313,6 @@ endif # LOG_BACKEND_NET
config LOG_BACKEND_ADSP
bool "Intel ADSP buffer backend"
depends on SOC_FAMILY_INTEL_ADSP
depends on !LOG1
help
Enable backend for the host trace protocol of the Intel ADSP
family of audio processors
@ -335,7 +327,7 @@ endif # LOG_BACKEND_ADSP
config LOG_BACKEND_CAVS_HDA
bool "cAVS HDA backend"
depends on SOC_FAMILY_INTEL_ADSP && DMA && DMA_CAVS_HDA && LOG2
depends on SOC_FAMILY_INTEL_ADSP && DMA && DMA_CAVS_HDA
help
Provide a logging backend which writes to a buffer and
periodically flushes to hardware using ringbuffer like
@ -371,7 +363,6 @@ endif # LOG_BACKEND_CAVS_HDA
config LOG_BACKEND_FS
bool "File system backend"
depends on FILE_SYSTEM
depends on !LOG1
help
When enabled, backend is using the configured file system to output logs.
As the file system must be mounted for the logging to work, it must be

View file

@ -31,7 +31,6 @@ if LOG_MIPI_SYST_ENABLE
config LOG_MIPI_SYST_USE_CATALOG
bool "Use MIPI Sys-T Catalog for logging"
depends on LOG2
select LOG2_FMT_SECTION
select LOG2_USE_TAGGED_ARGUMENTS
help
@ -82,7 +81,6 @@ endif # LOG_MIPI_SYST_ENABLE
config LOG_DICTIONARY_SUPPORT
bool
depends on LOG2
select LOG_DICTIONARY_DB
help
Enable support for dictionary based logging.

View file

@ -6,6 +6,7 @@ menu "Frontends"
config LOG_FRONTEND_DICT_UART
bool "UART dictionary frontend"
select LOG_DICTIONARY_DB
select MPSC_PBUF
depends on UART_ASYNC_API || UART_INTERRUPT_DRIVEN
help
Frontend sends data in binary dictionary mode.

View file

@ -21,7 +21,6 @@ config LOG_TEST_CLEAR_MESSAGE_SPACE
bool "Clear message after allocation"
default y
depends on ZTEST
depends on LOG2
help
Used in testing to simplify message comparision if message contains
paddings.
@ -67,7 +66,6 @@ config LOG_MEM_UTILIZATION
bool "Tracking maximum memory utilization"
depends on LOG_MODE_DEFERRED
default y if LOG_CMDS
select MEM_SLAB_TRACE_MAX_UTILIZATION if LOG1
help
When enabled, maximum usage of memory used for log messages in deferred
mode is tracked. It can be used to trim LOG_BUFFER_SIZE.

View file

@ -5,12 +5,11 @@ choice LOG_MODE
prompt "Mode"
depends on !LOG_FRONTEND_ONLY
default LOG_MODE_MINIMAL if LOG_DEFAULT_MINIMAL
default LOG_MODE_IMMEDIATE if LOG2_MODE_IMMEDIATE
default LOG_MODE_DEFERRED
config LOG_MODE_DEFERRED
bool "Deferred logging"
depends on !LOG2_MODE_IMMEDIATE
select MPSC_PBUF
help
Log messages are buffered and processed later. This mode has the
least impact on the application. Time consuming processing is
@ -18,7 +17,6 @@ config LOG_MODE_DEFERRED
config LOG_MODE_IMMEDIATE
bool "Synchronous"
depends on !LOG2_MODE_DEFERRED
help
When enabled log is processed in the context of the call. It impacts
performance of the system since time consuming operations are
@ -30,8 +28,6 @@ config LOG_MODE_IMMEDIATE
config LOG_MODE_MINIMAL
bool "Minimal-footprint"
imply PRINTK
depends on !LOG2_MODE_DEFERRED
depends on !LOG2_MODE_IMMEDIATE
help
Enable minimal logging implementation. This has very little footprint
overhead on top of the printk() implementation for standard
@ -45,57 +41,16 @@ endchoice
config LOG_FRONTEND
bool "Frontend"
depends on !LOG2_MODE_DEFERRED
depends on !LOG2_MODE_IMMEDIATE
help
When enabled, logs are redirected to a custom frontend which is the
fastest way of getting logs out.
config LOG_FRONTEND_ONLY
bool "No backends" if !LOG1
default y if LOG1
bool "No backends"
depends on LOG_FRONTEND
help
Option indicates that there are no backends intended to be used.
Code asserts if any backend is enabled.
config LOG2_MODE_DEFERRED
bool "Deferred v2 (DEPRECATED)"
help
Option has been deprecated. Use LOG_MODE_DEFERRED which defaults now
to v2.
config LOG2_MODE_IMMEDIATE
bool "Synchronous v2 (DEPRECATED)"
help
Option has been deprecated. Use LOG_MODE_IMMEDIATE which defaults now
to v2.
config LOG1
bool "Use v1 (DEPRECATED)"
help
Deprecated.
config LOG2
bool
select MPSC_PBUF
default y if !LOG1
config LOG1_IMMEDIATE
bool
default y if LOG1 && LOG_MODE_IMMEDIATE
config LOG1_DEFERRED
bool
default y if LOG1 && LOG_MODE_DEFERRED
config LOG2_IMMEDIATE
bool
default y if !LOG1 && LOG_MODE_IMMEDIATE
config LOG2_DEFERRED
bool
default y if !LOG1 && LOG_MODE_DEFERRED
config LOG_DEFAULT_MINIMAL
bool

View file

@ -10,15 +10,6 @@ config LOG_PRINTK
help
LOG_PRINTK messages are formatted in place and logged unconditionally.
config LOG_PRINTK_MAX_STRING_LENGTH
int "Maximum string length supported by LOG_PRINTK"
depends on LOG_PRINTK
depends on (!LOG_MODE_IMMEDIATE || USERSPACE)
depends on LOG1
default 128
help
Array is allocated on the stack.
if LOG_MODE_DEFERRED && !LOG_FRONTEND_ONLY
config LOG_MODE_OVERFLOW
@ -110,49 +101,6 @@ config LOG_BUFFER_SIZE
endif # LOG_MODE_DEFERRED && !LOG_FRONTEND_ONLY
if LOG1_DEFERRED
config LOG_DETECT_MISSED_STRDUP
bool "Detect missed handling of transient strings"
default y
help
If enabled, logger will assert and log error message is it detects
that string format specifier (%s) and string address which is not from
read only memory section and not from pool used for string duplicates.
String argument must be duplicated in that case using log_strdup().
Detection is performed during log processing thus it does not impact
logging timing.
config LOG_STRDUP_MAX_STRING
int "Longest string that can be duplicated using log_strdup()"
range 1 8192
default 66 if BT
default 46 if NETWORKING
default 32
help
Longer strings are truncated.
config LOG_STRDUP_BUF_COUNT
int "Number of buffers in the pool used by log_strdup()"
default 8 if BT
default 4
help
Number of calls to log_strdup() which can be pending before flushed
to output. If "<log_strdup alloc failed>" message is seen in the log
output, it means this value is too small and should be increased.
Each entry takes CONFIG_LOG_STRDUP_MAX_STRING bytes of memory plus
some additional fixed overhead.
config LOG_STRDUP_POOL_PROFILING
bool "Profiling of pool used for log_strdup()"
help
When enabled, maximal utilization of the pool is tracked. It can
be read out using shell command.
endif # LOG1_DEFERRED
if LOG2
config LOG_TRACE_SHORT_TIMESTAMP
bool "Use 24 bit timestamp for tracing"
default y
@ -169,7 +117,6 @@ config LOG_SPEED
depends on !LOG_FRONTEND
help
If enabled, logging may take more code size to get faster logging.
endif # LOG2
endif # !LOG_MODE_MINIMAL

View file

@ -18,7 +18,6 @@ config LOG_BACKEND_$(backend)_OUTPUT_SYST
config LOG_BACKEND_$(backend)_OUTPUT_DICTIONARY
bool "Dictionary"
depends on LOG2
select LOG_DICTIONARY_SUPPORT
help
Backend is in dictionary-based logging output mode.

View file

@ -6,7 +6,6 @@
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
@ -53,10 +52,6 @@ static uint32_t format_flags(void)
flags |= LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP;
}
if (IS_ENABLED(CONFIG_LOG_BACKEND_ADSP_OUTPUT_SYST)) {
flags |= LOG_OUTPUT_FLAG_FORMAT_SYST;
}
return flags;
}

View file

@ -7,7 +7,6 @@
#include <zephyr/arch/xtensa/cache.h>
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
#include <zephyr/logging/log_backend_cavs_hda.h>

View file

@ -10,7 +10,6 @@
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_backend_std.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/irq.h>
#include <zephyr/arch/posix/posix_trace.h>

View file

@ -10,7 +10,6 @@ LOG_MODULE_REGISTER(log_backend_net, CONFIG_LOG_DEFAULT_LEVEL);
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_context.h>

View file

@ -6,7 +6,6 @@
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
#include <SEGGER_RTT.h>

View file

@ -24,7 +24,6 @@
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
#include <soc.h>

View file

@ -6,7 +6,6 @@
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_output_dict.h>
#include <zephyr/logging/log_backend_std.h>

View file

@ -10,7 +10,6 @@
#include <stddef.h>
#include <zephyr/logging/log_backend.h>
#include <zephyr/logging/log_core.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_output.h>
#include <zephyr/logging/log_backend_std.h>
#include <xtensa/simcall.h>

View file

@ -362,48 +362,6 @@ static int cmd_log_backends_list(const struct shell *shell,
return 0;
}
static int cmd_log_strdup_utilization(const struct shell *shell,
size_t argc, char **argv)
{
/* Defines needed when string duplication is disabled (LOG2 or immediate
* mode). In that case, this function is not compiled in.
*/
#ifndef CONFIG_LOG_STRDUP_BUF_COUNT
#define CONFIG_LOG_STRDUP_BUF_COUNT 0
#endif
#ifndef CONFIG_LOG_STRDUP_MAX_STRING
#define CONFIG_LOG_STRDUP_MAX_STRING 0
#endif
uint32_t cur_cnt = log_get_strdup_pool_current_utilization();
uint32_t buf_cnt = log_get_strdup_pool_utilization();
uint32_t buf_size = log_get_strdup_longest_string();
uint32_t percent = CONFIG_LOG_STRDUP_BUF_COUNT ?
buf_cnt * 100U / CONFIG_LOG_STRDUP_BUF_COUNT : 0U;
shell_print(shell, "Current utilization of the buffer pool: %d.",
cur_cnt);
shell_print(shell,
"Maximal utilization of the buffer pool: %d / %d (%d %%).",
buf_cnt, CONFIG_LOG_STRDUP_BUF_COUNT, percent);
if (buf_cnt == CONFIG_LOG_STRDUP_BUF_COUNT) {
shell_warn(shell, "Buffer count too small.");
}
shell_print(shell,
"Longest duplicated string: %d, buffer capacity: %d.",
buf_size, CONFIG_LOG_STRDUP_MAX_STRING);
if (buf_size > CONFIG_LOG_STRDUP_MAX_STRING) {
shell_warn(shell, "Buffer size too small.");
}
return 0;
}
static int cmd_log_mem(const struct shell *sh, size_t argc, char **argv)
{
uint32_t size;
@ -477,9 +435,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(
SHELL_CMD_ARG(list_backends, NULL, "Lists logger backends.", cmd_log_backends_list, 1, 0),
SHELL_COND_CMD(CONFIG_SHELL_LOG_BACKEND, status, NULL, "Logger status",
cmd_log_self_status),
SHELL_COND_CMD_ARG(CONFIG_LOG_STRDUP_POOL_PROFILING, strdup_utilization, NULL,
"Get utilization of string duplicates pool", cmd_log_strdup_utilization,
1, 0),
SHELL_COND_CMD(CONFIG_LOG_MODE_DEFERRED, mem, NULL, "Logger memory usage",
cmd_log_mem),
SHELL_SUBCMD_SET_END);

File diff suppressed because it is too large Load diff

View file

@ -1,41 +0,0 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "log_list.h"
void log_list_init(struct log_list_t *list)
{
list->tail = NULL;
list->head = NULL;
}
void log_list_add_tail(struct log_list_t *list, struct log_msg *msg)
{
if (list->head == NULL) {
list->head = msg;
} else {
list->tail->next = msg;
}
list->tail = msg;
msg->next = NULL;
}
struct log_msg *log_list_head_peek(struct log_list_t *list)
{
return list->head;
}
struct log_msg *log_list_head_get(struct log_list_t *list)
{
struct log_msg *msg = list->head;
if (list->head != NULL) {
list->head = list->head->next;
}
return msg;
}

View file

@ -1,55 +0,0 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef LOG_LIST_H_
#define LOG_LIST_H_
#include <zephyr/logging/log_msg.h>
#ifdef __cplusplus
extern "C" {
#endif
/** @brief List instance structure. */
struct log_list_t {
struct log_msg *head;
struct log_msg *tail;
};
/** @brief Initialize log list instance.
*
* @param list List instance.
*/
void log_list_init(struct log_list_t *list);
/** @brief Add item to the tail of the list.
*
* @param list List instance.
* @param msg Message.
*
*/
void log_list_add_tail(struct log_list_t *list, struct log_msg *msg);
/** @brief Remove item from the head of the list.
*
* @param list List instance.
*
* @return Message.
*/
struct log_msg *log_list_head_get(struct log_list_t *list);
/** @brief Peek item from the head of the list.
*
* @param list List instance.
*
* @return Message.
*/
struct log_msg *log_list_head_peek(struct log_list_t *list);
#ifdef __cplusplus
}
#endif
#endif /* LOG_LIST_H_ */

View file

@ -183,10 +183,6 @@ void log_backend_enable(struct log_backend const *const backend,
id += backend - log_backend_get(0);
if (!IS_ENABLED(CONFIG_LOG1)) {
__ASSERT(backend->api->process, "Backend does not support v2 API");
}
log_backend_id_set(backend, id);
backend_filter_set(backend, level);
log_backend_activate(backend, ctx);

View file

@ -1,505 +0,0 @@
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/logging/log_msg.h>
#include <zephyr/logging/log_ctrl.h>
#include <zephyr/logging/log_internal.h>
#include <zephyr/sys/__assert.h>
#include <string.h>
BUILD_ASSERT((sizeof(struct log_msg_ids) == sizeof(uint16_t)),
"Structure must fit in 2 bytes");
BUILD_ASSERT((sizeof(struct log_msg_generic_hdr) == sizeof(uint16_t)),
"Structure must fit in 2 bytes");
BUILD_ASSERT((sizeof(struct log_msg_std_hdr) == sizeof(uint16_t)),
"Structure must fit in 2 bytes");
BUILD_ASSERT((sizeof(struct log_msg_hexdump_hdr) == sizeof(uint16_t)),
"Structure must fit in 2 bytes");
BUILD_ASSERT((sizeof(union log_msg_head_data) ==
sizeof(struct log_msg_ext_head_data)),
"Structure must be same size");
#ifndef CONFIG_LOG_BUFFER_SIZE
#define CONFIG_LOG_BUFFER_SIZE 0
#endif
/* Define needed when CONFIG_LOG_BLOCK_IN_THREAD is disabled to satisfy
* compiler. */
#ifndef CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS
#define CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS 0
#endif
#define MSG_SIZE sizeof(union log_msg_chunk)
#define NUM_OF_MSGS (CONFIG_LOG_BUFFER_SIZE / MSG_SIZE)
struct k_mem_slab log_msg_pool;
static uint8_t __noinit __aligned(sizeof(void *))
log_msg_pool_buf[CONFIG_LOG_BUFFER_SIZE];
void log_msg_pool_init(void)
{
k_mem_slab_init(&log_msg_pool, log_msg_pool_buf, MSG_SIZE, NUM_OF_MSGS);
}
/* Return true if interrupts were unlocked in the context of this call. */
static bool is_irq_unlocked(void)
{
unsigned int key = arch_irq_lock();
bool ret = arch_irq_unlocked(key);
arch_irq_unlock(key);
return ret;
}
/* Check if context can be blocked and pend on available memory slab. Context
* can be blocked if in a thread and interrupts are not locked.
*/
static bool block_on_alloc(void)
{
if (!IS_ENABLED(CONFIG_LOG_BLOCK_IN_THREAD)) {
return false;
}
return (!k_is_in_isr() && is_irq_unlocked());
}
union log_msg_chunk *log_msg_chunk_alloc(void)
{
union log_msg_chunk *msg = NULL;
int err = k_mem_slab_alloc(&log_msg_pool, (void **)&msg,
block_on_alloc()
? K_MSEC(CONFIG_LOG_BLOCK_IN_THREAD_TIMEOUT_MS)
: K_NO_WAIT);
if (err != 0) {
msg = log_msg_no_space_handle();
}
return msg;
}
void log_msg_get(struct log_msg *msg)
{
atomic_inc(&msg->hdr.ref_cnt);
}
static void cont_free(struct log_msg_cont *cont)
{
struct log_msg_cont *next;
while (cont != NULL) {
next = cont->next;
k_mem_slab_free(&log_msg_pool, (void **)&cont);
cont = next;
}
}
static void msg_free(struct log_msg *msg)
{
uint32_t nargs = log_msg_nargs_get(msg);
/* Free any transient string found in arguments. */
if (log_msg_is_std(msg) && nargs) {
uint32_t i;
uint32_t smask = 0U;
for (i = 0U; i < nargs; i++) {
void *buf = (void *)log_msg_arg_get(msg, i);
if (log_is_strdup(buf)) {
if (smask == 0U) {
/* Do string arguments scan only when
* string duplication candidate detected
* since it is time consuming and free
* can be called from any context when
* log message is being dropped.
*/
smask = z_log_get_s_mask(
log_msg_str_get(msg),
nargs);
if (smask == 0U) {
/* if no string argument is
* detected then stop searching
* for candidates.
*/
break;
}
}
if (smask & BIT(i)) {
z_log_free(buf);
}
}
}
} else if (IS_ENABLED(CONFIG_USERSPACE) &&
(log_msg_level_get(msg) != LOG_LEVEL_INTERNAL_RAW_STRING)) {
/*
* When userspace support is enabled, the hex message metadata
* might be located in log_strdup() memory pool.
*/
const char *str = log_msg_str_get(msg);
if (log_is_strdup(str)) {
z_log_free((void *)(str));
}
} else {
/* Message does not contain any arguments that might be a transient
* string. No action required.
*/
;
}
if (msg->hdr.params.generic.ext == 1) {
cont_free(msg->payload.ext.next);
}
k_mem_slab_free(&log_msg_pool, (void **)&msg);
}
union log_msg_chunk *log_msg_no_space_handle(void)
{
union log_msg_chunk *msg = NULL;
bool more;
int err;
if (IS_ENABLED(CONFIG_LOG_MODE_OVERFLOW)) {
do {
more = log_process(true);
z_log_dropped(true);
err = k_mem_slab_alloc(&log_msg_pool,
(void **)&msg,
K_NO_WAIT);
} while ((err != 0) && more);
} else {
z_log_dropped(false);
}
return msg;
}
void log_msg_put(struct log_msg *msg)
{
atomic_dec(&msg->hdr.ref_cnt);
if (msg->hdr.ref_cnt == 0) {
msg_free(msg);
}
}
uint32_t log_msg_nargs_get(struct log_msg *msg)
{
return msg->hdr.params.std.nargs;
}
static log_arg_t cont_arg_get(struct log_msg *msg, uint32_t arg_idx)
{
struct log_msg_cont *cont;
if (arg_idx < LOG_MSG_NARGS_HEAD_CHUNK) {
return msg->payload.ext.data.args[arg_idx];
}
cont = msg->payload.ext.next;
arg_idx -= LOG_MSG_NARGS_HEAD_CHUNK;
while (arg_idx >= ARGS_CONT_MSG) {
arg_idx -= ARGS_CONT_MSG;
cont = cont->next;
}
return cont->payload.args[arg_idx];
}
log_arg_t log_msg_arg_get(struct log_msg *msg, uint32_t arg_idx)
{
log_arg_t arg;
/* Return early if requested argument not present in the message. */
if (arg_idx >= msg->hdr.params.std.nargs) {
return 0;
}
if (msg->hdr.params.std.nargs <= LOG_MSG_NARGS_SINGLE_CHUNK) {
arg = msg->payload.single.args[arg_idx];
} else {
arg = cont_arg_get(msg, arg_idx);
}
return arg;
}
const char *log_msg_str_get(struct log_msg *msg)
{
return msg->str;
}
/** @brief Allocate chunk for extended standard log message.
*
* @details Extended standard log message is used when number of arguments
* exceeds capacity of one chunk. Extended message consists of two
* chunks. Such approach is taken to optimize memory usage and
* performance assuming that log messages with more arguments
* (@ref LOG_MSG_NARGS_SINGLE_CHUNK) are less common.
*
* @return Allocated chunk of NULL.
*/
static struct log_msg *msg_alloc(uint32_t nargs)
{
struct log_msg_cont *cont;
struct log_msg_cont **next;
struct log_msg *msg = z_log_msg_std_alloc();
int n = (int)nargs;
if ((msg == NULL) || nargs <= LOG_MSG_NARGS_SINGLE_CHUNK) {
return msg;
}
msg->hdr.params.std.nargs = 0U;
msg->hdr.params.generic.ext = 1;
n -= LOG_MSG_NARGS_HEAD_CHUNK;
next = &msg->payload.ext.next;
*next = NULL;
while (n > 0) {
cont = (struct log_msg_cont *)log_msg_chunk_alloc();
if (cont == NULL) {
msg_free(msg);
return NULL;
}
*next = cont;
cont->next = NULL;
next = &cont->next;
n -= ARGS_CONT_MSG;
}
return msg;
}
static void copy_args_to_msg(struct log_msg *msg, log_arg_t *args, uint32_t nargs)
{
struct log_msg_cont *cont = msg->payload.ext.next;
if (nargs > LOG_MSG_NARGS_SINGLE_CHUNK) {
(void)memcpy(msg->payload.ext.data.args, args,
LOG_MSG_NARGS_HEAD_CHUNK * sizeof(log_arg_t));
nargs -= LOG_MSG_NARGS_HEAD_CHUNK;
args += LOG_MSG_NARGS_HEAD_CHUNK;
} else {
(void)memcpy(msg->payload.single.args, args,
nargs * sizeof(log_arg_t));
nargs = 0U;
}
while (nargs != 0U) {
uint32_t cpy_args = MIN(nargs, ARGS_CONT_MSG);
(void)memcpy(cont->payload.args, args,
cpy_args * sizeof(log_arg_t));
nargs -= cpy_args;
args += cpy_args;
cont = cont->next;
}
}
struct log_msg *log_msg_create_n(const char *str, log_arg_t *args, uint32_t nargs)
{
__ASSERT_NO_MSG(nargs < LOG_MAX_NARGS);
struct log_msg *msg = NULL;
msg = msg_alloc(nargs);
if (msg != NULL) {
msg->str = str;
msg->hdr.params.std.nargs = nargs;
copy_args_to_msg(msg, args, nargs);
}
return msg;
}
struct log_msg *log_msg_hexdump_create(const char *str,
const uint8_t *data,
uint32_t length)
{
struct log_msg_cont **prev_cont;
struct log_msg_cont *cont;
struct log_msg *msg;
uint32_t chunk_length;
/* Saturate length. */
length = (length > LOG_MSG_HEXDUMP_MAX_LENGTH) ?
LOG_MSG_HEXDUMP_MAX_LENGTH : length;
msg = (struct log_msg *)log_msg_chunk_alloc();
if (msg == NULL) {
return NULL;
}
/* all fields reset to 0, reference counter to 1 */
msg->hdr.ref_cnt = 1;
msg->hdr.params.hexdump.type = LOG_MSG_TYPE_HEXDUMP;
msg->hdr.params.hexdump.length = length;
msg->str = str;
if (length > LOG_MSG_HEXDUMP_BYTES_SINGLE_CHUNK) {
(void)memcpy(msg->payload.ext.data.bytes,
data,
LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK);
msg->payload.ext.next = NULL;
msg->hdr.params.generic.ext = 1;
data += LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK;
length -= LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK;
} else {
(void)memcpy(msg->payload.single.bytes, data, length);
msg->hdr.params.generic.ext = 0;
length = 0U;
}
prev_cont = &msg->payload.ext.next;
while (length > 0) {
cont = (struct log_msg_cont *)log_msg_chunk_alloc();
if (cont == NULL) {
msg_free(msg);
return NULL;
}
*prev_cont = cont;
cont->next = NULL;
prev_cont = &cont->next;
chunk_length = (length > HEXDUMP_BYTES_CONT_MSG) ?
HEXDUMP_BYTES_CONT_MSG : length;
(void)memcpy(cont->payload.bytes, data, chunk_length);
data += chunk_length;
length -= chunk_length;
}
return msg;
}
static void log_msg_hexdump_data_op(struct log_msg *msg,
uint8_t *data,
size_t *length,
size_t offset,
bool put_op)
{
uint32_t available_len = msg->hdr.params.hexdump.length;
struct log_msg_cont *cont = NULL;
uint8_t *head_data;
uint32_t chunk_len;
uint32_t req_len;
uint32_t cpy_len;
if (offset >= available_len) {
*length = 0;
return;
}
if ((offset + *length) > available_len) {
*length = available_len - offset;
}
req_len = *length;
if (available_len > LOG_MSG_HEXDUMP_BYTES_SINGLE_CHUNK) {
chunk_len = LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK;
head_data = msg->payload.ext.data.bytes;
cont = msg->payload.ext.next;
} else {
head_data = msg->payload.single.bytes;
chunk_len = available_len;
}
if (offset < chunk_len) {
cpy_len = req_len > chunk_len ? chunk_len : req_len;
if (put_op) {
(void)memcpy(&head_data[offset], data, cpy_len);
} else {
(void)memcpy(data, &head_data[offset], cpy_len);
}
req_len -= cpy_len;
data += cpy_len;
} else {
offset -= chunk_len;
chunk_len = HEXDUMP_BYTES_CONT_MSG;
if (cont == NULL) {
cont = msg->payload.ext.next;
}
while (offset >= chunk_len) {
cont = cont->next;
offset -= chunk_len;
}
}
while ((req_len > 0) && (cont != NULL)) {
chunk_len = HEXDUMP_BYTES_CONT_MSG - offset;
cpy_len = req_len > chunk_len ? chunk_len : req_len;
if (put_op) {
(void)memcpy(&cont->payload.bytes[offset],
data, cpy_len);
} else {
(void)memcpy(data, &cont->payload.bytes[offset],
cpy_len);
}
offset = 0;
cont = cont->next;
req_len -= cpy_len;
data += cpy_len;
}
}
void log_msg_hexdump_data_put(struct log_msg *msg,
uint8_t *data,
size_t *length,
size_t offset)
{
log_msg_hexdump_data_op(msg, data, length, offset, true);
}
void log_msg_hexdump_data_get(struct log_msg *msg,
uint8_t *data,
size_t *length,
size_t offset)
{
log_msg_hexdump_data_op(msg, data, length, offset, false);
}
uint32_t log_msg_mem_get_free(void)
{
return k_mem_slab_num_free_get(&log_msg_pool);
}
uint32_t log_msg_mem_get_used(void)
{
return k_mem_slab_num_used_get(&log_msg_pool);
}
uint32_t log_msg_mem_get_max_used(void)
{
return k_mem_slab_max_used_get(&log_msg_pool);
}
size_t log_msg_get_slab_size(void)
{
return MSG_SIZE;
}

View file

@ -57,19 +57,8 @@ struct YMD_date {
uint32_t day;
};
extern void log_output_msg_syst_process(const struct log_output *output,
struct log_msg *msg, uint32_t flag);
extern void log_output_msg2_syst_process(const struct log_output *output,
struct log_msg2 *msg, uint32_t flag);
extern void log_output_string_syst_process(const struct log_output *output,
struct log_msg_ids src_level,
const char *fmt, va_list ap, uint32_t flag,
int16_t source_id);
extern void log_output_hexdump_syst_process(const struct log_output *output,
struct log_msg_ids src_level,
const char *metadata,
const uint8_t *data, uint32_t length,
uint32_t flag, int16_t source_id);
/* The RFC 5424 allows very flexible mapping and suggest the value 0 being the
* highest severity and 7 to be the lowest (debugging level) severity.
@ -367,95 +356,6 @@ static void newline_print(const struct log_output *ctx, uint32_t flags)
}
}
static void std_print(struct log_msg *msg,
const struct log_output *output)
{
const char *str = log_msg_str_get(msg);
uint32_t nargs = log_msg_nargs_get(msg);
log_arg_t *args = alloca(sizeof(log_arg_t)*nargs);
int i;
for (i = 0; i < nargs; i++) {
args[i] = log_msg_arg_get(msg, i);
}
switch (log_msg_nargs_get(msg)) {
case 0:
print_formatted(output, str);
break;
case 1:
print_formatted(output, str, args[0]);
break;
case 2:
print_formatted(output, str, args[0], args[1]);
break;
case 3:
print_formatted(output, str, args[0], args[1], args[2]);
break;
case 4:
print_formatted(output, str, args[0], args[1], args[2],
args[3]);
break;
case 5:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4]);
break;
case 6:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5]);
break;
case 7:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6]);
break;
case 8:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7]);
break;
case 9:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8]);
break;
case 10:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8], args[9]);
break;
case 11:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8], args[9], args[10]);
break;
case 12:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11]);
break;
case 13:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11], args[12]);
break;
case 14:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11], args[12],
args[13]);
break;
case 15:
print_formatted(output, str, args[0], args[1], args[2],
args[3], args[4], args[5], args[6], args[7],
args[8], args[9], args[10], args[11], args[12],
args[13], args[14]);
break;
default:
/* Unsupported number of arguments. */
__ASSERT_NO_MSG(true);
break;
}
}
static void hexdump_line_print(const struct log_output *output,
const uint8_t *data, uint32_t length,
int prefix_offset, uint32_t flags)
@ -496,30 +396,6 @@ static void hexdump_line_print(const struct log_output *output,
}
}
static void hexdump_print(struct log_msg *msg,
const struct log_output *output,
int prefix_offset, uint32_t flags)
{
uint32_t offset = 0U;
uint8_t buf[HEXDUMP_BYTES_IN_LINE];
size_t length;
print_formatted(output, "%s", log_msg_str_get(msg));
do {
length = sizeof(buf);
log_msg_hexdump_data_get(msg, buf, &length, offset);
if (length) {
hexdump_line_print(output, buf, length,
prefix_offset, flags);
offset += length;
} else {
break;
}
} while (true);
}
static void log_msg2_hexdump(const struct log_output *output,
uint8_t *data, uint32_t len,
int prefix_offset, uint32_t flags)
@ -536,35 +412,6 @@ static void log_msg2_hexdump(const struct log_output *output,
} while (len);
}
static void raw_string_print(struct log_msg *msg,
const struct log_output *output)
{
__ASSERT_NO_MSG(output->size);
size_t offset = 0;
size_t length;
bool eol = false;
do {
length = output->size;
/* Sting is stored in a hexdump message. */
log_msg_hexdump_data_get(msg, output->buf, &length, offset);
output->control_block->offset = length;
if (length != 0) {
eol = (output->buf[length - 1] == '\n');
}
log_output_flush(output);
offset += length;
} while (length > 0);
if (eol) {
print_formatted(output, "\r");
}
}
static uint32_t prefix_print(const struct log_output *output,
uint32_t flags, bool func_on, log_timestamp_t timestamp, uint8_t level,
uint8_t domain_id, int16_t source_id)
@ -626,43 +473,6 @@ static void postfix_print(const struct log_output *output,
newline_print(output, flags);
}
void log_output_msg_process(const struct log_output *output,
struct log_msg *msg,
uint32_t flags)
{
bool std_msg = log_msg_is_std(msg);
uint32_t timestamp = log_msg_timestamp_get(msg);
uint8_t level = (uint8_t)log_msg_level_get(msg);
uint8_t domain_id = (uint8_t)log_msg_domain_id_get(msg);
int16_t source_id = (int16_t)log_msg_source_id_get(msg);
bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING);
int prefix_offset;
if (IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) &&
flags & LOG_OUTPUT_FLAG_FORMAT_SYST) {
log_output_msg_syst_process(output, msg, flags);
return;
}
prefix_offset = raw_string ?
0 : prefix_print(output, flags, std_msg, timestamp,
level, domain_id, source_id);
if (log_msg_is_std(msg)) {
std_print(msg, output);
} else if (raw_string) {
raw_string_print(msg, output);
} else {
hexdump_print(msg, output, prefix_offset, flags);
}
if (!raw_string) {
postfix_print(output, flags, level);
}
log_output_flush(output);
}
void log_output_msg2_process(const struct log_output *output,
struct log_msg2 *msg, uint32_t flags)
{
@ -709,95 +519,6 @@ void log_output_msg2_process(const struct log_output *output,
log_output_flush(output);
}
static bool ends_with_newline(const char *fmt)
{
char c = '\0';
while (*fmt != '\0') {
c = *fmt;
fmt++;
}
return (c == '\n');
}
void log_output_string(const struct log_output *output,
struct log_msg_ids src_level, uint32_t timestamp,
const char *fmt, va_list ap, uint32_t flags)
{
int length;
uint8_t level = (uint8_t)src_level.level;
uint8_t domain_id = (uint8_t)src_level.domain_id;
int16_t source_id = (int16_t)src_level.source_id;
bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING);
if (IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) &&
flags & LOG_OUTPUT_FLAG_FORMAT_SYST) {
log_output_string_syst_process(output, src_level, fmt, ap,
flags, source_id);
return;
}
if (!raw_string) {
prefix_print(output, flags, true, timestamp,
level, domain_id, source_id);
}
length = cbvprintf(out_func, (void *)output, fmt, ap);
(void)length;
if (raw_string) {
/* add \r if string ends with newline. */
if (ends_with_newline(fmt)) {
print_formatted(output, "\r");
}
} else {
postfix_print(output, flags, level);
}
log_output_flush(output);
}
void log_output_hexdump(const struct log_output *output,
struct log_msg_ids src_level, uint32_t timestamp,
const char *metadata, const uint8_t *data,
uint32_t length, uint32_t flags)
{
uint32_t prefix_offset;
uint8_t level = (uint8_t)src_level.level;
uint8_t domain_id = (uint8_t)src_level.domain_id;
int16_t source_id = (int16_t)src_level.source_id;
if (IS_ENABLED(CONFIG_LOG_MIPI_SYST_ENABLE) &&
flags & LOG_OUTPUT_FLAG_FORMAT_SYST) {
log_output_hexdump_syst_process(output, src_level, metadata,
data, length, flags,
source_id);
return;
}
prefix_offset = prefix_print(output, flags, true, timestamp,
level, domain_id, source_id);
/* Print metadata */
print_formatted(output, "%s", metadata);
while (length != 0U) {
uint32_t part_len = length > HEXDUMP_BYTES_IN_LINE ?
HEXDUMP_BYTES_IN_LINE : length;
hexdump_line_print(output, data, part_len,
prefix_offset, flags);
data += part_len;
length -= part_len;
}
postfix_print(output, flags, level);
log_output_flush(output);
}
void log_output_dropped_process(const struct log_output *output, uint32_t cnt)
{
char buf[5];

View file

@ -22,11 +22,7 @@ static struct mipi_syst_handle log_syst_handle;
#define HEXDUMP_BYTES_IN_LINE 16
#ifdef CONFIG_LOG_STRDUP_MAX_STRING
#define STRING_BUF_MAX_LEN CONFIG_LOG_STRDUP_MAX_STRING
#else
#define STRING_BUF_MAX_LEN 128
#endif
#if defined(MIPI_SYST_PCFG_ENABLE_PLATFORM_STATE_DATA)
#if defined(CONFIG_MIPI_SYST_STP)
@ -420,7 +416,7 @@ static void update_systh_platform_data(struct mipi_syst_handle *handle,
#endif
}
#if defined(CONFIG_LOG1) || defined(CONFIG_LOG_MIPI_SYST_OUTPUT_LOG_MSG_SRC_ID)
#if defined(CONFIG_LOG_MIPI_SYST_OUTPUT_LOG_MSG_SRC_ID)
/**
* @brief Set module ID in the origin unit of Sys-T message
*
@ -599,199 +595,6 @@ static void hexdump_line_print(const uint8_t *data, uint32_t length,
MIPI_SYST_PRINTF(&log_syst_handle, severity, "%s", hexdump_buf);
}
#ifndef CONFIG_LOG2
static void std_print(struct log_msg *msg,
const struct log_output *log_output)
{
const char *str = log_msg_str_get(msg);
uint32_t nargs = log_msg_nargs_get(msg);
uint32_t *args = alloca(sizeof(uint32_t)*nargs);
uint32_t severity = level_to_syst_severity(log_msg_level_get(msg));
for (int i = 0; i < nargs; i++) {
args[i] = log_msg_arg_get(msg, i);
}
switch (log_msg_nargs_get(msg)) {
case 0:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str);
break;
case 1:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0]);
break;
case 2:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1]);
break;
case 3:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2]);
break;
case 4:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3]);
break;
case 5:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4]);
break;
case 6:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5]);
break;
case 7:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6]);
break;
case 8:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7]);
break;
case 9:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8]);
break;
case 10:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8], args[9]);
break;
case 11:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8], args[9], args[10]);
break;
case 12:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8], args[9], args[10],
args[11]);
break;
case 13:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8], args[9], args[10],
args[11], args[12]);
break;
case 14:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8], args[9], args[10],
args[11], args[12], args[13]);
break;
case 15:
MIPI_SYST_PRINTF(&log_syst_handle, severity, str, args[0],
args[1], args[2], args[3], args[4], args[5],
args[6], args[7], args[8], args[9], args[10],
args[11], args[12], args[13], args[14]);
break;
default:
/* Unsupported number of arguments. */
__ASSERT_NO_MSG(true);
break;
}
}
static void raw_string_print(struct log_msg *msg,
const struct log_output *log_output)
{
char buf[STRING_BUF_MAX_LEN + 1];
size_t length = STRING_BUF_MAX_LEN;
uint32_t severity = level_to_syst_severity(log_msg_level_get(msg));
log_msg_hexdump_data_get(msg, buf, &length, 0);
buf[length] = '\0';
MIPI_SYST_PRINTF(&log_syst_handle, severity, buf);
}
static void hexdump_print(struct log_msg *msg,
const struct log_output *log_output)
{
uint32_t offset = 0U;
uint8_t buf[HEXDUMP_BYTES_IN_LINE];
size_t length;
uint32_t severity = level_to_syst_severity(log_msg_level_get(msg));
MIPI_SYST_PRINTF(&log_syst_handle, severity, "%s", log_msg_str_get(msg));
do {
length = sizeof(buf);
log_msg_hexdump_data_get(msg, buf, &length, offset);
if (length) {
hexdump_line_print(buf, length, severity);
offset += length;
} else {
break;
}
} while (true);
}
void log_output_msg_syst_process(const struct log_output *log_output,
struct log_msg *msg, uint32_t flag)
{
uint8_t level = (uint8_t)log_msg_level_get(msg);
bool raw_string = (level == LOG_LEVEL_INTERNAL_RAW_STRING);
update_systh_platform_data(&log_syst_handle, log_output, flag);
#ifdef CONFIG_LOG_MIPI_SYST_OUTPUT_LOG_MSG_SRC_ID
int16_t source_id = (int16_t)log_msg_source_id_get(msg);
update_handle_origin_unit(&log_syst_handle, source_id);
#endif
if (log_msg_is_std(msg)) {
std_print(msg, log_output);
} else if (raw_string) {
raw_string_print(msg, log_output);
} else {
hexdump_print(msg, log_output);
}
}
void log_output_string_syst_process(const struct log_output *log_output,
struct log_msg_ids src_level,
const char *fmt, va_list ap, uint32_t flag,
int16_t source_id)
{
uint32_t severity = level_to_syst_severity((uint32_t)src_level.level);
update_systh_platform_data(&log_syst_handle, log_output, flag);
update_handle_origin_unit(&log_syst_handle, source_id);
MIPI_SYST_VPRINTF(&log_syst_handle, severity, fmt, ap);
}
void log_output_hexdump_syst_process(const struct log_output *log_output,
struct log_msg_ids src_level,
const char *metadata,
const uint8_t *data, uint32_t length,
uint32_t flag, int16_t source_id)
{
uint32_t severity = level_to_syst_severity((uint32_t)src_level.level);
update_systh_platform_data(&log_syst_handle, log_output, flag);
update_handle_origin_unit(&log_syst_handle, source_id);
MIPI_SYST_PRINTF(&log_syst_handle, severity, "%s", metadata);
while (length != 0U) {
uint32_t part_len = MIN(length, HEXDUMP_BYTES_IN_LINE);
hexdump_line_print(data, part_len, severity);
data += part_len;
length -= part_len;
}
}
#else /* !CONFIG_LOG2 */
static void hexdump2_print(const uint8_t *data, uint32_t length,
uint32_t severity)
{
@ -1070,7 +873,6 @@ void log_output_msg2_syst_process(const struct log_output *output,
hexdump2_print(data, hexdump_len, severity);
}
}
#endif /* !CONFIG_LOG2 */
static int syst_init(const struct device *arg)
{

View file

@ -39,35 +39,12 @@ static inline int log_translate(otLogLevel aLogLevel)
return -1;
}
#if defined(CONFIG_LOG)
static uint32_t count_args(const char *fmt)
{
uint32_t args = 0U;
bool prev = false; /* if previous char was a modificator. */
while (*fmt != '\0') {
if (*fmt == '%') {
prev = !prev;
} else if (prev) {
args++;
prev = false;
} else {
; /* standard character, continue walk */
}
fmt++;
}
return args;
}
#endif
void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
{
ARG_UNUSED(aLogRegion);
#if defined(CONFIG_LOG)
int level = log_translate(aLogLevel);
uint32_t args_num = count_args(aFormat);
va_list param_list;
if (level < 0) {
@ -75,13 +52,7 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat
}
va_start(param_list, aFormat);
/* We assume, that OT has no access to strdup utility,
* and we are not obliged to check, if string has already
* been duplicated. So, to save time, in Z_LOG_VA macro calls
* we will use LOG_STRDUP_EXEC option.
*/
Z_LOG_VA(level, aFormat, param_list, args_num, LOG_STRDUP_EXEC);
log2_generic(level, aFormat, param_list);
va_end(param_list);
#else
ARG_UNUSED(aLogLevel);

View file

@ -227,6 +227,7 @@ config SHELL_CMD_ROOT
config SHELL_LOG_BACKEND
bool "Shell log backend"
depends on LOG && !LOG_MODE_MINIMAL
select MPSC_PBUF
default y if LOG
help
When enabled, backend will use the shell for logging.

View file

@ -367,12 +367,6 @@ static size_t get_long_hexdump(void)
/* Hexdump message excluding data */
ROUND_UP(LOG_SIMPLE_MSG_LEN + STR_SIZE("hexdump") + extra_hexdump_sz,
sizeof(long long)) - 2 * sizeof(int);
uint32_t msgs_in_buf = (uint32_t)CONFIG_LOG_BUFFER_SIZE / sizeof(union log_msg_chunk);
return LOG_MSG_HEXDUMP_BYTES_HEAD_CHUNK +
HEXDUMP_BYTES_CONT_MSG * (msgs_in_buf - 1) -
HEXDUMP_BYTES_CONT_MSG;
}
/*

View file

@ -29,9 +29,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#define DBG_PRINT(...)
#endif
typedef void (*custom_put_callback_t)(struct log_backend const *const backend,
struct log_msg *msg, size_t counter);
struct backend_cb {
size_t counter;
bool panic;
@ -44,7 +41,6 @@ struct backend_cb {
uint32_t exp_nargs[100];
bool check_strdup;
bool exp_strdup[100];
custom_put_callback_t callback;
uint32_t total_drops;
};

View file

@ -158,14 +158,14 @@ static void log_setup(bool backend2_enable)
}
}
static bool log_test_process(bool bypass)
static bool log_test_process(void)
{
if (IS_ENABLED(CONFIG_LOG_PROCESS_THREAD)) {
/* waiting for all logs have been handled */
k_sem_take(&log_sem, K_FOREVER);
return false;
} else {
return log_process(bypass);
return log_process();
}
}
@ -187,7 +187,7 @@ void test_log_domain_id(void)
LOG_INF("info message for domain id test");
while (log_test_process(false)) {
while (log_test_process()) {
}
zassert_equal(backend1_cb.total_logs, backend1_cb.counter,
@ -256,7 +256,7 @@ void test_log_early_logging(void)
backend1_cb.total_logs = 3;
log_backend_enable(&backend1, &backend1_cb, LOG_LEVEL_DBG);
while (log_test_process(false)) {
while (log_test_process()) {
}
zassert_equal(backend1_cb.total_logs, backend1_cb.counter,
@ -288,7 +288,7 @@ void test_log_severity(void)
LOG_ERR("error message");
backend1_cb.total_logs = 3;
while (log_test_process(false)) {
while (log_test_process()) {
}
zassert_equal(backend1_cb.total_logs, backend1_cb.counter,
@ -336,7 +336,7 @@ void test_log_timestamping(void)
LOG_WRN("test timestamp");
backend1_cb.total_logs = 3;
while (log_test_process(false)) {
while (log_test_process()) {
}
zassert_equal(backend1_cb.total_logs,
@ -423,34 +423,28 @@ void test_log_thread(void)
}
#endif
static void call_log_generic(uint32_t source_id, const char *fmt, ...)
static void call_log_generic(const char *fmt, ...)
{
struct log_msg_ids src_level = {
.level = LOG_LEVEL_INF,
.domain_id = CONFIG_LOG_DOMAIN_ID,
.source_id = source_id,
};
va_list ap;
va_start(ap, fmt);
log_generic(src_level, fmt, ap, LOG_STRDUP_EXEC);
log2_generic(LOG_LEVEL_INF, fmt, ap);
va_end(ap);
}
void test_log_generic(void)
{
source_id = LOG_CURRENT_MODULE_ID();
char *log_msg = "log user space";
int i = 100;
log_setup(false);
backend1_cb.total_logs = 4;
call_log_generic(source_id, "log generic");
call_log_generic(source_id, "log generic: %s", log_msg);
call_log_generic(source_id, "log generic %d\n", source_id);
call_log_generic(source_id, "log generic %d, %d\n", source_id, 1);
while (log_test_process(false)) {
call_log_generic("log generic");
call_log_generic("log generic: %s", log_msg);
call_log_generic("log generic %d\n", i);
call_log_generic("log generic %d, %d\n", i, 1);
while (log_test_process()) {
}
}
@ -475,7 +469,7 @@ void test_log_msg2_create(void)
CONFIG_LOG_DOMAIN_ID, NULL,
LOG_LEVEL_INTERNAL_RAW_STRING, NULL, 0, test_msg_usr);
while (log_test_process(false)) {
while (log_test_process()) {
}
}
}
@ -499,7 +493,7 @@ void test_log_msg2_create_user(void)
CONFIG_LOG_DOMAIN_ID, NULL,
LOG_LEVEL_INTERNAL_RAW_STRING, NULL, 0, test_msg_usr);
while (log_test_process(false)) {
while (log_test_process()) {
}
}
/* The log process thread has the K_LOWEST_APPLICATION_THREAD_PRIO, adjust it

View file

@ -30,7 +30,7 @@ void test_log_from_user(void)
LOG_INF("log from user");
LOG_INF("log from user %d", d);
cnt0 = log_buffered_cnt();
while (log_process(false)) {
while (log_process()) {
}
cnt1 = log_buffered_cnt();
zassert_true(cnt1 <= cnt0, "no message is handled");
@ -42,7 +42,7 @@ void test_log_hexdump_from_user(void)
int32_t data = 128;
LOG_HEXDUMP_INF(&data, sizeof(data), "test_hexdump");
while (log_process(false)) {
while (log_process()) {
}
}
@ -61,7 +61,7 @@ void test_log_generic_user(void)
uint32_t source_id = 0;
call_log_generic(source_id, "log generic\n");
while (log_process(false)) {
while (log_process()) {
}
}

View file

@ -51,108 +51,16 @@ static int mock_output_func(uint8_t *buf, size_t size, void *ctx)
LOG_OUTPUT_DEFINE(log_output, mock_output_func,
log_output_buf, sizeof(log_output_buf));
static void validate_output_string(const char *exp)
static void test_log_output_empty(void)
{
int len = strlen(exp);
zassert_equal(len, mock_len, "Unexpected string length");
zassert_equal(0, memcmp(exp, mock_buffer, mock_len),
"Unexpected string");
}
static void log_output_string_varg(const struct log_output *log_output,
struct log_msg_ids src_level, uint32_t timestamp,
uint32_t flags, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
log_output_string(log_output, src_level, timestamp, fmt, ap, flags);
va_end(ap);
}
void test_log_output_raw_string(void)
{
const char *exp_str = "abc 1 3";
const char *exp_str2 = "abc efg 3\n\r";
struct log_msg_ids src_level = {
.level = LOG_LEVEL_INTERNAL_RAW_STRING,
.source_id = 0, /* not used as level indicates raw string. */
.domain_id = 0, /* not used as level indicates raw string. */
};
log_output_string_varg(&log_output, src_level, 0, 0,
"abc %d %d", 1, 3);
/* test if log_output flushed correct string */
validate_output_string(exp_str);
reset_mock_buffer();
/* Test adding \r after new line feed */
log_output_string_varg(&log_output, src_level, 0, 0,
"abc %s %d\n", "efg", 3);
/* test if log_output flushed correct string */
validate_output_string(exp_str2);
}
void test_log_output_string(void)
{
const char *exp_str = STRINGIFY(LOG_MODULE_NAME) ".abc 1 3\r\n";
const char *exp_str_lvl =
"<dbg> " STRINGIFY(LOG_MODULE_NAME) ".abc 1 3\r\n";
const char *exp_str_timestamp =
"[00123456] " STRINGIFY(LOG_MODULE_NAME) ".abc 1 3\r\n";
const char *exp_str_no_crlf = STRINGIFY(LOG_MODULE_NAME) ".abc 1 3";
struct log_msg_ids src_level = {
.level = LOG_LEVEL_DBG,
.source_id = log_const_source_id(
&Z_LOG_ITEM_CONST_DATA(LOG_MODULE_NAME)),
.domain_id = CONFIG_LOG_DOMAIN_ID,
};
log_output_string_varg(&log_output, src_level, 0,
0 /* no flags */,
"abc %d %d", 1, 3);
/* test if log_output flushed correct string */
validate_output_string(exp_str);
reset_mock_buffer();
/* Test that LOG_OUTPUT_FLAG_LEVEL adds log level prefix. */
log_output_string_varg(&log_output, src_level, 0,
LOG_OUTPUT_FLAG_LEVEL,
"abc %d %d", 1, 3);
/* test if log_output flushed correct string */
validate_output_string(exp_str_lvl);
reset_mock_buffer();
/* Test that LOG_OUTPUT_FLAG_TIMESTAMP adds timestamp. */
log_output_string_varg(&log_output, src_level, 123456,
LOG_OUTPUT_FLAG_TIMESTAMP,
"abc %d %d", 1, 3);
/* test if log_output flushed correct string */
validate_output_string(exp_str_timestamp);
reset_mock_buffer();
/* Test that LOG_OUTPUT_FLAG_CRLF_NONE adds no crlf */
log_output_string_varg(&log_output, src_level, 0,
LOG_OUTPUT_FLAG_CRLF_NONE,
"abc %d %d", 1, 3);
/* test if log_output flushed correct string */
validate_output_string(exp_str_no_crlf);
(void)&log_output;
}
/*test case main entry*/
void test_main(void)
{
ztest_test_suite(test_log_output,
ztest_unit_test_setup_teardown(test_log_output_raw_string,
setup, teardown),
ztest_unit_test_setup_teardown(test_log_output_string,
ztest_unit_test_setup_teardown(test_log_output_empty,
setup, teardown)
);
ztest_run_test_suite(test_log_output);

View file

@ -4,7 +4,6 @@ CONFIG_LOG_BUFFER_SIZE=1024
CONFIG_LOG_PROCESS_THREAD=y
CONFIG_LOG_PROCESS_THREAD_SLEEP_MS=100
CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=2
CONFIG_LOG_PRINTK_MAX_STRING_LENGTH=256
CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=4096
CONFIG_LOG_BLOCK_IN_THREAD=y
CONFIG_LOG_BACKEND_UART=y