From 572193cb9ad4cd909962b2dceff287431221577d Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Fri, 7 Jun 2013 11:27:23 +0800 Subject: Console input support for emulator This creates a separate thread that keeps reading characters from stdin and feed to UART process. BUG=chrome-os-partner:19235 TEST=Start up a emulator and type 'help'. See command list. TEST=Pass all tests for 300 times. BRANCH=None Change-Id: I190c1d939b0b4ad0f8f0517d8d7b06f2f3df3832 Signed-off-by: Vic Yang Reviewed-on: https://gerrit.chromium.org/gerrit/57866 Reviewed-by: Vincent Palatin --- chip/host/uart.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- core/host/main.c | 3 +++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/chip/host/uart.c b/chip/host/uart.c index cbae79974b..9add50d4d2 100644 --- a/chip/host/uart.c +++ b/chip/host/uart.c @@ -5,10 +5,14 @@ /* UART driver for emulator */ +#include #include +#include +#include #include "board.h" #include "config.h" +#include "queue.h" #include "task.h" #include "uart.h" @@ -16,8 +20,24 @@ static int stopped; static int int_disabled; static int init_done; +static pthread_t input_thread; + +#define INPUT_BUFFER_SIZE 16 +/* TODO: Guard these data with mutex lock when we have interrupt support. */ +static int char_available; +static char cached_char_buf[INPUT_BUFFER_SIZE]; +static struct queue cached_char = { + .buf_bytes = INPUT_BUFFER_SIZE, + .unit_bytes = sizeof(char), + .buf = cached_char_buf, +}; + static void trigger_interrupt(void) { + /* + * TODO: Check global interrupt status when we have + * interrupt support. + */ if (!int_disabled) uart_process(); } @@ -55,7 +75,7 @@ int uart_tx_ready(void) int uart_rx_available(void) { - return 0; + return char_available; } void uart_write_char(char c) @@ -66,8 +86,10 @@ void uart_write_char(char c) int uart_read_char(void) { - /* Should never be called for now */ - return 0; + char ret; + queue_remove_unit(&cached_char, &ret); + --char_available; + return ret; } void uart_disable_interrupt(void) @@ -80,7 +102,39 @@ void uart_enable_interrupt(void) int_disabled = 0; } +void *uart_monitor_stdin(void *d) +{ + struct termios org_settings, new_settings; + char buf[INPUT_BUFFER_SIZE]; + int rv; + + tcgetattr(0, &org_settings); + new_settings = org_settings; + new_settings.c_lflag &= ~(ECHO | ICANON); + new_settings.c_cc[VTIME] = 0; + new_settings.c_cc[VMIN] = 1; + + printf("Console input initialized\n"); + while (1) { + tcsetattr(0, TCSANOW, &new_settings); + rv = read(0, buf, INPUT_BUFFER_SIZE); + if (queue_has_space(&cached_char, rv)) + queue_add_units(&cached_char, buf, rv); + char_available = rv; + tcsetattr(0, TCSANOW, &org_settings); + /* + * TODO: Trigger emulated interrupt when we have + * interrupt support. Also, we will need a condition + * variable to indicate the character has been read. + */ + trigger_interrupt(); + } + + return 0; +} + void uart_init(void) { + pthread_create(&input_thread, NULL, uart_monitor_stdin, NULL); init_done = 1; } diff --git a/core/host/main.c b/core/host/main.c index ba8ec95dcf..f69107af4a 100644 --- a/core/host/main.c +++ b/core/host/main.c @@ -9,6 +9,7 @@ #include "hooks.h" #include "task.h" #include "timer.h" +#include "uart.h" int main(void) { @@ -18,6 +19,8 @@ int main(void) hook_init(); + uart_init(); + task_start(); return 0; -- cgit v1.2.1