1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef SHELL_UART_H__
8 #define SHELL_UART_H__
9 
10 #include <shell/shell.h>
11 #include <sys/ring_buffer.h>
12 #include <sys/atomic.h>
13 #include "mgmt/mcumgr/smp_shell.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 extern const struct shell_transport_api shell_uart_transport_api;
20 
21 /** @brief Shell UART transport instance control block (RW data). */
22 struct shell_uart_ctrl_blk {
23 	const struct device *dev;
24 	shell_transport_handler_t handler;
25 	void *context;
26 	atomic_t tx_busy;
27 	bool blocking_tx;
28 #ifdef CONFIG_MCUMGR_SMP_SHELL
29 	struct smp_shell_data smp;
30 #endif /* CONFIG_MCUMGR_SMP_SHELL */
31 };
32 
33 #ifdef CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN
34 #define Z_UART_SHELL_TX_RINGBUF_DECLARE(_name, _size) \
35 	RING_BUF_DECLARE(_name##_tx_ringbuf, _size)
36 
37 #define Z_UART_SHELL_RX_TIMER_DECLARE(_name) /* Empty */
38 #define Z_UART_SHELL_TX_RINGBUF_PTR(_name) (&_name##_tx_ringbuf)
39 
40 #define Z_UART_SHELL_RX_TIMER_PTR(_name) NULL
41 
42 #else /* CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN */
43 #define Z_UART_SHELL_TX_RINGBUF_DECLARE(_name, _size) /* Empty */
44 #define Z_UART_SHELL_RX_TIMER_DECLARE(_name) static struct k_timer _name##_timer
45 #define Z_UART_SHELL_TX_RINGBUF_PTR(_name) NULL
46 #define Z_UART_SHELL_RX_TIMER_PTR(_name) (&_name##_timer)
47 #endif /* CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN */
48 
49 /** @brief Shell UART transport instance structure. */
50 struct shell_uart {
51 	struct shell_uart_ctrl_blk *ctrl_blk;
52 	struct k_timer *timer;
53 	struct ring_buf *tx_ringbuf;
54 	struct ring_buf *rx_ringbuf;
55 };
56 
57 /** @brief Macro for creating shell UART transport instance. */
58 #define SHELL_UART_DEFINE(_name, _tx_ringbuf_size, _rx_ringbuf_size)	\
59 	static struct shell_uart_ctrl_blk _name##_ctrl_blk;		\
60 	Z_UART_SHELL_RX_TIMER_DECLARE(_name);				\
61 	Z_UART_SHELL_TX_RINGBUF_DECLARE(_name, _tx_ringbuf_size);	\
62 	RING_BUF_DECLARE(_name##_rx_ringbuf, _rx_ringbuf_size);		\
63 	static const struct shell_uart _name##_shell_uart = {		\
64 		.ctrl_blk = &_name##_ctrl_blk,				\
65 		.timer = Z_UART_SHELL_RX_TIMER_PTR(_name),		\
66 		.tx_ringbuf = Z_UART_SHELL_TX_RINGBUF_PTR(_name),	\
67 		.rx_ringbuf = &_name##_rx_ringbuf,			\
68 	};								\
69 	struct shell_transport _name = {				\
70 		.api = &shell_uart_transport_api,			\
71 		.ctx = (struct shell_uart *)&_name##_shell_uart		\
72 	}
73 
74 /**
75  * @brief This function provides pointer to shell uart backend instance.
76  *
77  * Function returns pointer to the shell uart instance. This instance can be
78  * next used with shell_execute_cmd function in order to test commands behavior.
79  *
80  * @returns Pointer to the shell instance.
81  */
82 const struct shell *shell_backend_uart_get_ptr(void);
83 
84 #ifdef __cplusplus
85 }
86 #endif
87 
88 #endif /* SHELL_UART_H__ */
89