From 948e430148e11e8df759d9c232f86e90a5884eb5 Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Fri, 24 Sep 2010 16:28:34 +0200 Subject: [PATCH] * initial posix_io support --- board/msba2/drivers/Jamfile | 2 +- board/msba2/drivers/include/uart0.h | 8 ++ board/msba2/drivers/msba2-uart0_thread.c | 101 +++++++++++++++++++++++ projects/test_shell/Jamfile | 2 +- projects/test_shell/test_shell.c | 18 +++- sys/Jamfile | 3 +- sys/include/posix_io.h | 19 +++++ sys/posix_io.c | 42 ++++++++++ sys/shell.c | 52 ++++++------ sys/sync_read.c | 98 ---------------------- 10 files changed, 216 insertions(+), 129 deletions(-) create mode 100644 board/msba2/drivers/include/uart0.h create mode 100644 board/msba2/drivers/msba2-uart0_thread.c create mode 100644 sys/include/posix_io.h create mode 100644 sys/posix_io.c delete mode 100644 sys/sync_read.c diff --git a/board/msba2/drivers/Jamfile b/board/msba2/drivers/Jamfile index 79705aca0..f7b223ce0 100644 --- a/board/msba2/drivers/Jamfile +++ b/board/msba2/drivers/Jamfile @@ -3,4 +3,4 @@ SubDir TOP board msba2 drivers ; Module board_cc1100 : msba2-cc1100.c ; Module board_hal : msba2-hal.c ; Module board_ltc4150 : msba2-ltc4150.c : gpioint ; -Module board_common : msba2-uart0.c ; +Module board_common : msba2-uart0.c msba2-uart0_thread.c : ringbuffer ; diff --git a/board/msba2/drivers/include/uart0.h b/board/msba2/drivers/include/uart0.h new file mode 100644 index 000000000..0c580becc --- /dev/null +++ b/board/msba2/drivers/include/uart0.h @@ -0,0 +1,8 @@ +#ifndef __UART0_H +#define __UART0_H + +#define UART0_BUFSIZE 32 + +extern int uart0_handler_pid; + +#endif /* __UART0_H */ diff --git a/board/msba2/drivers/msba2-uart0_thread.c b/board/msba2/drivers/msba2-uart0_thread.c new file mode 100644 index 000000000..c9c34c23d --- /dev/null +++ b/board/msba2/drivers/msba2-uart0_thread.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "uart0.h" + +//#define ENABLE_DEBUG +#include + +static char buffer[UART0_BUFSIZE]; +ringbuffer uart0_ringbuffer; + +static void uart0_loop(); + +void uart0_init() { + ringbuffer_init(&uart0_ringbuffer, buffer, UART0_BUFSIZE); + int pid = thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN-1, CREATE_STACKTEST, uart0_loop, "uart0"); + uart0_handler_pid = pid; + puts("uart0_init() [OK]"); +} + +static int min(int a, int b) { + if (b>a) return a; + else return b; +} + +static void uart0_loop() { + msg m; + + int pid = thread_getpid(); + + int reader_pid = -1; + struct posix_iop *r = NULL; + + puts("UART0 thread started."); + + while (1) { + msg_receive(&m); + + if (m.sender_pid == pid) { + } else { + switch (m.type) { + case OPEN: + if (reader_pid == -1) { + reader_pid = m.sender_pid; + m.content.value = 0; // no error + } else { + m.content.value = -EBUSY; + } + msg_reply(&m,&m); + break; + case READ: + if (m.sender_pid != reader_pid) { + m.content.value = -EINVAL; + msg_reply(&m, &m); + } else { + r = (struct posix_iop *)m.content.ptr; + } + break; + case CLOSE: + if (m.sender_pid == reader_pid) { + DEBUG("uart0_thread: closing file from %i\n", reader_pid); + reader_pid = -1; + r = NULL; + m.content.value = 0; + } else { + m.content.value = -EINVAL; + } + msg_reply(&m,&m); + break; + default: + m.content.value = -EINVAL; + msg_reply(&m, &m); + } + } + + if (uart0_ringbuffer.avail && (r != NULL)) { + int state = disableIRQ(); + int nbytes = min(r->nbytes, uart0_ringbuffer.avail); + DEBUG("uart0_thread: sending %i bytes to pid %i\n", nbytes, reader_pid); + rb_get_elements(&uart0_ringbuffer, r->buffer, nbytes); + r->nbytes = nbytes; + + m.sender_pid = reader_pid; + m.type = OPEN; + m.content.ptr = (char*)r; + + msg_reply(&m, &m); + // DEBUG("uart0_thread: sending res=%i\n", res); + + r = NULL; + restoreIRQ(state); + } + } +} diff --git a/projects/test_shell/Jamfile b/projects/test_shell/Jamfile index f8d4b1d8b..beb371b4c 100644 --- a/projects/test_shell/Jamfile +++ b/projects/test_shell/Jamfile @@ -6,6 +6,6 @@ SubDir TOP projects test_shell ; -Module test_shell : test_shell.c : shell ; +Module test_shell : test_shell.c : shell posix_io ; UseModule test_shell ; diff --git a/projects/test_shell/test_shell.c b/projects/test_shell/test_shell.c index 306c7f072..e40631d6e 100644 --- a/projects/test_shell/test_shell.c +++ b/projects/test_shell/test_shell.c @@ -6,6 +6,8 @@ #include #include +#include +#include #include void print_teststart(char* str) { @@ -16,8 +18,14 @@ void print_testend(char* str) { printf("[TEST_END]\n"); } -extern int uart0_init(); -extern int uart0_readc(); +//extern int uart0_init(); +//extern int uart0_handler_pid; + +int shell_readc() { + char c = 0; + posix_read(uart0_handler_pid, &c, 1); + return c; +} int main(void) { //printf("Moin. build on %s %s SVN-Revision: %s\n", kernel_builddate, kernel_buildtime, kernel_svnrevision); @@ -25,12 +33,14 @@ int main(void) { uart0_init(); + posix_open(uart0_handler_pid, 0); + shell_t shell; - shell_init(&shell, uart0_readc); + shell_init(&shell, shell_readc); shell_register_cmd(&shell, "start_test", print_teststart); shell_register_cmd(&shell, "end_test", print_testend); - + shell_run(&shell); return 0; diff --git a/sys/Jamfile b/sys/Jamfile index 41f98184d..5a618de0f 100644 --- a/sys/Jamfile +++ b/sys/Jamfile @@ -28,7 +28,8 @@ SubDir TOP sys ; Module swtimer : swtimer.c : hwtimer ; -Module shell : shell.c sync_read.c : hashtable hash_string ringbuffer ; +Module posix_io : posix_io.c ; +Module shell : shell.c : hashtable hash_string ; Module auto_init : auto_init.c ; diff --git a/sys/include/posix_io.h b/sys/include/posix_io.h new file mode 100644 index 000000000..656e1ea3e --- /dev/null +++ b/sys/include/posix_io.h @@ -0,0 +1,19 @@ +#ifndef __READ_H +#define __READ_H + +#define OPEN 0 +#define CLOSE 1 +#define READ 2 +#define WRITE 3 + +struct posix_iop { + int nbytes; + char *buffer; +}; + +int posix_open(int pid, int flags); +int posix_close(int pid); +int posix_read(int pid, char* buffer, int bufsize); +int posix_write(int pid, char* buffer, int bufsize); + +#endif /* __READ_H */ diff --git a/sys/posix_io.c b/sys/posix_io.c new file mode 100644 index 000000000..fd423e165 --- /dev/null +++ b/sys/posix_io.c @@ -0,0 +1,42 @@ +#include + +#include + + +static int _posix_fileop(int pid, int op, int flags) { + msg m; + m.type = op; + m.content.value = flags; + msg_send_receive(&m, &m, pid); + return m.content.value; +} + +static int _posix_fileop_data(int pid, int op, char* buffer, int nbytes) { + struct posix_iop r; + r.nbytes = nbytes; + r.buffer = buffer; + + msg m; + m.type = op; + m.content.ptr = (char*) &r; + + msg_send_receive(&m, &m, pid); + + return r.nbytes; +} + +int posix_open(int pid, int flags) { + return _posix_fileop(pid, OPEN, flags); +} + +int posix_close(int pid) { + return _posix_fileop(pid, CLOSE, 0); +} + +int posix_read(int pid, char* buffer, int bufsize) { + return _posix_fileop_data(pid, READ, buffer, bufsize); +} + +int posix_write(int pid, char* buffer, int bufsize) { + return _posix_fileop_data(pid, WRITE, buffer, bufsize); +} diff --git a/sys/shell.c b/sys/shell.c index 276f64fd4..8d00537a7 100644 --- a/sys/shell.c +++ b/sys/shell.c @@ -60,41 +60,45 @@ static void handle_input_line(shell_t *shell, char* line) { if (handler) { handler(line); } else { - printf("shell: command not found.\n"); + printf("shell: command \"%s\" not found.\n", command); } } free(line); } +int readline(shell_t *shell, char* buf, int size) { + char *line_buf_ptr = buf; + int c; + + while (1) { + if ( (line_buf_ptr - buf) >= size-1) { + return -1; + } + + c = shell->readchar(); + + write(STDOUT_FILENO, &c, 1); + + if (c == 13) continue; + + if (c == 10) { + *line_buf_ptr = '\0'; + return 0; + } else { + *line_buf_ptr++ = c; + } + } +} + void shell_run(shell_t *shell) { char line_buf[255]; - char *line_buf_ptr = line_buf; - int c; while(1) { write(STDOUT_FILENO, ">", 1); - - while (1) { - if ( (line_buf_ptr - line_buf) >= (sizeof(line_buf)-1)) { - printf("\nshell: input too long.\n"); - line_buf_ptr = line_buf; - } - - c = shell->readchar(); - - write(STDOUT_FILENO, &c, 1); - - if (c == 13) continue; - - if (c == 10) { - *line_buf_ptr = '\0'; - handle_input_line(shell, strdup(line_buf)); - line_buf_ptr = line_buf; - break; - } else { - *line_buf_ptr++ = c; - } + int res = readline(shell, line_buf, sizeof(line_buf)); + if (! res ) { + handle_input_line(shell, strdup(line_buf)); } } } diff --git a/sys/sync_read.c b/sys/sync_read.c deleted file mode 100644 index d4e89ab7b..000000000 --- a/sys/sync_read.c +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** -Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved. - -These sources were developed at the Freie Universitaet Berlin, Computer Systems -and Telematics group (http://cst.mi.fu-berlin.de). -------------------------------------------------------------------------------- -This file is part of FeuerWare. - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -FeuerWare is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see http://www.gnu.org/licenses/ . --------------------------------------------------------------------------------- -For further information and questions please use the web site - http://scatterweb.mi.fu-berlin.de -and the mailinglist (subscription via web site) - scatterweb@lists.spline.inf.fu-berlin.de -*******************************************************************************/ -#include -#include -#include -#include - -/** - * @file - * @ingroup simple_shell - * @brief contains implementation of synchronous read functions, - * @brief hardcoded to uart0 - * @author Kaspar Schleiser - * - */ - -extern void (*uart0_callback)(int); - -#define UART0_BUFSIZE 255 -static ringbuffer uart0_rb; -static char uart0_buffer[UART0_BUFSIZE]; -static char uart0_waiting = 0; - -static mutex_t uart0_mutex; - -void uart0_process_byte(int c) { - rb_add_element(&uart0_rb, c); - - if (uart0_waiting) { - uart0_waiting = 0; - mutex_unlock(&uart0_mutex, false); - } -} - -void uart0_init() { - dINT(); - mutex_init(&uart0_mutex); - mutex_lock(&uart0_mutex); - ringbuffer_init(&uart0_rb, uart0_buffer, UART0_BUFSIZE); - uart0_callback = uart0_process_byte; - eINT(); -} - -/** @brief read a char from uart0. Block if none available. */ -int uart0_readc() { - dINT(); - - if (uart0_rb.avail == 0) { - uart0_waiting++; - mutex_lock(&uart0_mutex); - } - - int c = rb_get_element(&uart0_rb); - - eINT(); - - return c; -} - -/** @brief read a char from uart0. return -1 if none available */ -int uart0_readc_nb() { - dINT(); - - if (uart0_rb.avail == 0) { - eINT(); - return -1; - } - - int c = rb_get_element(&uart0_rb); - - eINT(); - - return c; -} -