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 <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2018-11-28 14:06:40 +01:00 committed by Anas Nashif
commit f78067e1f9
3 changed files with 45 additions and 49 deletions

View file

@ -19,8 +19,6 @@ struct shell_rtt {
shell_transport_handler_t handler; shell_transport_handler_t handler;
struct k_timer timer; struct k_timer timer;
void *context; void *context;
u8_t rx[5];
size_t rx_cnt;
}; };
#define SHELL_RTT_DEFINE(_name) \ #define SHELL_RTT_DEFINE(_name) \

View file

@ -100,38 +100,48 @@ config SHELL_BACKEND_RTT
if 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 choice
prompt "Initial log level limit" 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)" bool "System limit (LOG_MAX_LEVEL)"
config SHELL_BACKEND_RTT_LOG_LEVEL_DBG config SHELL_RTT_INIT_LOG_LEVEL_DBG
bool "Debug" bool "Debug"
config SHELL_BACKEND_RTT_LOG_LEVEL_INF config SHELL_RTT_INIT_LOG_LEVEL_INF
bool "Info" bool "Info"
config SHELL_BACKEND_RTT_LOG_LEVEL_WRN config SHELL_RTT_INIT_LOG_LEVEL_WRN
bool "Warning" bool "Warning"
config SHELL_BACKEND_RTT_LOG_LEVEL_ERR config SHELL_RTT_INIT_LOG_LEVEL_ERR
bool "Error" bool "Error"
config SHELL_BACKEND_RTT_LOG_LEVEL_NONE config SHELL_RTT_INIT_LOG_LEVEL_NONE
bool "None" bool "None"
endchoice endchoice
config SHELL_BACKEND_RTT_LOG_LEVEL config SHELL_RTT_INIT_LOG_LEVEL
int int
default 0 if SHELL_BACKEND_RTT_LOG_LEVEL_NONE default 0 if SHELL_RTT_INIT_LOG_LEVEL_NONE
default 1 if SHELL_BACKEND_RTT_LOG_LEVEL_ERR default 1 if SHELL_RTT_INIT_LOG_LEVEL_ERR
default 2 if SHELL_BACKEND_RTT_LOG_LEVEL_WRN default 2 if SHELL_RTT_INIT_LOG_LEVEL_WRN
default 3 if SHELL_BACKEND_RTT_LOG_LEVEL_INF default 3 if SHELL_RTT_INIT_LOG_LEVEL_INF
default 4 if SHELL_BACKEND_RTT_LOG_LEVEL_DBG default 4 if SHELL_RTT_INIT_LOG_LEVEL_DBG
default 5 if SHELL_BACKEND_RTT_LOG_LEVEL_DEFAULT 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 endif #SHELL_BACKEND_RTT

View file

@ -7,33 +7,23 @@
#include <shell/shell_rtt.h> #include <shell/shell_rtt.h>
#include <init.h> #include <init.h>
#include <rtt/SEGGER_RTT.h> #include <rtt/SEGGER_RTT.h>
#include <logging/sys_log.h> #include <logging/log.h>
SHELL_RTT_DEFINE(shell_transport_rtt); SHELL_RTT_DEFINE(shell_transport_rtt);
SHELL_DEFINE(shell_rtt, "rtt:~$ ", &shell_transport_rtt, 10, SHELL_DEFINE(shell_rtt, "rtt:~$ ", &shell_transport_rtt, 10,
SHELL_FLAG_OLF_CRLF); SHELL_FLAG_OLF_CRLF);
static struct k_thread rtt_rx_thread; LOG_MODULE_REGISTER(shell_rtt, CONFIG_SHELL_RTT_LOG_LEVEL);
static K_THREAD_STACK_DEFINE(rtt_rx_stack, 1024);
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) { if (SEGGER_RTT_HasData(0)) {
count = SEGGER_RTT_Read(0, sh_rtt->rx, sizeof(sh_rtt->rx)); sh_rtt->handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_rtt->context);
if (count > 0) {
sh_rtt->rx_cnt = count;
sh_rtt->handler(SHELL_TRANSPORT_EVT_RX_RDY,
sh_rtt->context);
}
k_sleep(K_MSEC(10));
} }
} }
static int init(const struct shell_transport *transport, static int init(const struct shell_transport *transport,
const void *config, const void *config,
shell_transport_handler_t evt_handler, 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->handler = evt_handler;
sh_rtt->context = context; sh_rtt->context = context;
k_thread_create(&rtt_rx_thread, rtt_rx_stack, k_timer_init(&sh_rtt->timer, timer_handler, NULL);
K_THREAD_STACK_SIZEOF(rtt_rx_stack), k_timer_user_data_set(&sh_rtt->timer, (void *)sh_rtt);
(k_thread_entry_t)shell_rtt_rx_process, k_timer_start(&sh_rtt->timer, CONFIG_SHELL_RTT_RX_POLL_PERIOD,
sh_rtt, NULL, NULL, K_PRIO_COOP(8), CONFIG_SHELL_RTT_RX_POLL_PERIOD);
0, K_NO_WAIT);
return 0; return 0;
} }
@ -60,6 +49,12 @@ static int uninit(const struct shell_transport *transport)
static int enable(const struct shell_transport *transport, bool blocking) 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; return 0;
} }
@ -72,21 +67,14 @@ static int write(const struct shell_transport *transport,
*cnt = SEGGER_RTT_Write(0, data8, length); *cnt = SEGGER_RTT_Write(0, data8, length);
sh_rtt->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_rtt->context); sh_rtt->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_rtt->context);
return 0; return 0;
} }
static int read(const struct shell_transport *transport, static int read(const struct shell_transport *transport,
void *data, size_t length, size_t *cnt) void *data, size_t length, size_t *cnt)
{ {
struct shell_rtt *sh_rtt = (struct shell_rtt *)transport->ctx; *cnt = SEGGER_RTT_Read(0, data, length);
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;
}
return 0; return 0;
} }
@ -102,9 +90,9 @@ const struct shell_transport_api shell_rtt_transport_api = {
static int enable_shell_rtt(struct device *arg) static int enable_shell_rtt(struct device *arg)
{ {
ARG_UNUSED(arg); ARG_UNUSED(arg);
bool log_backend = CONFIG_SHELL_BACKEND_RTT_LOG_LEVEL > 0; bool log_backend = CONFIG_SHELL_RTT_INIT_LOG_LEVEL > 0;
u32_t level = (CONFIG_SHELL_BACKEND_RTT_LOG_LEVEL > LOG_LEVEL_DBG) ? u32_t level = (CONFIG_SHELL_RTT_INIT_LOG_LEVEL > LOG_LEVEL_DBG) ?
CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_BACKEND_RTT_LOG_LEVEL; CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_RTT_INIT_LOG_LEVEL;
shell_init(&shell_rtt, NULL, true, log_backend, level); shell_init(&shell_rtt, NULL, true, log_backend, level);