You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by pr...@apache.org on 2020/09/14 12:23:58 UTC

[incubator-nuttx] 02/02: libc/termios: modify termios setting follow linux and posix

This is an automated email from the ASF dual-hosted git repository.

protobits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 03c7951cbd1430f238f18582631e586269938997
Author: dongjiuzhu <do...@xiaomi.com>
AuthorDate: Mon Sep 7 22:28:45 2020 +0800

    libc/termios: modify termios setting follow linux and posix
    
    Change-Id: Id323b3169e74f4153fd8d132d20926b7fb8336a3
    Signed-off-by: dongjiuzhu <do...@xiaomi.com>
---
 include/termios.h                  | 242 +++++++++++++++++--------------------
 libs/libc/termios/Make.defs        |   2 +-
 libs/libc/termios/lib_cfgetspeed.c |  77 ------------
 libs/libc/termios/lib_cfsetspeed.c |  96 ---------------
 libs/libc/termios/lib_cfspeed.c    | 196 ++++++++++++++++++++++++++++++
 5 files changed, 309 insertions(+), 304 deletions(-)

diff --git a/include/termios.h b/include/termios.h
index 5032a6b..291b3f3 100644
--- a/include/termios.h
+++ b/include/termios.h
@@ -50,87 +50,81 @@
 
 /* Terminal input modes (c_iflag in the termios structure) */
 
-#define BRKINT    (1 << 0)  /* Bit 0:  Signal interrupt on break */
-#define ICRNL     (1 << 1)  /* Bit 1:  Map CR to NL on input */
-#define IGNBRK    (1 << 2)  /* Bit 2:  Ignore break condition */
-#define IGNCR     (1 << 3)  /* Bit 3:  Ignore CR */
-#define IGNPAR    (1 << 4)  /* Bit 4:  Ignore characters with parity errors */
-#define INLCR     (1 << 5)  /* Bit 5:  Map NL to CR on input */
-#define INPCK     (1 << 6)  /* Bit 6:  Enable input parity check */
-#define ISTRIP    (1 << 7)  /* Bit 7:  Strip character */
-#define IUCLC     (1 << 8)  /* Bit 8:  Map upper-case to lower-case on input
-                             *         (LEGACY) */
-#define IXANY     (1 << 9)  /* Bit 9:  Enable any character to restart output */
-#define IXOFF     (1 << 10) /* Bit 10: Enable start/stop input control */
-#define IXON      (1 << 11) /* Bit 11: Enable start/stop output control */
-#define PARMRK    (1 << 12) /* Bit 12: Mark parity errors */
+#define IGNBRK    (1 << 0)  /* Bit 0:  Ignore break condition */
+#define BRKINT    (1 << 1)  /* Bit 1:  Signal interrupt on break */
+#define IGNPAR    (1 << 2)  /* Bit 2:  Ignore characters with parity errors */
+#define PARMRK    (1 << 3)  /* Bit 3:  Mark parity errors */
+#define INPCK     (1 << 4)  /* Bit 4:  Enable input parity check */
+#define ISTRIP    (1 << 5)  /* Bit 5:  Strip character */
+#define INLCR     (1 << 6)  /* Bit 6:  Map NL to CR on input */
+#define IGNCR     (1 << 7)  /* Bit 7:  Ignore CR */
+#define ICRNL     (1 << 8)  /* Bit 8:  Map CR to NL on input */
+#define IUCLC     (1 << 9)  /* Bit 9:  Map upper-case to lower-case on input (LEGACY) */
+#define IXON      (1 << 10) /* Bit 10: Enable start/stop output control */
+#define IXANY     (1 << 11) /* Bit 11: Enable any character to restart output */
+#define IXOFF     (1 << 12) /* Bit 12: Enable start/stop input control */
 
 /* Terminal output modes (c_oflag in the termios structure) */
 
 #define OPOST     (1 << 0)  /* Bit 0:  Post-process output */
-#define OLCUC     (1 << 1)  /* Bit 1:  Map lower-case to upper-case on
-*                            *         output (LEGACY) */
+#define OLCUC     (1 << 1)  /* Bit 1:  Map lower-case to upper-case on output (LEGACY) */
 #define ONLCR     (1 << 2)  /* Bit 2:  Map NL to CR-NL on output */
 #define OCRNL     (1 << 3)  /* Bit 3:  Map CR to NL on output */
 #define ONOCR     (1 << 4)  /* Bit 4:  No CR output at column 0 */
 #define ONLRET    (1 << 5)  /* Bit 5:  NL performs CR function */
 #define OFILL     (1 << 6)  /* Bit 6:  Use fill characters for delay */
-#define NLDLY     (1 << 7)  /* Bit 7:  Select newline delays: */
-#  define NL0     (0 << 7)  /*   Newline character type 0 */
-#  define NL1     (1 << 7)  /*   Newline character type 1 */
-#define CRDLY     (3 << 8)  /* Bits 8-9:  Select carriage-return delays: */
-#  define CR0     (0 << 8)  /*   Carriage-return delay type 0 */
-#  define CR1     (1 << 8)  /*   Carriage-return delay type 1 */
-#  define CR2     (2 << 8)  /*   Carriage-return delay type 2 */
-#  define CR3     (3 << 8)  /*   Carriage-return delay type 3 */
-#define TABDLY    (3 << 10) /* Bit 10-11:  Select horizontal-tab delays: */
-#  define TAB0    (0 << 10) /*   Horizontal-tab delay type 0 */
-#  define TAB1    (1 << 10) /*   Horizontal-tab delay type 1 */
-#  define TAB2    (2 << 10) /*   Horizontal-tab delay type 2 */
-#  define TAB3    (3 << 10) /*   Expand tabs to spaces */
-#define BSDLY     (1 << 12) /* Bit 12:  Select backspace delays: */
-#  define BS0     (0 << 12) /*   Backspace-delay type 0 */
-#  define BS1     (1 << 12) /*   Backspace-delay type 1 */
-#define VTDLY     (1 << 13) /* Bit 13:  Select vertical-tab delays: */
-#  define VT0     (0 << 13) /*   Vertical-tab delay type 0 */
-#  define VT1     (1 << 13) /*   Vertical-tab delay type 1 */
-#define FFDLY     (1 << 14) /* Bit 14:  Select form-feed delays: */
-#  define FF0     (0 << 14) /*   Form-feed delay type 0 */
-#  define FF1     (1 << 14) /*   Form-feed delay type 1 */
+#define NLDLY     (1 << 8)  /* Bit 8:  Select newline delays: */
+#  define NL0     (0 << 8)  /*   Newline character type 0 */
+#  define NL1     (1 << 8)  /*   Newline character type 1 */
+#define CRDLY     (3 << 9)  /* Bits 9-10: Select carriage-return delays: */
+#  define CR0     (0 << 9)  /*   Carriage-return delay type 0 */
+#  define CR1     (1 << 9)  /*   Carriage-return delay type 1 */
+#  define CR2     (2 << 9)  /*   Carriage-return delay type 2 */
+#  define CR3     (3 << 9)  /*   Carriage-return delay type 3 */
+#define TABDLY    (3 << 11) /* Bits 11-12: Select horizontal-tab delays: */
+#  define TAB0    (0 << 11) /*   Horizontal-tab delay type 0 */
+#  define TAB1    (1 << 11) /*   Horizontal-tab delay type 1 */
+#  define TAB2    (2 << 11) /*   Horizontal-tab delay type 2 */
+#  define TAB3    (3 << 11) /*   Expand tabs to spaces */
+#define BSDLY     (1 << 13) /* Bit 13: Select backspace delays: */
+#  define BS0     (0 << 13) /*   Backspace-delay type 0 */
+#  define BS1     (1 << 13) /*   Backspace-delay type 1 */
+#define VTDLY     (1 << 14) /* Bit 14: Select vertical-tab delays: */
+#  define VT0     (0 << 14) /*   Vertical-tab delay type 0 */
+#  define VT1     (1 << 14) /*   Vertical-tab delay type 1 */
+#define FFDLY     (1 << 15) /* Bit 15: Select form-feed delays: */
+#  define FF0     (0 << 15) /*   Form-feed delay type 0 */
+#  define FF1     (1 << 15) /*   Form-feed delay type 1 */
 
 /* Control Modes (c_cflag in the termios structure) */
 
