logging: Add frontend support to v2
Extended logging v2 to support frontend api. Contrary to v1, it is possible to have frontend and backends in the system. Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
ca217fe189
commit
7c72b78660
12 changed files with 95 additions and 24 deletions
|
@ -287,7 +287,9 @@ void z_log_vprintk(const char *fmt, va_list ap);
|
|||
char *z_log_strdup(const char *str);
|
||||
static inline char *log_strdup(const char *str)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_LOG_MODE_MINIMAL) || IS_ENABLED(CONFIG_LOG2)) {
|
||||
if (IS_ENABLED(CONFIG_LOG_MODE_MINIMAL) ||
|
||||
IS_ENABLED(CONFIG_LOG_FRONTEND) ||
|
||||
IS_ENABLED(CONFIG_LOG2)) {
|
||||
return (char *)str;
|
||||
}
|
||||
|
||||
|
|
|
@ -201,7 +201,9 @@ extern "C" {
|
|||
|
||||
#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 { \
|
||||
|
@ -334,8 +336,8 @@ static inline char z_log_minimal_level_to_char(int level)
|
|||
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)) { \
|
||||
if (!IS_ENABLED(CONFIG_LOG_FRONTEND) && IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && \
|
||||
!is_user_context && _level > Z_LOG_RUNTIME_FILTER(filters)) { \
|
||||
break; \
|
||||
} \
|
||||
if (IS_ENABLED(CONFIG_LOG2)) { \
|
||||
|
@ -414,8 +416,8 @@ static inline char z_log_minimal_level_to_char(int level)
|
|||
(const char *)_data, _len);\
|
||||
break; \
|
||||
} \
|
||||
if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && !is_user_context && \
|
||||
_level > Z_LOG_RUNTIME_FILTER(filters)) { \
|
||||
if (!IS_ENABLED(CONFIG_LOG_FRONTEND) && IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING) && \
|
||||
!is_user_context && _level > Z_LOG_RUNTIME_FILTER(filters)) { \
|
||||
break; \
|
||||
} \
|
||||
if (IS_ENABLED(CONFIG_LOG2)) { \
|
||||
|
@ -440,8 +442,9 @@ static inline char z_log_minimal_level_to_char(int level)
|
|||
.source_id = src_id, \
|
||||
}; \
|
||||
if (is_user_context) { \
|
||||
log_hexdump_from_user(src_level, _str, \
|
||||
(const char *)_data, _len); \
|
||||
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 { \
|
||||
|
|
|
@ -263,7 +263,7 @@ int log_mem_get_usage(uint32_t *buf_size, uint32_t *usage);
|
|||
*/
|
||||
int log_mem_get_max_usage(uint32_t *max);
|
||||
|
||||
#if defined(CONFIG_LOG) && !defined(CONFIG_LOG_MODE_MINIMAL)
|
||||
#if defined(CONFIG_LOG) && !defined(CONFIG_LOG_MODE_MINIMAL) && !defined(CONFIG_LOG_FRONTEND_ONLY)
|
||||
#define LOG_CORE_INIT() log_core_init()
|
||||
#define LOG_INIT() log_init()
|
||||
#define LOG_PANIC() log_panic()
|
||||
|
|
|
@ -79,5 +79,27 @@ void log_frontend_hexdump(const char *str,
|
|||
uint32_t length,
|
||||
struct log_msg_ids src_level);
|
||||
|
||||
/** @brief Log message.
|
||||
*
|
||||
* Message details does not contain timestamp. Since function is called in the
|
||||
* context of log message call, implementation can use its own timestamping scheme.
|
||||
*
|
||||
* @param source Pointer to a structure associated with given source. It points to
|
||||
* static structure or dynamic structure if runtime filtering is enabled.
|
||||
* @ref log_const_source_id or @ref log_dynamic_source_id can be used to determine
|
||||
* source id.
|
||||
*
|
||||
* @param desc Message descriptor.
|
||||
*
|
||||
* @param package Cbprintf package containing logging formatted string. Length s in @p desc.
|
||||
*
|
||||
* @param data Hexdump data. Length is in @p desc.
|
||||
*/
|
||||
void log_frontend_msg(const void *source,
|
||||
const struct log_msg2_desc desc,
|
||||
uint8_t *package, const void *data);
|
||||
|
||||
/** @brief Panic state notification. */
|
||||
void log_frontend_panic(void);
|
||||
|
||||
#endif /* LOG_FRONTEND_H_ */
|
||||
|
|
|
@ -14,7 +14,7 @@ rsource "Kconfig.mode"
|
|||
|
||||
rsource "Kconfig.filtering"
|
||||
|
||||
if !LOG_FRONTEND && !LOG_MODE_MINIMAL
|
||||
if !LOG_FRONTEND_ONLY && !LOG_MODE_MINIMAL
|
||||
|
||||
rsource "Kconfig.formatting"
|
||||
|
||||
|
@ -22,7 +22,7 @@ rsource "Kconfig.processing"
|
|||
|
||||
rsource "Kconfig.backends"
|
||||
|
||||
endif # !LOG_FRONTEND && !LOG_MODE_MINIMAL
|
||||
endif # !LOG_FRONTEND_ONLY && !LOG_MODE_MINIMAL
|
||||
|
||||
rsource "Kconfig.misc"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ menu "Logging levels filtering"
|
|||
|
||||
config LOG_RUNTIME_FILTERING
|
||||
bool "Runtime filtering reconfiguration"
|
||||
depends on !LOG_FRONTEND && !LOG_MODE_MINIMAL
|
||||
depends on !LOG_FRONTEND_ONLY && !LOG_MODE_MINIMAL
|
||||
help
|
||||
Allow runtime configuration of maximal, independent severity
|
||||
level for instance.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
menu "Output Formatting"
|
||||
|
||||
menu "Prepend non-hexdump log message with function name"
|
||||
depends on !LOG_FRONTEND
|
||||
depends on !LOG_FRONTEND_ONLY
|
||||
|
||||
config LOG_FUNC_NAME_PREFIX_ERR
|
||||
bool "Error messages prepended"
|
||||
|
|
|
@ -14,7 +14,7 @@ config LOG_DOMAIN_ID
|
|||
config LOG_CMDS
|
||||
bool "Shell commands"
|
||||
depends on SHELL
|
||||
depends on !LOG_FRONTEND && !LOG_MODE_MINIMAL
|
||||
depends on !LOG_FRONTEND_ONLY && !LOG_MODE_MINIMAL
|
||||
default y if SHELL
|
||||
|
||||
config LOG_TEST_CLEAR_MESSAGE_SPACE
|
||||
|
|
|
@ -40,16 +40,23 @@ config LOG_MODE_MINIMAL
|
|||
colors, or asynchronous logging, and all messages are simply
|
||||
sent to printk().
|
||||
|
||||
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 instead
|
||||
of being processed by the logger. In this mode runtime filtering and
|
||||
multiple backends are not used.
|
||||
When enabled, logs are redirected to a custom frontend which is the
|
||||
fastest way of getting logs out.
|
||||
|
||||
endchoice
|
||||
config LOG_FRONTEND_ONLY
|
||||
bool "No backends" if !LOG1
|
||||
default y if LOG1
|
||||
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)"
|
||||
|
|
|
@ -164,6 +164,7 @@ config LOG_TIMESTAMP_64BIT
|
|||
config LOG_SPEED
|
||||
bool "Prefer performance over size"
|
||||
depends on LOG_MODE_DEFERRED
|
||||
depends on !LOG_FRONTEND
|
||||
help
|
||||
If enabled, logging may take more code size to get faster logging.
|
||||
endif # LOG2
|
||||
|
|
|
@ -60,6 +60,10 @@ LOG_MODULE_REGISTER(log);
|
|||
#define CONFIG_LOG_BUFFER_SIZE 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LOG_TAG_MAX_LEN
|
||||
#define CONFIG_LOG_TAG_MAX_LEN 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LOG2_ALWAYS_RUNTIME
|
||||
BUILD_ASSERT(!IS_ENABLED(CONFIG_NO_OPTIMIZATIONS),
|
||||
"Option must be enabled when CONFIG_NO_OPTIMIZATIONS is set");
|
||||
|
@ -687,6 +691,10 @@ void z_impl_log_panic(void)
|
|||
*/
|
||||
log_init();
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
log_frontend_panic();
|
||||
}
|
||||
|
||||
for (int i = 0; i < log_backend_count_get(); i++) {
|
||||
backend = log_backend_get(i);
|
||||
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
#include <syscall_handler.h>
|
||||
#include <logging/log_internal.h>
|
||||
#include <logging/log_ctrl.h>
|
||||
#include <logging/log_frontend.h>
|
||||
#include <logging/log_backend.h>
|
||||
|
||||
/* Returns true if any backend is in use. */
|
||||
#define BACKENDS_IN_USE() \
|
||||
!(IS_ENABLED(CONFIG_LOG_FRONTEND) && \
|
||||
(IS_ENABLED(CONFIG_LOG_FRONTEND_ONLY) || log_backend_count_get() == 0))
|
||||
|
||||
void z_log_msg2_finalize(struct log_msg2 *msg, const void *source,
|
||||
const struct log_msg2_desc desc, const void *data)
|
||||
|
@ -32,6 +39,14 @@ void z_impl_z_log_msg2_static_create(const void *source,
|
|||
const struct log_msg2_desc desc,
|
||||
uint8_t *package, const void *data)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
log_frontend_msg(source, desc, package, data);
|
||||
}
|
||||
|
||||
if (!BACKENDS_IN_USE()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t msg_wlen = log_msg2_get_total_wlen(desc);
|
||||
struct log_msg2 *msg = z_log_msg2_alloc(msg_wlen);
|
||||
|
||||
|
@ -72,21 +87,34 @@ void z_impl_z_log_msg2_runtime_vcreate(uint8_t domain_id, const void *source,
|
|||
|
||||
size_t msg_wlen = Z_LOG_MSG2_ALIGNED_WLEN(plen, dlen);
|
||||
struct log_msg2 *msg;
|
||||
uint8_t *pkg;
|
||||
struct log_msg2_desc desc =
|
||||
Z_LOG_MSG_DESC_INITIALIZER(domain_id, level, plen, dlen);
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE)) {
|
||||
msg = alloca(msg_wlen * sizeof(int));
|
||||
} else {
|
||||
if (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED) && BACKENDS_IN_USE()) {
|
||||
msg = z_log_msg2_alloc(msg_wlen);
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND) && msg == NULL) {
|
||||
pkg = alloca(plen);
|
||||
} else {
|
||||
pkg = msg ? msg->data : NULL;
|
||||
}
|
||||
} else {
|
||||
msg = alloca(msg_wlen * sizeof(int));
|
||||
pkg = msg->data;
|
||||
}
|
||||
|
||||
if (msg && fmt) {
|
||||
plen = cbvprintf_package(msg->data, (size_t)plen, package_flags, fmt, ap);
|
||||
if (pkg && fmt) {
|
||||
plen = cbvprintf_package(pkg, (size_t)plen, package_flags, fmt, ap);
|
||||
__ASSERT_NO_MSG(plen >= 0);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_LOG_FRONTEND)) {
|
||||
log_frontend_msg(source, desc, pkg, data);
|
||||
}
|
||||
|
||||
if (BACKENDS_IN_USE()) {
|
||||
z_log_msg2_finalize(msg, source, desc, data);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue