From 337a1869092779be0afca381dba674d3de4d7c9b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 21 Feb 2018 12:40:18 +0100 Subject: Add a simple task console driver Close #3320. --- cpukit/include/rtems/confdefs.h | 22 ++- cpukit/include/rtems/console.h | 13 +- cpukit/libcsupport/Makefile.am | 2 + cpukit/libcsupport/src/consolesimple.c | 26 +--- cpukit/libcsupport/src/consolesimple.h | 19 +++ cpukit/libcsupport/src/consolesimpleread.c | 44 ++++++ cpukit/libcsupport/src/consolesimpletask.c | 218 +++++++++++++++++++++++++++++ testsuites/ada/sptests/sp20/config.h | 4 +- testsuites/ada/support/init.c | 1 + testsuites/sptests/sp20/init.c | 19 +-- testsuites/sptests/sp20/system.h | 2 +- 11 files changed, 319 insertions(+), 51 deletions(-) create mode 100644 cpukit/libcsupport/src/consolesimple.h create mode 100644 cpukit/libcsupport/src/consolesimpleread.c create mode 100644 cpukit/libcsupport/src/consolesimpletask.c diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h index be937ab6c0..04b9708aca 100755 --- a/cpukit/include/rtems/confdefs.h +++ b/cpukit/include/rtems/confdefs.h @@ -1529,9 +1529,13 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; #define NULL_DRIVER_TABLE_ENTRY \ { NULL, NULL, NULL, NULL, NULL, NULL } -#if defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \ - defined(CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER) -#error "CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER and CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER are mutually exclusive" +#if (defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \ + defined(CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER)) || \ + (defined(CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER) && \ + defined(CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER)) || \ + (defined(CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER) && \ + defined(CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER)) +#error "CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER, CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER, and CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER are mutually exclusive" #endif #ifdef CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER @@ -1550,6 +1554,18 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; #endif #endif +#ifdef CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER + #include + + #ifdef CONFIGURE_INIT + RTEMS_SYSINIT_ITEM( + _Console_simple_task_Initialize, + RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_SECOND + ); + #endif +#endif + #ifdef CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #include #endif diff --git a/cpukit/include/rtems/console.h b/cpukit/include/rtems/console.h index f9a7de186c..522e6fef41 100644 --- a/cpukit/include/rtems/console.h +++ b/cpukit/include/rtems/console.h @@ -150,12 +150,19 @@ rtems_device_driver console_control( /** * @brief Initializes a simple console device. * - * This device writes via rtems_putc() and reads via getchark(). The Termios - * framework is not used. There is no support to change device settings, e.g. - * baud, stop bits, parity, etc. + * See CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER documentation in the + * "RTEMS Classic API Guide". */ void _Console_simple_Initialize( void ); +/** + * @brief Initializes a simple task console device. + * + * See CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER documentation in + * the "RTEMS Classic API Guide". + */ +void _Console_simple_task_Initialize( void ); + #ifdef __cplusplus } #endif 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 #include -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 + * + * + * 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 + * + * + * 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 +#include + +#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 + * + * + * 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 +#include +#include +#include + +#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 + ); +} diff --git a/testsuites/ada/sptests/sp20/config.h b/testsuites/ada/sptests/sp20/config.h index f509a8163d..55990e2218 100644 --- a/testsuites/ada/sptests/sp20/config.h +++ b/testsuites/ada/sptests/sp20/config.h @@ -13,10 +13,10 @@ /* configuration information */ -#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER -#define CONFIGURE_MAXIMUM_TASKS 7 +#define CONFIGURE_MAXIMUM_TASKS 8 #define ADA_TEST_NAME "ADA SP 20" #define CONFIGURE_MAXIMUM_PERIODS 10 diff --git a/testsuites/ada/support/init.c b/testsuites/ada/support/init.c index 413e52e1eb..c9a2327360 100644 --- a/testsuites/ada/support/init.c +++ b/testsuites/ada/support/init.c @@ -64,6 +64,7 @@ void ada_test_begin(void) void ada_test_end(void) { + fsync(STDOUT_FILENO); rtems_test_end(rtems_test_name); } diff --git a/testsuites/sptests/sp20/init.c b/testsuites/sptests/sp20/init.c index 65d32c9967..cace8c945d 100644 --- a/testsuites/sptests/sp20/init.c +++ b/testsuites/sptests/sp20/init.c @@ -28,18 +28,10 @@ const char rtems_test_name[] = "SP 20"; -#define BUFFER_COUNT 16 - -#define BUFFER_SIZE 512 - -static rtems_printer_task_context printer_task; - -static long buffers[ BUFFER_COUNT ][ BUFFER_SIZE / sizeof(long) ]; - void end_of_test( void ) { TEST_END(); - rtems_printer_task_drain( &printer_task ); + fsync(STDOUT_FILENO); rtems_test_exit( 0 ); } @@ -51,14 +43,7 @@ rtems_task Init( uint32_t index; rtems_status_code status; - rtems_printer_task_set_priority( &printer_task, 254 ); - rtems_printer_task_set_file_descriptor( &printer_task, 1 ); - rtems_printer_task_set_buffer_table( &printer_task, &buffers[ 0 ][ 0 ] ); - rtems_printer_task_set_buffer_count( &printer_task, BUFFER_COUNT ); - rtems_printer_task_set_buffer_size( &printer_task, BUFFER_SIZE ); - error = rtems_print_printer_task( &rtems_test_printer, &printer_task ); - rtems_test_assert( error == 0 ); - + rtems_print_printer_fprintf(&rtems_test_printer, stdout); TEST_BEGIN(); Task_name[ 1 ] = rtems_build_name( 'T', 'A', '1', ' ' ); diff --git a/testsuites/sptests/sp20/system.h b/testsuites/sptests/sp20/system.h index 6c5f679d72..26e837a45b 100644 --- a/testsuites/sptests/sp20/system.h +++ b/testsuites/sptests/sp20/system.h @@ -33,7 +33,7 @@ void Get_all_counters( void ); /* configuration information */ -#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_TASK_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_MICROSECONDS_PER_TICK 100000 -- cgit v1.2.3