logging: add minimal implementation
The log mechanism, even in immediate mode, adds somewhere between 1K-2K of footprint to applications that use it. We want to standardize the logging APIs for all logging within the kernel, but need to not let platforms with very constrained RAM/ROM in the dust. This patch introduces CONFIG_LOG_MINIMAL, which is a very thin wrapper to printk(). It supports the APIs expressed in logging/log.h. This will be the new default for test cases. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
1b900bf546
commit
7e29c9da0b
7 changed files with 222 additions and 94 deletions
|
@ -28,12 +28,6 @@ extern "C" {
|
|||
* @{
|
||||
*/
|
||||
|
||||
#define LOG_LEVEL_NONE 0
|
||||
#define LOG_LEVEL_ERR 1
|
||||
#define LOG_LEVEL_WRN 2
|
||||
#define LOG_LEVEL_INF 3
|
||||
#define LOG_LEVEL_DBG 4
|
||||
|
||||
/**
|
||||
* @brief Writes an ERROR level message to the log.
|
||||
*
|
||||
|
@ -247,6 +241,7 @@ extern "C" {
|
|||
#define LOG_INST_HEXDUMP_DBG(_log_inst, _data, _length, _str) \
|
||||
Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_DBG, _log_inst, _data, _length, _str)
|
||||
|
||||
#ifndef CONFIG_LOG_MINIMAL
|
||||
/**
|
||||
* @brief Writes an formatted string to the log.
|
||||
*
|
||||
|
@ -266,13 +261,29 @@ void log_printk(const char *fmt, va_list ap);
|
|||
* 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).
|
||||
* a buffer from the pool (see CONFIG_LOG_STRDUP_MAX_STRING). In
|
||||
* some configurations, the original string pointer is returned.
|
||||
*/
|
||||
char *log_strdup(const char *str);
|
||||
#else
|
||||
static inline void log_printk(const char *fmt, va_list ap)
|
||||
{
|
||||
vprintk(fmt, ap);
|
||||
}
|
||||
|
||||
static inline char *log_strdup(const char *str)
|
||||
{
|
||||
return (char *)str;
|
||||
}
|
||||
#endif /* CONFIG_LOG_MINIMAL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
#include <stdarg.h>
|
||||
#include <syscall.h>
|
||||
#include <sys/util.h>
|
||||
#include <sys/printk.h>
|
||||
|
||||
#define LOG_LEVEL_NONE 0
|
||||
#define LOG_LEVEL_ERR 1
|
||||
#define LOG_LEVEL_WRN 2
|
||||
#define LOG_LEVEL_INF 3
|
||||
#define LOG_LEVEL_DBG 4
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -20,10 +27,13 @@ extern "C" {
|
|||
|
||||
#ifndef CONFIG_LOG
|
||||
#define CONFIG_LOG_DEFAULT_LEVEL 0
|
||||
#define CONFIG_LOG_DOMAIN_ID 0
|
||||
#define CONFIG_LOG_MAX_LEVEL 0
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_LOG) || defined(CONFIG_LOG_MINIMAL)
|
||||
#define CONFIG_LOG_DOMAIN_ID 0
|
||||
#endif
|
||||
|
||||
#define LOG_FUNCTION_PREFIX_MASK \
|
||||
(((u32_t)IS_ENABLED(CONFIG_LOG_FUNC_NAME_PREFIX_ERR) << \
|
||||
LOG_LEVEL_ERR) | \
|
||||
|
@ -210,35 +220,67 @@ extern "C" {
|
|||
) \
|
||||
))
|
||||
|
||||
/******************************************************************************/
|
||||
/****************** Defiinitions used by minimal logging **********************/
|
||||
/******************************************************************************/
|
||||
void log_minimal_hexdump_print(int level, const char *data, size_t size);
|
||||
|
||||
#define Z_LOG_TO_PRINTK(_level, fmt, ...) do { \
|
||||
printk("%c: " fmt "\n", z_log_minimal_level_to_char(_level), \
|
||||
##__VA_ARGS__); \
|
||||
} while (false)
|
||||
|
||||
static inline char z_log_minimal_level_to_char(int level)
|
||||
{
|
||||
switch (level) {
|
||||
case LOG_LEVEL_ERR:
|
||||
return 'E';
|
||||
case LOG_LEVEL_WRN:
|
||||
return 'W';
|
||||
case LOG_LEVEL_INF:
|
||||
return 'I';
|
||||
case LOG_LEVEL_DBG:
|
||||
return 'D';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
/******************************************************************************/
|
||||
/****************** Macros for standard logging *******************************/
|
||||
/******************************************************************************/
|
||||
#define __LOG(_level, _id, _filter, ...) \
|
||||
do { \
|
||||
bool is_user_context = _is_user_context(); \
|
||||
\
|
||||
if (Z_LOG_CONST_LEVEL_CHECK(_level) && \
|
||||
(is_user_context || \
|
||||
(_level <= LOG_RUNTIME_FILTER(_filter)))) { \
|
||||
struct log_msg_ids src_level = { \
|
||||
.level = _level, \
|
||||
.domain_id = CONFIG_LOG_DOMAIN_ID, \
|
||||
.source_id = _id \
|
||||
}; \
|
||||
\
|
||||
if ((BIT(_level) & LOG_FUNCTION_PREFIX_MASK) != 0U) {\
|
||||
__LOG_INTERNAL(is_user_context, src_level, \
|
||||
Z_LOG_STR(__VA_ARGS__)); \
|
||||
} else { \
|
||||
__LOG_INTERNAL(is_user_context, src_level, \
|
||||
__VA_ARGS__); \
|
||||
} \
|
||||
} else if (false) { \
|
||||
/* Arguments checker present but never evaluated.*/ \
|
||||
/* Placed here to ensure that __VA_ARGS__ are*/ \
|
||||
/* evaluated once when log is enabled.*/ \
|
||||
log_printf_arg_checker(__VA_ARGS__); \
|
||||
} \
|
||||
#define __LOG(_level, _id, _filter, ...) \
|
||||
do { \
|
||||
bool is_user_context = _is_user_context(); \
|
||||
\
|
||||
if (Z_LOG_CONST_LEVEL_CHECK(_level)) { \
|
||||
if (IS_ENABLED(CONFIG_LOG_MINIMAL)) { \
|
||||
Z_LOG_TO_PRINTK(_level, __VA_ARGS__); \
|
||||
} else if (is_user_context || \
|
||||
(_level <= LOG_RUNTIME_FILTER(_filter))) { \
|
||||
struct log_msg_ids src_level = { \
|
||||
.level = _level, \
|
||||
.domain_id = CONFIG_LOG_DOMAIN_ID, \
|
||||
.source_id = _id \
|
||||
}; \
|
||||
\
|
||||
if ((BIT(_level) & \
|
||||
LOG_FUNCTION_PREFIX_MASK) != 0U) { \
|
||||
__LOG_INTERNAL(is_user_context, \
|
||||
src_level, \
|
||||
Z_LOG_STR(__VA_ARGS__));\
|
||||
} else { \
|
||||
__LOG_INTERNAL(is_user_context, \
|
||||
src_level, \
|
||||
__VA_ARGS__); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (false) { \
|
||||
/* Arguments checker present but never evaluated.*/ \
|
||||
/* Placed here to ensure that __VA_ARGS__ are*/ \
|
||||
/* evaluated once when log is enabled.*/ \
|
||||
log_printf_arg_checker(__VA_ARGS__); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define Z_LOG(_level, ...) \
|
||||
|
@ -259,29 +301,35 @@ extern "C" {
|
|||
/******************************************************************************/
|
||||
/****************** Macros for hexdump logging ********************************/
|
||||
/******************************************************************************/
|
||||
#define __LOG_HEXDUMP(_level, _id, _filter, _data, _length, _str) \
|
||||
do { \
|
||||
bool is_user_context = _is_user_context(); \
|
||||
\
|
||||
if (Z_LOG_CONST_LEVEL_CHECK(_level) && \
|
||||
(is_user_context || \
|
||||
(_level <= LOG_RUNTIME_FILTER(_filter)))) { \
|
||||
struct log_msg_ids src_level = { \
|
||||
.level = _level, \
|
||||
.source_id = _id, \
|
||||
.domain_id = CONFIG_LOG_DOMAIN_ID \
|
||||
}; \
|
||||
\
|
||||
if (is_user_context) { \
|
||||
log_hexdump_from_user(src_level, _str, \
|
||||
_data, _length); \
|
||||
} else if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
|
||||
log_hexdump_sync(src_level, _str, \
|
||||
_data, _length); \
|
||||
} else { \
|
||||
log_hexdump(_str, _data, _length, src_level); \
|
||||
} \
|
||||
} \
|
||||
#define __LOG_HEXDUMP(_level, _id, _filter, _data, _length, _str) \
|
||||
do { \
|
||||
bool is_user_context = _is_user_context(); \
|
||||
\
|
||||
if (Z_LOG_CONST_LEVEL_CHECK(_level)) { \
|
||||
if (IS_ENABLED(CONFIG_LOG_MINIMAL)) { \
|
||||
Z_LOG_TO_PRINTK(_level, "%s", _str); \
|
||||
log_minimal_hexdump_print(_level, _data, \
|
||||
_length); \
|
||||
} else if (is_user_context || \
|
||||
(_level <= LOG_RUNTIME_FILTER(_filter))) { \
|
||||
struct log_msg_ids src_level = { \
|
||||
.level = _level, \
|
||||
.source_id = _id, \
|
||||
.domain_id = CONFIG_LOG_DOMAIN_ID \
|
||||
}; \
|
||||
\
|
||||
if (is_user_context) { \
|
||||
log_hexdump_from_user(src_level, _str, \
|
||||
_data, _length); \
|
||||
} else if (IS_ENABLED(CONFIG_LOG_IMMEDIATE)) { \
|
||||
log_hexdump_sync(src_level, _str, \
|
||||
_data, _length); \
|
||||
} else { \
|
||||
log_hexdump(_str, _data, _length, \
|
||||
src_level); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define Z_LOG_HEXDUMP(_level, _data, _length, _str) \
|
||||
|
|
|
@ -169,7 +169,7 @@ void log_backend_enable(struct log_backend const *const backend,
|
|||
*/
|
||||
void log_backend_disable(struct log_backend const *const backend);
|
||||
|
||||
#if defined(CONFIG_LOG)
|
||||
#if defined(CONFIG_LOG) && !defined(CONFIG_LOG_MINIMAL)
|
||||
#define LOG_CORE_INIT() log_core_init()
|
||||
#define LOG_INIT() log_init()
|
||||
#define LOG_PANIC() log_panic()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue