summaryrefslogtreecommitdiffstats
path: root/testsuite
diff options
context:
space:
mode:
authorKevin Kirspel <kevin-kirspel@idexx.com>2017-05-12 08:16:25 -0400
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-05-12 14:18:38 +0200
commit534017c9ee99af974816fa8e31ef681d951d2861 (patch)
tree612a31ec27eff718b951bd23ba7af28078d8255e /testsuite
parentUpdate USB Serial Driver for use with RTEMS (diff)
downloadrtems-libbsd-534017c9ee99af974816fa8e31ef681d951d2861.tar.bz2
Adding USB Serial test
Diffstat (limited to 'testsuite')
-rw-r--r--testsuite/usbserial01/init.c329
1 files changed, 329 insertions, 0 deletions
diff --git a/testsuite/usbserial01/init.c b/testsuite/usbserial01/init.c
new file mode 100644
index 00000000..eee027fc
--- /dev/null
+++ b/testsuite/usbserial01/init.c
@@ -0,0 +1,329 @@
+/*-
+ * COPYRIGHT (c) 2017 Kevin Kirspel
+ * All rights reserved.
+ *
+ * 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)
+
+struct usb_test_message {
+ int fd;
+ char rbuf[USB_SERIAL_TEST_BUFFER_SIZE];
+ char wbuf[USB_SERIAL_TEST_BUFFER_SIZE];
+};
+
+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)
+{
+ struct usb_test_message 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)
+{
+ struct usb_test_message 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;
+ struct usb_test_message 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;
+ struct usb_test_message msg;
+ int ii;
+
+ (void) arg;
+ puts("*** " TEST_NAME " TEST ***");
+
+ sc = rtems_message_queue_create(
+ rtems_build_name ('M', 'U', 'O', 'P'),
+ 16,
+ sizeof(struct usb_test_message),
+ RTEMS_PRIORITY,
+ &omid
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_message_queue_create(
+ rtems_build_name ('M', 'U', 'R', 'D'),
+ 16,
+ sizeof(struct usb_test_message),
+ RTEMS_PRIORITY,
+ &rmid
+ );
+ assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_message_queue_create(
+ rtems_build_name ('M', 'U', 'W', 'R'),
+ 16,
+ sizeof(struct usb_test_message),
+ 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_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_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>
+
+SYSINIT_DRIVER_REFERENCE(uplcom, uhub);
+
+#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