From: Andrei Emeltchenko <[email protected]>
Input handler can be used to interact with OS from test scripts.
It is used for bluetooth testing at the moment.
Changes:
* v1: Use CONFIG_CONSOLE_* declarations, do init in system.c,
use correct error.
* RFCv3: Fix overflow bug
* RFCv2: change callback type to void, rename ISR.
Andrei Emeltchenko (2):
Add serial console input handler
Add UART_HOSTDRV_INTERRUPT_DRIVEN configure option
arch/x86/bsp/driver_static_irq_stubs.s | 14 ++++++
drivers/console/uart_console.c | 91 ++++++++++++++++++++++++++++++++++
drivers/console/uart_console.h | 1 +
make/target/kconfig/modules/io.kconf | 16 ++++++
4 files changed, 122 insertions(+)
--
2.1.0
On Mon, Apr 13, 2015 at 03:43:08PM +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <[email protected]>
Sorry please disconsider this set of patches.
Best regards
Andrei Emeltchenko
From: Andrei Emeltchenko <[email protected]>
Serial console handler when registered allows to interact with serial
line. It can either execute callback from ISR or defer execution to
fiber or task.
Signed-off-by: Andrei Emeltchenko <[email protected]>
---
arch/x86/bsp/driver_static_irq_stubs.s | 14 ++++++
drivers/console/uart_console.c | 91 ++++++++++++++++++++++++++++++++++
drivers/console/uart_console.h | 1 +
make/target/kconfig/modules/io.kconf | 8 +++
4 files changed, 114 insertions(+)
diff --git a/arch/x86/bsp/driver_static_irq_stubs.s b/arch/x86/bsp/driver_static_irq_stubs.s
index 7ff2ab5..4c6dc44 100644
--- a/arch/x86/bsp/driver_static_irq_stubs.s
+++ b/arch/x86/bsp/driver_static_irq_stubs.s
@@ -64,6 +64,10 @@ by x86 BSPs.
GTEXT(_i8253IntStub)
#endif
+#if defined(CONFIG_CONSOLE_HANDLER)
+ GTEXT(_console_uart_stub)
+#endif /* CONFIG_CONSOLE_HANDLER */
+
/* externs (internal APIs) */
GTEXT(_IntEnt)
@@ -142,4 +146,14 @@ SECTION_FUNC(TEXT, _i8253IntStub)
jmp _IntExit /* Inform kernel interrupt is done */
#endif /* CONFIG_PIT */
+#if defined(CONFIG_CONSOLE_HANDLER)
+SECTION_FUNC(TEXT, _console_uart_stub)
+ call _IntEnt /* Inform kernel interrupt has begun */
+ pushl $0 /* Push dummy parameter */
+ call console_uart_isr /* Call actual interrupt handler */
+ call _i8259_eoi_master /* Inform the PIC interrupt is done */
+ addl $4, %esp /* Clean-up stack from push above */
+ jmp _IntExit /* Inform kernel interrupt is done */
+#endif /* CONFIG_CONSOLE_HANDLER */
+
#endif /* !CONFIG_DYNAMIC_INT_STUBS */
diff --git a/drivers/console/uart_console.c b/drivers/console/uart_console.c
index 162ce7f..4088b40 100644
--- a/drivers/console/uart_console.c
+++ b/drivers/console/uart_console.c
@@ -37,8 +37,12 @@
Hooks into the printk and fputc (for printf) modules. Poll driven.
*/
+#include <nanokernel.h>
+#include <nanokernel/cpu.h>
+
#include <stdio.h>
#include <stdint.h>
+#include <errno.h>
#include <board.h>
#include <drivers/uart.h>
@@ -106,6 +110,92 @@ extern void __printk_hook_install(int (*fn)(int));
} while ((0))
#endif
+#if defined(CONFIG_CONSOLE_HANDLER)
+#define PACKET_MAX_SZ 1024
+static char rcv_data[PACKET_MAX_SZ];
+static uint8_t rcv_pos = 0;
+static void (*handler) (const char *string);
+
+/* Interrupt handling */
+extern void *_console_uart_stub;
+SYS_INT_REGISTER(_console_uart_stub,
+ CONFIG_UART_CONSOLE_IRQ, CONFIG_UART_CONSOLE_INT_PRI);
+
+static int read_uart(int uart, uint8_t *buf, unsigned int size)
+{
+ int rx;
+
+ rx = uart_fifo_read(uart, buf, size);
+ if (rx < 0) {
+ /* Overrun issue. Stop the UART */
+ uart_irq_rx_disable(uart);
+
+ return -EIO;
+ }
+
+ return rx;
+}
+
+void console_uart_isr(void *unused)
+{
+ ARG_UNUSED(unused);
+
+ while (uart_irq_update(UART) && uart_irq_is_pending(UART)) {
+ /* Character(s) have been received */
+ if (uart_irq_rx_ready(UART)) {
+ int rx;
+ uint8_t byte;
+
+ rx = read_uart(UART, &byte, 1);
+ if (rx < 0)
+ return;
+
+ /* Echo back to console */
+ uart_poll_out(UART, byte);
+
+ if (byte == '\r' || rcv_pos >= sizeof(rcv_data) - 1) {
+ rcv_data[rcv_pos] = '\0';
+ uart_poll_out(UART, '\n');
+ rcv_pos = 0;
+
+ if (handler)
+ handler(rcv_data);
+ } else {
+ rcv_data[rcv_pos++] = byte;
+ }
+
+ }
+ }
+}
+
+static void console_handler_init(void)
+{
+ uint8_t c;
+
+ uart_irq_rx_disable(UART);
+ uart_irq_tx_disable(UART);
+ uart_int_connect(UART, console_uart_isr, NULL, NULL);
+
+ /* Drain the fifo */
+ while (uart_irq_rx_ready(UART))
+ uart_fifo_read(UART, &c, 1);
+
+ uart_irq_rx_enable(UART);
+}
+
+void uart_register_handler(void (*cb) (const char *string))
+{
+ handler = cb;
+}
+#else
+#define console_handler_init(x) \
+ do {/* nothing */ \
+ } while ((0))
+#define uart_register_handler(x) \
+ do {/* nothing */ \
+ } while ((0))
+#endif
+
/******************************************************************************
*
* uartConsoleInit - initialize one UART as the console/debug port
@@ -117,4 +207,5 @@ void uartConsoleInit(void)
{
__stdout_hook_install(consoleOut);
__printk_hook_install(consoleOut);
+ console_handler_init();
}
diff --git a/drivers/console/uart_console.h b/drivers/console/uart_console.h
index d45b60f..bc7240c 100644
--- a/drivers/console/uart_console.h
+++ b/drivers/console/uart_console.h
@@ -40,6 +40,7 @@ extern "C" {
#include <cputype.h>
extern void uartConsoleInit(void);
+void uart_register_handler(void (*cb) (const char *string));
#ifdef __cplusplus
}
diff --git a/make/target/kconfig/modules/io.kconf b/make/target/kconfig/modules/io.kconf
index ff2cb56..acf6677 100644
--- a/make/target/kconfig/modules/io.kconf
+++ b/make/target/kconfig/modules/io.kconf
@@ -51,3 +51,11 @@ config PRINTK
rather than suppressing the generation of printk() output entirely.
Output is sent immediately, without any mutual exclusion or
buffering.
+
+config CONSOLE_HANDLER
+ bool
+ prompt "Enable console input handler"
+ default n
+ help
+ This option enables console input handler allowing to write simple
+ interaction between serial console and OS.
--
2.1.0
From: Andrei Emeltchenko <[email protected]>
Configure option UART_HOSTDRV_INTERRUPT_DRIVEN enables ISR support
making it possible to use CONSOLE_HANDLER and other dependent options.
Signed-off-by: Andrei Emeltchenko <[email protected]>
---
make/target/kconfig/modules/io.kconf | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/make/target/kconfig/modules/io.kconf b/make/target/kconfig/modules/io.kconf
index acf6677..ec4461a 100644
--- a/make/target/kconfig/modules/io.kconf
+++ b/make/target/kconfig/modules/io.kconf
@@ -52,6 +52,14 @@ config PRINTK
Output is sent immediately, without any mutual exclusion or
buffering.
+config UART_HOSTDRV_INTERRUPT_DRIVEN
+ bool
+ prompt "Interrupt driven console support"
+ default n
+ help
+ This option enables interrupt support for UART allowing console
+ input.
+
config CONSOLE_HANDLER
bool
prompt "Enable console input handler"
--
2.1.0