Skip to content

Commit

Permalink
shell: backends: add SHELL_BACKEND_RTT_BUFFER option
Browse files Browse the repository at this point in the history
This new configuration option, SHELL_BACKEND_RTT_BUFFER, allows selecting
an alternative buffer for the Shell's RTT backend. By default buffer 0 is
used, which conflicts with the default logging subsystem RTT backend
buffer.
This option is the counterpart to the logger's LOG_BACKEND_RTT_BUFFER.

Signed-off-by: Maurits Fassaert <[email protected]>
  • Loading branch information
MauritsFassaert authored and carlescufi committed Apr 13, 2023
1 parent 1cb259a commit 6bfb663
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 8 deletions.
27 changes: 27 additions & 0 deletions doc/services/shell/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,33 @@ This feature is activated by: :kconfig:option:`CONFIG_SHELL_LOG_BACKEND` set to
RTT (:kconfig:option:`CONFIG_LOG_BACKEND_RTT`), which are available earlier
during system initialization.

RTT Backend Channel Selection
*****************************

Instead of using the shell as a logger backend, RTT shell backend and RTT log
backend can also be used simulatenously, but over different channels. By
separating them, the log can be captured or monitored without shell output or
the shell may be scripted without log interference. Enabling both the Shell RTT
backend and the Log RTT backend does not work by default, because both default
to channel ``0``. There are two options:

1. The Shell buffer can use an alternate channel, for example using
:kconfig:option:`SHELL_BACKEND_RTT_BUFFER` set to ``1``.
This allows monitoring the log using `JLinkRTTViewer
<https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/#j-link-rtt-viewer>`_
while a script interfaces over channel 1.

2. The Log buffer can use an alternate channel, for example using
:kconfig:option:`LOG_BACKEND_RTT_BUFFER` set to ``1``.
This allows interactive use of the shell through JLinkRTTViewer, while the log
is written to file.

.. warning::
Regardless of the channel selection, the RTT log backend must be explicitly
enabled using :kconfig:option:`LOG_BACKEND_RTT` set to ``y``, because it
defaults to ``n`` when the Shell RTT backend is also enabled using
:kconfig:option:`SHELL_BACKEND_RTT` being set to ``y``.

Usage
*****

Expand Down
8 changes: 8 additions & 0 deletions subsys/shell/backends/Kconfig.backends
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ config SHELL_PROMPT_RTT
Displayed prompt name for RTT backend. If prompt is set, the shell will
send two newlines during initialization.

config SHELL_BACKEND_RTT_BUFFER
int "Buffer number used for shell input and output."
range 0 SEGGER_RTT_MAX_NUM_UP_BUFFERS
default 0
help
Select index of up-buffer used for shell output, by default it uses
terminal up-buffer and its settings.

config SHELL_RTT_RX_POLL_PERIOD
int "RX polling period (in milliseconds)"
default 10
Expand Down
30 changes: 22 additions & 8 deletions subsys/shell/backends/shell_rtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@
#include <SEGGER_RTT.h>
#include <zephyr/logging/log.h>

BUILD_ASSERT(!(IS_ENABLED(CONFIG_LOG_BACKEND_RTT) &&
COND_CODE_0(CONFIG_LOG_BACKEND_RTT_BUFFER, (1), (0))),
#if IS_ENABLED(CONFIG_LOG_BACKEND_RTT)
BUILD_ASSERT(!(CONFIG_SHELL_BACKEND_RTT_BUFFER == CONFIG_LOG_BACKEND_RTT_BUFFER),
"Conflicting log RTT backend enabled on the same channel");
#endif

static uint8_t shell_rtt_up_buf[CONFIG_SEGGER_RTT_BUFFER_SIZE_UP];
static uint8_t shell_rtt_down_buf[CONFIG_SEGGER_RTT_BUFFER_SIZE_DOWN];

SHELL_RTT_DEFINE(shell_transport_rtt);
SHELL_DEFINE(shell_rtt, CONFIG_SHELL_PROMPT_RTT, &shell_transport_rtt,
Expand All @@ -27,7 +31,7 @@ static void timer_handler(struct k_timer *timer)
{
const struct shell_rtt *sh_rtt = k_timer_user_data_get(timer);

if (SEGGER_RTT_HasData(0)) {
if (SEGGER_RTT_HasData(CONFIG_SHELL_BACKEND_RTT_BUFFER)) {
sh_rtt->handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_rtt->context);
}
}
Expand All @@ -45,7 +49,17 @@ static int init(const struct shell_transport *transport,
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, K_MSEC(CONFIG_SHELL_RTT_RX_POLL_PERIOD),
K_MSEC(CONFIG_SHELL_RTT_RX_POLL_PERIOD));
K_MSEC(CONFIG_SHELL_RTT_RX_POLL_PERIOD));

if (CONFIG_SHELL_BACKEND_RTT_BUFFER > 0) {
SEGGER_RTT_ConfigUpBuffer(CONFIG_SHELL_BACKEND_RTT_BUFFER, "Shell",
shell_rtt_up_buf, sizeof(shell_rtt_up_buf),
SEGGER_RTT_MODE_NO_BLOCK_SKIP);

SEGGER_RTT_ConfigDownBuffer(CONFIG_SHELL_BACKEND_RTT_BUFFER, "Shell",
shell_rtt_down_buf, sizeof(shell_rtt_down_buf),
SEGGER_RTT_MODE_NO_BLOCK_SKIP);
}

return 0;
}
Expand Down Expand Up @@ -78,12 +92,12 @@ static int write(const struct shell_transport *transport,
const uint8_t *data8 = (const uint8_t *)data;

if (rtt_blocking) {
*cnt = SEGGER_RTT_WriteNoLock(0, data8, length);
while (SEGGER_RTT_HasDataUp(0)) {
*cnt = SEGGER_RTT_WriteNoLock(CONFIG_SHELL_BACKEND_RTT_BUFFER, data8, length);
while (SEGGER_RTT_HasDataUp(CONFIG_SHELL_BACKEND_RTT_BUFFER)) {
/* empty */
}
} else {
*cnt = SEGGER_RTT_Write(0, data8, length);
*cnt = SEGGER_RTT_Write(CONFIG_SHELL_BACKEND_RTT_BUFFER, data8, length);
}

sh_rtt->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_rtt->context);
Expand All @@ -94,7 +108,7 @@ static int write(const struct shell_transport *transport,
static int read(const struct shell_transport *transport,
void *data, size_t length, size_t *cnt)
{
*cnt = SEGGER_RTT_Read(0, data, length);
*cnt = SEGGER_RTT_Read(CONFIG_SHELL_BACKEND_RTT_BUFFER, data, length);

return 0;
}
Expand Down

0 comments on commit 6bfb663

Please sign in to comment.