shell: parsing output LF character
Some terminals literally interprets shell output data. Hence to print a message in new line shell needs to send `\r\n` each time. To minimize flash usage user can now send `\n` as a line delimiter and shell will automatically add missing CR character. Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
This commit is contained in:
parent
026f06efeb
commit
b0571746e2
7 changed files with 69 additions and 47 deletions
|
@ -166,7 +166,6 @@ enum shell_receive_state {
|
|||
SHELL_RECEIVE_TILDE_EXP
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @internal @brief Internal shell state.
|
||||
*/
|
||||
|
@ -346,6 +345,14 @@ struct shell_ctx {
|
|||
|
||||
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.
|
||||
*/
|
||||
|
@ -357,6 +364,8 @@ struct shell {
|
|||
|
||||
struct shell_history *history;
|
||||
|
||||
const enum shell_flag shell_flag;
|
||||
|
||||
const struct shell_fprintf *fprintf_ctx;
|
||||
|
||||
struct shell_stats *stats;
|
||||
|
@ -376,9 +385,10 @@ struct shell {
|
|||
* @param[in] _prompt Shell prompt string.
|
||||
* @param[in] transport_iface Pointer to the transport interface.
|
||||
* @param[in] log_queue_size Logger processing queue size.
|
||||
* @param[in] _shell_flag Shell output newline sequence.
|
||||
*/
|
||||
#define SHELL_DEFINE(_name, _prompt, transport_iface, \
|
||||
log_queue_size) \
|
||||
log_queue_size, _shell_flag) \
|
||||
static const struct shell _name; \
|
||||
static struct shell_ctx UTIL_CAT(_name, _ctx); \
|
||||
static char _name##prompt[CONFIG_SHELL_PROMPT_LENGTH + 1] = _prompt; \
|
||||
|
@ -398,6 +408,7 @@ struct shell {
|
|||
.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), \
|
||||
|
|
|
@ -34,7 +34,6 @@ struct shell_fprintf {
|
|||
struct shell_fprintf_control_block *ctrl_blk;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Macro for defining shell_fprintf instance.
|
||||
*
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
LOG_MODULE_REGISTER(app);
|
||||
|
||||
SHELL_UART_DEFINE(shell_transport_uart);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10,
|
||||
SHELL_FLAG_OLF_CRLF);
|
||||
|
||||
#define PR_SHELL(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_NORMAL, fmt, ##__VA_ARGS__)
|
||||
#define PR_ERROR(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_ERROR, fmt, ##__VA_ARGS__)
|
||||
#define PR_INFO(fshell, fmt, ...) \
|
||||
#define PR_INFO(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_INFO, fmt, ##__VA_ARGS__)
|
||||
#define PR_WARNING(shell, fmt, ...) \
|
||||
shell_fprintf(shell, SHELL_WARNING, fmt, ##__VA_ARGS__)
|
||||
|
@ -91,7 +92,7 @@ static int check_flash_device(const struct shell *shell)
|
|||
{
|
||||
if (flash_device == NULL) {
|
||||
PR_ERROR(shell, "Flash device is unknown."
|
||||
" Run set_device first.\r\n");
|
||||
" Run set_device first.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
|
@ -103,7 +104,7 @@ static void dump_buffer(const struct shell *shell, u8_t *buf, size_t size)
|
|||
u8_t *p = buf;
|
||||
|
||||
while (size >= 8) {
|
||||
PR_SHELL(shell, "%02x %02x %02x %02x | %02x %02x %02x %02x\r\n",
|
||||
PR_SHELL(shell, "%02x %02x %02x %02x | %02x %02x %02x %02x\n",
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
p += 8;
|
||||
size -= 8;
|
||||
|
@ -120,7 +121,7 @@ static void dump_buffer(const struct shell *shell, u8_t *buf, size_t size)
|
|||
newline = true;
|
||||
}
|
||||
if (newline) {
|
||||
PR_SHELL(shell, "\r\n");
|
||||
PR_SHELL(shell, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +174,7 @@ static int do_read(const struct shell *shell, off_t offset, size_t len)
|
|||
return 0;
|
||||
|
||||
err_read:
|
||||
PR_ERROR(shell, "flash_read error: %d\r\n", ret);
|
||||
PR_ERROR(shell, "flash_read error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -185,18 +186,18 @@ static int do_erase(const struct shell *shell, off_t offset, size_t size)
|
|||
ret = flash_write_protection_set(flash_device, false);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "Failed to disable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
"\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_erase(flash_device, offset, size);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "flash_erase failed (err:%d).\r\n", ret);
|
||||
PR_ERROR(shell, "flash_erase failed (err:%d).\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_write_protection_set(flash_device, true);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "Failed to enable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
"\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -210,22 +211,22 @@ static int do_write(const struct shell *shell, off_t offset, u8_t *buf,
|
|||
ret = flash_write_protection_set(flash_device, false);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "Failed to disable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
"\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_write(flash_device, offset, buf, len);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "flash_write failed (err:%d).\r\n", ret);
|
||||
PR_ERROR(shell, "flash_write failed (err:%d).\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = flash_write_protection_set(flash_device, true);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "Failed to enable flash protection (err: %d)."
|
||||
"\r\n", ret);
|
||||
"\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (read_back) {
|
||||
PR_SHELL(shell, "Reading back written bytes:\r\n");
|
||||
PR_SHELL(shell, "Reading back written bytes:\n");
|
||||
ret = do_read(shell, offset, len);
|
||||
}
|
||||
return ret;
|
||||
|
@ -252,7 +253,7 @@ static int cmd_write_block_size(const struct shell *shell, size_t argc,
|
|||
|
||||
err = check_flash_device(shell);
|
||||
if (!err) {
|
||||
PR_SHELL(shell, "%d\r\n",
|
||||
PR_SHELL(shell, "%d\n",
|
||||
flash_get_write_block_size(flash_device));
|
||||
}
|
||||
|
||||
|
@ -274,7 +275,7 @@ static int cmd_read(const struct shell *shell, size_t argc, char **argv)
|
|||
}
|
||||
|
||||
if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &len)) {
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
PR_ERROR(shell, "Invalid arguments.\n");
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -300,7 +301,7 @@ static int cmd_erase(const struct shell *shell, size_t argc, char **argv)
|
|||
}
|
||||
|
||||
if (parse_ul(argv[1], &offset) || parse_ul(argv[2], &size)) {
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
PR_ERROR(shell, "Invalid arguments.\n");
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -327,15 +328,15 @@ static int cmd_write(const struct shell *shell, size_t argc, char **argv)
|
|||
|
||||
err = parse_ul(argv[1], &offset);
|
||||
if (err) {
|
||||
PR_ERROR(shell, "Invalid argument.\r\n");
|
||||
PR_ERROR(shell, "Invalid argument.\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((argc - 2) > ARGC_MAX) {
|
||||
/* Can only happen if Zephyr limit is increased. */
|
||||
PR_ERROR(shell, "At most %lu bytes can be written.\r\n"
|
||||
PR_ERROR(shell, "At most %lu bytes can be written.\n"
|
||||
"In order to write more bytes please increase"
|
||||
" parameter: CONFIG_SHELL_ARGC_MAX.\r\n",
|
||||
" parameter: CONFIG_SHELL_ARGC_MAX.\n",
|
||||
(unsigned long)ARGC_MAX);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
|
@ -346,9 +347,9 @@ static int cmd_write(const struct shell *shell, size_t argc, char **argv)
|
|||
argv += 2;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (parse_u8(argv[i], &buf[i])) {
|
||||
PR_ERROR(shell, "Argument %lu (%s) is not a byte.\r\n"
|
||||
PR_ERROR(shell, "Argument %lu (%s) is not a byte.\n"
|
||||
"Bytes shall be passed in decimal"
|
||||
" notation.\r\n",
|
||||
" notation.\n",
|
||||
i + 1, argv[i]);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
|
@ -374,7 +375,7 @@ static int cmd_page_count(const struct shell *shell, size_t argc, char **argv)
|
|||
err = check_flash_device(shell);
|
||||
if (!err) {
|
||||
page_count = flash_get_page_count(flash_device);
|
||||
PR_SHELL(shell, "Flash device contains %lu pages.\r\n",
|
||||
PR_SHELL(shell, "Flash device contains %lu pages.\n",
|
||||
(unsigned long int)page_count);
|
||||
}
|
||||
|
||||
|
@ -400,7 +401,7 @@ static bool page_layout_cb(const struct flash_pages_info *info, void *datav)
|
|||
|
||||
sz = info->size;
|
||||
PR_SHELL(data->shell,
|
||||
"\tPage %u: start 0x%08x, length 0x%lx (%lu, %lu KB)\r\n",
|
||||
"\tPage %u: start 0x%08x, length 0x%lx (%lu, %lu KB)\n",
|
||||
info->index, info->start_offset, sz, sz, sz / KB(1));
|
||||
return true;
|
||||
}
|
||||
|
@ -440,7 +441,7 @@ static int cmd_page_layout(const struct shell *shell, size_t argc, char **argv)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
PR_ERROR(shell, "Invalid argument count.\r\n");
|
||||
PR_ERROR(shell, "Invalid argument count.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -451,7 +452,7 @@ static int cmd_page_layout(const struct shell *shell, size_t argc, char **argv)
|
|||
return 0;
|
||||
|
||||
bail:
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
PR_ERROR(shell, "Invalid arguments.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -485,7 +486,7 @@ static int cmd_page_read(const struct shell *shell, size_t argc, char **argv)
|
|||
ret = flash_get_page_info_by_idx(flash_device, page, &info);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "Function flash_page_info_by_idx returned an"
|
||||
" error: %d\r\n", ret);
|
||||
" error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
offset += info.start_offset;
|
||||
|
@ -493,7 +494,7 @@ static int cmd_page_read(const struct shell *shell, size_t argc, char **argv)
|
|||
return ret;
|
||||
|
||||
bail:
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
PR_ERROR(shell, "Invalid arguments.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -526,11 +527,11 @@ static int cmd_page_erase(const struct shell *shell, size_t argc, char **argv)
|
|||
ret = flash_get_page_info_by_idx(flash_device, page + i, &info);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "flash_get_page_info_by_idx error:"
|
||||
" %d\r\n", ret);
|
||||
" %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
PR_SHELL(shell, "Erasing page %u (start offset 0x%x,"
|
||||
" size 0x%x)\r\n",
|
||||
" size 0x%x)\n",
|
||||
info.index, info.start_offset, info.size);
|
||||
ret = do_erase(shell, info.start_offset, info.size);
|
||||
if (ret) {
|
||||
|
@ -541,7 +542,7 @@ static int cmd_page_erase(const struct shell *shell, size_t argc, char **argv)
|
|||
return ret;
|
||||
|
||||
bail:
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
PR_ERROR(shell, "Invalid arguments.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -570,7 +571,7 @@ static int cmd_page_write(const struct shell *shell, size_t argc, char **argv)
|
|||
argv += 3;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (parse_u8(argv[i], &buf[i])) {
|
||||
PR_ERROR(shell, "Argument %d (%s) is not a byte.\r\n",
|
||||
PR_ERROR(shell, "Argument %d (%s) is not a byte.\n",
|
||||
i + 2, argv[i]);
|
||||
ret = -EINVAL;
|
||||
goto bail;
|
||||
|
@ -579,14 +580,14 @@ static int cmd_page_write(const struct shell *shell, size_t argc, char **argv)
|
|||
|
||||
ret = flash_get_page_info_by_idx(flash_device, page, &info);
|
||||
if (ret) {
|
||||
PR_ERROR(shell, "flash_get_page_info_by_idx: %d\r\n", ret);
|
||||
PR_ERROR(shell, "flash_get_page_info_by_idx: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = do_write(shell, info.start_offset + off, buf, i, true);
|
||||
return ret;
|
||||
|
||||
bail:
|
||||
PR_ERROR(shell, "Invalid arguments.\r\n");
|
||||
PR_ERROR(shell, "Invalid arguments.\n");
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_FLASH_PAGE_LAYOUT */
|
||||
|
@ -605,11 +606,11 @@ static int cmd_set_dev(const struct shell *shell, size_t argc, char **argv)
|
|||
/* Run command. */
|
||||
dev = device_get_binding(name);
|
||||
if (!dev) {
|
||||
PR_ERROR(shell, "No device named %s.\r\n", name);
|
||||
PR_ERROR(shell, "No device named %s.\n", name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
if (flash_device) {
|
||||
PR_SHELL(shell, "Leaving behind device %s\r\n",
|
||||
PR_SHELL(shell, "Leaving behind device %s\n",
|
||||
flash_device->config->name);
|
||||
}
|
||||
flash_device = dev;
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
LOG_MODULE_REGISTER(app);
|
||||
|
||||
SHELL_UART_DEFINE(shell_transport_uart);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10,
|
||||
SHELL_FLAG_OLF_CRLF);
|
||||
|
||||
extern void foo(void);
|
||||
|
||||
|
@ -37,7 +38,7 @@ static int cmd_log_test_start(const struct shell *shell, size_t argc,
|
|||
}
|
||||
|
||||
k_timer_start(&log_timer, period, period);
|
||||
shell_fprintf(shell, SHELL_NORMAL, "Log test started\r\n");
|
||||
shell_fprintf(shell, SHELL_NORMAL, "Log test started\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -66,7 +67,7 @@ static int cmd_log_test_stop(const struct shell *shell, size_t argc,
|
|||
}
|
||||
|
||||
k_timer_stop(&log_timer);
|
||||
shell_fprintf(shell, SHELL_NORMAL, "Log test stopped\r\n");
|
||||
shell_fprintf(shell, SHELL_NORMAL, "Log test stopped\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -96,7 +97,7 @@ static int cmd_demo_ping(const struct shell *shell, size_t argc, char **argv)
|
|||
ARG_UNUSED(argc);
|
||||
ARG_UNUSED(argv);
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL, "pong\r\n");
|
||||
shell_fprintf(shell, SHELL_NORMAL, "pong\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,10 +106,10 @@ static int cmd_demo_params(const struct shell *shell, size_t argc, char **argv)
|
|||
{
|
||||
int cnt;
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL, "argc = %d\r\n", argc);
|
||||
shell_fprintf(shell, SHELL_NORMAL, "argc = %d\n", argc);
|
||||
for (cnt = 0; cnt < argc; cnt++) {
|
||||
shell_fprintf(shell, SHELL_NORMAL,
|
||||
" argv[%d] = %s\r\n", cnt, argv[cnt]);
|
||||
" argv[%d] = %s\n", cnt, argv[cnt]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ static int cmd_version(const struct shell *shell, size_t argc, char **argv)
|
|||
ARG_UNUSED(argv);
|
||||
|
||||
shell_fprintf(shell, SHELL_NORMAL,
|
||||
"Zephyr version %s\r\n", KERNEL_VERSION_STRING);
|
||||
"Zephyr version %s\n", KERNEL_VERSION_STRING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1154,6 +1154,8 @@ static int shell_instance_init(const struct shell *shell, const void *p_config,
|
|||
{
|
||||
__ASSERT_NO_MSG(shell);
|
||||
__ASSERT_NO_MSG(shell->ctx && shell->iface && shell->prompt);
|
||||
__ASSERT_NO_MSG((shell->shell_flag == SHELL_FLAG_CRLF_DEFAULT) ||
|
||||
(shell->shell_flag == SHELL_FLAG_OLF_CRLF));
|
||||
|
||||
int err;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <shell/shell_fprintf.h>
|
||||
#include <shell/shell.h>
|
||||
|
||||
#ifdef CONFIG_NEWLIB_LIBC
|
||||
typedef int (*out_func_t)(int c, void *ctx);
|
||||
|
@ -16,8 +17,14 @@ extern int _prf(int (*func)(), void *dest, char *format, va_list vargs);
|
|||
static int out_func(int c, void *ctx)
|
||||
{
|
||||
const struct shell_fprintf *sh_fprintf;
|
||||
const struct shell *shell;
|
||||
|
||||
sh_fprintf = (const struct shell_fprintf *)ctx;
|
||||
shell = (const struct shell *)sh_fprintf->user_ctx;
|
||||
|
||||
if ((shell->shell_flag == SHELL_FLAG_OLF_CRLF) && (c == '\n')) {
|
||||
(void)out_func('\r', ctx);
|
||||
}
|
||||
|
||||
sh_fprintf->buffer[sh_fprintf->ctrl_blk->buffer_cnt] = (u8_t)c;
|
||||
sh_fprintf->ctrl_blk->buffer_cnt++;
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
|
||||
|
||||
SHELL_UART_DEFINE(shell_transport_uart);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10);
|
||||
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10,
|
||||
SHELL_FLAG_CRLF_DEFAULT);
|
||||
|
||||
#if defined(CONFIG_BT_CONN)
|
||||
static bool hrs_simulate;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue