GDB: Add set/show serial parity command.
authorYury Grechishchev <yury.grechishchev@yotadevices.com>
Mon, 23 Mar 2015 21:15:42 +0000 (00:15 +0300)
committerJoel Brobecker <brobecker@adacore.com>
Mon, 23 Mar 2015 22:34:42 +0000 (15:34 -0700)
The "set serial parity" command allows the user to control which
parity to use when communicating over a serial connection, rather
than having the parity hardcoded to none.

gdb/ChangeLog:

        * NEWS: Mention set/show serial parity command.
        * monitor.c (monitor_open): Call serial_setparity.
        * remote.c (remote_open_1): Likewise.
        * ser-base.c (ser_base_serparity): New function.
        * ser-base.h (ser_base_setparity): Add  declaration.
        * ser-go32.c (dos_ops): Set "setparity" field.
        * ser-mingw.c (ser_windows_raw): Do not set state.fParity and
        state.Parity.
        (ser_windows_setparity): New function.
        (hardwire_ops): Add ser_windows_setparity.
        (tty_ops): Add NULL for setparity field.
        (pipe_ops): Add ser_base_setparity.
        (tcp_ops): Likewise.
        * ser-pipe.c (pipe_ops): Likewise.
        * ser-tcp.c (tcp_ops): Likewise.
        * ser-unix.c (hardwire_setparity): Add declaration.
        (hardwire_raw): Don't reset PARENB flag.
        (hardwire_setparity): New function.
        (hardwire_ops): Add hardwire_setparity.
        * serial.c (serial_setparity): New function.
        (serial_parity): New global.
        (parity_none, parity_odd, parity_even, parity_enums, parity):
        New static globals.
        (set_parity): New function.
        (_initialize_serial): Add set/show serial parity commands.
        * serial.h (GDBPARITY_NONE): Define.
        (GDBPARITY_ODD): Define.
        (GDBPARITY_EVEN): Define.
        (serial_setparity) Add declaration.
        (struct serial_ops): Add setparity field.
        * target.h (serial_parity): Add declaration.

gdb/doc/ChangeLog:

        * gdb.texinfo (Remote configuration): Document "set/show
        serial parity" command.

16 files changed:
gdb/ChangeLog
gdb/NEWS
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/monitor.c
gdb/remote.c
gdb/ser-base.c
gdb/ser-base.h
gdb/ser-go32.c
gdb/ser-mingw.c
gdb/ser-pipe.c
gdb/ser-tcp.c
gdb/ser-unix.c
gdb/serial.c
gdb/serial.h
gdb/target.h

index 3c59d09308900b48cb8dde6882615736cd3ae26f..e5e925506e47d5b8108f7f955e9c1be673885f31 100644 (file)
@@ -1,3 +1,37 @@
+2015-03-23  Yurij Grechishhev  <yurij.grechishhev@gmail.com>
+
+       * NEWS: Mention set/show serial parity command.
+       * monitor.c (monitor_open): Call serial_setparity.
+       * remote.c (remote_open_1): Likewise.
+       * ser-base.c (ser_base_serparity): New function.
+       * ser-base.h (ser_base_setparity): Add  declaration.
+       * ser-go32.c (dos_ops): Set "setparity" field.
+       * ser-mingw.c (ser_windows_raw): Do not set state.fParity and
+       state.Parity.
+       (ser_windows_setparity): New function.
+       (hardwire_ops): Add ser_windows_setparity.
+       (tty_ops): Add NULL for setparity field.
+       (pipe_ops): Add ser_base_setparity.
+       (tcp_ops): Likewise.
+       * ser-pipe.c (pipe_ops): Likewise.
+       * ser-tcp.c (tcp_ops): Likewise.
+       * ser-unix.c (hardwire_setparity): Add declaration.
+       (hardwire_raw): Don't reset PARENB flag.
+       (hardwire_setparity): New function.
+       (hardwire_ops): Add hardwire_setparity.
+       * serial.c (serial_setparity): New function.
+       (serial_parity): New global.
+       (parity_none, parity_odd, parity_even, parity_enums, parity):
+       New static globals.
+       (set_parity): New function.
+       (_initialize_serial): Add set/show serial parity commands.
+       * serial.h (GDBPARITY_NONE): Define.
+       (GDBPARITY_ODD): Define.
+       (GDBPARITY_EVEN): Define.
+       (serial_setparity) Add declaration.
+       (struct serial_ops): Add setparity field.
+       * target.h (serial_parity): Add declaration.
+
 2015-03-23  Keith Seitz  <keiths@redhat.com>
 
        * linespec.c (linespec_lexer_lex_keyword): Update comment.
index bda4a356556e06875fdcee7e067a4f27c31589f9..3fa33c90247f28d275be13594052aa75299fffee 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,10 @@
 
 *** Changes since GDB 7.9
 
+* GDB has two new commands: "set serial parity odd|even|none" and
+  "show serial parity".  These allows to set or show parity for the
+  remote serial I/O.
+
 * The "info source" command now displays the producer string if it was
   present in the debug info.  This typically includes the compiler version
   and may include things like its command line arguments.
index 1f120da3c65e39f79ae1edb292eba461f35f954e..b41c5cb3058e01c07efed25468fbeb4fabe9ef74 100644 (file)
@@ -1,3 +1,8 @@
+2015-03-23  Yurij Grechishhev  <yurij.grechishhev@gmail.com>
+
+       * gdb.texinfo (Remote configuration): Document "set/show
+       serial parity" command.
+
 2015-03-18  Gary Benson <gbenson@redhat.com>
 
        * gdb.texinfo (General Query Packets): Remove documentation
index 552da3111eff79cd2b1af0ec12e1ec677d9fcf54..7117e42c38e55de25b689f74fa324d8766fa25ce 100644 (file)
@@ -19443,6 +19443,13 @@ remote targets.
 @item show serial baud
 Show the current speed of the remote connection.
 
+@item set serial parity @var{parity}
+Set the parity for the remote serial I/O.  Supported values of @var{parity} are:
+@code{even}, @code{none}, and @code{odd}.  The default is @code{none}.
+
+@item show serial parity
+Show the current parity of the serial port.
+
 @item set remotebreak
 @cindex interrupt remote programs
 @cindex BREAK signal instead of Ctrl-C
index b040ec4cba0ad58e501a1c4863667940235dad08..548dae3d5b3408a929e0932065a3b036cb70210e 100644 (file)
@@ -767,6 +767,7 @@ monitor_open (const char *args, struct monitor_ops *mon_ops, int from_tty)
        }
     }
 
+  serial_setparity (monitor_desc, serial_parity);
   serial_raw (monitor_desc);
 
   serial_flush_input (monitor_desc);
index dfa68b3a4d4339cdb87b54eb03396ff1a1d7f60b..fd677fe22c955c37d53b853a21eb12584d9e27b8 100644 (file)
@@ -4308,6 +4308,7 @@ remote_open_1 (const char *name, int from_tty,
        }
     }
 
+  serial_setparity (rs->remote_desc, serial_parity);
   serial_raw (rs->remote_desc);
 
   /* If there is something sitting in the buffer we might take it as a
index 87817c40e0312a9a587485e3633cedd406c4633f..09aaceca0300030c5c0cbeb9ce22525f8415f6e4 100644 (file)
@@ -541,6 +541,14 @@ ser_base_setstopbits (struct serial *scb, int num)
   return 0;                    /* Never fails!  */
 }
 
+/* Implement the "setparity" serial_ops callback.  */
+
+int
+ser_base_setparity (struct serial *scb, int parity)
+{
+  return 0;                    /* Never fails!  */
+}
+
 /* Put the SERIAL device into/out-of ASYNC mode.  */
 
 void
index 6aac9256360f7dacad6fbdcc5e772cbd4ce79776..bb1c51d20d936ed30d8cf5932eeea3dc8188c263 100644 (file)
@@ -43,6 +43,7 @@ extern int ser_base_noflush_set_tty_state (struct serial *scb,
                                           serial_ttystate old_ttystate);
 extern int ser_base_setbaudrate (struct serial *scb, int rate);
 extern int ser_base_setstopbits (struct serial *scb, int num);
