Boot Linux faster!

Check our new training course

Boot Linux faster!

Check our new training course
and Creative Commons CC-BY-SA
lecture and lab materials

Bootlin logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef SHELL_H__
#define SHELL_H__

#include <zephyr.h>
#include <shell/shell_types.h>
#include <shell/shell_history.h>
#include <shell/shell_fprintf.h>
#include <shell/shell_log_backend.h>
#include <logging/log_instance.h>
#include <logging/log.h>
#include <misc/util.h>

#ifdef __cplusplus
extern "C" {
#endif

#define SHELL_RX_BUFF_SIZE 16

#ifndef CONFIG_SHELL_CMD_BUFF_SIZE
#define CONFIG_SHELL_CMD_BUFF_SIZE 0
#endif

#ifndef CONFIG_SHELL_PRINTF_BUFF_SIZE
#define CONFIG_SHELL_PRINTF_BUFF_SIZE 0
#endif

#define SHELL_CMD_ROOT_LVL		(0u)

/**
 * @brief Shell API
 * @defgroup shell_api Shell API
 * @ingroup shell
 * @{
 */

struct shell_static_entry;

/**
 * @brief Shell dynamic command descriptor.
 *
 * @details Function shall fill the received shell_static_entry structure
 * with requested (idx) dynamic subcommand data. If there is more than
 * one dynamic subcommand available, the function shall ensure that the
 * returned commands: entry->syntax are sorted in alphabetical order.
 * If idx exceeds the available dynamic subcommands, the function must
 * write to entry->syntax NULL value. This will indicate to the shell
 * module that there are no more dynamic commands to read.
 */
typedef void (*shell_dynamic_get)(size_t idx,
				  struct shell_static_entry *entry);

/**
 * @brief Shell command descriptor.
 */
struct shell_cmd_entry {
	bool is_dynamic;
	union union_cmd_entry {
		/*!< Pointer to function returning dynamic commands.*/
		shell_dynamic_get dynamic_get;

		/*!< Pointer to array of static commands. */
		const struct shell_static_entry *entry;
	} u;
};

struct shell;

struct shell_static_args {
	u8_t mandatory; /*!< Number of mandatory arguments. */
	u8_t optional;  /*!< Number of optional arguments. */
};

/**
 * @brief Shell command handler prototype.
 *
 * @param shell Shell instance.
 * @param argc  Arguments count.
 * @param argv  Arguments.
 *
 * @retval 0 Successful command execution.
 * @retval 1 Help printed and command not executed.
 * @retval -EINVAL Argument validation failed.
 * @retval -ENOEXEC Command not executed.
 */
typedef int (*shell_cmd_handler)(const struct shell *shell,
				 size_t argc, char **argv);

/*
 * @brief Shell static command descriptor.
 */
struct shell_static_entry {
	const char *syntax;			/*!< Command syntax strings. */
	const char *help;			/*!< Command help string. */
	const struct shell_cmd_entry *subcmd;	/*!< Pointer to subcommand. */
	shell_cmd_handler handler;		/*!< Command handler. */
	struct shell_static_args args;		/*!< Command arguments. */
};

/**
 * @brief Macro for defining and adding a root command (level 0) with required
 * number of arguments.
 *
 * @note Each root command shall have unique syntax. If a command will be called
 * with wrong number of arguments shell will print an error message and command
 * handler will not be called.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 * @param[in] mandatory	Number of mandatory arguments.
 * @param[in] optional	Number of optional arguments.
 */
#define SHELL_CMD_ARG_REGISTER(syntax, subcmd, help, handler,		   \
			       mandatory, optional)			   \
	static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
	SHELL_CMD_ARG(syntax, subcmd, help, handler, mandatory, optional); \
	static const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax)   \
	__attribute__ ((section("."					   \
			STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax)))))	   \
	__attribute__((used)) = {					   \
		.is_dynamic = false,					   \
		.u = {.entry = &UTIL_CAT(_shell_, syntax)}		   \
	}

