sys/console: migrated to new console functionality This patch brings improved console functionality. Some of the features: * support for different console backends; UART and RTT for now * improved ANSI codes handling * backward compatible API, so it doesn't break existing apps although the old API is deprecated and will be deleted in the future * support for tab completion, which will be added later * ability to compile out input handling code to save flash
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/4863008f Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/4863008f Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/4863008f Branch: refs/heads/master Commit: 4863008f847b25d86a7f180d7a7635682bf03420 Parents: f7acf77 Author: MichaÅ Narajowski <michal.narajow...@codecoup.pl> Authored: Thu Apr 20 07:51:19 2017 +0200 Committer: MichaÅ Narajowski <michal.narajow...@codecoup.pl> Committed: Tue Apr 25 17:49:15 2017 -0700 ---------------------------------------------------------------------- sys/console/full/include/console/console.h | 18 +- sys/console/full/include/console/prompt.h | 21 +- sys/console/full/pkg.yml | 3 + sys/console/full/src/cons_fmt.c | 112 ---- sys/console/full/src/cons_tty.c | 574 --------------------- sys/console/full/src/console.c | 447 ++++++++++++++++ sys/console/full/src/console_fmt.c | 103 ++++ sys/console/full/src/console_priv.h | 37 ++ sys/console/full/src/prompt.c | 57 -- sys/console/full/src/rtt_console.c | 96 ++++ sys/console/full/src/ticks.c | 2 +- sys/console/full/src/uart_console.c | 193 +++++++ sys/console/full/syscfg.yml | 42 +- sys/console/minimal/include/console/console.h | 63 --- sys/console/minimal/include/console/prompt.h | 55 -- sys/console/minimal/include/console/ticks.h | 51 -- sys/console/minimal/pkg.yml | 33 -- sys/console/minimal/src/cons_tty.c | 253 --------- sys/console/minimal/syscfg.yml | 33 -- sys/console/stub/include/console/console.h | 37 +- 20 files changed, 970 insertions(+), 1260 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/include/console/console.h ---------------------------------------------------------------------- diff --git a/sys/console/full/include/console/console.h b/sys/console/full/include/console/console.h index c7ae04c..0f37b79 100644 --- a/sys/console/full/include/console/console.h +++ b/sys/console/full/include/console/console.h @@ -16,28 +16,44 @@ * specific language governing permissions and limitations * under the License. */ + #ifndef __CONSOLE_H__ #define __CONSOLE_H__ -#include <stdarg.h> +#include <inttypes.h> +#include "syscfg/syscfg.h" #ifdef __cplusplus extern "C" { #endif +struct os_eventq; + +struct console_input { + char line[MYNEWT_VAL(CONSOLE_MAX_INPUT_LEN)]; +}; + typedef void (*console_rx_cb)(void); int console_init(console_rx_cb rx_cb); int console_is_init(void); void console_write(const char *str, int cnt); +#if MYNEWT_VAL(CONSOLE_COMPAT) int console_read(char *str, int cnt, int *newline); +#endif void console_blocking_mode(void); void console_echo(int on); int console_printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));; +void console_set_queues(struct os_eventq *avail_queue, + struct os_eventq *cmd_queue); +void console_set_completion_cb(uint8_t (*completion)(char *str, uint8_t len)); +int console_handle_char(uint8_t byte); + extern int console_is_midline; +extern int console_out(int character); #ifdef __cplusplus } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/include/console/prompt.h ---------------------------------------------------------------------- diff --git a/sys/console/full/include/console/prompt.h b/sys/console/full/include/console/prompt.h index d4bf8bf..ab5518b 100644 --- a/sys/console/full/include/console/prompt.h +++ b/sys/console/full/include/console/prompt.h @@ -28,13 +28,26 @@ extern "C" { #endif /* print console prompt */ -void console_print_prompt(); +static void inline +console_print_prompt(void) +{ +} + /* set the console prompt character */ -void console_set_prompt(char); +static void inline +console_set_prompt(char ch) +{ +} -void console_no_prompt(void); +static void inline +console_no_prompt(void) +{ +} -void console_yes_prompt(void); +static void inline +console_yes_prompt(void) +{ +} #ifdef __cplusplus } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/pkg.yml ---------------------------------------------------------------------- diff --git a/sys/console/full/pkg.yml b/sys/console/full/pkg.yml index e56c7fd..d69fbb0 100644 --- a/sys/console/full/pkg.yml +++ b/sys/console/full/pkg.yml @@ -26,7 +26,10 @@ pkg.keywords: pkg.deps: - hw/hal - kernel/os +pkg.deps.CONSOLE_UART: - hw/drivers/uart +pkg.deps.CONSOLE_RTT: + - hw/drivers/rtt pkg.apis: console pkg.init: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/cons_fmt.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/cons_fmt.c b/sys/console/full/src/cons_fmt.c deleted file mode 100644 index cd848c6..0000000 --- a/sys/console/full/src/cons_fmt.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#include <stdarg.h> -#include <stdio.h> -#include "syscfg/syscfg.h" -#include "console/console.h" -#include "console/ticks.h" -#include "os/os_time.h" - -#define CONS_OUTPUT_MAX_LINE 128 - - -#if MYNEWT_VAL(BASELIBC_PRESENT) -size_t console_file_write(FILE *p, const char *str, size_t cnt); - -static const struct File_methods console_file_ops = { - .write = console_file_write, - .read = NULL -}; - -static const FILE console_file = { - .vmt = &console_file_ops -}; - -/** - * Prints the specified format string to the console. - * - * @return The number of characters that would have been - * printed if the console buffer were - * unlimited. This return value is analogous - * to that of snprintf. - */ -int -console_printf(const char *fmt, ...) -{ - va_list args; - int num_chars; - - num_chars = 0; - - if (console_get_ticks()) { - /* Prefix each line with a timestamp. */ - if (!console_is_midline) { - num_chars += fprintf((FILE *)&console_file, "%lu:", - (unsigned long)os_time_get()); - } - } - va_start(args, fmt); - num_chars += vfprintf((FILE *)&console_file, fmt, args); - va_end(args); - - return num_chars; -} - -#else - -/** - * Prints the specified format string to the console. - * - * @return The number of characters that would have been - * printed if the console buffer were - * unlimited. This return value is analogous - * to that of snprintf. - */ -int -console_printf(const char *fmt, ...) -{ - va_list args; - char buf[CONS_OUTPUT_MAX_LINE]; - int num_chars; - int len; - - num_chars = 0; - - if (console_get_ticks()) { - /* Prefix each line with a timestamp. */ - if (!console_is_midline) { - len = snprintf(buf, sizeof(buf), "%lu:", - (unsigned long)os_time_get()); - num_chars += len; - console_write(buf, len); - } - } - - va_start(args, fmt); - len = vsnprintf(buf, sizeof(buf), fmt, args); - num_chars += len; - if (len >= sizeof(buf)) { - len = sizeof(buf) - 1; - } - console_write(buf, len); - va_end(args); - - return num_chars; -} -#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/cons_tty.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/cons_tty.c b/sys/console/full/src/cons_tty.c deleted file mode 100644 index 50870f1..0000000 --- a/sys/console/full/src/cons_tty.c +++ /dev/null @@ -1,574 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include <inttypes.h> -#include <assert.h> -#include "syscfg/syscfg.h" -#include "sysinit/sysinit.h" -#include "os/os.h" -#include "uart/uart.h" -#include "bsp/bsp.h" - -#include "console/console.h" -#include "console/prompt.h" - -/** Indicates whether the previous line of output was completed. */ -int console_is_midline; - -#define CONSOLE_RX_CHUNK 16 - -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) -#define CONSOLE_HIST_SZ 32 -#endif - -#define CONSOLE_DEL 0x7f /* del character */ -#define CONSOLE_ESC 0x1b /* esc character */ -#define CONSOLE_LEFT 'D' /* esc-[-D emitted when moving left */ -#define CONSOLE_UP 'A' /* esc-[-A moving up */ -#define CONSOLE_RIGHT 'C' /* esc-[-C moving right */ -#define CONSOLE_DOWN 'B' /* esc-[-B moving down */ - -#define CONSOLE_HEAD_INC(cr) (((cr)->cr_head + 1) & ((cr)->cr_size - 1)) -#define CONSOLE_TAIL_INC(cr) (((cr)->cr_tail + 1) & ((cr)->cr_size - 1)) - -typedef void (*console_write_char)(char); -void console_print_prompt(void); - -struct console_ring { - uint8_t cr_head; - uint8_t cr_tail; - uint16_t cr_size; - uint8_t *cr_buf; -}; - -struct console_tty { - struct uart_dev *ct_dev; - - struct console_ring ct_tx; - /* must be after console_ring */ - uint8_t ct_tx_buf[MYNEWT_VAL(CONSOLE_TX_BUF_SIZE)]; - - struct console_ring ct_rx; - /* must be after console_ring */ - uint8_t ct_rx_buf[MYNEWT_VAL(CONSOLE_RX_BUF_SIZE)]; - - console_rx_cb ct_rx_cb; /* callback that input is ready */ - console_write_char ct_write_char; - uint8_t ct_echo_off:1; - uint8_t ct_esc_seq:2; -} console_tty; - -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) -struct console_hist { - uint8_t ch_head; - uint8_t ch_tail; - uint8_t ch_size; - uint8_t ch_curr; - uint8_t ch_buf[CONSOLE_HIST_SZ][MYNEWT_VAL(CONSOLE_RX_BUF_SIZE)]; -} console_hist; -#endif - -static void -console_add_char(struct console_ring *cr, char ch) -{ - cr->cr_buf[cr->cr_head] = ch; - cr->cr_head = CONSOLE_HEAD_INC(cr); -} - -static uint8_t -console_pull_char(struct console_ring *cr) -{ - uint8_t ch; - - ch = cr->cr_buf[cr->cr_tail]; - cr->cr_tail = CONSOLE_TAIL_INC(cr); - return ch; -} - -static int -console_pull_char_head(struct console_ring *cr) -{ - if (cr->cr_head != cr->cr_tail) { - cr->cr_head = (cr->cr_head - 1) & (cr->cr_size - 1); - return 0; - } else { - return -1; - } -} - -static void -console_queue_char(char ch) -{ - struct console_tty *ct = &console_tty; - int sr; - - OS_ENTER_CRITICAL(sr); - while (CONSOLE_HEAD_INC(&ct->ct_tx) == ct->ct_tx.cr_tail) { - /* TX needs to drain */ - uart_start_tx(ct->ct_dev); - OS_EXIT_CRITICAL(sr); - if (os_started()) { - os_time_delay(1); - } - OS_ENTER_CRITICAL(sr); - } - console_add_char(&ct->ct_tx, ch); - OS_EXIT_CRITICAL(sr); -} - -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) -static void -console_hist_init(void) -{ - struct console_hist *ch = &console_hist; - - ch->ch_head = 0; - ch->ch_tail = 0; - ch->ch_curr = 0; - ch->ch_size = CONSOLE_HIST_SZ; -} - -static void -console_hist_add(struct console_ring *rx) -{ - struct console_hist *ch = &console_hist; - uint8_t *str = ch->ch_buf[ch->ch_head]; - uint8_t tail; - uint8_t empty = 1; - - tail = rx->cr_tail; - while (tail != rx->cr_head) { - *str = rx->cr_buf[tail]; - if (*str != ' ' && *str != '\t' && *str != '\n') { - empty = 0; - } - if (*str == '\n') { - *str = '\0'; - /* don't save empty history */ - if (empty) { - return; - } - break; - } - str++; - tail = (tail + 1) % MYNEWT_VAL(CONSOLE_RX_BUF_SIZE); - } - - ch->ch_head = (ch->ch_head + 1) & (ch->ch_size - 1); - ch->ch_curr = ch->ch_head; - - /* buffer full, start overwriting old history */ - if (ch->ch_head == ch->ch_tail) { - ch->ch_tail = (ch->ch_tail + 1) & (ch->ch_size - 1); - } -} - -static int -console_hist_move(struct console_ring *rx, uint8_t *tx_buf, uint8_t direction) -{ - struct console_hist *ch = &console_hist; - uint8_t *str = NULL; - int space = 0; - int i; - uint8_t limit = direction == CONSOLE_UP ? ch->ch_tail : ch->ch_head; - - /* no more history to return in this direction */ - if (ch->ch_curr == limit) { - return 0; - } - - if (direction == CONSOLE_UP) { - ch->ch_curr = (ch->ch_curr - 1) & (ch->ch_size - 1); - } else { - ch->ch_curr = (ch->ch_curr + 1) & (ch->ch_size - 1); - } - - /* consume all chars */ - while (console_pull_char_head(rx) == 0) { - /* do nothing */ - } - - str = ch->ch_buf[ch->ch_curr]; - for (i = 0; i < MYNEWT_VAL(CONSOLE_RX_BUF_SIZE); ++i) { - if (str[i] == '\0') { - break; - } - tx_buf[i] = str[i]; - console_add_char(rx, str[i]); - space++; - } - - return space; -} -#endif - -static void -console_blocking_tx(char ch) -{ - struct console_tty *ct = &console_tty; - - uart_blocking_tx(ct->ct_dev, ch); -} - -/* - * Flush cnt characters from console output queue. - */ -static void -console_tx_flush(struct console_tty *ct, int cnt) -{ - int i; - uint8_t byte; - - for (i = 0; i < cnt; i++) { - if (ct->ct_tx.cr_head == ct->ct_tx.cr_tail) { - /* - * Queue is empty. - */ - break; - } - byte = console_pull_char(&ct->ct_tx); - console_blocking_tx(byte); - } -} - -void -console_blocking_mode(void) -{ - struct console_tty *ct = &console_tty; - int sr; - - OS_ENTER_CRITICAL(sr); - if (ct->ct_write_char) { - ct->ct_write_char = console_blocking_tx; - - console_tx_flush(ct, MYNEWT_VAL(CONSOLE_TX_BUF_SIZE)); - } - OS_EXIT_CRITICAL(sr); -} - -void -console_echo(int on) -{ - struct console_tty *ct = &console_tty; - - ct->ct_echo_off = !on; -} - -size_t -console_file_write(void *arg, const char *str, size_t cnt) -{ - struct console_tty *ct = &console_tty; - int i; - - if (!ct->ct_write_char) { - return cnt; - } - for (i = 0; i < cnt; i++) { - if (str[i] == '\n') { - ct->ct_write_char('\r'); - } - ct->ct_write_char(str[i]); - } - if (cnt > 0) { - console_is_midline = str[cnt - 1] != '\n'; - } - uart_start_tx(ct->ct_dev); - return cnt; -} - -void -console_write(const char *str, int cnt) -{ - console_file_write(NULL, str, cnt); -} - -int -console_read(char *str, int cnt, int *newline) -{ - struct console_tty *ct = &console_tty; - struct console_ring *cr = &ct->ct_rx; - int sr; - int i; - uint8_t ch; - - *newline = 0; - OS_ENTER_CRITICAL(sr); - for (i = 0; i < cnt; i++) { - if (cr->cr_head == cr->cr_tail) { - break; - } - - if ((i & (CONSOLE_RX_CHUNK - 1)) == (CONSOLE_RX_CHUNK - 1)) { - /* - * Make a break from blocking interrupts during the copy. - */ - OS_EXIT_CRITICAL(sr); - OS_ENTER_CRITICAL(sr); - } - - ch = console_pull_char(cr); - if (ch == '\n') { - *str = '\0'; - *newline = 1; - break; - } - *str++ = ch; - } - OS_EXIT_CRITICAL(sr); - if (i > 0 || *newline) { - uart_start_rx(ct->ct_dev); - } - return i; -} - -/* - * Interrupts disabled when console_tx_char/console_rx_char are called. - */ -static int -console_tx_char(void *arg) -{ - struct console_tty *ct = (struct console_tty *)arg; - struct console_ring *cr = &ct->ct_tx; - - if (cr->cr_head == cr->cr_tail) { - /* - * No more data. - */ - return -1; - } - return console_pull_char(cr); -} - -static int -console_buf_space(struct console_ring *cr) -{ - int space; - - space = (cr->cr_tail - cr->cr_head) & (cr->cr_size - 1); - return space - 1; -} - -static int -console_rx_char(void *arg, uint8_t data) -{ - struct console_tty *ct = (struct console_tty *)arg; - struct console_ring *tx = &ct->ct_tx; - struct console_ring *rx = &ct->ct_rx; - int tx_space = 0; - int i; -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) - uint8_t tx_buf[MYNEWT_VAL(CONSOLE_RX_BUF_SIZE)]; -#else - uint8_t tx_buf[3]; -#endif - - if (CONSOLE_HEAD_INC(&ct->ct_rx) == ct->ct_rx.cr_tail) { - /* - * RX queue full. Reader must drain this. - */ - if (ct->ct_rx_cb) { - ct->ct_rx_cb(); - } - return -1; - } - - /* echo */ - switch (data) { - case '\r': - case '\n': - /* - * linefeed - */ - tx_buf[0] = '\n'; - tx_buf[1] = '\r'; - tx_space = 2; - console_add_char(rx, '\n'); -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) - console_hist_add(rx); -#endif - if (ct->ct_rx_cb) { - ct->ct_rx_cb(); - } - break; - case CONSOLE_ESC: - ct->ct_esc_seq = 1; - goto out; - case '[': - if (ct->ct_esc_seq == 1) { - ct->ct_esc_seq = 2; - goto out; - } else { - goto queue_char; - } - break; - case CONSOLE_LEFT: - if (ct->ct_esc_seq == 2) { - goto backspace; - } else { - goto queue_char; - } - break; - case CONSOLE_UP: - case CONSOLE_DOWN: - if (ct->ct_esc_seq != 2) { - goto queue_char; - } -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) - tx_space = console_hist_move(rx, tx_buf, data); - tx_buf[tx_space] = 0; - ct->ct_esc_seq = 0; - /* - * when moving up, stop on oldest history entry - * when moving down, let it delete input before leaving... - */ - if (data == CONSOLE_UP && tx_space == 0) { - goto out; - } - if (!ct->ct_echo_off) { - /* HACK: clean line by backspacing up to maximum possible space */ - for (i = 0; i < MYNEWT_VAL(CONSOLE_TX_BUF_SIZE); i++) { - if (console_buf_space(tx) < 3) { - console_tx_flush(ct, 3); - } - console_add_char(tx, '\b'); - console_add_char(tx, ' '); - console_add_char(tx, '\b'); - uart_start_tx(ct->ct_dev); - } - if (tx_space == 0) { - goto out; - } - } else { - goto queue_char; - } - break; -#else - ct->ct_esc_seq = 0; - goto out; -#endif - case CONSOLE_RIGHT: - if (ct->ct_esc_seq == 2) { - data = ' '; /* add space */ - } - goto queue_char; - case '\b': - case CONSOLE_DEL: -backspace: - /* - * backspace - */ - ct->ct_esc_seq = 0; - if (console_pull_char_head(rx) == 0) { - /* - * Only wipe out char if we can pull stuff off from head. - */ - tx_buf[0] = '\b'; - tx_buf[1] = ' '; - tx_buf[2] = '\b'; - tx_space = 3; - } else { - goto out; - } - break; - default: -queue_char: - tx_buf[0] = data; - tx_space = 1; - ct->ct_esc_seq = 0; - console_add_char(rx, data); - break; - } - if (!ct->ct_echo_off) { - if (console_buf_space(tx) < tx_space) { - console_tx_flush(ct, tx_space); - } - for (i = 0; i < tx_space; i++) { - console_add_char(tx, tx_buf[i]); - } - uart_start_tx(ct->ct_dev); - } -out: - return 0; -} - -int -console_is_init(void) -{ - struct console_tty *ct = &console_tty; - - return (ct->ct_dev != NULL); -} - -static int is_power_of_two (unsigned int x) -{ - return ((x != 0) && !(x & (x - 1))); -} - -int -console_init(console_rx_cb rx_cb) -{ - struct console_tty *ct = &console_tty; - struct uart_conf uc = { - .uc_speed = MYNEWT_VAL(CONSOLE_BAUD), - .uc_databits = 8, - .uc_stopbits = 1, - .uc_parity = UART_PARITY_NONE, - .uc_flow_ctl = MYNEWT_VAL(CONSOLE_FLOW_CONTROL), - .uc_tx_char = console_tx_char, - .uc_rx_char = console_rx_char, - .uc_cb_arg = ct - }; - - ct->ct_rx_cb = rx_cb; - if (!ct->ct_dev) { - ct->ct_tx.cr_size = MYNEWT_VAL(CONSOLE_TX_BUF_SIZE); - ct->ct_tx.cr_buf = ct->ct_tx_buf; - ct->ct_rx.cr_size = MYNEWT_VAL(CONSOLE_RX_BUF_SIZE); - ct->ct_rx.cr_buf = ct->ct_rx_buf; - ct->ct_write_char = console_queue_char; - - ct->ct_dev = (struct uart_dev *)os_dev_open(CONSOLE_UART, - OS_TIMEOUT_NEVER, &uc); - if (!ct->ct_dev) { - return -1; - } - ct->ct_echo_off = ! MYNEWT_VAL(CONSOLE_ECHO); - } - - /* must be a power of 2 */ - assert(is_power_of_two(MYNEWT_VAL(CONSOLE_RX_BUF_SIZE))); - -#if MYNEWT_VAL(CONSOLE_HIST_ENABLE) - console_hist_init(); -#endif - - return 0; -} - -void -console_pkg_init(void) -{ - int rc; - - /* Ensure this function only gets called by sysinit. */ - SYSINIT_ASSERT_ACTIVE(); - - rc = console_init(NULL); - SYSINIT_PANIC_ASSERT(rc == 0); -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/console.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/console.c b/sys/console/full/src/console.c new file mode 100644 index 0000000..18ff755 --- /dev/null +++ b/sys/console/full/src/console.c @@ -0,0 +1,447 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include <assert.h> +#include <inttypes.h> +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "syscfg/syscfg.h" +#include "os/os.h" +#include "sysinit/sysinit.h" +#include "console/console.h" +#include "console/ticks.h" +#include "console_priv.h" + +/* Control characters */ +#define ESC 0x1b +#define DEL 0x7f + +/* ANSI escape sequences */ +#define ANSI_ESC '[' +#define ANSI_UP 'A' +#define ANSI_DOWN 'B' +#define ANSI_FORWARD 'C' +#define ANSI_BACKWARD 'D' +#define ANSI_END 'F' +#define ANSI_HOME 'H' +#define ANSI_DEL '~' + +#define ESC_ESC (1 << 0) +#define ESC_ANSI (1 << 1) +#define ESC_ANSI_FIRST (1 << 2) +#define ESC_ANSI_VAL (1 << 3) +#define ESC_ANSI_VAL_2 (1 << 4) + +/* Indicates whether the previous line of output was completed. */ +int console_is_midline; + +#if MYNEWT_VAL(CONSOLE_COMPAT) +#define CONSOLE_COMPAT_MAX_CMD_QUEUED 1 +static struct console_input buf[CONSOLE_COMPAT_MAX_CMD_QUEUED]; +static struct os_event shell_console_ev[CONSOLE_COMPAT_MAX_CMD_QUEUED]; +static console_rx_cb console_compat_rx_cb; /* callback that input is ready */ +static struct os_eventq compat_avail_queue; +static struct os_eventq compat_lines_queue; +#endif + +static int esc_state; +static int echo = 1; +static unsigned int ansi_val, ansi_val_2; + +static uint8_t cur, end; +static struct os_eventq *avail_queue; +static struct os_eventq *lines_queue; +static uint8_t (*completion_cb)(char *line, uint8_t len); + +void +console_echo(int on) +{ + echo = on; +} + +void +console_write(const char *str, int cnt) +{ + int i; + + for (i = 0; i < cnt; i++) { + if (console_out((int)str[i]) == EOF) { + break; + } + } +} + +#if MYNEWT_VAL(CONSOLE_COMPAT) +int +console_read(char *str, int cnt, int *newline) +{ + struct os_event *ev; + struct console_input *cmd; + size_t len; + + *newline = 0; + ev = os_eventq_get_no_wait(lines_queue); + if (!ev) { + return 0; + } + cmd = ev->ev_arg; + len = strlen(cmd->line); + strncpy(str, cmd->line, len+1); + os_eventq_put(avail_queue, ev); + *newline = 1; + return len; +} +#endif + +void +console_blocking_mode(void) +{ +#if MYNEWT_VAL(CONSOLE_UART) + uart_console_blocking_mode(); +#endif +} + +static inline void +cursor_forward(unsigned int count) +{ + console_printf("\x1b[%uC", count); +} + +static inline void +cursor_backward(unsigned int count) +{ + console_printf("\x1b[%uD", count); +} + +static inline void +cursor_save(void) +{ + console_out(ESC); + console_out('['); + console_out('s'); +} + +static inline void +cursor_restore(void) +{ + console_out(ESC); + console_out('['); + console_out('u'); +} + +static void +insert_char(char *pos, char c, uint8_t end) +{ + char tmp; + + if (echo) { + /* Echo back to console */ + console_out(c); + } + + if (end == 0) { + *pos = c; + return; + } + + tmp = *pos; + *(pos++) = c; + + cursor_save(); + + while (end-- > 0) { + console_out(tmp); + c = *pos; + *(pos++) = tmp; + tmp = c; + } + + /* Move cursor back to right place */ + cursor_restore(); +} + +static void +del_char(char *pos, uint8_t end) +{ + console_out('\b'); + + if (end == 0) { + console_out(' '); + console_out('\b'); + return; + } + + cursor_save(); + + while (end-- > 0) { + *pos = *(pos + 1); + console_out(*(pos++)); + } + + console_out(' '); + + /* Move cursor back to right place */ + cursor_restore(); +} + +static void +handle_ansi(uint8_t byte, char *line) +{ + if (esc_state & ESC_ANSI_FIRST) { + esc_state &= ~ESC_ANSI_FIRST; + if (!isdigit(byte)) { + ansi_val = 1; + goto ansi_cmd; + } + + esc_state |= ESC_ANSI_VAL; + ansi_val = byte - '0'; + ansi_val_2 = 0; + return; + } + + if (esc_state & ESC_ANSI_VAL) { + if (isdigit(byte)) { + if (esc_state & ESC_ANSI_VAL_2) { + ansi_val_2 *= 10; + ansi_val_2 += byte - '0'; + } else { + ansi_val *= 10; + ansi_val += byte - '0'; + } + return; + } + + /* Multi value sequence, e.g. Esc[Line;ColumnH */ + if (byte == ';' && !(esc_state & ESC_ANSI_VAL_2)) { + esc_state |= ESC_ANSI_VAL_2; + return; + } + + esc_state &= ~ESC_ANSI_VAL; + esc_state &= ~ESC_ANSI_VAL_2; + } + +ansi_cmd: + switch (byte) { + case ANSI_BACKWARD: + if (ansi_val > cur) { + break; + } + + end += ansi_val; + cur -= ansi_val; + cursor_backward(ansi_val); + break; + case ANSI_FORWARD: + if (ansi_val > end) { + break; + } + + end -= ansi_val; + cur += ansi_val; + cursor_forward(ansi_val); + break; + case ANSI_HOME: + if (!cur) { + break; + } + + cursor_backward(cur); + end += cur; + cur = 0; + break; + case ANSI_END: + if (!end) { + break; + } + + cursor_forward(end); + cur += end; + end = 0; + break; + case ANSI_DEL: + if (!end) { + break; + } + + cursor_forward(1); + del_char(&line[cur], --end); + break; + default: + break; + } + + esc_state &= ~ESC_ANSI; +} + +int +console_handle_char(uint8_t byte) +{ +#if !MYNEWT_VAL(CONSOLE_INPUT) + return 0; +#endif + + static struct os_event *ev; + static struct console_input *input; + + if (!avail_queue || !lines_queue) { + return 0; + } + + if (!ev) { + ev = os_eventq_get_no_wait(avail_queue); + if (!ev) + return 0; + input = ev->ev_arg; + } + + /* Handle ANSI escape mode */ + if (esc_state & ESC_ANSI) { + handle_ansi(byte, input->line); + return 0; + } + + /* Handle escape mode */ + if (esc_state & ESC_ESC) { + esc_state &= ~ESC_ESC; + handle_ansi(byte, input->line); + switch (byte) { + case ANSI_ESC: + esc_state |= ESC_ANSI; + esc_state |= ESC_ANSI_FIRST; + break; + default: + break; + } + + return 0; + } + + /* Handle special control characters */ + if (!isprint(byte)) { + handle_ansi(byte, input->line); + switch (byte) { + case DEL: + if (cur > 0) { + del_char(&input->line[--cur], end); + } + break; + case ESC: + esc_state |= ESC_ESC; + break; + case '\r': + input->line[cur + end] = '\0'; + console_out('\r'); + console_out('\n'); + cur = 0; + end = 0; + os_eventq_put(lines_queue, ev); + +#if MYNEWT_VAL(CONSOLE_COMPAT) + if (console_compat_rx_cb) { + console_compat_rx_cb(); + } +#endif + + input = NULL; + ev = NULL; + break; + case '\t': + if (completion_cb && !end) { + cur += completion_cb(input->line, cur); + } + break; + default: + break; + } + + return 0; + } + + /* Ignore characters if there's no more buffer space */ + if (cur + end < sizeof(input->line) - 1) { + insert_char(&input->line[cur++], byte, end); + } + return 0; +} + +int +console_is_init(void) +{ +#if MYNEWT_VAL(CONSOLE_UART) + return uart_console_is_init(); +#endif +#if MYNEWT_VAL(CONSOLE_RTT) + return rtt_console_is_init(); +#endif + return 0; +} + +void +console_set_queues(struct os_eventq *avail, struct os_eventq *lines) +{ + avail_queue = avail; + lines_queue = lines; +} + +void +console_set_completion_cb(uint8_t (*completion)(char *str, uint8_t len)) +{ + completion_cb = completion; +} + +#if MYNEWT_VAL(CONSOLE_COMPAT) +int +console_init(console_rx_cb rx_cb) +{ + int i; + + os_eventq_init(&compat_lines_queue); + os_eventq_init(&compat_avail_queue); + console_set_queues(&compat_avail_queue, &compat_lines_queue); + + for (i = 0; i < CONSOLE_COMPAT_MAX_CMD_QUEUED; i++) { + shell_console_ev[i].ev_arg = &buf[i]; + os_eventq_put(avail_queue, &shell_console_ev[i]); + } + console_compat_rx_cb = rx_cb; + return 0; +} +#endif + +void +console_pkg_init(void) +{ + int rc = 0; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + +#if MYNEWT_VAL(CONSOLE_UART) + rc = uart_console_init(); +#endif +#if MYNEWT_VAL(CONSOLE_RTT) + rc = rtt_console_init(); +#endif + SYSINIT_PANIC_ASSERT(rc == 0); +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/console_fmt.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/console_fmt.c b/sys/console/full/src/console_fmt.c new file mode 100644 index 0000000..32b68e3 --- /dev/null +++ b/sys/console/full/src/console_fmt.c @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +#include <stdarg.h> +#include <stdio.h> +#include "syscfg/syscfg.h" +#include "console/console.h" +#include "console/ticks.h" +#include "os/os_time.h" + +#define CONS_OUTPUT_MAX_LINE 128 + + +#if MYNEWT_VAL(BASELIBC_PRESENT) + +/** + * Prints the specified format string to the console. + * + * @return The number of characters that would have been + * printed if the console buffer were + * unlimited. This return value is analogous + * to that of snprintf. + */ +int +console_printf(const char *fmt, ...) +{ + va_list args; + int num_chars; + + num_chars = 0; + + if (console_get_ticks()) { + /* Prefix each line with a timestamp. */ + if (!console_is_midline) { + num_chars += printf("%06lu ", (unsigned long)os_time_get()); + } + } + + va_start(args, fmt); + num_chars += vprintf(fmt, args); + va_end(args); + + return num_chars; +} + + +#else + +/** + * Prints the specified format string to the console. + * + * @return The number of characters that would have been + * printed if the console buffer were + * unlimited. This return value is analogous + * to that of snprintf. + */ +int +console_printf(const char *fmt, ...) +{ + va_list args; + char buf[CONS_OUTPUT_MAX_LINE]; + int num_chars; + int len; + + num_chars = 0; + + if (console_get_ticks()) { + /* Prefix each line with a timestamp. */ + if (!console_is_midline) { + len = snprintf(buf, sizeof(buf), "%06lu ", + (unsigned long)os_time_get()); + num_chars += len; + console_write(buf, len); + } + } + + va_start(args, fmt); + len = vsnprintf(buf, sizeof(buf), fmt, args); + num_chars += len; + if (len >= sizeof(buf)) { + len = sizeof(buf) - 1; + } + console_write(buf, len); + va_end(args); + + return num_chars; +} +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/console_priv.h ---------------------------------------------------------------------- diff --git a/sys/console/full/src/console_priv.h b/sys/console/full/src/console_priv.h new file mode 100644 index 0000000..d307b5d --- /dev/null +++ b/sys/console/full/src/console_priv.h @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef __CONSOLE_PRIV_H__ +#define __CONSOLE_PRIV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int uart_console_is_init(void); +int uart_console_init(void); +void uart_console_blocking_mode(void); +int rtt_console_is_init(void); +int rtt_console_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __CONSOLE_PRIV_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/prompt.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/prompt.c b/sys/console/full/src/prompt.c deleted file mode 100644 index 251c249..0000000 --- a/sys/console/full/src/prompt.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -#include "console/console.h" -#include "console/prompt.h" -#include <syscfg/syscfg.h> - -/* console prompt, always followed by a space */ -static char console_prompt[] = " > "; -static char do_prompt = MYNEWT_VAL(CONSOLE_PROMPT); - - -/* set the prompt character, leave the space */ -void -console_set_prompt(char p) -{ - do_prompt = 1; - console_prompt[1] = p; -} - -void -console_no_prompt(void) -{ - do_prompt = 0; -} - -void -console_yes_prompt(void) -{ - do_prompt = 1; -} - -/* print the prompt to the console */ -void -console_print_prompt(void) -{ - if (do_prompt) { - console_printf("%s", console_prompt); - } -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/rtt_console.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/rtt_console.c b/sys/console/full/src/rtt_console.c new file mode 100644 index 0000000..63067c1 --- /dev/null +++ b/sys/console/full/src/rtt_console.c @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(CONSOLE_RTT) +#include <ctype.h> + +#include "os/os.h" +#include "os/os_cputime.h" +#include "rtt/SEGGER_RTT.h" +#include "console/console.h" +#include "console_priv.h" + +#if MYNEWT_VAL(CONSOLE_INPUT) +static struct hal_timer rtt_timer; +#endif + +static const char CR = '\r'; + +int +console_out(int character) +{ + char c = (char)character; + + if ('\n' == c) { + SEGGER_RTT_WriteNoLock(0, &CR, 1); + console_is_midline = 0; + } else { + console_is_midline = 1; + } + + SEGGER_RTT_WriteNoLock(0, &c, 1); + + return character; +} + +#if MYNEWT_VAL(CONSOLE_INPUT) +void +rtt(void *arg) +{ + int key; + int i = 0; + uint32_t timeout; + + key = SEGGER_RTT_GetKey(); + if (key >= 0) { + console_handle_char((char)key); + i = 0; + } + /* These values were selected to keep the shell responsive + * and at the same time reduce context switches. + * Min sleep is 50ms and max is 250ms. + */ + if (i < 5) { + ++i; + } + timeout = 50000 * i; + os_cputime_timer_relative(&rtt_timer, timeout); +} +#endif + +int +rtt_console_is_init(void) +{ + return 1; +} + +int +rtt_console_init(void) +{ +#if MYNEWT_VAL(CONSOLE_INPUT) + os_cputime_timer_init(&rtt_timer, rtt, NULL); + /* start after a second */ + os_cputime_timer_relative(&rtt_timer, 1000000); +#endif + return 0; +} + +#endif /* MYNEWT_VAL(CONSOLE_RTT) */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/ticks.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/ticks.c b/sys/console/full/src/ticks.c index 1a442aa..06d1c8f 100644 --- a/sys/console/full/src/ticks.c +++ b/sys/console/full/src/ticks.c @@ -18,9 +18,9 @@ */ +#include "syscfg/syscfg.h" #include "console/console.h" #include "console/prompt.h" -#include "syscfg/syscfg.h" static char do_ticks = MYNEWT_VAL(CONSOLE_TICKS); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/src/uart_console.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/uart_console.c b/sys/console/full/src/uart_console.c new file mode 100644 index 0000000..44943d2 --- /dev/null +++ b/sys/console/full/src/uart_console.c @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "syscfg/syscfg.h" + +#if MYNEWT_VAL(CONSOLE_UART) +#include <ctype.h> +#include <assert.h> + +#include "os/os.h" +#include "uart/uart.h" +#include "bsp/bsp.h" + +#include "console/console.h" +#include "console_priv.h" + +#define CONSOLE_HEAD_INC(cr) (((cr)->cr_head + 1) & ((cr)->cr_size - 1)) +#define CONSOLE_TAIL_INC(cr) (((cr)->cr_tail + 1) & ((cr)->cr_size - 1)) + +static struct uart_dev *uart_dev; +static struct console_ring cr_tx; +/* must be after console_ring */ +static uint8_t cr_tx_buf[MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE)]; +typedef void (*console_write_char)(struct uart_dev*, uint8_t); +static console_write_char write_char_cb; + +struct console_ring { + uint8_t cr_head; + uint8_t cr_tail; + uint16_t cr_size; + uint8_t *cr_buf; +}; + +static void +console_add_char(struct console_ring *cr, char ch) +{ + cr->cr_buf[cr->cr_head] = ch; + cr->cr_head = CONSOLE_HEAD_INC(cr); +} + +static uint8_t +console_pull_char(struct console_ring *cr) +{ + uint8_t ch; + + ch = cr->cr_buf[cr->cr_tail]; + cr->cr_tail = CONSOLE_TAIL_INC(cr); + return ch; +} + +static void +console_queue_char(struct uart_dev *uart_dev, uint8_t ch) +{ + int sr; + + OS_ENTER_CRITICAL(sr); + while (CONSOLE_HEAD_INC(&cr_tx) == cr_tx.cr_tail) { + /* TX needs to drain */ + uart_start_tx(uart_dev); + OS_EXIT_CRITICAL(sr); + if (os_started()) { + os_time_delay(1); + } + OS_ENTER_CRITICAL(sr); + } + console_add_char(&cr_tx, ch); + OS_EXIT_CRITICAL(sr); +} + +/* + * Flush cnt characters from console output queue. + */ +static void +console_tx_flush(int cnt) +{ + int i; + uint8_t byte; + + for (i = 0; i < cnt; i++) { + if (cr_tx.cr_head == cr_tx.cr_tail) { + /* + * Queue is empty. + */ + break; + } + byte = console_pull_char(&cr_tx); + uart_blocking_tx(uart_dev, byte); + } +} + +void +uart_console_blocking_mode(void) +{ + int sr; + + OS_ENTER_CRITICAL(sr); + if (write_char_cb) { + write_char_cb = uart_blocking_tx; + + console_tx_flush(MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE)); + } + OS_EXIT_CRITICAL(sr); +} + +int +console_out(int c) +{ + if ('\n' == c) { + write_char_cb(uart_dev, '\r'); + console_is_midline = 0; + } else { + console_is_midline = 1; + } + write_char_cb(uart_dev, c); + uart_start_tx(uart_dev); + + return c; +} + +/* + * Interrupts disabled when console_tx_char/console_rx_char are called. + * Characters sent only in blocking mode. + */ +static int +console_tx_char(void *arg) +{ + if (cr_tx.cr_head == cr_tx.cr_tail) { + /* + * No more data. + */ + return -1; + } + return console_pull_char(&cr_tx); +} + +/* + * Interrupts disabled when console_tx_char/console_rx_char are called. + */ +static int +console_rx_char(void *arg, uint8_t byte) +{ + return console_handle_char(byte); +} + +int +uart_console_is_init(void) +{ + return uart_dev != NULL; +} + +int +uart_console_init(void) +{ + struct uart_conf uc = { + .uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD), + .uc_databits = 8, + .uc_stopbits = 1, + .uc_parity = UART_PARITY_NONE, + .uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL), + .uc_tx_char = console_tx_char, + .uc_rx_char = console_rx_char, + }; + + cr_tx.cr_size = MYNEWT_VAL(CONSOLE_UART_TX_BUF_SIZE); + cr_tx.cr_buf = cr_tx_buf; + write_char_cb = console_queue_char; + + if (!uart_dev) { + uart_dev = (struct uart_dev *)os_dev_open(CONSOLE_UART, + OS_TIMEOUT_NEVER, &uc); + if (!uart_dev) { + return -1; + } + } + return 0; +} +#endif /* MYNEWT_VAL(CONSOLE_UART) */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/full/syscfg.yml ---------------------------------------------------------------------- diff --git a/sys/console/full/syscfg.yml b/sys/console/full/syscfg.yml index 68eedaf..45fc2ed 100644 --- a/sys/console/full/syscfg.yml +++ b/sys/console/full/syscfg.yml @@ -19,27 +19,31 @@ # Package: sys/console/full syscfg.defs: - CONSOLE_BAUD: + CONSOLE_UART: + description: 'Set console output to UART' + value: 1 + CONSOLE_RTT: + description: 'Set console output to RTT' + value: 0 + CONSOLE_INPUT: + description: 'Enable console input' + value: 1 + CONSOLE_TICKS: + description: 'Print OS Ticks' + value: 1 + CONSOLE_COMPAT: + description: 'Console backward compatibility' + value: 1 + CONSOLE_MAX_INPUT_LEN: + description: 'Maximum input line length' + value: 256 + + CONSOLE_UART_BAUD: description: 'Console UART baud rate.' value: '115200' - CONSOLE_FLOW_CONTROL: + CONSOLE_UART_FLOW_CONTROL: description: 'Console UART flow control.' value: 'UART_FLOW_CTL_NONE' - CONSOLE_TX_BUF_SIZE: - description: 'Console transmit buffer size; must be power of 2.' + CONSOLE_UART_TX_BUF_SIZE: + description: 'UART console transmit buffer size; must be power of 2.' value: 32 - CONSOLE_RX_BUF_SIZE: - description: 'Console receive buffer size.' - value: 128 - CONSOLE_TICKS: - description: 'Print OS Ticks' - value: '1' - CONSOLE_PROMPT: - description: 'Default console prompt ' - value: '0' - CONSOLE_ECHO: - description: 'Default console echo ' - value: '1' - CONSOLE_HIST_ENABLE: - description: 'Console history ' - value: 0 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/minimal/include/console/console.h ---------------------------------------------------------------------- diff --git a/sys/console/minimal/include/console/console.h b/sys/console/minimal/include/console/console.h deleted file mode 100644 index 61f6534..0000000 --- a/sys/console/minimal/include/console/console.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -#ifndef __CONSOLE_H__ -#define __CONSOLE_H__ - -#include <stdarg.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*console_rx_cb)(void); - -int console_init(console_rx_cb rx_cb); -static int inline -console_is_init(void) -{ - return 0; -} - -void console_write(const char *str, int cnt); -int console_read(char *str, int cnt, int *newline); -static void inline -console_blocking_mode(void) -{ -} - -static void inline -console_echo(int on) -{ -} - -static int console_printf(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2)));; -static int inline -console_printf(const char *fmt, ...) -{ - return 0; -} - -#define console_is_midline 0 - -#ifdef __cplusplus -} -#endif - -#endif /* __CONSOLE_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/minimal/include/console/prompt.h ---------------------------------------------------------------------- diff --git a/sys/console/minimal/include/console/prompt.h b/sys/console/minimal/include/console/prompt.h deleted file mode 100644 index 6de36f5..0000000 --- a/sys/console/minimal/include/console/prompt.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef __CONSOLE_PROMPT_H__ -#define __CONSOLE_PROMPT_H__ - -#include <stdarg.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* print console prompt */ -static void inline -console_print_prompt(void) -{ -} - -/* set the console prompt character */ -static void inline -console_set_prompt(char ch) -{ -} - -static void inline -console_no_prompt(void) -{ -} - -static void inline -console_yes_prompt(void) -{ -} - -#ifdef __cplusplus -} -#endif - -#endif /* __CONSOLE_PROMPT_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/minimal/include/console/ticks.h ---------------------------------------------------------------------- diff --git a/sys/console/minimal/include/console/ticks.h b/sys/console/minimal/include/console/ticks.h deleted file mode 100644 index 97f6a05..0000000 --- a/sys/console/minimal/include/console/ticks.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#ifndef __CONSOLE_TICKS_H__ -#define __CONSOLE_TICKS_H__ - -#include <stdarg.h> - - -#ifdef __cplusplus -extern "C" { -#endif - - -static void inline -console_no_ticks(void) -{ -} - -static void inline -console_yes_ticks(void) -{ -} - -static char inline -console_get_ticks(void) -{ - return 0; -} - -#ifdef __cplusplus -} -#endif - -#endif /* __CONSOLE_PROMPT_H__ */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/minimal/pkg.yml ---------------------------------------------------------------------- diff --git a/sys/console/minimal/pkg.yml b/sys/console/minimal/pkg.yml deleted file mode 100644 index 40e8980..0000000 --- a/sys/console/minimal/pkg.yml +++ /dev/null @@ -1,33 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -pkg.name: sys/console/minimal -pkg.description: Text-based IO interface (minimized). -pkg.author: "Apache Mynewt <d...@mynewt.incubator.apache.org>" -pkg.homepage: "http://mynewt.apache.org/" -pkg.keywords: - -pkg.deps: - - hw/hal - - kernel/os - - hw/drivers/uart -pkg.apis: console - -pkg.init: - console_pkg_init: 20 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/minimal/src/cons_tty.c ---------------------------------------------------------------------- diff --git a/sys/console/minimal/src/cons_tty.c b/sys/console/minimal/src/cons_tty.c deleted file mode 100644 index d837878..0000000 --- a/sys/console/minimal/src/cons_tty.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * Minimal line-based console implementation. Does not include - * echo, command line history, prompt or console_printf(). - * Only offers console_write() and console_read(). - */ -#include <inttypes.h> -#include <assert.h> -#include "syscfg/syscfg.h" -#include "sysinit/sysinit.h" -#include "os/os.h" -#include "uart/uart.h" -#include "bsp/bsp.h" - -#include "console/console.h" -#include "console/prompt.h" - -#define CONSOLE_RX_CHUNK 16 - -#define CONSOLE_HEAD_INC(cr) (((cr)->cr_head + 1) & ((cr)->cr_size - 1)) -#define CONSOLE_TAIL_INC(cr) (((cr)->cr_tail + 1) & ((cr)->cr_size - 1)) - -struct console_ring { - uint8_t cr_head; - uint8_t cr_tail; - uint16_t cr_size; - uint8_t *cr_buf; -}; - -struct console_tty { - struct uart_dev *ct_dev; - - struct console_ring ct_tx; - /* must be after console_ring */ - uint8_t ct_tx_buf[MYNEWT_VAL(CONSOLE_TX_BUF_SIZE)]; - - struct console_ring ct_rx; - /* must be after console_ring */ - uint8_t ct_rx_buf[MYNEWT_VAL(CONSOLE_RX_BUF_SIZE)]; - - console_rx_cb ct_rx_cb; /* callback that input is ready */ -} console_tty; - -static void -console_add_char(struct console_ring *cr, char ch) -{ - cr->cr_buf[cr->cr_head] = ch; - cr->cr_head = CONSOLE_HEAD_INC(cr); -} - -static uint8_t -console_pull_char(struct console_ring *cr) -{ - uint8_t ch; - - ch = cr->cr_buf[cr->cr_tail]; - cr->cr_tail = CONSOLE_TAIL_INC(cr); - return ch; -} - -static void -console_queue_char(char ch) -{ - struct console_tty *ct = &console_tty; - int sr; - - OS_ENTER_CRITICAL(sr); - while (CONSOLE_HEAD_INC(&ct->ct_tx) == ct->ct_tx.cr_tail) { - /* TX needs to drain */ - uart_start_tx(ct->ct_dev); - OS_EXIT_CRITICAL(sr); - OS_ENTER_CRITICAL(sr); - } - console_add_char(&ct->ct_tx, ch); - OS_EXIT_CRITICAL(sr); -} - -void -console_write(const char *str, int cnt) -{ - struct console_tty *ct = &console_tty; - int i; - - for (i = 0; i < cnt; i++) { - if (str[i] == '\n') { - console_queue_char('\r'); - } - console_queue_char(str[i]); - } - uart_start_tx(ct->ct_dev); -} - -int -console_read(char *str, int cnt, int *newline) -{ - struct console_tty *ct = &console_tty; - struct console_ring *cr = &ct->ct_rx; - int sr; - int i; - uint8_t ch; - - *newline = 0; - OS_ENTER_CRITICAL(sr); - for (i = 0; i < cnt; i++) { - if (cr->cr_head == cr->cr_tail) { - break; - } - - if ((i & (CONSOLE_RX_CHUNK - 1)) == (CONSOLE_RX_CHUNK - 1)) { - /* - * Make a break from blocking interrupts during the copy. - */ - OS_EXIT_CRITICAL(sr); - OS_ENTER_CRITICAL(sr); - } - - ch = console_pull_char(cr); - if (ch == '\n') { - *str = '\0'; - *newline = 1; - break; - } - *str++ = ch; - } - OS_EXIT_CRITICAL(sr); - if (i > 0 || *newline) { - uart_start_rx(ct->ct_dev); - } - return i; -} - -/* - * Interrupts disabled when console_tx_char/console_rx_char are called. - */ -static int -console_tx_char(void *arg) -{ - struct console_tty *ct = (struct console_tty *)arg; - struct console_ring *cr = &ct->ct_tx; - - if (cr->cr_head == cr->cr_tail) { - /* - * No more data. - */ - return -1; - } - return console_pull_char(cr); -} - -static int -console_rx_char(void *arg, uint8_t data) -{ - struct console_tty *ct = (struct console_tty *)arg; - struct console_ring *rx = &ct->ct_rx; - - if (CONSOLE_HEAD_INC(&ct->ct_rx) == ct->ct_rx.cr_tail) { - /* - * RX queue full. Reader must drain this. - */ - if (ct->ct_rx_cb) { - ct->ct_rx_cb(); - } - return -1; - } - - /* echo */ - switch (data) { - case '\r': - case '\n': - /* - * linefeed - */ - console_add_char(rx, '\n'); - if (ct->ct_rx_cb) { - ct->ct_rx_cb(); - } - break; - default: - console_add_char(rx, data); - break; - } - return 0; -} - -static int is_power_of_two (unsigned int x) -{ - return ((x != 0) && !(x & (x - 1))); -} - -int -console_init(console_rx_cb rx_cb) -{ - struct console_tty *ct = &console_tty; - struct uart_conf uc = { - .uc_speed = MYNEWT_VAL(CONSOLE_BAUD), - .uc_databits = 8, - .uc_stopbits = 1, - .uc_parity = UART_PARITY_NONE, - .uc_flow_ctl = MYNEWT_VAL(CONSOLE_FLOW_CONTROL), - .uc_tx_char = console_tx_char, - .uc_rx_char = console_rx_char, - .uc_cb_arg = ct - }; - - ct->ct_rx_cb = rx_cb; - if (!ct->ct_dev) { - ct->ct_tx.cr_size = MYNEWT_VAL(CONSOLE_TX_BUF_SIZE); - ct->ct_tx.cr_buf = ct->ct_tx_buf; - ct->ct_rx.cr_size = MYNEWT_VAL(CONSOLE_RX_BUF_SIZE); - ct->ct_rx.cr_buf = ct->ct_rx_buf; - - ct->ct_dev = (struct uart_dev *)os_dev_open(CONSOLE_UART, - OS_TIMEOUT_NEVER, &uc); - if (!ct->ct_dev) { - return -1; - } - } - - /* must be a power of 2 */ - assert(is_power_of_two(MYNEWT_VAL(CONSOLE_RX_BUF_SIZE))); - - return 0; -} - -void -console_pkg_init(void) -{ - int rc; - - /* Ensure this function only gets called by sysinit. */ - SYSINIT_ASSERT_ACTIVE(); - - rc = console_init(NULL); - SYSINIT_PANIC_ASSERT(rc == 0); -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/minimal/syscfg.yml ---------------------------------------------------------------------- diff --git a/sys/console/minimal/syscfg.yml b/sys/console/minimal/syscfg.yml deleted file mode 100644 index 8b4732b..0000000 --- a/sys/console/minimal/syscfg.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -# Package: sys/console/minimal - -syscfg.defs: - CONSOLE_BAUD: - description: 'Console UART baud rate.' - value: '115200' - CONSOLE_FLOW_CONTROL: - description: 'Console UART flow control.' - value: 'UART_FLOW_CTL_NONE' - CONSOLE_TX_BUF_SIZE: - description: 'Console transmit buffer size; must be power of 2.' - value: 32 - CONSOLE_RX_BUF_SIZE: - description: 'Console receive buffer size.' - value: 128 http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4863008f/sys/console/stub/include/console/console.h ---------------------------------------------------------------------- diff --git a/sys/console/stub/include/console/console.h b/sys/console/stub/include/console/console.h index 3c83b9d..d60aaf8 100644 --- a/sys/console/stub/include/console/console.h +++ b/sys/console/stub/include/console/console.h @@ -19,12 +19,18 @@ #ifndef __CONSOLE_H__ #define __CONSOLE_H__ -#include <stdarg.h> +#include <inttypes.h> #ifdef __cplusplus extern "C" { #endif +struct os_eventq; + +struct console_input { + char line[0]; +}; + typedef void (*console_rx_cb)(void); static int inline @@ -34,11 +40,16 @@ console_is_init(void) } static int inline -console_init(console_rx_cb rxcb) +console_init(console_rx_cb rx_cb) { return 0; } +static void inline +console_write(const char *str, int cnt) +{ +} + static int inline console_read(char *str, int cnt, int *newline) { @@ -52,7 +63,7 @@ console_blocking_mode(void) } static void inline -console_write(const char *str, int cnt) +console_echo(int on) { } @@ -66,8 +77,26 @@ console_printf(const char *fmt, ...) } static void inline -console_echo(int on) +console_set_queues(struct os_eventq *avail_queue, + struct os_eventq *cmd_queue) +{ +} + +static void inline +console_set_completion_cb(uint8_t (*completion)(char *str, uint8_t len)) +{ +} + +static int inline +console_handle_char(uint8_t byte) { + return 0; +} + +static int inline +console_out(int character) +{ + return 0; } #define console_is_midline (0)