+extern int ser_base_setparity (struct serial *scb, int parity);
 extern int ser_base_drain_output (struct serial *scb);
 
 extern int ser_base_write (struct serial *scb, const void *buf, size_t count);
index 6bf1b4e8bfdda2235e5f8cb0f07ca987d0c908cc..bbcf6afe60c4302079ac4ec609c544505f17c277 100644 (file)
@@ -864,6 +864,7 @@ static const struct serial_ops dos_ops =
   dos_noflush_set_tty_state,
   dos_setbaudrate,
   dos_setstopbits,
+  dos_noop,
   dos_noop,                    /* Wait for output to drain.  */
   (void (*)(struct serial *, int))NULL /* Change into async mode.  */
 };
index 7f335e9858de75fb3bf0b13f928a04875582a7d0..6d383ace41d51093d4302882b5ef85b099717bab 100644 (file)
@@ -153,7 +153,6 @@ ser_windows_raw (struct serial *scb)
   if (GetCommState (h, &state) == 0)
     return;
 
-  state.fParity = FALSE;
   state.fOutxCtsFlow = FALSE;
   state.fOutxDsrFlow = FALSE;
   state.fDtrControl = DTR_CONTROL_ENABLE;
@@ -163,7 +162,6 @@ ser_windows_raw (struct serial *scb)
   state.fNull = FALSE;
   state.fAbortOnError = FALSE;
   state.ByteSize = 8;
-  state.Parity = NOPARITY;
 
   scb->current_timeout = 0;
 
@@ -198,6 +196,40 @@ ser_windows_setstopbits (struct serial *scb, int num)
   return (SetCommState (h, &state) != 0) ? 0 : -1;
 }
 
+/* Implement the "setparity" serial_ops callback.  */
+
+static int
+ser_windows_setparity (struct serial *scb, int parity)
+{
+  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
+  DCB state;
+
+  if (GetCommState (h, &state) == 0)
+    return -1;
+
+  switch (parity)
+    {
+    case GDBPARITY_NONE:
+      state.Parity = NOPARITY;
+      state.fParity = FALSE;
+      break;
+    case GDBPARITY_ODD:
+      state.Parity = ODDPARITY;
+      state.fParity = TRUE;
+      break;
+    case GDBPARITY_EVEN:
+      state.Parity = EVENPARITY;
+      state.fParity = TRUE;
+      break;
+    default:
+      internal_warning (__FILE__, __LINE__,
+                  "Incorrect parity value: %d", parity);
+      return -1;
+    }
+
+  return (SetCommState (h, &state) != 0) ? 0 : -1;
+}
+
 static int
 ser_windows_setbaudrate (struct serial *scb, int rate)
 {
@@ -1227,6 +1259,7 @@ static const struct serial_ops hardwire_ops =
   ser_base_noflush_set_tty_state,
   ser_windows_setbaudrate,
   ser_windows_setstopbits,
+  ser_windows_setparity,
   ser_windows_drain_output,
   ser_base_async,
   ser_windows_read_prim,
@@ -1257,6 +1290,7 @@ static const struct serial_ops tty_ops =
   ser_base_noflush_set_tty_state,
   NULL,
   NULL,
+  NULL,
   ser_base_drain_output,
   NULL,
   NULL,
@@ -1287,6 +1321,7 @@ static const struct serial_ops pipe_ops =
   ser_base_noflush_set_tty_state,
   ser_base_setbaudrate,
   ser_base_setstopbits,
+  ser_base_setparity,
   ser_base_drain_output,
   ser_base_async,
   pipe_windows_read,
@@ -1317,6 +1352,7 @@ static const struct serial_ops tcp_ops =
   ser_base_noflush_set_tty_state,
   ser_base_setbaudrate,
   ser_base_setstopbits,
+  ser_base_setparity,
   ser_base_drain_output,
   ser_base_async,
   net_read_prim,
index bf5e4d4943c9f09c9bb4e95710032feab7304748..07001326afcbc056fd1499d9f18b7a4f1b795336 100644 (file)
@@ -224,6 +224,7 @@ static const struct serial_ops pipe_ops =
   ser_base_noflush_set_tty_state,
   ser_base_setbaudrate,
   ser_base_setstopbits,
+  ser_base_setparity,
   ser_base_drain_output,
   ser_base_async,
   ser_unix_read_prim,
index 9c3dcf4ee4d227013354b0898d3e6e0790ffc9ed..35512e676e06a01bf5ec9407b8ffe44abe0ba32f 100644 (file)
@@ -394,6 +394,7 @@ static const struct serial_ops tcp_ops =
   ser_base_noflush_set_tty_state,
   ser_base_setbaudrate,
   ser_base_setstopbits,
+  ser_base_setparity,
   ser_base_drain_output,
   ser_base_async,
   net_read_prim,
index 4125797ad7dcb5ef380c5f17b2a60652a488bc3b..280fb6ae8e95fe2776f56b396779aedf99903019 100644 (file)
@@ -83,6 +83,7 @@ static int hardwire_readchar (struct serial *scb, int timeout);
 static int do_hardwire_readchar (struct serial *scb, int timeout);
 static int rate_to_code (int rate);
 static int hardwire_setbaudrate (struct serial *scb, int rate);
+static int hardwire_setparity (struct serial *scb, int parity);
 static void hardwire_close (struct serial *scb);
 static int get_tty_state (struct serial *scb,
                          struct hardwire_ttystate * state);
@@ -409,7 +410,7 @@ hardwire_raw (struct serial *scb)
   state.termios.c_iflag = 0;
   state.termios.c_oflag = 0;
   state.termios.c_lflag = 0;
-  state.termios.c_cflag &= ~(CSIZE | PARENB);
+  state.termios.c_cflag &= ~CSIZE;
   state.termios.c_cflag |= CLOCAL | CS8;
 #ifdef CRTSCTS
   /* h/w flow control.  */
@@ -432,7 +433,7 @@ hardwire_raw (struct serial *scb)
   state.termio.c_iflag = 0;
   state.termio.c_oflag = 0;
   state.termio.c_lflag = 0;
-  state.termio.c_cflag &= ~(CSIZE | PARENB);
+  state.termio.c_cflag &= ~CSIZE;
   state.termio.c_cflag |= CLOCAL | CS8;
   state.termio.c_cc[VMIN] = 0;
   state.termio.c_cc[VTIME] = 0;
@@ -893,6 +894,51 @@ hardwire_setstopbits (struct serial *scb, int num)
   return set_tty_state (scb, &state);
 }
 
+/* Implement the "setparity" serial_ops callback.  */
+
+static int
+hardwire_setparity (struct serial *scb, int parity)
+{
+  struct hardwire_ttystate state;
+  int newparity = 0;
+
+  if (get_tty_state (scb, &state))
+    return -1;
+
+  switch (parity)
+    {
+    case GDBPARITY_NONE:
+      newparity = 0;
+      break;
+    case GDBPARITY_ODD:
+      newparity = PARENB | PARODD;
+      break;
+    case GDBPARITY_EVEN:
+      newparity = PARENB;
+      break;
+    default:
+      internal_warning (__FILE__, __LINE__,
+                  "Incorrect parity value: %d", parity);
+      return -1;
+    }
+
+#ifdef HAVE_TERMIOS
+  state.termios.c_cflag &= ~(PARENB | PARODD);
+  state.termios.c_cflag |= newparity;
+#endif
+
+#ifdef HAVE_TERMIO
+  state.termio.c_cflag &= ~(PARENB | PARODD);
+  state.termio.c_cflag |= newparity;
+#endif
+
+#ifdef HAVE_SGTTY
+  return 0;            /* sgtty doesn't support this */
+#endif
+  return set_tty_state (scb, &state);
+}
+
+
 static void
 hardwire_close (struct serial *scb)
 {
@@ -929,6 +975,7 @@ static const struct serial_ops hardwire_ops =
   hardwire_noflush_set_tty_state,
   hardwire_setbaudrate,
   hardwire_setstopbits,
+  hardwire_setparity,
   hardwire_drain_output,
   ser_base_async,
   ser_unix_read_prim,
index b7e620d0f411c2bdff2c43e9dd25c2aaae225867..74567dbc4973a12d834ca5d46b3d14c481ce9643 100644 (file)
@@ -524,6 +524,14 @@ serial_setstopbits (struct serial *scb, int num)
   return scb->ops->setstopbits (scb, num);
 }
 
