sys/console: switch to blocking mode for tab completion This patch solves an issue with tab completion and async console. Tab completion is triggered in interrupt context and it outputs text into the buffer. As the buffer fills up, the console tries to wait until the uart pulls out the data from the buffer, but since it all happens in the interrupt context, the uart cannot issue another interrupt to pull the data thus freezing the console.
To avoid this we switch the console to blocking mode until the completion is finished. 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/6f739538 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/6f739538 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/6f739538 Branch: refs/heads/master Commit: 6f739538e1eacf35948bcbd53702306cda869e14 Parents: 4863008 Author: MichaÅ Narajowski <michal.narajow...@codecoup.pl> Authored: Thu Apr 13 10:40: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 | 1 + sys/console/full/src/console.c | 10 ++++++++++ sys/console/full/src/console_priv.h | 1 + sys/console/full/src/uart_console.c | 12 ++++++++++++ sys/console/stub/include/console/console.h | 5 +++++ 5 files changed, 29 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6f739538/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 0f37b79..3126c5c 100644 --- a/sys/console/full/include/console/console.h +++ b/sys/console/full/include/console/console.h @@ -42,6 +42,7 @@ void console_write(const char *str, int cnt); int console_read(char *str, int cnt, int *newline); #endif void console_blocking_mode(void); +void console_non_blocking_mode(void); void console_echo(int on); int console_printf(const char *fmt, ...) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6f739538/sys/console/full/src/console.c ---------------------------------------------------------------------- diff --git a/sys/console/full/src/console.c b/sys/console/full/src/console.c index 18ff755..f4a0257 100644 --- a/sys/console/full/src/console.c +++ b/sys/console/full/src/console.c @@ -120,6 +120,14 @@ console_blocking_mode(void) #endif } +void +console_non_blocking_mode(void) +{ +#if MYNEWT_VAL(CONSOLE_UART) + uart_console_non_blocking_mode(); +#endif +} + static inline void cursor_forward(unsigned int count) { @@ -368,7 +376,9 @@ console_handle_char(uint8_t byte) break; case '\t': if (completion_cb && !end) { + console_blocking_mode(); cur += completion_cb(input->line, cur); + console_non_blocking_mode(); } break; default: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6f739538/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 index d307b5d..5d448c4 100644 --- a/sys/console/full/src/console_priv.h +++ b/sys/console/full/src/console_priv.h @@ -27,6 +27,7 @@ extern "C" { int uart_console_is_init(void); int uart_console_init(void); void uart_console_blocking_mode(void); +void uart_console_non_blocking_mode(void); int rtt_console_is_init(void); int rtt_console_init(void); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6f739538/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 index 44943d2..fcf6c6f 100644 --- a/sys/console/full/src/uart_console.c +++ b/sys/console/full/src/uart_console.c @@ -118,6 +118,18 @@ uart_console_blocking_mode(void) OS_EXIT_CRITICAL(sr); } +void +uart_console_non_blocking_mode(void) +{ + int sr; + + OS_ENTER_CRITICAL(sr); + if (write_char_cb) { + write_char_cb = console_queue_char; + } + OS_EXIT_CRITICAL(sr); +} + int console_out(int c) { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/6f739538/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 d60aaf8..b54ae1e 100644 --- a/sys/console/stub/include/console/console.h +++ b/sys/console/stub/include/console/console.h @@ -63,6 +63,11 @@ console_blocking_mode(void) } static void inline +console_non_blocking_mode(void) +{ +} + +static void inline console_echo(int on) { }