From f78067e1f941523db2abd0a928742eeede41f893 Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Wed, 28 Nov 2018 14:06:40 +0100 Subject: [PATCH] shell: Refactor RTT backend Improved reception in the backend and replaced thread with periodic timer as thread was used only to periodically poll RTT data availability and using timer is more RAM-wise efficient. Signed-off-by: Krzysztof Chruscinski --- include/shell/shell_rtt.h | 2 -- subsys/shell/Kconfig.backends | 38 +++++++++++++++--------- subsys/shell/shell_rtt.c | 54 ++++++++++++++--------------------- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/include/shell/shell_rtt.h b/include/shell/shell_rtt.h index cf749c0e029..e8924f061e6 100644 --- a/include/shell/shell_rtt.h +++ b/include/shell/shell_rtt.h @@ -19,8 +19,6 @@ struct shell_rtt { shell_transport_handler_t handler; struct k_timer timer; void *context; - u8_t rx[5]; - size_t rx_cnt; }; #define SHELL_RTT_DEFINE(_name) \ diff --git a/subsys/shell/Kconfig.backends b/subsys/shell/Kconfig.backends index b53e69de9d9..94f3b1eb9dc 100644 --- a/subsys/shell/Kconfig.backends +++ b/subsys/shell/Kconfig.backends @@ -100,38 +100,48 @@ config SHELL_BACKEND_RTT if SHELL_BACKEND_RTT +config SHELL_RTT_RX_POLL_PERIOD + int "RX polling period (in milliseconds)" + default 10 + help + Determines how often RTT is polled for RX byte. + choice prompt "Initial log level limit" - default SHELL_BACKEND_RTT_LOG_LEVEL_DEFAULT + default SHELL_RTT_INIT_LOG_LEVEL_DEFAULT -config SHELL_BACKEND_RTT_LOG_LEVEL_DEFAULT +config SHELL_RTT_INIT_LOG_LEVEL_DEFAULT bool "System limit (LOG_MAX_LEVEL)" -config SHELL_BACKEND_RTT_LOG_LEVEL_DBG +config SHELL_RTT_INIT_LOG_LEVEL_DBG bool "Debug" -config SHELL_BACKEND_RTT_LOG_LEVEL_INF +config SHELL_RTT_INIT_LOG_LEVEL_INF bool "Info" -config SHELL_BACKEND_RTT_LOG_LEVEL_WRN +config SHELL_RTT_INIT_LOG_LEVEL_WRN bool "Warning" -config SHELL_BACKEND_RTT_LOG_LEVEL_ERR +config SHELL_RTT_INIT_LOG_LEVEL_ERR bool "Error" -config SHELL_BACKEND_RTT_LOG_LEVEL_NONE +config SHELL_RTT_INIT_LOG_LEVEL_NONE bool "None" endchoice -config SHELL_BACKEND_RTT_LOG_LEVEL +config SHELL_RTT_INIT_LOG_LEVEL int - default 0 if SHELL_BACKEND_RTT_LOG_LEVEL_NONE - default 1 if SHELL_BACKEND_RTT_LOG_LEVEL_ERR - default 2 if SHELL_BACKEND_RTT_LOG_LEVEL_WRN - default 3 if SHELL_BACKEND_RTT_LOG_LEVEL_INF - default 4 if SHELL_BACKEND_RTT_LOG_LEVEL_DBG - default 5 if SHELL_BACKEND_RTT_LOG_LEVEL_DEFAULT + default 0 if SHELL_RTT_INIT_LOG_LEVEL_NONE + default 1 if SHELL_RTT_INIT_LOG_LEVEL_ERR + default 2 if SHELL_RTT_INIT_LOG_LEVEL_WRN + default 3 if SHELL_RTT_INIT_LOG_LEVEL_INF + default 4 if SHELL_RTT_INIT_LOG_LEVEL_DBG + default 5 if SHELL_RTT_INIT_LOG_LEVEL_DEFAULT + +module = SHELL_RTT +module-str = RTT shell backend +source "subsys/logging/Kconfig.template.log_config" endif #SHELL_BACKEND_RTT diff --git a/subsys/shell/shell_rtt.c b/subsys/shell/shell_rtt.c index 45a4baa1671..fb1e2c02a4e 100644 --- a/subsys/shell/shell_rtt.c +++ b/subsys/shell/shell_rtt.c @@ -7,33 +7,23 @@ #include #include #include -#include +#include SHELL_RTT_DEFINE(shell_transport_rtt); SHELL_DEFINE(shell_rtt, "rtt:~$ ", &shell_transport_rtt, 10, SHELL_FLAG_OLF_CRLF); -static struct k_thread rtt_rx_thread; -static K_THREAD_STACK_DEFINE(rtt_rx_stack, 1024); +LOG_MODULE_REGISTER(shell_rtt, CONFIG_SHELL_RTT_LOG_LEVEL); -static void shell_rtt_rx_process(struct shell_rtt *sh_rtt) +static void timer_handler(struct k_timer *timer) { - u32_t count; + const struct shell_rtt *sh_rtt = k_timer_user_data_get(timer); - while (1) { - count = SEGGER_RTT_Read(0, sh_rtt->rx, sizeof(sh_rtt->rx)); - - if (count > 0) { - sh_rtt->rx_cnt = count; - sh_rtt->handler(SHELL_TRANSPORT_EVT_RX_RDY, - sh_rtt->context); - } - - k_sleep(K_MSEC(10)); + if (SEGGER_RTT_HasData(0)) { + sh_rtt->handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_rtt->context); } } - static int init(const struct shell_transport *transport, const void *config, shell_transport_handler_t evt_handler, @@ -44,11 +34,10 @@ static int init(const struct shell_transport *transport, sh_rtt->handler = evt_handler; sh_rtt->context = context; - k_thread_create(&rtt_rx_thread, rtt_rx_stack, - K_THREAD_STACK_SIZEOF(rtt_rx_stack), - (k_thread_entry_t)shell_rtt_rx_process, - sh_rtt, NULL, NULL, K_PRIO_COOP(8), - 0, K_NO_WAIT); + k_timer_init(&sh_rtt->timer, timer_handler, NULL); + k_timer_user_data_set(&sh_rtt->timer, (void *)sh_rtt); + k_timer_start(&sh_rtt->timer, CONFIG_SHELL_RTT_RX_POLL_PERIOD, + CONFIG_SHELL_RTT_RX_POLL_PERIOD); return 0; } @@ -60,6 +49,12 @@ static int uninit(const struct shell_transport *transport) static int enable(const struct shell_transport *transport, bool blocking) { + struct shell_rtt *sh_rtt = (struct shell_rtt *)transport->ctx; + + if (blocking) { + k_timer_stop(&sh_rtt->timer); + } + return 0; } @@ -72,21 +67,14 @@ static int write(const struct shell_transport *transport, *cnt = SEGGER_RTT_Write(0, data8, length); sh_rtt->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_rtt->context); + return 0; } static int read(const struct shell_transport *transport, void *data, size_t length, size_t *cnt) { - struct shell_rtt *sh_rtt = (struct shell_rtt *)transport->ctx; - - if (sh_rtt->rx_cnt) { - memcpy(data, sh_rtt->rx, sh_rtt->rx_cnt); - *cnt = sh_rtt->rx_cnt; - sh_rtt->rx_cnt = 0; - } else { - *cnt = 0; - } + *cnt = SEGGER_RTT_Read(0, data, length); return 0; } @@ -102,9 +90,9 @@ const struct shell_transport_api shell_rtt_transport_api = { static int enable_shell_rtt(struct device *arg) { ARG_UNUSED(arg); - bool log_backend = CONFIG_SHELL_BACKEND_RTT_LOG_LEVEL > 0; - u32_t level = (CONFIG_SHELL_BACKEND_RTT_LOG_LEVEL > LOG_LEVEL_DBG) ? - CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_BACKEND_RTT_LOG_LEVEL; + bool log_backend = CONFIG_SHELL_RTT_INIT_LOG_LEVEL > 0; + u32_t level = (CONFIG_SHELL_RTT_INIT_LOG_LEVEL > LOG_LEVEL_DBG) ? + CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_RTT_INIT_LOG_LEVEL; shell_init(&shell_rtt, NULL, true, log_backend, level);