zephyr/subsys/shell/shell_uart.c
Jakub Rzeszutko c3bc7180b0 subsys: shell: add dummy backend to simplify commands testing
Added dummy backend which can be enabled with Kconfig. By default it is
disabled because it needs the same amount of memory as other phisical
backends. It shall be use only for commands testing purposes.

Improved shell_execute_cmd function, now it clears command context
before new command will be executed.

Signed-off-by: Jakub Rzeszutko <jakub.rzeszutko@nordicsemi.no>
2018-10-28 11:45:41 -04:00

107 lines
2.3 KiB
C

/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <shell/shell_uart.h>
#include <uart.h>
#include <init.h>
SHELL_UART_DEFINE(shell_transport_uart);
SHELL_DEFINE(uart_shell, "uart:~$ ", &shell_transport_uart, 10,
SHELL_FLAG_OLF_CRLF);
static void timer_handler(struct k_timer *timer)
{
struct shell_uart *sh_uart =
CONTAINER_OF(timer, struct shell_uart, timer);
if (uart_poll_in(sh_uart->dev, sh_uart->rx) == 0) {
sh_uart->rx_cnt = 1;
sh_uart->handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->context);
}
}
static int init(const struct shell_transport *transport,
const void *config,
shell_transport_handler_t evt_handler,
void *context)
{
struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx;
sh_uart->dev = device_get_binding(CONFIG_UART_CONSOLE_ON_DEV_NAME);
sh_uart->handler = evt_handler;
sh_uart->context = context;
k_timer_init(&sh_uart->timer, timer_handler, NULL);
k_timer_start(&sh_uart->timer, 20, 20);
return 0;
}
static int uninit(const struct shell_transport *transport)
{
return 0;
}
static int enable(const struct shell_transport *transport, bool blocking)
{
return 0;
}
static int write(const struct shell_transport *transport,
const void *data, size_t length, size_t *cnt)
{
struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx;
const u8_t *data8 = (const u8_t *)data;
for (size_t i = 0; i < length; i++) {
uart_poll_out(sh_uart->dev, data8[i]);
}
*cnt = length;
sh_uart->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->context);
return 0;
}
static int read(const struct shell_transport *transport,
void *data, size_t length, size_t *cnt)
{
struct shell_uart *sh_uart = (struct shell_uart *)transport->ctx;
if (sh_uart->rx_cnt) {
memcpy(data, sh_uart->rx, 1);
sh_uart->rx_cnt = 0;
*cnt = 1;
} else {
*cnt = 0;
}
return 0;
}
const struct shell_transport_api shell_uart_transport_api = {
.init = init,
.uninit = uninit,
.enable = enable,
.write = write,
.read = read
};
static int enable_shell_uart(struct device *arg)
{
ARG_UNUSED(arg);
shell_init(&uart_shell, NULL, true, true, LOG_LEVEL_INF);
return 0;
}
SYS_INIT(enable_shell_uart, POST_KERNEL, 0);
const struct shell *shell_backend_uart_get_ptr(void)
{
return &uart_shell;
}