+/* See serial.h.  */
+
+int
+serial_setparity (struct serial *scb, int parity)
+{
+  return scb->ops->setparity (scb, parity);
+}
+
 int
 serial_can_async_p (struct serial *scb)
 {
@@ -638,6 +646,30 @@ serial_baud_show_cmd (struct ui_file *file, int from_tty,
                    value);
 }
 
+/* Parity for serial port.  */
+
+int serial_parity = GDBPARITY_NONE;
+
+static const char parity_none[] = "none";
+static const char parity_odd[] = "odd";
+static const char parity_even[] = "even";
+static const char *const parity_enums[] =
+  {parity_none, parity_odd, parity_even,  NULL};
+static const char *parity = parity_none;
+
+/* Set serial_parity value.  */
+
+static void
+set_parity (char *ignore_args, int from_tty, struct cmd_list_element *c)
+{
+  if (parity == parity_odd)
+    serial_parity = GDBPARITY_ODD;
+  else if (parity == parity_even)
+    serial_parity = GDBPARITY_EVEN;
+  else
+    serial_parity = GDBPARITY_NONE;
+}
+
 void
 _initialize_serial (void)
 {
@@ -670,6 +702,14 @@ using remote targets."),
                            serial_baud_show_cmd,
                            &serial_set_cmdlist, &serial_show_cmdlist);
 
+  add_setshow_enum_cmd ("parity", no_class, parity_enums,
+                        &parity, _("\
+Set parity for remote serial I/O"), _("\
+Show parity for remote serial I/O"), NULL,
+                        set_parity,
+                        NULL, /* FIXME: i18n: */
+                        &serial_set_cmdlist, &serial_show_cmdlist);
+
   add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
 Set filename for remote session recording."), _("\
 Show filename for remote session recording."), _("\
index 9eb1c3958fd93cb3dd07db2c162be48334433eb3..add0f1595ba7385fe0e629ff9315235dc488c3b1 100644 (file)
@@ -186,6 +186,14 @@ extern int serial_setbaudrate (struct serial *scb, int rate);
 
 extern int serial_setstopbits (struct serial *scb, int num);
 
+#define GDBPARITY_NONE     0
+#define GDBPARITY_ODD      1
+#define GDBPARITY_EVEN     2
+
+/* Set parity for serial port. Returns 0 for success, -1 for failure.  */
+
+extern int serial_setparity (struct serial *scb, int parity);
+
 /* Asynchronous serial interface: */
 
 /* Can the serial device support asynchronous mode?  */
@@ -271,6 +279,9 @@ struct serial_ops
                                  serial_ttystate);
     int (*setbaudrate) (struct serial *, int rate);
     int (*setstopbits) (struct serial *, int num);
+    /* Set the value PARITY as parity setting for serial object.
+       Return 0 in the case of success.  */
+    int (*setparity) (struct serial *, int parity);
     /* Wait for output to drain.  */
     int (*drain_output) (struct serial *);
     /* Change the serial device into/out of asynchronous mode, call
index c95e1a471141629db73f5687ac575c1eaf9fe54d..05dcd9feaead06bfde24c0647e429b59a638da28 100644 (file)
@@ -2236,6 +2236,10 @@ extern int remote_debug;
 
 /* Speed in bits per second, or -1 which means don't mess with the speed.  */
 extern int baud_rate;
+
+/* Parity for serial port  */
+extern int serial_parity;
+
 /* Timeout limit for response from target.  */
 extern int remote_timeout;