/**
 * @brief Macro for defining and adding a root command (level 0) with
 * arguments.
 *
 * @note All root commands must have different name.
 *
 * @param[in] syntax	Command syntax (for example: history).
 * @param[in] subcmd	Pointer to a subcommands array.
 * @param[in] help	Pointer to a command help string.
 * @param[in] handler	Pointer to a function handler.
 */
#define SHELL_CMD_REGISTER(syntax, subcmd, help, handler) \
	static const struct shell_static_entry UTIL_CAT(_shell_, syntax) = \
	SHELL_CMD(syntax, subcmd, help, handler);			   \
	const struct shell_cmd_entry UTIL_CAT(shell_cmd_, syntax)	   \
	__attribute__ ((section("."					   \
			STRINGIFY(UTIL_CAT(shell_root_cmd_, syntax)))))	   \
	__attribute__((used)) = {					   \
		.is_dynamic = false,					   \
		.u = { .entry = &UTIL_CAT(_shell_, syntax) }		   \
	}

/**
 * @brief Macro for creating a subcommand set. It must be used outside of any
 * function body.
 *
 * Example usage:
 * SHELL_STATIC_SUBCMD_SET_CREATE(
 *	foo,
 *	SHELL_CMD(abc, ...),
 *	SHELL_CMD(def, ...),
 *	SHELL_SUBCMD_SET_END
 * )
 *
 * @param[in] name	Name of the subcommand set.
 * @param[in] ...	List of commands created with @ref SHELL_CMD_ARG or
 *			or @ref SHELL_CMD
 */
#define SHELL_STATIC_SUBCMD_SET_CREATE(name, ...)			\
	static const struct shell_static_entry shell_##name[] = {	\
		__VA_ARGS__						\
	};								\
	static const struct shell_cmd_entry name = {			\
		.is_dynamic = false,					\
		.u = { .entry = shell_##name }				\
	}

/**
 * @brief Deprecated macro for creating a subcommand set.
 *
 * It must be used outside of any function body.
 *
 * @param[in] name	Name of the subcommand set.
 */
#define SHELL_CREATE_STATIC_SUBCMD_SET(name)			\
	__DEPRECATED_MACRO					\
	static const struct shell_static_entry shell_##name[];	\
	static const struct shell_cmd_entry name = {		\
		.is_dynamic = false,				\
		.u.entry = shell_##name				\
	};							\
	static const struct shell_static_entry shell_##name[] =


/**
 * @brief Define ending subcommands set.
 *
 */
#define SHELL_SUBCMD_SET_END {NULL}

/**
 * @brief Macro for creating a dynamic entry.
 *
 * @param[in] name	Name of the dynamic entry.
 * @param[in] get	Pointer to the function returning dynamic commands array
 */
#define SHELL_DYNAMIC_CMD_CREATE(name, get)		\
	static const struct shell_cmd_entry name = {	\
		.is_dynamic = true,			\
		.u = { .dynamic_get = get }		\
	}

/**
 * @brief Deprecated macro for creating a dynamic entry.
 *
 * @param[in] name	Name of the dynamic entry.
 * @param[in] get	Pointer to the function returning dynamic commands array
 */
#define SHELL_CREATE_DYNAMIC_CMD(name, get)		\
	__DEPRECATED_MACRO SHELL_DYNAMIC_CMD_CREATE(name, get)

/**
 * @brief Initializes a shell command with arguments.
 *
 * @note If a command will be called with wrong number of arguments shell will
 * print an error message and command handler will not be called.
 *
 * @param[in] _syntax	 Command syntax (for example: history).
 * @param[in] _subcmd	 Pointer to a subcommands array.
 * @param[in] _help	 Pointer to a command help string.
 * @param[in] _handler	 Pointer to a function handler.
 * @param[in] _mandatory Number of mandatory arguments.
 * @param[in] _optional	 Number of optional arguments.
 */
#define SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler,		      \
		      _mandatory, _optional) {				      \
	.syntax = (const char *)STRINGIFY(_syntax),			      \
	.help  = (const char *)_help,					      \
	.subcmd = _subcmd,						      \
	.handler = _handler,						      \
	.args = {. mandatory = _mandatory, .optional =  _optional}	      \
}

/**
 * @brief Initializes a shell command.
 *
 * @param[in] _syntax	Command syntax (for example: history).
 * @param[in] _subcmd	Pointer to a subcommands array.
 * @param[in] _help	Pointer to a command help string.
 * @param[in] _handler	Pointer to a function handler.
 */
#define SHELL_CMD(_syntax, _subcmd, _help, _handler) \
	SHELL_CMD_ARG(_syntax, _subcmd, _help, _handler, 0, 0)


/**
 * @internal @brief Internal shell state in response to data received from the
 * terminal.
 */
enum shell_receive_state {
	SHELL_RECEIVE_DEFAULT,
	SHELL_RECEIVE_ESC,
	SHELL_RECEIVE_ESC_SEQ,
	SHELL_RECEIVE_TILDE_EXP
};

/**
 * @internal @brief Internal shell state.
 */
enum shell_state {
	SHELL_STATE_UNINITIALIZED,
	SHELL_STATE_INITIALIZED,
	SHELL_STATE_ACTIVE,
	SHELL_STATE_PANIC_MODE_ACTIVE,  /*!< Panic activated.*/
	SHELL_STATE_PANIC_MODE_INACTIVE /*!< Panic requested, not supported.*/
};

/** @brief Shell transport event. */
enum shell_transport_evt {
	SHELL_TRANSPORT_EVT_RX_RDY,
	SHELL_TRANSPORT_EVT_TX_RDY
};

typedef void (*shell_transport_handler_t)(enum shell_transport_evt evt,
					  void *context);

struct shell_transport;

/**
 * @brief Unified shell transport interface.
 */
struct shell_transport_api {
	/**
	 * @brief Function for initializing the shell transport interface.
	 *
	 * @param[in] transport   Pointer to the transfer instance.
	 * @param[in] config      Pointer to instance configuration.
	 * @param[in] evt_handler Event handler.
	 * @param[in] context     Pointer to the context passed to event
	 *			  handler.
	 *
	 * @return Standard error code.
	 */
	int (*init)(const struct shell_transport *transport,
		    const void *config,
		    shell_transport_handler_t evt_handler,
		    void *context);

	/**
	 * @brief Function for uninitializing the shell transport interface.
	 *
	 * @param[in] transport  Pointer to the transfer instance.
	 *
	 * @return Standard error code.
	 */
	int (*uninit)(const struct shell_transport *transport);

	/**
	 * @brief Function for enabling transport in given TX mode.
	 *
	 * Function can be used to reconfigure TX to work in blocking mode.
	 *
	 * @param transport   Pointer to the transfer instance.
	 * @param blocking_tx If true, the transport TX is enabled in blocking
	 *		      mode.
	 *
	 * @return NRF_SUCCESS on successful enabling, error otherwise (also if
	 * not supported).
	 */
	int (*enable)(const struct shell_transport *transport,
		      bool blocking_tx);

	/**
	 * @brief Function for writing data to the transport interface.
	 *
	 * @param[in]  transport  Pointer to the transfer instance.
	 * @param[in]  data       Pointer to the source buffer.
	 * @param[in]  length     Source buffer length.
	 * @param[out] cnt        Pointer to the sent bytes counter.
	 *
	 * @return Standard error code.
	 */
	int (*write)(const struct shell_transport *transport,
		     const void *data, size_t length, size_t *cnt);

