Skip to content

Commit 2e32820

Browse files
shell: fix shell: fix threadless option
The shell at some point supported CONFIG_MULTITHREADING=n but this has not been maintained. Adjust the shell to support threadless operation similar to how logging works with no logging thread. With these adjustments, building with CONFIG_SHELL_MINIMAL and CONFIG_MULTITHREADING=n, shells can now be used like logging by calling shell_process() with non-polling backends, like async or irq driven UART based backends. Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
1 parent 954f8b6 commit 2e32820

File tree

5 files changed

+68
-12
lines changed

5 files changed

+68
-12
lines changed

include/zephyr/shell/shell.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -961,10 +961,11 @@ struct shell_ctx {
961961
volatile union shell_backend_cfg cfg;
962962
volatile union shell_backend_ctx ctx;
963963

964+
#if CONFIG_MULTITHREADING
964965
struct k_event signal_event;
965-
966966
struct k_sem lock_sem;
967967
k_tid_t tid;
968+
#endif
968969
int ret_val;
969970
};
970971

@@ -1000,13 +1001,29 @@ struct shell {
10001001
LOG_INSTANCE_PTR_DECLARE(log);
10011002

10021003
const char *name;
1004+
1005+
#if CONFIG_MULTITHREADING
10031006
struct k_thread *thread;
10041007
k_thread_stack_t *stack;
1008+
#endif
10051009
};
10061010

10071011
extern void z_shell_print_stream(const void *user_ctx, const char *data,
10081012
size_t data_len);
10091013

