From b8ca7edac8ecac3bf3bc6b8d44a386b9ada3b57e Mon Sep 17 00:00:00 2001 From: Kaspar Schleiser Date: Thu, 30 Sep 2010 15:10:39 +0200 Subject: [PATCH] * refactored uart / chardev handling --- board/msba2/drivers/Jamfile | 3 +- board/msba2/drivers/msba2-uart0.c | 23 +++--- board/msba2/drivers/msba2-uart0_thread.c | 100 +++-------------------- projects/test_shell/Jamfile | 2 +- projects/test_shell/test_shell.c | 10 ++- sys/Jamfile | 2 + sys/chardev_thread.c | 87 ++++++++++++++++++++ sys/include/board_uart0.h | 8 ++ sys/include/chardev_thread.h | 8 ++ sys/include/shell.h | 9 +- sys/shell/shell.c | 8 +- 11 files changed, 147 insertions(+), 113 deletions(-) create mode 100644 sys/chardev_thread.c create mode 100644 sys/include/board_uart0.h create mode 100644 sys/include/chardev_thread.h diff --git a/board/msba2/drivers/Jamfile b/board/msba2/drivers/Jamfile index f7b223ce01..4961670ed8 100644 --- a/board/msba2/drivers/Jamfile +++ b/board/msba2/drivers/Jamfile @@ -3,4 +3,5 @@ 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 msba2-uart0_thread.c : ringbuffer ; +Module board_common : msba2-uart0.c : ringbuffer ; +Module board_uart : msba2-uart0_thread.c : chardev_thread ; diff --git a/board/msba2/drivers/msba2-uart0.c b/board/msba2/drivers/msba2-uart0.c index 71c35854af..fcd21fcd82 100644 --- a/board/msba2/drivers/msba2-uart0.c +++ b/board/msba2/drivers/msba2-uart0.c @@ -110,11 +110,9 @@ int uart_active(void){ } static void notify_handler() { - if (uart0_handler_pid) { - msg m; - m.type = 0; - msg_send_int(&m, uart0_handler_pid); - } + msg m; + m.type = 0; + msg_send_int(&m, uart0_handler_pid); } void stdio_flush(void) @@ -142,14 +140,15 @@ void UART0_IRQHandler(void) case UIIR_CTI_INT: // Character Timeout Indicator case UIIR_RDA_INT: // Receive Data Available - do { - int c = U0RBR; - rb_add_element(&uart0_ringbuffer, c); - } while (U0LSR & ULSR_RDR); - - notify_handler(); - break; + if (uart0_handler_pid) { + do { + int c = U0RBR; + rb_add_element(&uart0_ringbuffer, c); + } while (U0LSR & ULSR_RDR); + notify_handler(); + break; + } default: U0LSR; U0RBR; diff --git a/board/msba2/drivers/msba2-uart0_thread.c b/board/msba2/drivers/msba2-uart0_thread.c index c9c34c23d7..f343e32401 100644 --- a/board/msba2/drivers/msba2-uart0_thread.c +++ b/board/msba2/drivers/msba2-uart0_thread.c @@ -1,101 +1,25 @@ -#include -#include -#include -#include +#include #include - #include -#include -#include -#include -#include "uart0.h" +#include -//#define ENABLE_DEBUG -#include +#include + +#define UART0_BUFSIZE 32 + +extern ringbuffer uart0_ringbuffer; +extern int uart0_handler_pid; static char buffer[UART0_BUFSIZE]; -ringbuffer uart0_ringbuffer; -static void uart0_loop(); +static void uart0_loop() { + chardev_loop(&uart0_ringbuffer); +} -void uart0_init() { +void board_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 d27d8ae791..b4dcc8f976 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 posix_io shell_auto_init ps ; +Module test_shell : test_shell.c : shell posix_io shell_auto_init ps board_uart ; UseModule test_shell ; diff --git a/projects/test_shell/test_shell.c b/projects/test_shell/test_shell.c index ea2fb9cfba..bfdc480f42 100644 --- a/projects/test_shell/test_shell.c +++ b/projects/test_shell/test_shell.c @@ -6,9 +6,9 @@ #include #include -#include #include #include +#include void print_teststart(char* str) { printf("[TEST_START]\n"); @@ -27,16 +27,20 @@ int shell_readc() { return c; } +void shell_putchar(int c) { + putchar(c); +} + int main(void) { //printf("Moin. build on %s %s SVN-Revision: %s\n", kernel_builddate, kernel_buildtime, kernel_svnrevision); printf("test_shell.\n"); - uart0_init(); + board_uart0_init(); posix_open(uart0_handler_pid, 0); shell_t shell; - shell_init(&shell, shell_readc); + shell_init(&shell, shell_readc, shell_putchar); shell_auto_init(&shell); shell_register_cmd(&shell, "start_test", print_teststart); diff --git a/sys/Jamfile b/sys/Jamfile index 27e8f52a6a..72a7429131 100644 --- a/sys/Jamfile +++ b/sys/Jamfile @@ -32,6 +32,8 @@ Module posix_io : posix_io.c ; Module auto_init : auto_init.c ; +Module chardev_thread : chardev_thread.c : ringbuffer ; + SubInclude TOP sys net ; SubInclude TOP sys lib ; SubInclude TOP sys shell ; diff --git a/sys/chardev_thread.c b/sys/chardev_thread.c new file mode 100644 index 0000000000..6c90928c44 --- /dev/null +++ b/sys/chardev_thread.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +//#define ENABLE_DEBUG +#include + +static int min(int a, int b) { + if (b>a) return a; + else return b; +} + +void chardev_loop(ringbuffer *rb) { + 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 (rb->avail && (r != NULL)) { + int state = disableIRQ(); + int nbytes = min(r->nbytes, rb->avail); + DEBUG("uart0_thread: sending %i bytes to pid %i\n", nbytes, reader_pid); + rb_get_elements(rb, 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/sys/include/board_uart0.h b/sys/include/board_uart0.h new file mode 100644 index 0000000000..74a5295317 --- /dev/null +++ b/sys/include/board_uart0.h @@ -0,0 +1,8 @@ +#ifndef __BOARD_UART0_H +#define __BOARD_UART0_H + +extern int uart0_handler_pid; + +void board_uart0_init(); + +#endif /* __BOARD_UART0_H */ diff --git a/sys/include/chardev_thread.h b/sys/include/chardev_thread.h new file mode 100644 index 0000000000..4596cda832 --- /dev/null +++ b/sys/include/chardev_thread.h @@ -0,0 +1,8 @@ +#ifndef __CHARDEV_THREAD_H +#define __CHARDEV_THREAD_H + +#include + +void chardev_loop(ringbuffer *rb); + +#endif /* __CHARDEV_THREAD_H */ diff --git a/sys/include/shell.h b/sys/include/shell.h index b9fcb91466..4af18a6e67 100644 --- a/sys/include/shell.h +++ b/sys/include/shell.h @@ -24,8 +24,8 @@ and the mailinglist (subscription via web site) scatterweb@lists.spline.inf.fu-berlin.de *******************************************************************************/ -#ifndef __SIMPLE_SHELL_H -#define __SIMPLE_SHELL_H +#ifndef __SHELL_H +#define __SHELL_H /** * @defgroup shell Simple Shell Interpreter @@ -37,12 +37,13 @@ and the mailinglist (subscription via web site) typedef struct shell_t { struct hashtable *h; int (*readchar)(void); + void (*put_char)(int); } shell_t; /** * @brief Initialize a shell object */ -void shell_init(shell_t *shell, int(*readchar)(void)); +void shell_init(shell_t *shell, int(*read_char)(void), void (*put_char)(int)); /** * @brief Register a new command handler for a shell. @@ -60,4 +61,4 @@ void shell_run(shell_t *shell); void shell_auto_init(shell_t *shell); -#endif /* __SIMPLE_SHELL_H */ +#endif /* __SHELL_H */ diff --git a/sys/shell/shell.c b/sys/shell/shell.c index 8d00537a74..863a2a108a 100644 --- a/sys/shell/shell.c +++ b/sys/shell/shell.c @@ -77,8 +77,7 @@ int readline(shell_t *shell, char* buf, int size) { } c = shell->readchar(); - - write(STDOUT_FILENO, &c, 1); + shell->put_char(c); if (c == 13) continue; @@ -95,7 +94,7 @@ void shell_run(shell_t *shell) { char line_buf[255]; while(1) { - write(STDOUT_FILENO, ">", 1); + shell->put_char('>'); int res = readline(shell, line_buf, sizeof(line_buf)); if (! res ) { handle_input_line(shell, strdup(line_buf)); @@ -103,9 +102,10 @@ void shell_run(shell_t *shell) { } } -void shell_init(shell_t *shell, int(*readchar)(void)) { +void shell_init(shell_t *shell, int(*readchar)(void), void(*put_char)(int)) { shell->h = create_hashtable(16, (unsigned int (*)(void*)) hash_string, (int (*) (void*,void*)) cmp_string); shell->readchar = readchar; + shell->put_char = put_char; } void shell_register_cmd(shell_t *shell, char* name, void (*handler)(char* args)) {