diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-02-21 12:40:18 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-03-06 12:32:09 +0100 |
commit | 337a1869092779be0afca381dba674d3de4d7c9b (patch) | |
tree | 02a8dc8e446160b69b4053caf51ef0cc6bf68b5a /cpukit/libcsupport | |
parent | 4899759f73fd195500e149dd6bffbe418636c0de (diff) |
Add a simple task console driver
Close #3320.
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r-- | cpukit/libcsupport/Makefile.am | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/consolesimple.c | 26 | ||||
-rw-r--r-- | cpukit/libcsupport/src/consolesimple.h | 19 | ||||
-rw-r--r-- | cpukit/libcsupport/src/consolesimpleread.c | 44 | ||||
-rw-r--r-- | cpukit/libcsupport/src/consolesimpletask.c | 218 |
5 files changed, 284 insertions, 25 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index 253c2c9924..586085916c 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -116,6 +116,8 @@ libcsupport_a_SOURCES = src/gxx_wrappers.c src/getchark.c src/printk.c \ $(BSD_LIBC_C_FILES) $(BASE_FS_C_FILES) $(MALLOC_C_FILES) \ $(ERROR_C_FILES) $(ASSOCIATION_C_FILES) libcsupport_a_SOURCES += src/consolesimple.c +libcsupport_a_SOURCES += src/consolesimpleread.c +libcsupport_a_SOURCES += src/consolesimpletask.c libcsupport_a_SOURCES += src/printertask.c libcsupport_a_SOURCES += src/printerfprintfputc.c diff --git a/cpukit/libcsupport/src/consolesimple.c b/cpukit/libcsupport/src/consolesimple.c index 5aa0f98528..94aa40c9fd 100644 --- a/cpukit/libcsupport/src/consolesimple.c +++ b/cpukit/libcsupport/src/consolesimple.c @@ -16,31 +16,7 @@ #include <rtems/bspIo.h> #include <rtems/imfs.h> -static ssize_t _Console_simple_Read( - rtems_libio_t *iop, - void *buffer, - size_t count -) -{ - char *buf; - ssize_t i; - ssize_t n; - - buf = buffer; - n = (ssize_t) count; - - for ( i = 0; i < n; ++i ) { - int c; - - do { - c = getchark(); - } while (c == -1); - - buf[ i ] = (char) c; - } - - return n; -} +#include "consolesimple.h" static ssize_t _Console_simple_Write( rtems_libio_t *iop, diff --git a/cpukit/libcsupport/src/consolesimple.h b/cpukit/libcsupport/src/consolesimple.h new file mode 100644 index 0000000000..82f5cd9cd3 --- /dev/null +++ b/cpukit/libcsupport/src/consolesimple.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2018 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +ssize_t _Console_simple_Read( + rtems_libio_t *iop, + void *buffer, + size_t count +); diff --git a/cpukit/libcsupport/src/consolesimpleread.c b/cpukit/libcsupport/src/consolesimpleread.c new file mode 100644 index 0000000000..a796e4380f --- /dev/null +++ b/cpukit/libcsupport/src/consolesimpleread.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <rtems/bspIo.h> +#include <rtems/libio.h> + +#include "consolesimple.h" + +ssize_t _Console_simple_Read( + rtems_libio_t *iop, + void *buffer, + size_t count +) +{ + char *buf; + ssize_t i; + ssize_t n; + + buf = buffer; + n = (ssize_t) count; + + for ( i = 0; i < n; ++i ) { + int c; + + do { + c = getchark(); + } while (c == -1); + + buf[ i ] = (char) c; + } + + return n; +} diff --git a/cpukit/libcsupport/src/consolesimpletask.c b/cpukit/libcsupport/src/consolesimpletask.c new file mode 100644 index 0000000000..29bab8cb86 --- /dev/null +++ b/cpukit/libcsupport/src/consolesimpletask.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2018 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <rtems/console.h> +#include <rtems/bspIo.h> +#include <rtems/imfs.h> +#include <rtems/thread.h> + +#include "consolesimple.h" + +#define CONSOLE_SIMPLE_TASK_BUFFER_SIZE 2048 + +#define CONSOLE_SIMPLE_TASK_MAX_JUNK_SIZE 80 + +typedef struct { + RTEMS_INTERRUPT_LOCK_MEMBER( buf_lock ) + rtems_mutex output_mutex; + rtems_id task; + size_t head; + size_t tail; + char buf[ CONSOLE_SIMPLE_TASK_BUFFER_SIZE ]; +} Console_simple_task_Control; + +static Console_simple_task_Control _Console_simple_task_Instance; + +static size_t _Console_simple_task_Capacity( + const Console_simple_task_Control *cons +) +{ + return ( cons->tail - cons->head - 1 ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE; +} + +static size_t _Console_simple_task_Available( + const Console_simple_task_Control *cons +) +{ + return ( cons->head - cons->tail ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE; +} + +static ssize_t _Console_simple_task_Write( + rtems_libio_t *iop, + const void *buffer, + size_t count +) +{ + Console_simple_task_Control *cons; + const char *buf; + size_t todo; + + cons = IMFS_generic_get_context_by_iop( iop ); + buf = buffer; + todo = count; + + while ( todo > 0 ) { + rtems_interrupt_lock_context lock_context; + size_t junk; + size_t head; + size_t i; + + rtems_interrupt_lock_acquire( &cons->buf_lock, &lock_context ); + + junk = _Console_simple_task_Capacity( cons ); + + if ( junk > todo ) { + junk = todo; + } + + if ( junk > CONSOLE_SIMPLE_TASK_MAX_JUNK_SIZE ) { + junk = CONSOLE_SIMPLE_TASK_MAX_JUNK_SIZE; + } + + head = cons->head; + + for ( i = 0; i < junk; ++i ) { + cons->buf[ head ] = *buf; + head = ( head + 1 ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE; + --todo; + ++buf; + } + + cons->head = head; + + rtems_interrupt_lock_release( &cons->buf_lock, &lock_context ); + + if ( junk == 0 ) { + break; + } + } + + rtems_event_system_send( cons->task, RTEMS_EVENT_SYSTEM_SERVER ); + + return (ssize_t) ( count - todo ); +} + +static void _Console_simple_task_Put_chars( Console_simple_task_Control *cons ) +{ + rtems_interrupt_lock_context lock_context; + size_t available; + size_t tail; + size_t i; + + rtems_mutex_lock( &cons->output_mutex ); + + rtems_interrupt_lock_acquire( &cons->buf_lock, &lock_context ); + + available = _Console_simple_task_Available( cons ); + tail = cons->tail; + + rtems_interrupt_lock_release( &cons->buf_lock, &lock_context ); + + for ( i = 0; i < available; ++i) { + rtems_putc( cons->buf[ tail ] ); + tail = ( tail + 1 ) % CONSOLE_SIMPLE_TASK_BUFFER_SIZE; + } + + rtems_interrupt_lock_acquire( &cons->buf_lock, &lock_context ); + + cons->tail = tail; + + rtems_interrupt_lock_release( &cons->buf_lock, &lock_context ); + + rtems_mutex_unlock( &cons->output_mutex ); +} + +static int _Console_simple_task_Fsync( rtems_libio_t *iop ) +{ + Console_simple_task_Control *cons; + + cons = IMFS_generic_get_context_by_iop( iop ); + _Console_simple_task_Put_chars( cons ); +} + +static const rtems_filesystem_file_handlers_r _Console_simple_task_Handlers = { + .open_h = rtems_filesystem_default_open, + .close_h = rtems_filesystem_default_close, + .read_h = _Console_simple_Read, + .write_h = _Console_simple_task_Write, + .ioctl_h = rtems_filesystem_default_ioctl, + .lseek_h = rtems_filesystem_default_lseek, + .fstat_h = IMFS_stat, + .ftruncate_h = rtems_filesystem_default_ftruncate, + .fsync_h = _Console_simple_task_Fsync, + .fdatasync_h = _Console_simple_task_Fsync, + .fcntl_h = rtems_filesystem_default_fcntl, + .readv_h = rtems_filesystem_default_readv, + .writev_h = rtems_filesystem_default_writev, + .mmap_h = rtems_filesystem_default_mmap +}; + +static const IMFS_node_control +_Console_simple_task_Node_control = IMFS_GENERIC_INITIALIZER( + &_Console_simple_task_Handlers, + IMFS_node_initialize_generic, + IMFS_node_destroy_default +); + +static void _Console_simple_task_Task( rtems_task_argument arg ) +{ + Console_simple_task_Control *cons; + + cons = (Console_simple_task_Control *) arg; + + while ( true ) { + rtems_event_set events; + + rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_SERVER, + RTEMS_WAIT | RTEMS_EVENT_ALL, + RTEMS_NO_TIMEOUT, + &events + ); + + _Console_simple_task_Put_chars( cons ); + } +} + +void _Console_simple_task_Initialize( void ) +{ + Console_simple_task_Control *cons; + + cons = &_Console_simple_task_Instance; + + rtems_interrupt_lock_initialize( &cons->buf_lock, "Console" ); + rtems_mutex_init( &cons->output_mutex, "Console" ); + + IMFS_make_generic_node( + CONSOLE_DEVICE_NAME, + S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO, + &_Console_simple_task_Node_control, + cons + ); + + rtems_task_create( + rtems_build_name('C', 'O', 'N', 'S'), + RTEMS_MAXIMUM_PRIORITY - 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_ATTRIBUTES, + RTEMS_DEFAULT_MODES, + &cons->task + ); + + rtems_task_start( + cons->task, + _Console_simple_task_Task, + (rtems_task_argument) cons + ); +} |