	/**
	 * @brief Function for reading data from the transport interface.
	 *
	 * @param[in]  p_transport  Pointer to the transfer instance.
	 * @param[in]  p_data       Pointer to the destination buffer.
	 * @param[in]  length       Destination buffer length.
	 * @param[out] cnt          Pointer to the received bytes counter.
	 *
	 * @return Standard error code.
	 */
	int (*read)(const struct shell_transport *transport,
		    void *data, size_t length, size_t *cnt);

	/**
	 * @brief Function called in shell thread loop.
	 *
	 * Can be used for backend operations that require longer execution time
	 *
	 * @param[in] transport Pointer to the transfer instance.
	 */
	void (*update)(const struct shell_transport *transport);

};

struct shell_transport {
	const struct shell_transport_api *api;
	void *ctx;
};

/**
 * @brief Shell statistics structure.
 */
struct shell_stats {
	u32_t log_lost_cnt; /*!< Lost log counter.*/
};

#if CONFIG_SHELL_STATS
#define SHELL_STATS_DEFINE(_name) static struct shell_stats _name##_stats
#define SHELL_STATS_PTR(_name) (&(_name##_stats))
#else
#define SHELL_STATS_DEFINE(_name)
#define SHELL_STATS_PTR(_name) NULL
#endif /* CONFIG_SHELL_STATS */

/**
 * @internal @brief Flags for internal shell usage.
 */
struct shell_flags {
	u32_t insert_mode :1; /*!< Controls insert mode for text introduction.*/
	u32_t use_colors  :1; /*!< Controls colored syntax.*/
	u32_t echo        :1; /*!< Controls shell echo.*/
	u32_t processing  :1; /*!< Shell is executing process function.*/
	u32_t tx_rdy      :1;
	u32_t mode_delete :1; /*!< Operation mode of backspace key */
	u32_t history_exit:1; /*!< Request to exit history mode */
	u32_t cmd_ctx	  :1; /*!< Shell is executing command */
	u32_t last_nl     :8; /*!< Last received new line character */
};

BUILD_ASSERT_MSG((sizeof(struct shell_flags) == sizeof(u32_t)),
		 "Structure must fit in 4 bytes");


/**
 * @internal @brief Union for internal shell usage.
 */
union shell_internal {
	u32_t value;
	struct shell_flags flags;
};

enum shell_signal {
	SHELL_SIGNAL_RXRDY,
	SHELL_SIGNAL_LOG_MSG,
	SHELL_SIGNAL_KILL,
	SHELL_SIGNAL_TXDONE, /* TXDONE must be last one before SHELL_SIGNALS */
	SHELL_SIGNALS
};

/**
 * @brief Shell instance context.
 */
struct shell_ctx {
	const char *prompt; /*!< shell current prompt. */

	enum shell_state state; /*!< Internal module state.*/
	enum shell_receive_state receive_state;/*!< Escape sequence indicator.*/

	/*!< Currently executed command.*/
	struct shell_static_entry active_cmd;

	/*!< VT100 color and cursor position, terminal width.*/
	struct shell_vt100_ctx vt100_ctx;

	u16_t cmd_buff_len; /*!< Command length.*/
	u16_t cmd_buff_pos; /*!< Command buffer cursor position.*/

	u16_t cmd_tmp_buff_len; /*!< Command length in tmp buffer.*/

	/*!< Command input buffer.*/
	char cmd_buff[CONFIG_SHELL_CMD_BUFF_SIZE];

	/*!< Command temporary buffer.*/
	char temp_buff[CONFIG_SHELL_CMD_BUFF_SIZE];

	/*!< Printf buffer size.*/
	char printf_buff[CONFIG_SHELL_PRINTF_BUFF_SIZE];

	volatile union shell_internal internal; /*!< Internal shell data.*/

	struct k_poll_signal signals[SHELL_SIGNALS];
	struct k_poll_event events[SHELL_SIGNALS];

	struct k_mutex wr_mtx;
	k_tid_t tid;
};

extern const struct log_backend_api log_backend_shell_api;

/**
 * @brief Flags for setting shell output newline sequence.
 */