-#define CSIZE     (3 << 0)  /* Bits 0-1: Character size: */
-#  define CS5     (0 << 0)  /*   5 bits */
-#  define CS6     (1 << 0)  /*   6 bits */
-#  define CS7     (2 << 0)  /*   7 bits */
-#  define CS8     (3 << 0)  /*   8 bits */
-#define CSTOPB    (1 << 2)  /* Bit 2: Send two stop bits, else one */
-#define CREAD     (1 << 3)  /* Bit 3: Enable receiver */
-#define PARENB    (1 << 4)  /* Bit 4: Parity enable */
-#define PARODD    (1 << 5)  /* Bit 5: Odd parity, else even */
-#define HUPCL     (1 << 6)  /* Bit 6: Hang up on last close */
-#define CLOCAL    (1 << 7)  /* Bit 7: Ignore modem status lines */
-#define CCTS_OFLOW (1 << 8) /* Bit 8: CTS flow control of output */
-#define CRTS_IFLOW (1 << 9) /* Bit 9: RTS flow control of input */
-#define CRTSCTS   (CRTS_IFLOW | CCTS_OFLOW)
+#define CSIZE     (3 << 4)  /* Bits 4-5: Character size: */
+#  define CS5     (0 << 4)  /*   5 bits */
+#  define CS6     (1 << 4)  /*   6 bits */
+#  define CS7     (2 << 4)  /*   7 bits */
+#  define CS8     (3 << 4)  /*   8 bits */
+#define CSTOPB    (1 << 6)  /* Bit 6:  Send two stop bits, else one */
+#define CREAD     (1 << 7)  /* Bit 7:  Enable receiver */
+#define PARENB    (1 << 8)  /* Bit 8: Parity enable */
+#define PARODD    (1 << 9)  /* Bit 9: Odd parity, else even */
+#define HUPCL     (1 << 10) /* Bit 10: Hang up on last close */
+#define CLOCAL    (1 << 11) /* Bit 11: Ignore modem status lines */
+#define CCTS_OFLOW (1 << 29)/* Bit 29: CTS flow control of output */
+#define CRTS_IFLOW (1 << 31)/* Bit 31: RTS flow control of input */
+#define CRTSCTS   (CCTS_OFLOW | CRTS_IFLOW)
 
 /* Local Modes (c_lflag in the termios structure) */
 
-#define ECHO      (1 << 0)  /* Bit 0:  Enable echo */
-#define ECHOE     (1 << 1)  /* Bit 1:  Echo erase character as error-
-                             *         correcting backspace */
-#define ECHOK     (1 << 2)  /* Bit 2:  Echo KILL */
-#define ECHONL    (1 << 3)  /* Bit 3:  Echo NL */
-#define ICANON    (1 << 4)  /* Bit 4:  Canonical input (erase and kill
-                             *         processing) */
-#define IEXTEN    (1 << 5)  /* Bit 5:  Enable extended input character
-                             *         processing */
-#define ISIG      (1 << 6)  /* Bit 6:  Enable signals */
+#define ISIG      (1 << 0)  /* Bit 0:  Enable signals */
+#define ICANON    (1 << 1)  /* Bit 1:  Canonical input (erase and kill processing) */
+#define XCASE     (1 << 2)  /* Bit 2:  Canonical upper/lower presentation (LEGACY) */
+#define ECHO      (1 << 3)  /* Bit 3:  Enable echo */
+#define ECHOE     (1 << 4)  /* Bit 4:  Echo erase character as error correcting backspace */
+#define ECHOK     (1 << 5)  /* Bit 5:  Echo KILL */
+#define ECHONL    (1 << 6)  /* Bit 6:  Echo NL */
 #define NOFLSH    (1 << 7)  /* Bit 7:  Disable flush after interrupt or quit */
 #define TOSTOP    (1 << 8)  /* Bit 8:  Send SIGTTOU for background output */
-#define XCASE     (1 << 9)  /* Bit 9:  Canonical upper/lower presentation
-                             *         (LEGACY) */
+#define IEXTEN    (1 << 15) /* Bit 15: Enable extended input character processing */
 
 /* The following are subscript names for the termios c_cc array.
  *
@@ -155,63 +149,57 @@
  *   VTIME:  Timeout in deciseconds for non-canonical read
  */
 
-#define VEOF      0         /* Bit 0:  EOF character (canonical mode) */
-#define VMIN      VEOF      /* Bit 0:  MIN value (non-canonical mode) */
-#define VEOL      1         /* Bit 1:  EOL character (canonical mode) */
-#define VTIME     VEOL      /* Bit 1:  TIME value (non-canonical mode) */
+#define VINTR     0         /* Bit 0:  INTR character */
+#define VQUIT     1         /* Bit 1:  QUIT character */
 #define VERASE    2         /* Bit 2:  ERASE character (canonical mode) */
-#define VINTR     3         /* Bit 3:  INTR character */
-#define VKILL     4         /* Bit 4:  KILL character (canonical mode) */
-#define VQUIT     5         /* Bit 5:  QUIT character */
-#define VSTART    6         /* Bit 6:  START character */
-#define VSTOP     7         /* Bit 7:  STOP character */
-#define VSUSP     8         /* Bit 8:  SUSP character */
-#define NCCS      9         /* Bit 9:  Size of the array c_cc for control
-                             *         characters */
+#define VKILL     3         /* Bit 3:  KILL character (canonical mode) */
+#define VEOF      4         /* Bit 4:  EOF character (canonical mode) */
+#define VTIME     5         /* Bit 5:  TIME value (non-canonical mode) */
+#define VMIN      6         /* Bit 6:  MIN value (non-canonical mode) */
+#define VSTART    8         /* Bit 8:  START character */
+#define VSTOP     9         /* Bit 9:  STOP character */
+#define VSUSP     10        /* Bit 10: SUSP character */
+#define VEOL      11        /* Bit 11: EOL character (canonical mode) */
+#define NCCS      12        /* Bit 12: Size of the array c_cc for control characters */
 
 /* Baud Rate Selection.  These are instances of type speed_t.  Values of
  * 38400 and below are specified by POSIX; values above 38400 are sometimes
  * referred to as extended values and most values appear in most termios.h
  * implementations.
- *
- * NOTE that is NuttX that the encoding of the speed_t values is simply the
- * value of the baud itself.  So this opens a window for non-portable abuse
- * of the speed-related interfaces:  The defined values should be used where-
- * ever possible for reasons of portability.
  */
 
