[rtems commit] termios: Add rtems_termios_set_best_baud()

Sebastian Huber sebh at rtems.org
Wed Jul 9 13:57:21 UTC 2014


Module:    rtems
Branch:    master
Commit:    93726e5205daaa7475cf17c8f916a8b1842affca
Changeset: http://git.rtems.org/rtems/commit/?id=93726e5205daaa7475cf17c8f916a8b1842affca

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jul  9 15:44:13 2014 +0200

termios: Add rtems_termios_set_best_baud()

---

 cpukit/libcsupport/Makefile.am                  |    2 +-
 cpukit/libcsupport/include/rtems/termiostypes.h |   21 +++++++-
 cpukit/libcsupport/src/termios_setbestbaud.c    |   45 ++++++++++++++++++
 testsuites/libtests/termios01/init.c            |   55 ++++++++++++++++++++++-
 testsuites/libtests/termios01/termios01.doc     |    4 ++
 5 files changed, 122 insertions(+), 5 deletions(-)

diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 0d7597d..41de471 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 df3ec0c..6339456 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 0000000..3d7a3a8
--- /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 at 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 8968678..d1de3f8 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 7d0589c..ebc9c7a 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.



More information about the vc mailing list