[PATCH 6/9] Adding USB serial driver test cases
Kevin Kirspel
kevin-kirspel at idexx.com
Thu Feb 9 03:21:37 UTC 2017
---
.../include/rtems/bsd/test/default-usb-init.h | 158 +++++
testsuite/usbserial/init.c | 373 ++++++++++++
testsuite/usbserial01/test_main.c | 666 +++++++++++++++++++++
testsuite/usbserial02/test_main.c | 252 ++++++++
testsuite/usbserial03/test_main.c | 240 ++++++++
testsuite/usbserial04/test_main.c | 226 +++++++
testsuite/usbserial05/test_main.c | 303 ++++++++++
testsuite/usbserial06/test_main.c | 218 +++++++
8 files changed, 2436 insertions(+)
create mode 100755 testsuite/include/rtems/bsd/test/default-usb-init.h
create mode 100755 testsuite/usbserial/init.c
create mode 100755 testsuite/usbserial01/test_main.c
create mode 100755 testsuite/usbserial02/test_main.c
create mode 100755 testsuite/usbserial03/test_main.c
create mode 100755 testsuite/usbserial04/test_main.c
create mode 100755 testsuite/usbserial05/test_main.c
create mode 100755 testsuite/usbserial06/test_main.c
diff --git a/testsuite/include/rtems/bsd/test/default-usb-init.h b/testsuite/include/rtems/bsd/test/default-usb-init.h
new file mode 100755
index 0000000..051da86
--- /dev/null
+++ b/testsuite/include/rtems/bsd/test/default-usb-init.h
@@ -0,0 +1,158 @@
+/*
+ * Shared Network Test Initialization File
+ */
+
+#ifndef RTEMS_BSD_TEST_DEFAULT_INIT_H
+#define RTEMS_BSD_TEST_DEFAULT_INIT_H
+
+#include <bsp.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <rtems/printer.h>
+#include <rtems/stackchk.h>
+#include <rtems/bsd/bsd.h>
+
+static void default_set_self_prio( rtems_task_priority prio )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
+ assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void default_on_exit( int exit_code, void *arg )
+{
+ rtems_printer printer;
+
+ rtems_print_printer_printf(&printer);
+ rtems_stack_checker_report_usage_with_plugin(&printer);
+
+ if ( exit_code == 0 ) {
+ puts( "*** END OF TEST " TEST_NAME " ***" );
+ }
+}
+
+rtems_task Init(
+ rtems_task_argument ignored
+)
+{
+ rtems_status_code sc;
+
+ /*
+ * Default the syslog priority to 'debug' to aid developers.
+ */
+ rtems_bsd_setlogpriority("debug");
+
+ puts( "*** " TEST_NAME " TEST ***" );
+
+ /*
+ * BSD must support the new "shared IRQ PIC implementation" at this point.
+ * BSPs must also provide rtems_interrupt_server_initialize() which
+ * just requires including irq-server.[ch] in their build.
+ */
+
+ on_exit( default_on_exit, NULL );
+
+#ifdef DEFAULT_EARLY_INITIALIZATION
+ early_initialization();
+#endif
+
+ /* Let other tasks run to complete background work */
+ default_set_self_prio( RTEMS_MAXIMUM_PRIORITY - 2 );
+
+ rtems_bsd_initialize();
+
+ /* Let the callout timer allocate its resources */
+ sc = rtems_task_wake_after( 2 );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ test_main();
+ /* should not return */
+
+ assert( 0 );
+}
+
+/*
+ * Configure RTEMS.
+ */
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
+#define CONFIGURE_MAXIMUM_DRIVERS 32
+
+#define CONFIGURE_FILESYSTEM_DOSFS
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+
+#define CONFIGURE_STACK_CHECKER_ENABLED
+
+#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024)
+#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (256 * 1024)
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/*
+ * Configure LIBBSD device.
+ */
+ #include <bsp/nexus-devices.h>
+
+/*
+ * Configure RTEMS Shell.
+ */
+#define CONFIGURE_SHELL_COMMANDS_INIT
+
+#include <bsp/irq-info.h>
+
+#include <rtems/netcmds-config.h>
+
+#define CONFIGURE_SHELL_USER_COMMANDS \
+ &bsp_interrupt_shell_command, \
+ &rtems_shell_STTY_Command, \
+ &rtems_shell_SYSCTL_Command
+
+#define CONFIGURE_SHELL_COMMAND_CPUUSE
+#define CONFIGURE_SHELL_COMMAND_PERIODUSE
+#define CONFIGURE_SHELL_COMMAND_STACKUSE
+#define CONFIGURE_SHELL_COMMAND_PROFREPORT
+
+#define CONFIGURE_SHELL_COMMAND_CP
+#define CONFIGURE_SHELL_COMMAND_PWD
+#define CONFIGURE_SHELL_COMMAND_LS
+#define CONFIGURE_SHELL_COMMAND_LN
+#define CONFIGURE_SHELL_COMMAND_LSOF
+#define CONFIGURE_SHELL_COMMAND_CHDIR
+#define CONFIGURE_SHELL_COMMAND_CD
+#define CONFIGURE_SHELL_COMMAND_MKDIR
+#define CONFIGURE_SHELL_COMMAND_RMDIR
+#define CONFIGURE_SHELL_COMMAND_CAT
+#define CONFIGURE_SHELL_COMMAND_MV
+#define CONFIGURE_SHELL_COMMAND_RM
+#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
+
+#define CONFIGURE_SHELL_COMMAND_BLKSTATS
+#define CONFIGURE_SHELL_COMMAND_BLKSYNC
+#define CONFIGURE_SHELL_COMMAND_MOUNT
+#define CONFIGURE_SHELL_COMMAND_UNMOUNT
+
+#include <rtems/shellconfig.h>
+
+#endif /* RTEMS_BSD_TEST_DEFAULT_INIT_H */
diff --git a/testsuite/usbserial/init.c b/testsuite/usbserial/init.c
new file mode 100755
index 0000000..2a65e6f
--- /dev/null
+++ b/testsuite/usbserial/init.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2010, 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/malloc.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL"
+
+#define USB_SERIAL_TEST_BUFFER_SIZE 48
+#define PRIO_OPEN (RTEMS_MAXIMUM_PRIORITY - 12)
+#define PRIO_READ (RTEMS_MAXIMUM_PRIORITY - 11)
+#define PRIO_WRITE (RTEMS_MAXIMUM_PRIORITY - 10)
+
+typedef struct
+{
+ int fd;
+ char rbuf[USB_SERIAL_TEST_BUFFER_SIZE];
+ char wbuf[USB_SERIAL_TEST_BUFFER_SIZE];
+}usb_test_message_t;
+
+static rtems_id oid, rid, wid, omid, rmid, wmid;
+static volatile bool kill_otask, kill_rtask, kill_wtask;
+static volatile bool otask_active, rtask_active, wtask_active;
+
+static void
+usb_serial_read_task(rtems_task_argument arg)
+{
+ usb_test_message_t msg;
+ uint32_t size, end_time;
+ int bytes, index;
+
+ rtask_active = true;
+ kill_rtask = false;
+ while(!kill_rtask)
+ {
+ rtems_message_queue_receive( rmid, &msg, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ index = 0;
+ msg.rbuf[0] = 0;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(500);
+ while(( rtems_clock_get_ticks_since_boot() < end_time ) && ( index < sizeof(msg.rbuf)))
+ {
+ bytes = read(msg.fd, &msg.rbuf[index], sizeof(msg.rbuf) - index - 1);
+ if( bytes < 0)
+ {
+ msg.fd = -1;
+ rtems_message_queue_send( omid, &msg, sizeof( msg ));
+ printf( "serial device read error: %d\n", errno );
+ }
+ else if( bytes > 0)
+ {
+ index += bytes;
+ msg.rbuf[index] = 0;
+ if( strcmp( msg.rbuf, msg.wbuf ) == 0 )
+ {
+ break;
+ }
+ }
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(10));
+ }
+ printf( "serial device read: %s - %s\n", msg.rbuf, strcmp( msg.rbuf, msg.wbuf ) == 0 ? "PASS" : "FAIL" );
+ }
+ rtask_active = false;
+}
+
+static void
+usb_serial_write_task(rtems_task_argument arg)
+{
+ usb_test_message_t msg;
+ uint32_t size;
+ int bytes, write_len, count = 0;
+
+ wtask_active = true;
+ kill_wtask = false;
+ while(!kill_wtask)
+ {
+ rtems_message_queue_receive( wmid, &msg, &size, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ count++;
+ sprintf( msg.wbuf, "Hello World %d", count );
+ write_len = strlen( msg.wbuf );
+ bytes = write(msg.fd, msg.wbuf, write_len);
+ if( bytes < 0)
+ {
+ msg.fd = -1;
+ rtems_message_queue_send( omid, &msg, sizeof( msg ));
+ printf( "serial device write error: %d\n", errno );
+ }
+ else if( bytes != write_len)
+ {
+ printf( "serial device failed to write all bytes: %d\n", bytes );
+ }
+ else
+ {
+ printf( "serial device write: %s\n", msg.wbuf );
+ rtems_message_queue_send( rmid, &msg, sizeof( msg ));
+ }
+ }
+ wtask_active = false;
+}
+
+static void
+usb_serial_open_task(rtems_task_argument arg)
+{
+ rtems_status_code sc;
+ usb_test_message_t msg;
+ struct termios t;
+ uint32_t size;
+ int fd, iret;
+
+ fd = -2;
+ otask_active = true;
+ kill_otask = false;
+ while(!kill_otask)
+ {
+ sc = rtems_message_queue_receive( omid, &msg, &size, RTEMS_WAIT, RTEMS_MILLISECONDS_TO_TICKS(1000));
+ if(sc == RTEMS_SUCCESSFUL)
+ {
+ if(fd >= 0)
+ {
+ close(fd);
+ printf( "serial device closed\n" );
+ }
+ fd = msg.fd;
+ }
+ if(fd == -1)
+ {
+ fd = open( "/dev/ttyU0", LIBIO_FLAGS_READ_WRITE );
+ if( fd != -1 )
+ {
+ printf( "serial device opened\n" );
+ //get terminal settings
+ iret = tcgetattr ( fd, &t );
+ assert( iret != -1 );
+ //set timeouts to zero for non-blocking mode
+ t.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+ //t.c_iflag &= ~(BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP);
+ //t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP);
+ t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+ t.c_iflag |= IXON; // Enable XON/XOFF flow control on output.
+ t.c_cflag &= ~(CSIZE | PARENB);
+ t.c_oflag &= ~(OPOST);
+ t.c_cflag |= ( CS8 | CREAD );
+ t.c_cc[VMIN] = 0;
+ t.c_cc[VTIME] = 0;
+ //save settings
+ iret = tcsetattr ( fd, TCSANOW, &t );
+ assert( iret != -1 );
+ msg.fd = fd;
+ rtems_message_queue_send( wmid, &msg, sizeof( msg ));
+ }
+ }
+ else
+ {
+ msg.fd = fd;
+ rtems_message_queue_send( wmid, &msg, sizeof( msg ));
+ }
+ }
+ otask_active = false;
+}
+
+static void
+Init(rtems_task_argument arg)
+{
+ rtems_status_code sc;
+ usb_test_message_t msg;
+ int ii;
+
+ (void) arg;
+ puts( "*** " TEST_NAME " TEST ***" );
+
+ sc = rtems_message_queue_create(
+ rtems_build_name ( 'M', 'U', 'O', 'P' ),
+ 16,
+ sizeof(usb_test_message_t),
+ RTEMS_PRIORITY,
+ &omid
+ );
+ assert( sc == RTEMS_SUCCESSFUL );
+
+ sc = rtems_message_queue_create(
+ rtems_build_name ( 'M', 'U', 'R', 'D' ),
+ 16,
+ sizeof(usb_test_message_t),
+ RTEMS_PRIORITY,
+ &rmid
+ );
+ assert( sc == RTEMS_SUCCESSFUL );
+
+ sc = rtems_message_queue_create(
+ rtems_build_name ( 'M', 'U', 'W', 'R' ),
+ 16,
+ sizeof(usb_test_message_t),
+ RTEMS_PRIORITY,
+ &wmid
+ );
+ assert( sc == RTEMS_SUCCESSFUL );
+
+ sc = rtems_task_create(
+ rtems_build_name('U', 'S', 'B', 'R'),
+ PRIO_READ,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_FLOATING_POINT,
+ &rid
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_create(
+ rtems_build_name('U', 'S', 'B', 'W'),
+ PRIO_WRITE,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_FLOATING_POINT,
+ &wid
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_create(
+ rtems_build_name('U', 'S', 'B', 'O'),
+ PRIO_OPEN,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_FLOATING_POINT,
+ &oid
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(rid, usb_serial_read_task, NULL);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(oid, usb_serial_open_task, NULL);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(wid, usb_serial_write_task, NULL);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_bsd_initialize();
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ msg.fd = -1;
+ rtems_message_queue_send( omid, &msg, sizeof( msg ));
+
+ sc = rtems_shell_init("SHLL", 16 * 1024, 1, CONSOLE_DEVICE_NAME,
+ false, true, NULL);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ kill_otask = true;
+ kill_rtask = true;
+ kill_wtask = true;
+ while(otask_active || rtask_active || wtask_active)
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(10));
+ }
+
+ sc = rtems_message_queue_delete(wmid);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_message_queue_delete(rmid);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_message_queue_delete(omid);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ exit(0);
+}
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_STUB_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_ZERO_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
+#define CONFIGURE_MAXIMUM_DRIVERS 32
+
+#define CONFIGURE_FILESYSTEM_DOSFS
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+
+#define CONFIGURE_STACK_CHECKER_ENABLED
+
+#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE (64 * 1024)
+#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (256 * 1024)
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_STACK_SIZE (32 * 1024)
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+#include <bsp/nexus-devices.h>
+
+#define CONFIGURE_SHELL_COMMANDS_INIT
+
+#include <bsp/irq-info.h>
+
+#include <rtems/netcmds-config.h>
+
+#define CONFIGURE_SHELL_USER_COMMANDS \
+ &bsp_interrupt_shell_command, \
+ &rtems_shell_STTY_Command, \
+ &rtems_shell_SYSCTL_Command
+
+#define CONFIGURE_SHELL_COMMAND_CPUUSE
+#define CONFIGURE_SHELL_COMMAND_PERIODUSE
+#define CONFIGURE_SHELL_COMMAND_STACKUSE
+#define CONFIGURE_SHELL_COMMAND_PROFREPORT
+
+#define CONFIGURE_SHELL_COMMAND_CP
+#define CONFIGURE_SHELL_COMMAND_PWD
+#define CONFIGURE_SHELL_COMMAND_LS
+#define CONFIGURE_SHELL_COMMAND_LN
+#define CONFIGURE_SHELL_COMMAND_LSOF
+#define CONFIGURE_SHELL_COMMAND_CHDIR
+#define CONFIGURE_SHELL_COMMAND_CD
+#define CONFIGURE_SHELL_COMMAND_MKDIR
+#define CONFIGURE_SHELL_COMMAND_RMDIR
+#define CONFIGURE_SHELL_COMMAND_CAT
+#define CONFIGURE_SHELL_COMMAND_MV
+#define CONFIGURE_SHELL_COMMAND_RM
+#define CONFIGURE_SHELL_COMMAND_MALLOC_INFO
+
+#define CONFIGURE_SHELL_COMMAND_BLKSTATS
+#define CONFIGURE_SHELL_COMMAND_BLKSYNC
+#define CONFIGURE_SHELL_COMMAND_MOUNT
+#define CONFIGURE_SHELL_COMMAND_UNMOUNT
+
+#include <rtems/shellconfig.h>
diff --git a/testsuite/usbserial01/test_main.c b/testsuite/usbserial01/test_main.c
new file mode 100755
index 0000000..63fcc83
--- /dev/null
+++ b/testsuite/usbserial01/test_main.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 1"
+
+/* rtems_termios_baud_t is a typedefs to int32_t */
+#define PRIdrtems_termios_baud_t PRId32
+
+/**
+ * This macro defines the standard name for the USB serial device
+ * that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+/*
+ * Baud Rate Constant Mapping Entry
+ */
+typedef struct {
+ tcflag_t constant;
+ rtems_termios_baud_t baud;
+} termios_baud_test_r;
+
+#define INVALID_CONSTANT ((tcflag_t) -2)
+
+#define INVALID_BAUD ((rtems_termios_baud_t) -2)
+/*
+ * Baud Rate Constant Mapping Table
+ */
+static const termios_baud_test_r baud_table[] = {
+ { B0, 0 },
+ { B50, 50 },
+ { B75, 75 },
+ { B110, 110 },
+ { B134, 134 },
+ { B150, 150 },
+ { B200, 200 },
+ { B300, 300 },
+ { B600, 600 },
+ { B1200, 1200 },
+ { B1800, 1800 },
+ { B2400, 2400 },
+ { B4800, 4800 },
+ { B9600, 9600 },
+ { B19200, 19200 },
+ { B38400, 38400 },
+ { B57600, 57600 },
+ { B115200, 115200 },
+ { B230400, 230400 },
+ { B460800, 460800 },
+ { INVALID_CONSTANT, INVALID_BAUD }
+};
+
+/*
+ * Character Size Constant Mapping Entry
+ */
+typedef struct {
+ tcflag_t constant;
+ int bits;
+} termios_character_size_test_r;
+
+/*
+ * Character Size Constant Mapping Table
+ */
+static const termios_character_size_test_r char_size_table[] = {
+ { CS5, 5 },
+ { CS6, 6 },
+ { CS7, 7 },
+ { CS8, 8 },
+ { INVALID_CONSTANT, -1 }
+};
+
+/*
+ * Parity Constant Mapping Entry
+ */
+typedef struct {
+ tcflag_t constant;
+ const char *parity;
+} termios_parity_test_r;
+
+/*
+ * Parity Constant Mapping Table
+ */
+static const termios_parity_test_r parity_table[] = {
+ { 0, "none" },
+ { PARENB, "even" },
+ { PARENB | PARODD, "odd" },
+ { INVALID_CONSTANT, NULL }
+};
+
+/*
+ * Stop Bit Constant Mapping Entry
+ */
+typedef struct {
+ tcflag_t constant;
+ int stop;
+} termios_stop_bits_test_r;
+
+/*
+ * Stop Bit Constant Mapping Table
+ */
+static const termios_stop_bits_test_r stop_bits_table[] = {
+ { 0, 1 },
+ { CSTOPB, 2 },
+ { INVALID_CONSTANT, -1 }
+};
+
+/*
+ * Test converting baud rate into an index
+ */
+static void test_termios_baud2index(void)
+{
+ int i;
+ int index;
+
+ puts( "Test termios_baud2index..." );
+ puts( "termios_baud_to_index(-2) - NOT OK" );
+ i = rtems_termios_baud_to_index( INVALID_CONSTANT );
+ assert( i == -1 );
+
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ printf(
+ "termios_baud_to_index(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ index = rtems_termios_baud_to_index( baud_table[i].constant );
+ assert(index == i);
+ }
+}
+
+/*
+ * Test converting termios baud constant to baud number
+ */
+static void test_termios_baud2number(void)
+{
+ int i;
+ rtems_termios_baud_t number;
+
+ puts(
+ "\n"
+ "Test termios_baud2number..."
+ );
+ puts( "termios_baud_to_number(-2) - NOT OK" );
+ number = rtems_termios_baud_to_number( INVALID_CONSTANT );
+ assert( number == 0 );
+
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ printf(
+ "termios_baud_to_number(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ number = rtems_termios_baud_to_number( baud_table[i].constant );
+ assert( number == baud_table[i].baud );
+ }
+}
+
+/*
+ * Test converting baud number to termios baud constant
+ */
+static void test_termios_number_to_baud(void)
+{
+ int i;
+ tcflag_t termios_baud;
+
+ puts(
+ "\n"
+ "Test termios_number_to_baud..."
+ );
+ puts( "termios_number_to_baud(-2) - NOT OK" );
+ termios_baud = rtems_termios_number_to_baud( INVALID_BAUD );
+ assert( termios_baud == 0 );
+
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ printf(
+ "termios_number_to_baud(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ termios_baud = rtems_termios_number_to_baud( baud_table[i].baud );
+ assert( termios_baud == baud_table[i].constant );
+ }
+}
+
+/*
+ * Test all the baud rate options
+ */
+static void test_termios_set_baud(
+ int test
+)
+{
+ int sc;
+ int i;
+ struct termios attr;
+
+ puts( "Test termios setting device baud rate..." );
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ tcflag_t cbaud = CBAUD;
+
+ sc = tcgetattr( test, &attr );
+ assert(sc == 0);
+
+ attr.c_cflag &= ~cbaud;
+ attr.c_cflag |= baud_table[i].constant;
+
+ printf(
+ "tcsetattr(TCSANOW, B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+
+ printf(
+ "tcsetattr(TCSADRAIN, B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+ }
+}
+
+/*
+ * Test all the character size options
+ */
+static void test_termios_set_charsize(
+ int test
+)
+{
+ int sc;
+ int i;
+ struct termios attr;
+
+ puts(
+ "\n"
+ "Test termios setting device character size ..."
+ );
+ for (i=0 ; char_size_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ tcflag_t csize = CSIZE;
+
+ sc = tcgetattr( test, &attr );
+ assert(sc == 0);
+
+ attr.c_cflag &= ~csize;
+ attr.c_cflag |= char_size_table[i].constant;
+
+ printf( "tcsetattr(TCSANOW, CS%d) - OK\n", char_size_table[i].bits );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+
+ printf( "tcsetattr(TCSADRAIN, CS%d) - OK\n", char_size_table[i].bits );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+ }
+}
+
+/*
+ * Test all the parity options
+ */
+static void test_termios_set_parity(
+ int test
+)
+{
+ int sc;
+ int i;
+ struct termios attr;
+ tcflag_t par;
+
+ puts(
+ "\n"
+ "Test termios setting device parity ..."
+ );
+ for (i=0 ; parity_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ par = PARENB | PARODD;
+
+ sc = tcgetattr( test, &attr );
+ assert(sc == 0);
+
+ attr.c_cflag &= ~par;
+ attr.c_cflag |= parity_table[i].constant;
+
+ printf( "tcsetattr(TCSANOW, %s) - OK\n", parity_table[i].parity );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+
+ printf( "tcsetattr(TCSADRAIN, %s) - OK\n", parity_table[i].parity );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+ }
+}
+
+/*
+ * Test all the stop bit options
+ */
+static void test_termios_set_stop_bits(
+ int test
+)
+{
+ int sc;
+ int i;
+ struct termios attr;
+
+ puts(
+ "\n"
+ "Test termios setting device character size ..."
+ );
+ for (i=0 ; stop_bits_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ tcflag_t cstopb = CSTOPB;
+
+ sc = tcgetattr( test, &attr );
+ assert(sc == 0);
+
+ attr.c_cflag &= ~cstopb;
+ attr.c_cflag |= stop_bits_table[i].constant;
+
+ printf( "tcsetattr(TCSANOW, %d bit%s) - OK\n",
+ stop_bits_table[i].stop,
+ ((stop_bits_table[i].stop == 1) ? "" : "s")
+ );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+
+ printf( "tcsetattr(TCSADRAIN, %d bits) - OK\n", stop_bits_table[i].stop );
+ sc = tcsetattr( test, TCSANOW, &attr );
+ assert(sc == 0);
+ }
+}
+
+static void test_termios_cfoutspeed(void)
+{
+ int i;
+ int sc;
+ speed_t speed;
+ struct termios term;
+ tcflag_t bad;
+
+ bad = CBAUD << 1;
+ memset( &term, '\0', sizeof(term) );
+ puts( "cfsetospeed(BAD BAUD) - EINVAL" );
+ sc = cfsetospeed( &term, bad );
+ assert( sc == -1 );
+ assert( errno == EINVAL );
+
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ memset( &term, '\0', sizeof(term) );
+ printf(
+ "cfsetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ sc = cfsetospeed( &term, baud_table[i].constant );
+ assert( !sc );
+ printf(
+ "cfgetospeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ speed = cfgetospeed( &term );
+ assert( speed == baud_table[i].constant );
+ }
+}
+
+static void test_termios_cfinspeed(void)
+{
+ int i;
+ int sc;
+ speed_t speed;
+ struct termios term;
+ tcflag_t bad;
+
+ bad = CBAUD << 1;
+ memset( &term, '\0', sizeof(term) );
+ puts( "cfsetispeed(BAD BAUD) - EINVAL" );
+ sc = cfsetispeed( &term, bad );
+ assert( sc == -1 );
+ assert( errno == EINVAL );
+
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ memset( &term, '\0', sizeof(term) );
+ printf(
+ "cfsetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ sc = cfsetispeed( &term, baud_table[i].constant );
+ assert( !sc );
+
+ printf(
+ "cfgetispeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ speed = cfgetispeed( &term );
+ assert( speed == baud_table[i].constant );
+ }
+}
+
+static void test_termios_cfsetspeed(void)
+{
+ int i;
+ int status;
+ speed_t speed;
+ struct termios term;
+ tcflag_t bad;
+
+ bad = CBAUD << 1;
+ memset( &term, '\0', sizeof(term) );
+ puts( "cfsetspeed(BAD BAUD) - EINVAL" );
+ status = cfsetspeed( &term, bad );
+ assert( status == -1 );
+ assert( errno == EINVAL );
+
+ for (i=0 ; baud_table[i].constant != INVALID_CONSTANT ; i++ ) {
+ memset( &term, '\0', sizeof(term) );
+ printf(
+ "cfsetspeed(B%" PRIdrtems_termios_baud_t ") - OK\n",
+ baud_table[i].baud
+ );
+ status = cfsetspeed( &term, baud_table[i].constant );
+ assert( !status );
+
+ printf(
+ "cfgetspeed(B%" PRIdrtems_termios_baud_t ") - checking both inspeed and outspeed - OK\n",
+ baud_table[i].baud
+ );
+ speed = cfgetispeed( &term );
+ assert( speed == baud_table[i].constant );
+
+ speed = cfgetospeed( &term );
+ assert( speed == baud_table[i].constant );
+ }
+}
+
+static void test_termios_cfmakeraw(void)
+{
+ struct termios term;
+
+ memset( &term, '\0', sizeof(term) );
+ cfmakeraw( &term );
+ puts( "cfmakeraw - OK" );
+
+ /* Check that all of the flags were set correctly */
+ assert( ~(term.c_iflag & (IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON)) );
+
+ assert( ~(term.c_oflag & OPOST) );
+
+ assert( ~(term.c_lflag & (ECHO|ECHONL|ICANON|ISIG|IEXTEN)) );
+
+ assert( ~(term.c_cflag & (CSIZE|PARENB)) );
+
+ assert( term.c_cflag & CS8 );
+}
+
+static void test_set_best_baud(void)
+{
+ static const struct {
+ uint32_t baud;
+ tcflag_t cflag;
+ } baud_to_cflag_table[] = {
+ { 0, B0 },
+ { 25, B0 },
+ { 26, B50 },
+ { 50, B50 },
+ { 62, B50 },
+ { 63, B75 },
+ { 75, B75 },
+ { 110, B110 },
+ { 134, B134 },
+ { 150, B150 },
+ { 200, B200 },
+ { 300, B300 },
+ { 600, B600 },
+ { 1200, B1200 },
+ { 1800, B1800 },
+ { 2400, B2400 },
+ { 4800, B4800 },
+ { 9600, B9600 },
+ { 19200, B19200 },
+ { 38400, B38400 },
+ { 57600, B57600 },
+ { 115200, B115200 },
+ { 230400, B230400 },
+ { 460800, B460800 },
+ { 0xffffffff, B460800 }
+ };
+
+ size_t n = RTEMS_ARRAY_SIZE(baud_to_cflag_table);
+ size_t i;
+
+ for ( i = 0; i < n; ++i ) {
+ struct termios term;
+ tcflag_t cbaud_mask = CBAUD;
+
+ memset( &term, 0xff, sizeof( term ) );
+ rtems_termios_set_best_baud( &term, baud_to_cflag_table[ i ].baud );
+
+ assert(
+ (term.c_cflag & cbaud_mask) == baud_to_cflag_table[ i ].cflag
+ );
+ }
+}
+
+static void
+test_main(void)
+{
+ int rc;
+ rtems_status_code sc;
+ rtems_device_major_number registered;
+ int test;
+ struct termios t;
+ int index = 0;
+ int end_time;
+
+ /*
+ * Test baud rate
+ */
+ test_termios_baud2index();
+ test_termios_baud2number();
+ test_termios_number_to_baud();
+
+ puts( "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+ test = -1;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+ while((test == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+ test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ if(test == -1) {
+ puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+ }
+ }
+ assert(test != -1);
+ /*
+ * tcsetattr - ERROR invalid operation
+ */
+ puts( "tcsetattr - invalid operation - ENOTSUP" );
+ rc = tcsetattr( test, INT_MAX, &t );
+ assert(rc == -1);
+ assert(errno == ENOTSUP);
+
+ test_termios_cfmakeraw();
+
+ /*
+ * tcsetattr - TCSADRAIN
+ */
+ puts( "\ntcsetattr - drain - OK" );
+ rc = tcsetattr( test, TCSADRAIN, &t );
+ assert(rc == 0);
+
+ test_termios_set_baud(test);
+
+ puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+ rc = close( test );
+ assert(rc == 0);
+
+ /*
+ * Test character size
+ */
+ puts(
+ "\n"
+ "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
+ );
+ test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ assert(test != -1);
+
+ test_termios_set_charsize(test);
+
+ puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+ rc = close( test );
+ assert(rc == 0);
+
+ /*
+ * Test parity
+ */
+ puts(
+ "\n"
+ "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
+ );
+ test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ assert(test != -1);
+
+ test_termios_set_parity(test);
+
+ puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+ rc = close( test );
+ assert(rc == 0);
+
+ /*
+ * Test stop bits
+ */
+ puts(
+ "\n"
+ "Init - open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK"
+ );
+ test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ assert(test != -1);
+
+ test_termios_set_stop_bits(test);
+
+ test_termios_cfoutspeed();
+
+ test_termios_cfinspeed();
+
+ test_termios_cfsetspeed();
+
+ puts( "Init - close - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - OK" );
+ rc = close( test );
+ assert(rc == 0);
+
+ puts( "Multiple open of the device" );
+ for( ; index < 26; ++index ) {
+ test = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ assert(test != -1);
+ rc = close( test );
+ assert(rc == 0);
+ }
+ puts( "" );
+
+ test_set_best_baud();
+
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial02/test_main.c b/testsuite/usbserial02/test_main.c
new file mode 100755
index 0000000..036b57b
--- /dev/null
+++ b/testsuite/usbserial02/test_main.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 2"
+
+/**
+ * This macro defines the standard name for the USB serial device
+ * that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+
+int Test_fd;
+
+void open_it(void)
+{
+ int end_time;
+
+ puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ Test_fd = -1;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+ while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+ Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ if(Test_fd == -1) {
+ puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+ }
+ }
+ assert( Test_fd != -1 );
+
+ change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+ change_lflag("", ECHO|ECHONL|ISIG|IEXTEN, 0);
+ change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+ int rc;
+
+ puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ rc = close( Test_fd );
+ assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_iflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_iflag &= ~mask;
+ attr.c_iflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_lflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_lflag &= ~mask;
+ attr.c_lflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_oflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_oflag &= ~mask;
+ attr.c_oflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+static void
+test_main(void)
+{
+ int sc;
+ pid_t pid;
+ char *term_name_p;
+ char term_name[32];
+
+ open_it();
+
+ puts( "tcdrain() - OK" );
+ sc = tcdrain(Test_fd);
+ assert( !sc );
+
+ puts( "" );
+
+ /***** TEST TCFLOW *****/
+ puts( "tcflow(TCOOFF) - ENOTSUP" );
+ errno = 0;
+ sc = tcflow( Test_fd, TCOOFF );
+ assert( sc == -1 );
+ assert( errno == ENOTSUP );
+
+ puts( "tcflow(TCOON) - ENOTSUP" );
+ errno = 0;
+ sc = tcflow( Test_fd, TCOON );
+ assert( sc == -1 );
+ assert( errno == ENOTSUP );
+
+ puts( "tcflow(TCIOFF) - ENOTSUP" );
+ errno = 0;
+ sc = tcflow( Test_fd, TCIOFF );
+ assert( sc == -1 );
+ assert( errno == ENOTSUP );
+
+ puts( "tcflow(TCION) - ENOTSUP" );
+ errno = 0;
+ sc = tcflow( Test_fd, TCION );
+ assert( sc == -1 );
+ assert( errno == ENOTSUP );
+
+ puts( "tcflow(22) - EINVAL" );
+ errno = 0;
+ sc = tcflow( Test_fd, 22 );
+ assert( sc == -1 );
+ assert( errno == EINVAL );
+
+ puts( "" );
+
+ /***** TEST TCFLUSH *****/
+ puts( "tcflush(TCIFLUSH) - OK" );
+ errno = 0;
+ sc = tcflush( Test_fd, TCIFLUSH );
+ assert( sc == 0 );
+ assert( errno == 0 );
+
+ puts( "tcflush(TCOFLUSH) - OK" );
+ sc = tcflush( Test_fd, TCOFLUSH );
+ assert( sc == 0 );
+ assert( errno == 0 );
+
+ puts( "tcflush(TCIOFLUSH) - OK" );
+ sc = tcflush( Test_fd, TCIOFLUSH );
+ assert( sc == 0 );
+ assert( errno == 0 );
+
+ puts( "tcflush(22) - EINVAL" );
+ errno = 0;
+ sc = tcflush( Test_fd, 22 );
+ assert( sc == -1 );
+ assert( errno == EINVAL );
+
+ puts( "" );
+
+ /***** TEST TCGETPGRP *****/
+ puts( "tcgetpgrp() - OK" );
+ pid = tcgetpgrp(Test_fd);
+ assert( pid == getpid() );
+
+ puts( "tcsetpgrp(3) - OK" );
+ sc = tcsetpgrp( Test_fd, 3 );
+ assert( !sc );
+
+ puts( "" );
+
+ /***** TEST TCSENDBREAK *****/
+ puts( "tcsendbreak(0) - OK" );
+ sc = tcsendbreak( Test_fd, 0 );
+ assert( !sc );
+
+ puts( "" );
+
+ /***** TEST CTERMID *****/
+ puts( "ctermid( NULL ) - OK" );
+ term_name_p = ctermid( NULL );
+ assert( term_name_p );
+ printf( "ctermid ==> %s\n", term_name_p );
+
+ puts( "ctermid( term_name ) - OK" );
+ term_name_p = ctermid( term_name );
+ assert( term_name_p == term_name );
+ printf( "ctermid ==> %s\n", term_name_p );
+
+ close_it();
+
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial03/test_main.c b/testsuite/usbserial03/test_main.c
new file mode 100755
index 0000000..e914ce0
--- /dev/null
+++ b/testsuite/usbserial03/test_main.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 3"
+
+/**
+ * This macro defines the standard name for the USB serial device
+ * that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void write_helper(int fd, const char *c);
+void read_helper(int fd, const char *expected);
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+
+void write_helper(
+ int fd,
+ const char *c
+)
+{
+ size_t len;
+ int rc;
+
+ len = strlen( c );
+ printf( "Writing: %s", c );
+
+ rc = write( fd, c, len );
+ assert( rc == len );
+}
+
+uint8_t read_helper_buffer[256];
+
+void read_helper(
+ int fd,
+ const char *expected
+)
+{
+ int rc;
+ size_t len;
+
+ len = strlen( expected );
+
+ printf( "\nReading (expected):\n" );
+ rtems_print_buffer( (unsigned char *)expected, len-1 );
+
+ rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) );
+ assert( rc != -1 );
+
+ printf( "Read %d bytes from read(2)\n", rc );
+ rtems_print_buffer( read_helper_buffer, rc );
+}
+
+int Test_fd;
+
+void open_it(void)
+{
+ int end_time;
+
+ puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ Test_fd = -1;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+ while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+ Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ if(Test_fd == -1) {
+ puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+ }
+ }
+ assert( Test_fd != -1 );
+
+ change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+ change_lflag("", ECHO|ECHONL|ISIG|IEXTEN, 0);
+ change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+ int rc;
+
+ puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ rc = close( Test_fd );
+ assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_iflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_iflag &= ~mask;
+ attr.c_iflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_lflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_lflag &= ~mask;
+ attr.c_lflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_oflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_oflag &= ~mask;
+ attr.c_oflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+const char ExpectedOutput_1[] = "This is test output.\n";
+const char ExpectedInput_1[] = "Test input this is.\n";
+const char ExpectedInput_2[] = "1235\b456.\n";
+const char ExpectedInput_3[] = "tab\ttab.\n";
+const char ExpectedInput_4[] = "cr\r.\n";
+const char ExpectedInput_5[] = "aBcDeFgH.\n";
+const char ExpectedInput_6[] = "Testing VERASE\177.\n";
+const char ExpectedInput_7[] = "Testing VKILL\025.\n";
+const char ExpectedInput_8[] = "\177Testing VERASE in column 1.\n";
+const char ExpectedInput_9[] = "\t tab \tTesting VKILL after tab.\025\n";
+
+static void
+test_main(void)
+{
+ open_it();
+
+ /* some basic cases */
+ write_helper( Test_fd, ExpectedOutput_1 );
+ read_helper( Test_fd, ExpectedOutput_1 );
+ write_helper( Test_fd, ExpectedInput_1 );
+ read_helper( Test_fd, ExpectedInput_1 );
+ write_helper( Test_fd, ExpectedInput_2 );
+ read_helper( Test_fd, ExpectedInput_2 );
+ write_helper( Test_fd, ExpectedInput_3 );
+ read_helper( Test_fd, ExpectedInput_3 );
+ write_helper( Test_fd, ExpectedInput_4 );
+ read_helper( Test_fd, ExpectedInput_4 );
+
+ /* test to lower case input mapping */
+ write_helper( Test_fd, ExpectedInput_5 );
+ read_helper( Test_fd, ExpectedInput_5 );
+ //IUCLC is not supported within FREEBSD so this should not change the output
+ change_iflag( "Enable to lower case mapping on input", IUCLC, IUCLC );
+ write_helper( Test_fd, ExpectedInput_5 );
+ read_helper( Test_fd, ExpectedInput_5 );
+ change_iflag( "Disable to lower case mapping on input", IUCLC, 0 );
+
+ write_helper( Test_fd, ExpectedInput_6 );
+ read_helper( Test_fd, ExpectedInput_6 );
+ write_helper( Test_fd, ExpectedInput_7 );
+ read_helper( Test_fd, ExpectedInput_7 );
+ write_helper( Test_fd, ExpectedInput_8 );
+ read_helper( Test_fd, ExpectedInput_8 );
+ write_helper( Test_fd, ExpectedInput_9 );
+ read_helper( Test_fd, ExpectedInput_9 );
+
+ puts( "" );
+ close_it();
+
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial04/test_main.c b/testsuite/usbserial04/test_main.c
new file mode 100755
index 0000000..1f40159
--- /dev/null
+++ b/testsuite/usbserial04/test_main.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 4"
+
+/**
+ * This macro defines the standard name for the USB serial device
+ * that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void write_helper(int fd, const char *c);
+void read_helper(int fd, const char *expected);
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+
+void write_helper(
+ int fd,
+ const char *c
+)
+{
+ size_t len;
+ int rc;
+
+ len = strlen( c );
+ printf( "Writing: %s", c );
+
+ rc = write( fd, c, len );
+ assert( rc == len );
+}
+
+uint8_t read_helper_buffer[256];
+
+void read_helper(
+ int fd,
+ const char *expected
+)
+{
+ int rc;
+ size_t len;
+
+ len = strlen( expected );
+
+ printf( "\nReading (expected):\n" );
+ rtems_print_buffer( (unsigned char *)expected, len-1 );
+
+ rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) );
+ assert( rc != -1 );
+
+ printf( "Read %d bytes from read(2)\n", rc );
+ rtems_print_buffer( read_helper_buffer, rc );
+}
+
+int Test_fd;
+
+void open_it(void)
+{
+ int end_time;
+
+ puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ Test_fd = -1;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+ while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+ Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ if(Test_fd == -1) {
+ puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+ }
+ }
+ assert( Test_fd != -1 );
+
+ change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+ change_lflag("", ECHO|ECHONL|ISIG|IEXTEN, 0);
+ change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+ int rc;
+
+ puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ rc = close( Test_fd );
+ assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_iflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_iflag &= ~mask;
+ attr.c_iflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_lflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_lflag &= ~mask;
+ attr.c_lflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_oflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_oflag &= ~mask;
+ attr.c_oflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+const char ExpectedOutput_1[] = "This is test output.\n";
+const char ExpectedInput_1[] = "Test input this is.\n";
+const char ExpectedInput_2[] = "1235\b456.\n";
+const char ExpectedInput_3[] = "tab\ttab.\n";
+const char ExpectedInput_4[] = "cr\r.\n";
+const char ExpectedInput_5[] = "aBcDeFgH.\n";
+
+static void
+test_main(void)
+{
+ open_it();
+
+ /* some basic cases */
+ write_helper( Test_fd, ExpectedOutput_1 );
+ read_helper( Test_fd, ExpectedOutput_1 );
+ write_helper( Test_fd, ExpectedInput_1 );
+ read_helper( Test_fd, ExpectedInput_1 );
+ write_helper( Test_fd, ExpectedInput_2 );
+ read_helper( Test_fd, ExpectedInput_2 );
+ write_helper( Test_fd, ExpectedInput_3 );
+ read_helper( Test_fd, ExpectedInput_3 );
+ write_helper( Test_fd, ExpectedInput_4 );
+ read_helper( Test_fd, ExpectedInput_4 );
+
+ /* test to lower case input mapping */
+ write_helper( Test_fd, ExpectedInput_5 );
+ read_helper( Test_fd, ExpectedInput_5 );
+ //IUCLC is not supported within FREEBSD so this should not change the output
+ change_iflag( "Enable to lower case mapping on input", IUCLC, IUCLC );
+ write_helper( Test_fd, ExpectedInput_5 );
+ read_helper( Test_fd, ExpectedInput_5 );
+ change_iflag( "Disable to lower case mapping on input", IUCLC, 0 );
+
+ close_it();
+
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial05/test_main.c b/testsuite/usbserial05/test_main.c
new file mode 100755
index 0000000..7e657ff
--- /dev/null
+++ b/testsuite/usbserial05/test_main.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires an external program with Xon/Xoff Flow control enabled.
+ * The external program should monitor the number of bytes received and transmitted
+ * to verify no bytes were drop. Using the USB serial device with a loopback plug
+ * not not seem to work.
+ */
+
+#include <machine/rtems-bsd-kernel-space.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <sys/systm.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <sys/_termios.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 5"
+//#define USE_LOOPBACK_TEST
+
+/**
+ * This macro defines the standard name for the USB serial device
+ * that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+#define PRIO_READ (RTEMS_MAXIMUM_PRIORITY - 3)
+#define USB_SERIAL_XON_BUFFER_WRITES 25
+
+void write_helper(int fd, const char *c);
+void read_helper(int fd, const char *expected);
+void open_it(void);
+void close_it(void);
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+void change_vmin_vtime( const char *desc, int min, int time );
+
+static rtems_id rid;
+static volatile bool kill_rtask;
+static volatile bool rtask_active;
+static volatile int bytes_written;
+static volatile int bytes_read;
+
+void write_helper(
+ int fd,
+ const char *c
+)
+{
+ size_t len;
+ int rc;
+
+ len = strlen( c );
+
+ rc = write( fd, c, len );
+ assert( rc == len );
+
+ bytes_written += rc;
+}
+
+const char ExpectedInput_1[] = "Blocking interrupt driven read.\n";
+uint8_t read_helper_buffer[256];
+
+void read_helper(
+ int fd,
+ const char *expected
+)
+{
+ int rc;
+
+ rc = read( fd, read_helper_buffer, sizeof(read_helper_buffer) );
+ assert( rc != -1 );
+
+ bytes_read += rc;
+}
+
+int Test_fd;
+
+void open_it(void)
+{
+ int end_time;
+
+ puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ Test_fd = -1;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+ while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+ Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ if(Test_fd == -1) {
+ puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+ }
+ }
+ assert( Test_fd != -1 );
+
+ change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+ change_lflag("", ECHO|ECHONL|ICANON|ISIG|IEXTEN, 0);
+ change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+ int rc;
+
+ puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ rc = close( Test_fd );
+ assert( rc == 0 );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_iflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_iflag &= ~mask;
+ attr.c_iflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_lflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_lflag &= ~mask;
+ attr.c_lflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_oflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_oflag &= ~mask;
+ attr.c_oflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_vmin_vtime( const char *desc, int min, int time )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing %s - VMIN=%d VTIME=%d\n", desc, min, time );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_cc[VMIN] = min;
+ attr.c_cc[VTIME] = time;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+const char ExpectedOutput_1[] =
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789"
+"0123456789012345678901234567890123456789\r\n";
+
+static void
+usb_serial_read_task(rtems_task_argument arg)
+{
+ int i;
+ int end_time;
+
+ rtask_active = true;
+ kill_rtask = false;
+ printf( "Read Begin\n");
+ i = 0;
+ change_vmin_vtime( "to 5 second timeout", 0, 50 );
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(30000);
+ while(!kill_rtask && (rtems_clock_get_ticks_since_boot() < end_time)) {
+ read_helper( Test_fd, ExpectedOutput_1 );
+ i++;
+ printf( "%d: Bytes Read: %d\n", i, bytes_read );
+ }
+ printf( "Read End\n");
+ rtask_active = false;
+
+ rtems_task_delete(RTEMS_SELF);
+}
+
+static void
+test_main(void)
+{
+ rtems_status_code sc;
+ int i;
+ int end_time;
+
+ bytes_written = 0;
+ bytes_read = 0;
+
+ open_it();
+
+ change_iflag( "Set XON/XOFF", IXON|IXOFF, IXON|IXOFF );
+
+#ifdef USE_LOOPBACK_TEST
+ sc = rtems_task_create(
+ rtems_build_name('U', 'S', 'B', 'R'),
+ PRIO_READ,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_FLOATING_POINT,
+ &rid
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(rid, usb_serial_read_task, NULL);
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(250));
+#endif
+
+ printf( "Write Begin\n");
+ for(i = 0; i < USB_SERIAL_XON_BUFFER_WRITES; i++) {
+ write_helper( Test_fd, ExpectedOutput_1 );
+ printf( "%d: Bytes Written: %d\n", i, bytes_written );
+ }
+ printf( "Write End\n");
+
+#ifndef USE_LOOPBACK_TEST
+ printf( "Read Begin\n");
+ i = 0;
+ change_vmin_vtime( "to 5 second timeout", 0, 50 );
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(30000);
+ while(rtems_clock_get_ticks_since_boot() < end_time) {
+ read_helper( Test_fd, ExpectedOutput_1 );
+ i++;
+ printf( "%d: Bytes Read: %d\n", i, bytes_read );
+ }
+ printf( "Read End\n");
+#else
+ //kill_rtask = true;
+ while(rtask_active)
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(100));
+ }
+#endif
+
+ close_it();
+
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
diff --git a/testsuite/usbserial06/test_main.c b/testsuite/usbserial06/test_main.c
new file mode 100755
index 0000000..bb7aa13
--- /dev/null
+++ b/testsuite/usbserial06/test_main.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This test requires a USB serial adapater with a loopback plug attached to be
+ * plugged into a USB port.
+ */
+
+#include <sys/ttydefaults.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include <rtems/console.h>
+#include <rtems/shell.h>
+#include <rtems/bsd/bsd.h>
+
+#include <termios.h>
+#include <rtems/libcsupport.h>
+#include <rtems/termiostypes.h>
+
+#define TEST_NAME "LIBBSD USB SERIAL 6"
+
+/**
+ * This macro defines the standard name for the USB serial device
+ * that is available to applications.
+ */
+#define TERMIOS_TEST_DRIVER_DEVICE_NAME "/dev/ttyU0"
+
+void open_it(void);
+void close_it(void);
+void write_it( const char *data );
+void read_it( ssize_t expected, ssize_t lookfor );
+void change_iflag( const char *desc, int mask, int new );
+void change_lflag( const char *desc, int mask, int new );
+void change_oflag( const char *desc, int mask, int new );
+void change_vmin_vtime( const char *desc, int min, int time );
+
+int Test_fd;
+
+void open_it(void)
+{
+ int end_time;
+
+ puts( "open(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ Test_fd = -1;
+ end_time = rtems_clock_get_ticks_since_boot() + RTEMS_MILLISECONDS_TO_TICKS(20000);
+ while((Test_fd == -1) && (rtems_clock_get_ticks_since_boot() < end_time))
+ {
+ rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(1000));
+ Test_fd = open( TERMIOS_TEST_DRIVER_DEVICE_NAME, O_RDWR );
+ if(Test_fd == -1) {
+ puts( "open - " TERMIOS_TEST_DRIVER_DEVICE_NAME " - NOT ATTACHED" );
+ }
+ }
+ assert( Test_fd != -1 );
+
+ change_iflag("", IMAXBEL|IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXANY|IXOFF, 0);
+ change_lflag("", ECHO|ECHONL|ICANON|ISIG|IEXTEN, 0);
+ change_oflag("", OPOST, 0);
+}
+
+void close_it(void)
+{
+ int rc;
+
+ puts( "close(" TERMIOS_TEST_DRIVER_DEVICE_NAME ") - OK " );
+ rc = close( Test_fd );
+ assert( rc == 0 );
+}
+
+void write_it( const char *data )
+{
+ ssize_t sc;
+ ssize_t len = strlen( data );
+
+ puts( "write() - OK " );
+ sc = write(Test_fd, data, len);
+ assert( sc == len );
+}
+
+void read_it( ssize_t expected, ssize_t lookfor )
+{
+ ssize_t rc, ii, jj;
+ char buf[32];
+
+ assert( lookfor <= sizeof(buf) );
+
+ printf( "read - %zd expected\n", expected );
+ rc = read( Test_fd, buf, lookfor );
+ if ( expected != rc )
+ printf( "ERROR - expected=%zd rc=%zd\n", expected, rc );
+ assert( expected == rc );
+}
+
+void change_iflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_iflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_iflag &= ~mask;
+ attr.c_iflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_lflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_lflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_lflag &= ~mask;
+ attr.c_lflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_oflag( const char *desc, int mask, int new )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing c_oflag to: %s\n", desc );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_oflag &= ~mask;
+ attr.c_oflag |= new;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+void change_vmin_vtime( const char *desc, int min, int time )
+{
+ int rc;
+ struct termios attr;
+
+ printf( "Changing %s - VMIN=%d VTIME=%d\n", desc, min, time );
+ rc = tcgetattr( Test_fd, &attr );
+ assert( rc == 0 );
+
+ attr.c_cc[VMIN] = min;
+ attr.c_cc[VTIME] = time;
+
+ rc = tcsetattr( Test_fd, TCSANOW, &attr );
+ assert( rc == 0 );
+}
+
+static void
+test_main(void)
+{
+ open_it();
+
+ change_vmin_vtime( "to polling", 0, 0 );
+ read_it( 0, 10 );
+
+ change_vmin_vtime( "to 5 second timeout", 0, 50 );
+ read_it( 0, 10 );
+
+ change_vmin_vtime( "to 5 second timeout", 5, 50 );
+ puts( "Enqueue 2 characters" );
+ write_it( "ab" );
+ read_it( 2, 10 );
+
+ puts( "Enqueue 7 characters" );
+ write_it( "1234567" );
+ read_it( 5, 5 );
+ read_it( 2, 2 );
+
+ close_it();
+
+ exit(0);
+}
+
+#include <rtems/bsd/test/default-usb-init.h>
+
--
1.9.1
More information about the devel
mailing list