enum shell_flag {
	SHELL_FLAG_CRLF_DEFAULT	= (1<<0),	/* Do not map CR or LF */
	SHELL_FLAG_OLF_CRLF	= (1<<1)	/* Map LF to CRLF on output */
};

/**
 * @brief Shell instance internals.
 */
struct shell {
	const char *default_prompt; /*!< shell default prompt. */

	const struct shell_transport *iface; /*!< Transport interface.*/
	struct shell_ctx *ctx; /*!< Internal context.*/

	struct shell_history *history;

	const enum shell_flag shell_flag;

	const struct shell_fprintf *fprintf_ctx;

	struct shell_stats *stats;

	const struct shell_log_backend *log_backend;

	LOG_INSTANCE_PTR_DECLARE(log);

	const char *thread_name;
	struct k_thread *thread;
	k_thread_stack_t *stack;
};

extern void shell_print_stream(const void *user_ctx, const char *data,
			       size_t data_len);
/**
 * @brief Macro for defining a shell instance.
 *
 * @param[in] _name		Instance name.
 * @param[in] _prompt		Shell default prompt string.
 * @param[in] _transport_iface	Pointer to the transport interface.
 * @param[in] _log_queue_size	Logger processing queue size.
 * @param[in] _log_timeout	Logger thread timeout in milliseconds on full
 *				log queue. If queue is full logger thread is
 *				blocked for given amount of time before log
 *				message is dropped.
 * @param[in] _shell_flag	Shell output newline sequence.
 */