-#define B0        0         /* Hang up */
-#define B50       50        /* 50 baud */
-#define B75       75        /* 75 baud */
-#define B110      110       /* 110 baud */
-#define B134      134       /* 134.5 baud */
-#define B150      150       /* 150 baud */
-#define B200      200       /* 200 baud */
-#define B300      300       /* 300 baud */
-#define B600      600       /* 600 baud */
-#define B1200     1200      /* 1,200 baud */
-#define B1800     1800      /* 1,800 baud */
-#define B2400     2400      /* 2,400 baud */
-#define B4800     4800      /* 4,800 baud */
-#define B9600     9600      /* 9,600 baud */
-#define B19200    19200     /* 19,200 baud */
-#define B38400    38400     /* 38,400 baud */
-
-#define B57600    57600     /* 57,600 baud */
-#define B115200   115200    /* 115,200 baud */
-#define B128000   128000    /* 128,000 baud */
-#define B230400   230400    /* 230,400 baud */
-#define B256000   256000    /* 256,000 baud */
-#define B460800   460800    /* 460,800 baud */
-#define B500000   500000    /* 500,000 baud */
-#define B576000   576000    /* 576,000 baud */
-#define B921600   921600    /* 921,600 baud */
-#define B1000000  1000000   /* 1,000,000 baud */
-#define B1152000  1152000   /* 1,152,000 baud */
-#define B1500000  1500000   /* 1,500,000 baud */
-#define B2000000  2000000   /* 2,000,000 baud */
-#define B2500000  2500000   /* 2,500,000 baud */
-#define B3000000  3000000   /* 3,000,000 baud */
+#define B0        0000000   /* Hang up */
+#define B50       0000001   /* 50 baud */
+#define B75       0000002   /* 75 baud */
+#define B110      0000003   /* 110 baud */
+#define B134      0000004   /* 134.5 baud */
+#define B150      0000005   /* 150 baud */
+#define B200      0000006   /* 200 baud */
+#define B300      0000007   /* 300 baud */
+#define B600      0000010   /* 600 baud */
+#define B1200     0000011   /* 1,200 baud */
+#define B1800     0000012   /* 1,800 baud */
+#define B2400     0000013   /* 2,400 baud */
+#define B4800     0000014   /* 4,800 baud */
+#define B9600     0000015   /* 9,600 baud */
+#define B19200    0000016   /* 19,200 baud */
+#define B38400    0000017   /* 38,400 baud */
+
+#define B57600    0010001   /* 57,600 baud */
+#define B115200   0010002   /* 115,200 baud */
+#define B230400   0010003   /* 230,400 baud */
+#define B460800   0010004   /* 460,800 baud */
+#define B500000   0010005   /* 500,000 baud */
+#define B576000   0010006   /* 576,000 baud */
+#define B921600   0010007   /* 921,600 baud */
+#define B1000000  0010010   /* 1,000,000 baud */
+#define B1152000  0010011   /* 1,152,000 baud */
+#define B1500000  0010012   /* 1,500,000 baud */
+#define B2000000  0010013   /* 2,000,000 baud */
+#define B2500000  0010014   /* 2,500,000 baud */
+#define B3000000  0010015   /* 3,000,000 baud */
+#define B3500000  0010016   /* 3,500,000 baud */
+#define B4000000  0010017   /* 4,000,000 baud */
 
 /* Attribute Selection (used with tcsetattr()) */
 
@@ -223,18 +211,18 @@
 /* Line Control (used with tcflush()) */
 
 #define TCIFLUSH  0         /* Flush pending input */
-#define TCIOFLUSH 1         /* Flush both pending input and untransmitted
+#define TCOFLUSH  1         /* Flush untransmitted output */
+#define TCIOFLUSH 2         /* Flush both pending input and untransmitted
                              * output */
-#define TCOFLUSH  2         /* Flush untransmitted output */
 
 /* Constants for use with tcflow() */
 
-#define TCIOFF    0         /* Transmit a STOP character, intended to
+#define TCOOFF    0         /* Suspend output */
+#define TCOON     1         /* Restart output */
+#define TCIOFF    2         /* Transmit a STOP character, intended to
                              * suspend input data */
-#define TCION     1         /* Transmit a START character, intended to
+#define TCION     3         /* Transmit a START character, intended to
                              * restart input data */
-#define TCOOFF    2         /* Suspend output */
-#define TCOON     3         /* Restart output */
 
 /****************************************************************************
  * Public Type Definitions
@@ -242,12 +230,12 @@
 
 /* Baud rate selection */
 
-typedef uint32_t speed_t;   /* Used for terminal baud rates */
+typedef unsigned int  speed_t;   /* Used for terminal baud rates */
 
 /* Types used within the termios structure */
 
-typedef uint16_t tcflag_t;  /* Used for terminal modes */
-typedef int      cc_t;      /* Used for terminal special characters */
+typedef unsigned int  tcflag_t;  /* Used for terminal modes */
+typedef unsigned char cc_t;      /* Used for terminal special characters */
 
 /* The termios structure */
 
@@ -260,13 +248,6 @@ struct termios
   tcflag_t  c_cflag;        /* Control modes */
   tcflag_t  c_lflag;        /* Local modes */
   cc_t      c_cc[NCCS];     /* Control chars */
-
-  /* Implementation specific fields.  For portability reasons, these fields
-   * should not be accessed directly, but rather through only through the
-   * cf[set|get][o|i]speed() POSIX interfaces.
-   */
-
-  speed_t c_speed;          /* Input/output speed (non-POSIX)*/
 };
 
 /****************************************************************************
@@ -286,6 +267,7 @@ extern "C"
  * does not control input/output baud independently.  Both must be the same.
  * The POSIX standard interfaces, cfigetispeed() and cfigetospeed() are
  * supported by simply defining them to be cfgetspeed().
+ * The return value is baud value(9600).
  */
 
 speed_t cfgetspeed(FAR const struct termios *termiosp);
@@ -297,6 +279,7 @@ speed_t cfgetspeed(FAR const struct termios *termiosp);
  * not control input/output baud independently.  Both must be the same.
  * The POSIX standard interfaces, cfigetispeed() and cfigetospeed() are
  * supported by simply defining them to be cfsetspeed().
+ * Speed could be baud value(9600) or could be baud mask(B9600).
  */
 
 int cfsetspeed(FAR struct termios *termiosp, speed_t speed);
@@ -337,7 +320,6 @@ int tcsendbreak(int fd, int duration);
 
 int tcsetattr(int fd, int options, FAR const struct termios *termiosp);
 
-
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/libs/libc/termios/Make.defs b/libs/libc/termios/Make.defs
index 2d9f345..a6f8df9 100644
--- a/libs/libc/termios/Make.defs
+++ b/libs/libc/termios/Make.defs
@@ -40,7 +40,7 @@ ifeq ($(CONFIG_SERIAL_TERMIOS),y)
 
 # Add the termios C files to the build
 
-CSRCS += lib_cfgetspeed.c lib_cfsetspeed.c lib_cfmakeraw.c lib_isatty.c lib_tcflush.c
+CSRCS += lib_cfspeed.c lib_cfmakeraw.c lib_isatty.c lib_tcflush.c
 CSRCS += lib_tcflow.c lib_tcgetattr.c lib_tcsetattr.c
 
 # Add the termios directory to the build
diff --git a/libs/libc/termios/lib_cfgetspeed.c b/libs/libc/termios/lib_cfgetspeed.c
deleted file mode 100644
index ce53227..0000000
--- a/libs/libc/termios/lib_cfgetspeed.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
- * libs/libc/termios/lib_cfgetspeed.c
- *
- *   Copyright (C) 2012 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * 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.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <termios.h>
-#include <assert.h>
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cfgetspeed
- *
- * Description:
- *   The cfgetspeed() function is a non-POSIX function will extract the baud
- *   from the termios structure to which the termiosp argument points.
- *
- *   This function will return exactly the value in the termios data
- *   structure, without interpretation.
- *
- *   NOTE 1: NuttX does not control input/output baud independently.  Both
- *   must be the same.  The POSIX standard interfaces, cfisetispeed() and
- *   cfisetospeed() are defined to be cfgetspeed() in termios.h.
- *   NOTE 2.  In Nuttx, the speed_t is defined to be uint32_t and the baud
- *   encodings of termios.h are the actual baud values themselves.  Therefore,
- *   any baud value may be returned here... not just those enumerated in
- *   termios.h
- *
- * Input Parameters:
- *   termiosp - The termiosp argument is a pointer to a termios structure.
- *
- * Returned Value:
- *   Encoded baud value from the termios structure.
- *
- ****************************************************************************/
-
-speed_t cfgetspeed(FAR const struct termios *termiosp)
-{
-  DEBUGASSERT(termiosp);
-  return termiosp->c_speed;
-}
diff --git a/libs/libc/termios/lib_cfsetspeed.c b/libs/libc/termios/lib_cfsetspeed.c
deleted file mode 100644
index fe7bdb1..0000000
--- a/libs/libc/termios/lib_cfsetspeed.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
- * libs/libc/termios/lib_cfsetspeed.c
- *
- *   Copyright (C) 2012 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * 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.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <sys/types.h>
-#include <termios.h>
-#include <assert.h>
-
-/****************************************************************************
- * Name: cfsetspeed
- *
- * Description:
- *   The cfsetspeed() function is a non-POSIX function that sets the baud
- *   stored in the structure pointed to by termiosp to speed.
- *
- *   There is no effect on the baud set in the hardware until a subsequent
- *   successful call to tcsetattr() on the same termios structure.
- *
- *   NOTE 1: NuttX does not control input/output baud independently.  Both
- *   must be the same.  The POSIX standard interfaces, cfisetispeed() and
- *   cfisetospeed() are defined to be cfsetspeed() in termios.h.
- *
- *   NOTE 3:  A consequence of NOTE 1 is that you should never attempt to
- *   set the input and output baud to different values.
- *
- *   Also, the following POSIX requirement cannot be supported: "If the input
- *   baud rate stored in the termios structure pointed to by termios_p is 0,
- *   the input baud rate given to the hardware will be the same as the output
- *   baud rate stored in the termios structure."
- *
- *   NOTE 2.  In Nuttx, the speed_t is defined to be uint32_t and the baud
- *   encodings of termios.h are the actual baud values themselves.  Therefore,
- *   any baud value can be provided as the speed argument here.  However, if
- *   you do so, your code will *NOT* be portable to other environments where
- *   speed_t is smaller and where the termios.h baud values are encoded! To
- *   avoid portability issues, use the baud definitions in termios.h!
- *
- *   Linux, for example, would require this (also non-portable) sequence:
- *
- *     cfsetispeed(termiosp, BOTHER);
- *     termiosp->c_ispeed = baud;
- *
- *     cfsetospeed(termiosp, BOTHER);
- *     termiosp->c_ospeed = baud;
- *
- * Input Parameters:
- *   termiosp - The termiosp argument is a pointer to a termios structure.
- *   speed - The new input speed
- *
- * Returned Value:
- *   Baud is not checked... OK is always returned (this is non-standard
- *   behavior).
- *
- ****************************************************************************/
-
-int cfsetspeed(FAR struct termios *termiosp, speed_t speed)
-{
-  DEBUGASSERT(termiosp);
-  termiosp->c_speed = speed;
-  return OK;
-}
diff --git a/libs/libc/termios/lib_cfspeed.c b/libs/libc/termios/lib_cfspeed.c
new file mode 100644
index 0000000..b0e08f8
--- /dev/null
+++ b/libs/libc/termios/lib_cfspeed.c
@@ -0,0 +1,196 @@
+/****************************************************************************
+ * libs/libc/termios/lib_cfspeed.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <sys/types.h>
+#include <termios.h>
+#include <assert.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CBAUD          0010017  /* Baud speed mask (not in POSIX) */
+#define CBAUDEX        0010000  /* Extra baud speed mask, included in CBAUD.
+                                 * (not in POSIX) */
+
+#define ARRAYSIZE(a)   (sizeof((a))/sizeof(a[0]))
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Routine which returns the baud rate of the tty
+ *
+ * Note that the baud_table needs to be kept in sync with the
+ * include/termios.h file.
+ */
+
+static const speed_t g_baud_table[] =
+{
+  0,       50,      75,      110,     134,
+  150,     200,     300,     600,     1200,
+  1800,    2400,    4800,    9600,    19200,
+  38400,   57600,   115200,  230400,  460800,
+  500000,  576000,  921600,  1000000, 1152000,
+  1500000, 2000000, 2500000, 3000000, 3500000,
+  4000000
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int baud_mask(speed_t speed)
+{
+  speed_t idx = 0;
+
+  for (; idx < ARRAYSIZE(g_baud_table); idx++)
+    {
+      if (speed == g_baud_table[idx])
+        {
+          break;
+        }
+    }
+
+  /* we don't find the speed value, it could be mask */
+
+  if (idx == ARRAYSIZE(g_baud_table))
+    {
+      return (speed & ~CBAUD) ? -1 : speed;
+    }
+
+  /* If idx > B38400, we should will idx minus 15, and or CBAUDEX */
+
+  if (idx > B38400)
+    {
+      idx -= B38400;
+      idx |= CBAUDEX;
+    }
+
+  return idx;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cfsetspeed
+ *
+ * Description:
+ *   The cfsetspeed() function is a non-POSIX function that sets the baud
+ *   stored in the structure pointed to by termiosp to speed.
+ *
+ *   There is no effect on the baud set in the hardware until a subsequent
+ *   successful call to tcsetattr() on the same termios structure.
+ *
+ *   NOTE 1: NuttX does not control input/output baud independently.  Both
+ *   must be the same.  The POSIX standard interfaces, cfisetispeed() and
+ *   cfisetospeed() are defined to be cfsetspeed() in termios.h.
+ *
+ *   NOTE 3: A consequence of NOTE 1 is that you should never attempt to
+ *   set the input and output baud to different values.
+ *
+ *   Also, the following POSIX requirement cannot be supported: "If the input
+ *   baud rate stored in the termios structure pointed to by termios_p is 0,
+ *   the input baud rate given to the hardware will be the same as the output
+ *   baud rate stored in the termios structure."
+ *
+ *   NOTE 2. In Nuttx, the speed_t is defined to be unsigned int and the baud
+ *   encodings of termios.h are baud value mask. And their corresponding
+ *   values are in array g_baud_table. However, if you do so, your code will
+ *   *NOT* be portable to other environments where speed_t is smaller and
+ *   where the termios.h baud values are encoded! To avoid portability
+ *   issues, use the baud definitions in termios.h!
+ *
+ *   Linux, for example, would require this (also non-portable) sequence:
+ *
+ *     cfsetispeed(termiosp, BOTHER);
+ *     termiosp->c_ispeed = baud;
+ *
+ *     cfsetospeed(termiosp, BOTHER);
+ *     termiosp->c_ospeed = baud;
+ *
+ * Input Parameters:
+ *   termiosp - The termiosp argument is a pointer to a termios structure.
+ *   speed - The new input speed. It could be baud rate or could be mask.
+ *
+ * Returned Value:
+ *   Baud is returned. If speed don't match g_baud_table and mask in
+ *   termios.h, -1 is returned and set errno EINVAL.
+ *
+ ****************************************************************************/
+
+int cfsetspeed(FAR struct termios *termiosp, speed_t speed)
+{
+  int mask = baud_mask(speed);
+
+  DEBUGASSERT(termiosp);
+  if (mask == -1)
+    {
+      set_errno(EINVAL);
+      return mask;
+    }
+
+  termiosp->c_cflag &= ~CBAUD;
+  termiosp->c_cflag |= mask;
+  return 0;
+}
+
+/****************************************************************************
+ * Name: cfgetspeed
+ *
+ * Description:
+ *   The cfgetspeed() function is a non-POSIX function will extract the baud
+ *   from the termios structure to which the termiosp argument points.
+ *
+ *   This function will return exactly the value in the termios data
+ *   structure, without interpretation.
+ *
+ *   NOTE 1: NuttX does not control input/output baud independently.  Both
+ *   must be the same.  The POSIX standard interfaces, cfisetispeed() and
+ *   cfisetospeed() are defined to be cfgetspeed() in termios.h.
+ *   NOTE 2.  In Nuttx, the speed_t is defined to be uint32_t and the baud
+ *   encodings of termios.h are the actual baud values themselves. Therefore,
+ *   any baud value may be returned here... not just those enumerated in
+ *   termios.h
+ *
+ * Input Parameters:
+ *   termiosp - The termiosp argument is a pointer to a termios structure.
+ *
+ * Returned Value:
+ *   Encoded baud value from the termios structure.
+ *
+ ****************************************************************************/
+
+speed_t cfgetspeed(FAR const struct termios *termiosp)
+{
+  int idx;
+
+  DEBUGASSERT(termiosp);
+  idx = termiosp->c_cflag & CBAUD & ~CBAUDEX;
+  idx += (termiosp->c_cflag & CBAUDEX) ? 15 : 0;
+  return g_baud_table[idx];
+}