summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-07-09 15:44:13 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-07-09 15:56:43 +0200
commit93726e5205daaa7475cf17c8f916a8b1842affca (patch)
treedd2ca55f2d16ee1d9b5951212e7bd4d531aa66bf
parenttermios: Add rtems_termios_get_termios() (diff)
downloadrtems-93726e5205daaa7475cf17c8f916a8b1842affca.tar.bz2
termios: Add rtems_termios_set_best_baud()
-rw-r--r--cpukit/libcsupport/Makefile.am2
-rw-r--r--cpukit/libcsupport/include/rtems/termiostypes.h21
-rw-r--r--cpukit/libcsupport/src/termios_setbestbaud.c45
-rw-r--r--testsuites/libtests/termios01/init.c55
-rw-r--r--testsuites/libtests/termios01/termios01.doc4
5 files changed, 122 insertions, 5 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 0d7597d666..41de47150e 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -65,7 +65,7 @@ TERMIOS_C_FILES = src/cfgetispeed.c src/cfgetospeed.c src/cfsetispeed.c \
src/tcsetpgrp.c src/termios.c src/termiosinitialize.c \
src/termios_baud2index.c src/termios_baud2num.c src/termios_num2baud.c \
src/termios_setinitialbaud.c src/termios_baudtable.c src/cfsetspeed.c \
- src/cfmakeraw.c
+ src/cfmakeraw.c src/termios_setbestbaud.c
SYSTEM_CALL_C_FILES = src/open.c src/close.c src/read.c src/write.c \
src/write_r.c \
diff --git a/cpukit/libcsupport/include/rtems/termiostypes.h b/cpukit/libcsupport/include/rtems/termiostypes.h
index df3ec0c2d7..6339456b20 100644
--- a/cpukit/libcsupport/include/rtems/termiostypes.h
+++ b/cpukit/libcsupport/include/rtems/termiostypes.h
@@ -78,7 +78,8 @@ typedef struct {
* @retval true Successful operation.
* @retval false Cannot open device.
*
- * @see rtems_termios_get_device_context() and rtems_termios_get_termios().
+ * @see rtems_termios_get_device_context(), rtems_termios_set_best_baud() and
+ * rtems_termios_get_termios().
*/
bool (*first_open)(
struct rtems_termios_tty *tty,
@@ -291,7 +292,7 @@ typedef struct rtems_termios_tty {
} rtems_termios_tty;
/**
- * @brief Installes a Termios device.
+ * @brief Installs a Termios device.
*
* @param[in] device_file If not @c NULL, then a device file for the specified
* major and minor number will be created.
@@ -379,12 +380,26 @@ RTEMS_INLINE_ROUTINE void *rtems_termios_get_device_context(
* initial attributes.
*/
RTEMS_INLINE_ROUTINE struct termios *rtems_termios_get_termios(
- const rtems_termios_tty *tty
+ rtems_termios_tty *tty
)
{
return &tty->termios;
}
+/**
+ * @brief Sets the best baud value in the Termios control.
+ *
+ * The valid Termios baud values are between 0 and 460800. The Termios baud
+ * value is chosen which minimizes the difference to the value specified.
+ *
+ * @param[in] tty The Termios control.
+ * @param[in] baud The current baud setting of the device.
+ */
+void rtems_termios_set_best_baud(
+ rtems_termios_tty *tty,
+ uint32_t baud
+);
+
struct rtems_termios_linesw {
int (*l_open) (struct rtems_termios_tty *tp);
int (*l_close)(struct rtems_termios_tty *tp);
diff --git a/cpukit/libcsupport/src/termios_setbestbaud.c b/cpukit/libcsupport/src/termios_setbestbaud.c
new file mode 100644
index 0000000000..3d7a3a80f0
--- /dev/null
+++ b/cpukit/libcsupport/src/termios_setbestbaud.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/termiostypes.h>
+
+void rtems_termios_set_best_baud(
+ rtems_termios_tty *tty,
+ uint32_t baud
+)
+{
+ const rtems_assoc_t *current = &rtems_termios_baud_table[ 0 ];
+ const rtems_assoc_t *last = current;
+ tcflag_t cbaud_mask = CBAUD;
+ tcflag_t cbaud;
+
+ while ( current->name != NULL && current->local_value < baud ) {
+ last = current;
+ ++current;
+ }
+
+ if ( current->name != NULL ) {
+ uint32_t mid = (last->local_value + current->local_value) / UINT32_C( 2 );
+
+ cbaud = baud <= mid ? last->remote_value : current->remote_value;
+ } else {
+ cbaud = B460800;
+ }
+
+ tty->termios.c_cflag = (tty->termios.c_cflag & ~cbaud_mask) | cbaud;
+}
diff --git a/testsuites/libtests/termios01/init.c b/testsuites/libtests/termios01/init.c
index 896867895d..d1de3f869d 100644
--- a/testsuites/libtests/termios01/init.c
+++ b/testsuites/libtests/termios01/init.c
@@ -517,7 +517,7 @@ static void test_termios_cfmakeraw(void)
rtems_test_assert( term.c_cflag & CS8 );
}
-static void test_early_device_install_remove(
+static rtems_status_code test_early_device_install_remove(
rtems_device_major_number major,
rtems_device_minor_number minor,
void *arg
@@ -535,6 +535,8 @@ static void test_early_device_install_remove(
rtems_test_assert( sc == RTEMS_INCORRECT_STATE );
rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
+
+ return RTEMS_SUCCESSFUL;
}
static void test_device_install_remove(void)
@@ -716,6 +718,56 @@ static void test_set_attributes_error(void)
rtems_test_assert( rtems_resource_snapshot_check( &snapshot ) );
}
+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 ) {
+ rtems_termios_tty tty;
+ struct termios *term = rtems_termios_get_termios( &tty );
+ tcflag_t cbaud_mask = CBAUD;
+
+ memset( &tty, 0xff, sizeof( tty ) );
+ rtems_termios_set_best_baud( &tty, baud_to_cflag_table[ i ].baud );
+
+ rtems_test_assert(
+ (term->c_cflag & cbaud_mask) == baud_to_cflag_table[ i ].cflag
+ );
+ }
+}
+
static rtems_task Init(
rtems_task_argument ignored
)
@@ -872,6 +924,7 @@ static rtems_task Init(
test_device_install_remove();
test_first_open_error();
test_set_attributes_error();
+ test_set_best_baud();
TEST_END();
rtems_test_exit(0);
diff --git a/testsuites/libtests/termios01/termios01.doc b/testsuites/libtests/termios01/termios01.doc
index 7d0589c343..ebc9c7aef2 100644
--- a/testsuites/libtests/termios01/termios01.doc
+++ b/testsuites/libtests/termios01/termios01.doc
@@ -28,9 +28,13 @@ directives:
rtems_termios_device_remove
rtems_termios_device_open
rtems_termios_device_close
+ rtems_termios_set_best_baud
concepts:
+ Exercise termios ioctl for all baud, character size, parity and
bits per character options.
+ Ensure that Termios device install/remove works.
++ Ensure that Termios first open works in the error case.
++ Ensure that Termios set attributes works in the error case.
++ Ensure that Termios set best baud works.