#define SHELL_DEFINE(_name, _prompt, _transport_iface,			      \
		     _log_queue_size, _log_timeout, _shell_flag)	      \
	static const struct shell _name;				      \
	static struct shell_ctx UTIL_CAT(_name, _ctx);			      \
	static u8_t _name##_out_buffer[CONFIG_SHELL_PRINTF_BUFF_SIZE];	      \
	SHELL_LOG_BACKEND_DEFINE(_name, _name##_out_buffer,		      \
				 CONFIG_SHELL_PRINTF_BUFF_SIZE,		      \
				 _log_queue_size, _log_timeout);	      \
	SHELL_HISTORY_DEFINE(_name, CONFIG_SHELL_CMD_BUFF_SIZE, 7);	      \
	SHELL_FPRINTF_DEFINE(_name##_fprintf, &_name, _name##_out_buffer,     \
			     CONFIG_SHELL_PRINTF_BUFF_SIZE,		      \
			     true, shell_print_stream);			      \
	LOG_INSTANCE_REGISTER(shell, _name, CONFIG_SHELL_LOG_LEVEL);	      \
	SHELL_STATS_DEFINE(_name);					      \
	static K_THREAD_STACK_DEFINE(_name##_stack, CONFIG_SHELL_STACK_SIZE); \
	static struct k_thread _name##_thread;				      \
	static const struct shell _name = {				      \
		.default_prompt = _prompt,				      \
		.iface = _transport_iface,				      \
		.ctx = &UTIL_CAT(_name, _ctx),				      \
		.history = SHELL_HISTORY_PTR(_name),			      \
		.shell_flag = _shell_flag,				      \
		.fprintf_ctx = &_name##_fprintf,			      \
		.stats = SHELL_STATS_PTR(_name),			      \
		.log_backend = SHELL_LOG_BACKEND_PTR(_name),		      \
		LOG_INSTANCE_PTR_INIT(log, shell, _name)		      \
		.thread_name = STRINGIFY(_name),			      \
		.thread = &_name##_thread,				      \
		.stack = _name##_stack					      \
	}

/**
 * @brief Function for initializing a transport layer and internal shell state.
 *
 * @param[in] shell		Pointer to shell instance.
 * @param[in] transport_config	Transport configuration during initialization.
 * @param[in] use_colors	Enables colored prints.
 * @param[in] log_backend	If true, the console will be used as logger
 *				backend.
 * @param[in] init_log_level	Default severity level for the logger.
 *
 * @return Standard error code.
 */
int shell_init(const struct shell *shell, const void *transport_config,
	       bool use_colors, bool log_backend, u32_t init_log_level);

/**
 * @brief Uninitializes the transport layer and the internal shell state.
 *
 * @param shell Pointer to shell instance.
 *
 * @return Standard error code.
 */
int shell_uninit(const struct shell *shell);

/**
 * @brief Function for starting shell processing.
 *
 * @param shell Pointer to the shell instance.
 *
 * @return Standard error code.
 */
int shell_start(const struct shell *shell);

/**
 * @brief Function for stopping shell processing.
 *
 * @param shell Pointer to shell instance.
 *
 * @return Standard error code.
 */
int shell_stop(const struct shell *shell);

/**
 * @brief Terminal default text color for shell_fprintf function.
 */
#define SHELL_NORMAL	SHELL_VT100_COLOR_DEFAULT

/**
 * @brief Green text color for shell_fprintf function.
 */
#define SHELL_INFO	SHELL_VT100_COLOR_GREEN

/**
 * @brief Cyan text color for shell_fprintf function.
 */
#define SHELL_OPTION	SHELL_VT100_COLOR_CYAN

/**
 * @brief Yellow text color for shell_fprintf function.
 */
#define SHELL_WARNING	SHELL_VT100_COLOR_YELLOW

/**
 * @brief Red text color for shell_fprintf function.
 */
#define SHELL_ERROR	SHELL_VT100_COLOR_RED

/**
 * @brief printf-like function which sends formatted data stream to the shell.
 *
 * This function can be used from the command handler or from threads, but not
 * from an interrupt context.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] color	Printed text color.
 * @param[in] fmt	Format string.
 * @param[in] ...	List of parameters to print.
 */
void shell_fprintf(const struct shell *shell, enum shell_vt100_color color,
		   const char *fmt, ...);

/**
 * @brief Print info message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_info(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_INFO, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Print normal message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_print(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_NORMAL, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Print warning message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_warn(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_WARNING, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Print error message to the shell.
 *
 * See @ref shell_fprintf.
 *
 * @param[in] _sh Pointer to the shell instance.
 * @param[in] _ft Format string.
 * @param[in] ... List of parameters to print.
 */
#define shell_error(_sh, _ft, ...) \
	shell_fprintf(_sh, SHELL_ERROR, _ft "\n", ##__VA_ARGS__)

/**
 * @brief Process function, which should be executed when data is ready in the
 *	  transport interface. To be used if shell thread is disabled.
 *
 * @param[in] shell Pointer to the shell instance.
 */
void shell_process(const struct shell *shell);

/**
 * @brief Change displayed shell prompt.
 *
 * @param[in] shell	Pointer to the shell instance.
 * @param[in] prompt	New shell prompt.
 *
 * @return 0		Success.
 * @return -EINVAL	Pointer to new prompt is not correct.
 */
int shell_prompt_change(const struct shell *shell, const char *prompt);

/**
 * @brief Prints the current command help.
 *
 * Function will print a help string with: the currently entered command
 * and subcommands (if they exist).
 *
 * @param[in] shell      Pointer to the shell instance.
 */
void shell_help(const struct shell *shell);

/* @brief Command's help has been printed */
#define SHELL_CMD_HELP_PRINTED	(1)

/** @brief Execute command.
 *
 * Pass command line to shell to execute.
 *
 * Note: This by no means makes any of the commands a stable interface, so
 * 	 this function should only be used for debugging/diagnostic.
 *
 *	 This function must not be called from shell command context!

 *
 * @param[in] shell	Pointer to the shell instance. It can be NULL when
 *			the :option:`CONFIG_SHELL_BACKEND_DUMMY` option is
 *			enabled.
 * @param[in] cmd	Command to be executed.
 *
 * @returns		Result of the execution
 */
int shell_execute_cmd(const struct shell *shell, const char *cmd);

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* SHELL_H__ */