1014+
#if CONFIG_MULTITHREADING
1015+
#define Z_SHELL_THREAD_DEFINE(_name) \
1016+
static K_KERNEL_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \
1017+
static struct k_thread _name##_thread
1018+
1019+
#define Z_SHELL_THREAD_INIT(_name) \
1020+
.thread = &_name##_thread, \
1021+
.stack = _name##_stack,
1022+
#else
1023+
#define Z_SHELL_THREAD_DEFINE(_name)
1024+
#define Z_SHELL_THREAD_INIT(_name)
1025+
#endif
1026+
10101027
/** @brief Internal macro for defining a shell instance.
10111028
*
10121029
* As it does not create the default shell logging backend it allows to use
@@ -1027,8 +1044,7 @@ extern void z_shell_print_stream(const void *user_ctx, const char *data,
10271044
IS_ENABLED(CONFIG_SHELL_PRINTF_AUTOFLUSH), z_shell_print_stream); \
10281045
LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL); \
10291046
Z_SHELL_STATS_DEFINE(_name); \
1030-
static K_KERNEL_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \
1031-
static struct k_thread _name##_thread; \
1047+
Z_SHELL_THREAD_DEFINE(_name); \
10321048
static const STRUCT_SECTION_ITERABLE(shell, _name) = { \
10331049
.default_prompt = _prompt, \
10341050
.iface = _transport_iface, \
@@ -1038,8 +1054,9 @@ extern void z_shell_print_stream(const void *user_ctx, const char *data,
10381054
.fprintf_ctx = &_name##_fprintf, \
10391055
.stats = Z_SHELL_STATS_PTR(_name), \
10401056
.log_backend = _log_backend, \
1041-
LOG_INSTANCE_PTR_INIT(log, shell, _name).name = \
1042-
STRINGIFY(_name), .thread = &_name##_thread, .stack = _name##_stack}
1057+
LOG_INSTANCE_PTR_INIT(log, shell, _name).name = STRINGIFY(_name), \
1058+
Z_SHELL_THREAD_INIT(_name) \
1059+
}
10431060

10441061
/**
10451062
* @brief Macro for defining a shell instance.

subsys/shell/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
menuconfig SHELL
99
bool "Shell"
1010
imply LOG_RUNTIME_FILTERING
11-
select EVENTS
11+
select EVENTS if MULTITHREADING
1212

1313
if SHELL
1414

subsys/shell/shell.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,13 +1171,21 @@ static void state_collect(const struct shell *sh)
11711171
static void transport_evt_handler(enum shell_transport_evt evt_type, void *ctx)
11721172
{
11731173
struct shell *sh = (struct shell *)ctx;
1174+
1175+
#if CONFIG_MULTITHREADING
11741176
enum shell_signal sig = evt_type == SHELL_TRANSPORT_EVT_RX_RDY
11751177
? SHELL_SIGNAL_RXRDY
11761178
: SHELL_SIGNAL_TXDONE;
11771179

11781180
k_event_post(&sh->ctx->signal_event, sig);
1181+
#endif
1182+
1183+
if (evt_type == SHELL_TRANSPORT_EVT_TX_RDY) {
1184+
z_flag_tx_rdy_set(sh, true);
1185+
}
11791186
}
11801187

1188+
#if CONFIG_MULTITHREADING
11811189
static void shell_log_process(const struct shell *sh)
11821190
{
11831191
bool processed = false;
@@ -1201,6 +1209,7 @@ static void shell_log_process(const struct shell *sh)
12011209

12021210
} while (processed && !k_event_test(&sh->ctx->signal_event, SHELL_SIGNAL_RXRDY));
12031211
}
1212+
#endif
12041213

12051214
static int instance_init(const struct shell *sh,
12061215
const void *transport_config,
@@ -1216,8 +1225,10 @@ static int instance_init(const struct shell *sh,
12161225

12171226
history_init(sh);
12181227

1228+
#if CONFIG_MULTITHREADING
12191229
k_event_init(&sh->ctx->signal_event);
12201230
k_sem_init(&sh->ctx->lock_sem, 1, 1);
1231+
#endif
12211232

12221233
if (IS_ENABLED(CONFIG_SHELL_STATS)) {
12231234
sh->stats->log_lost_cnt = 0;
@@ -1284,6 +1295,7 @@ static int instance_uninit(const struct shell *sh)
12841295
return 0;
12851296
}
12861297

1298+
#if CONFIG_MULTITHREADING
12871299
typedef void (*shell_signal_handler_t)(const struct shell *sh);
12881300

12891301
static void shell_signal_handle(const struct shell *sh,
@@ -1358,6 +1370,7 @@ void shell_thread(void *shell_handle, void *arg_log_backend,
13581370
z_shell_unlock(sh);
13591371
}
13601372
}
1373+
#endif
13611374

13621375
int shell_init(const struct shell *sh, const void *transport_config,
13631376
struct shell_backend_config_flags cfg_flags,
@@ -1366,16 +1379,19 @@ int shell_init(const struct shell *sh, const void *transport_config,
13661379
__ASSERT_NO_MSG(sh);
13671380
__ASSERT_NO_MSG(sh->ctx && sh->iface && sh->default_prompt);
13681381

1382+
#if CONFIG_MULTITHREADING
13691383
if (sh->ctx->tid) {
13701384
return -EALREADY;
13711385
}
1386+
#endif
13721387

13731388
int err = instance_init(sh, transport_config, cfg_flags);
13741389

13751390
if (err != 0) {
13761391
return err;
13771392
}
13781393

1394+
#if CONFIG_MULTITHREADING
13791395
k_tid_t tid = k_thread_create(sh->thread,
13801396
sh->stack, CONFIG_SHELL_STACK_SIZE,
13811397
shell_thread, (void *)sh, (void *)log_backend,
@@ -1384,6 +1400,7 @@ int shell_init(const struct shell *sh, const void *transport_config,
13841400

13851401
sh->ctx->tid = tid;
13861402
k_thread_name_set(tid, sh->name);
1403+
#endif
13871404

13881405
return 0;
13891406
}
@@ -1392,10 +1409,9 @@ void shell_uninit(const struct shell *sh, shell_uninit_cb_t cb)
13921409
{
13931410
__ASSERT_NO_MSG(sh);
13941411

1395-
if (IS_ENABLED(CONFIG_MULTITHREADING)) {
1396-
k_event_post(&sh->ctx->signal_event, SHELL_SIGNAL_KILL);
1397-
return;
1398-
}
1412+
#if CONFIG_MULTITHREADING
1413+
k_event_post(&sh->ctx->signal_event, SHELL_SIGNAL_KILL);
1414+
#else
13991415

14001416
int err = instance_uninit(sh);
14011417

@@ -1404,6 +1420,7 @@ void shell_uninit(const struct shell *sh, shell_uninit_cb_t cb)
14041420
} else {
14051421
__ASSERT_NO_MSG(0);
14061422
}
1423+
#endif
14071424
}
14081425

14091426
int shell_start(const struct shell *sh)

subsys/shell/shell_ops.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,14 @@ void z_shell_print_prompt_and_cmd(const struct shell *sh)
430430

431431
static void shell_pend_on_txdone(const struct shell *sh)
432432
{
433-
if (IS_ENABLED(CONFIG_MULTITHREADING) &&
434-
(sh->ctx->state < SHELL_STATE_PANIC_MODE_ACTIVE)) {
433+
#if CONFIG_MULTITHREADING
434+
if (sh->ctx->state < SHELL_STATE_PANIC_MODE_ACTIVE) {
435435
k_event_wait(&sh->ctx->signal_event, SHELL_SIGNAL_TXDONE, false, K_FOREVER);
436436
k_event_clear(&sh->ctx->signal_event, SHELL_SIGNAL_TXDONE);
437437
} else {
438+
#else
439+
{
440+
#endif
438441
/* Blocking wait in case of bare metal. */
439442
while (!z_flag_tx_rdy_get(sh)) {
440443
}

subsys/shell/shell_ops.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ void z_shell_vfprintf(const struct shell *sh, enum shell_vt100_color color,
381381
*/
382382
void z_shell_backend_rx_buffer_flush(const struct shell *sh);
383383

384+
#if CONFIG_MULTITHREADING
384385
static inline bool z_shell_trylock(const struct shell *sh, k_timeout_t timeout)
385386
{
386387
return k_sem_take(&sh->ctx->lock_sem, timeout) == 0;
@@ -395,6 +396,24 @@ static inline void z_shell_unlock(const struct shell *sh)
395396
{
396397
k_sem_give(&sh->ctx->lock_sem);
397398
}
399+
#else
400+
static inline bool z_shell_trylock(const struct shell *sh, k_timeout_t timeout)
401+
{
402+
ARG_UNUSED(sh);
403+
ARG_UNUSED(timeout);
404+
return true;
405+
}
406+
407+
static inline void z_shell_lock(const struct shell *sh)
408+
{
409+
ARG_UNUSED(sh);
410+
}
411+
412+
static inline void z_shell_unlock(const struct shell *sh)
413+
{
414+
ARG_UNUSED(sh);
415+
}
416+
#endif
398417

399418
#ifdef __cplusplus
400419
}

0 commit comments

Comments
 (0)