--- .../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 + * <rt...@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 + * <rt...@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 + * <rt...@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 + * <rt...@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 + * <rt...@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 + * <rt...@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 + * <rt...@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 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel