diff --git a/include/shell/shell_log_backend.h b/include/shell/shell_log_backend.h index 6be97d96a19..d1f5121a8b0 100644 --- a/include/shell/shell_log_backend.h +++ b/include/shell/shell_log_backend.h @@ -40,6 +40,12 @@ struct shell_log_backend { u32_t timeout; }; +/** @brief Shell log backend message structure. */ +struct shell_log_backend_msg { + struct log_msg *msg; + u32_t timestamp; +}; + /** @brief Prototype of function outputing processed data. */ int shell_log_backend_output_func(u8_t *data, size_t length, void *ctx); @@ -61,7 +67,7 @@ int shell_log_backend_output_func(u8_t *data, size_t length, void *ctx); #if CONFIG_LOG #define SHELL_LOG_BACKEND_DEFINE(_name, _buf, _size, _queue_size, _timeout) \ LOG_BACKEND_DEFINE(_name##_backend, log_backend_shell_api, false); \ - K_MSGQ_DEFINE(_name##_msgq, sizeof(void *), \ + K_MSGQ_DEFINE(_name##_msgq, sizeof(struct shell_log_backend_msg), \ _queue_size, sizeof(void *)); \ LOG_OUTPUT_DEFINE(_name##_log_output, shell_log_backend_output_func, \ _buf, _size); \ diff --git a/subsys/shell/shell_log_backend.c b/subsys/shell/shell_log_backend.c index 69ca0300572..bcb3d72edb9 100644 --- a/subsys/shell/shell_log_backend.c +++ b/subsys/shell/shell_log_backend.c @@ -26,12 +26,12 @@ void shell_log_backend_enable(const struct shell_log_backend *backend, static struct log_msg *msg_from_fifo(const struct shell_log_backend *backend) { - struct log_msg *msg; + struct shell_log_backend_msg msg; int err; err = k_msgq_get(backend->msgq, &msg, K_NO_WAIT); - return (err == 0) ? msg : NULL; + return (err == 0) ? msg.msg : NULL; } static void fifo_flush(const struct shell_log_backend *backend) @@ -44,12 +44,40 @@ static void fifo_flush(const struct shell_log_backend *backend) } } +static void flush_expired_messages(const struct shell *shell) +{ + int err; + struct shell_log_backend_msg msg; + struct k_msgq *msgq = shell->log_backend->msgq; + u32_t timeout = shell->log_backend->timeout; + u32_t now = k_uptime_get_32(); + + while (1) { + err = k_msgq_peek(msgq, &msg); + + if (err == 0 && ((now - msg.timestamp) > timeout)) { + (void)k_msgq_get(msgq, &msg, K_NO_WAIT); + log_msg_put(msg.msg); + + if (IS_ENABLED(CONFIG_SHELL_STATS)) { + shell->stats->log_lost_cnt++; + } + } else { + break; + } + } +} + static void msg_to_fifo(const struct shell *shell, struct log_msg *msg) { int err; + struct shell_log_backend_msg t_msg = { + .msg = msg, + .timestamp = k_uptime_get_32() + }; - err = k_msgq_put(shell->log_backend->msgq, &msg, + err = k_msgq_put(shell->log_backend->msgq, &t_msg, shell->log_backend->timeout); switch (err) { @@ -58,18 +86,7 @@ static void msg_to_fifo(const struct shell *shell, case -EAGAIN: case -ENOMSG: { - struct log_msg *old_msg; - - /* drop one message */ - old_msg = msg_from_fifo(shell->log_backend); - - if (old_msg) { - log_msg_put(old_msg); - - if (IS_ENABLED(CONFIG_SHELL_STATS)) { - shell->stats->log_lost_cnt++; - } - } + flush_expired_messages(shell); err = k_msgq_put(shell->log_backend->msgq, &msg, K_NO_WAIT); if (err) {