summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-02-21 12:40:18 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-03-06 12:32:09 +0100
commit337a1869092779be0afca381dba674d3de4d7c9b (patch)
tree02a8dc8e446160b69b4053caf51ef0cc6bf68b5a
parentbsps/sparc: Fix global construction/destruction (diff)
downloadrtems-337a1869092779be0afca381dba674d3de4d7c9b.tar.bz2
Add a simple task console driver
Close #3320.
-rwxr-xr-xcpukit/include/rtems/confdefs.h22
-rw-r--r--cpukit/include/rtems/console.h13
-rw-r--r--cpukit/libcsupport/Makefile.am2
-rw-r--r--cpukit/libcsupport/src/consolesimple.c26
-rw-r--r--cpukit/libcsupport/src/consolesimple.h19
-rw-r--r--cpukit/libcsupport/src/consolesimpleread.c44
-rw-r--r--cpukit/libcsupport/src/consolesimpletask.c218
-rw-r--r--testsuites/ada/sptests/sp20/config.h4
-rw-r--r--testsuites/ada/support/init.c1
-rw-r--r--testsuites/sptests/sp20/init.c19
-rw-r--r--testsuites/sptests/sp20/system.h2
11 files changed, 319 insertions, 51 deletions
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 <rtems/console.h>
+
+ #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 <rtems/clockdrv.h>
#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 <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
+ );
+}
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