[PATCH] gdb: unix: allow to use custom baud rate
Alexey Lapshin
alexey.lapshin@espressif.com
Thu Sep 26 18:00:07 GMT 2024
Modern unix systems allow to set custom baud rate instead of predefined in termios.h.
- To use this in Linux it must have BOTHER macro in "asm/termio.h"
- MacOS could handle this using IOSSIOSPEED passed to ioctl()
---
gdb/config.in | 3 ++
gdb/configure | 37 +++++++++++++++++
gdb/configure.ac | 20 ++++++++++
gdb/ser-unix.c | 102 +++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 158 insertions(+), 4 deletions(-)
diff --git a/gdb/config.in b/gdb/config.in
index 57be033802e..b445fc3dd8f 100644
--- a/gdb/config.in
+++ b/gdb/config.in
@@ -562,6 +562,9 @@
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
+/* Define if asm/termio.h defines the BOTHER request. */
+#undef HAVE_TERMIOS_BOTHER
+
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
diff --git a/gdb/configure b/gdb/configure
index 53eaad4f0e2..1016737c09a 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -30386,6 +30386,43 @@ $as_echo "#define HAVE_PT_GETDBREGS 1" >>confdefs.h
fi
+# See if <asm/termios.h> provides the BOTHER request.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PT_GETDBREGS" >&5
+$as_echo_n "checking for PT_GETDBREGS... " >&6; }
+if ${gdb_cv_have_termios_bother+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <asm/termios.h>
+int
+main ()
+{
+BOTHER; TCGETS2;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gdb_cv_have_termios_bother=yes
+else
+ gdb_cv_have_termios_bother=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_have_termios_bother" >&5
+$as_echo "$gdb_cv_have_termios_bother" >&6; }
+if test "$gdb_cv_have_termios_bother" = yes; then
+
+$as_echo "#define HAVE_TERMIOS_BOTHER 1" >>confdefs.h
+
+fi
+
+
# See if <sys/ptrace.h> supports LWP names on FreeBSD
# Older FreeBSD versions don't have the pl_tdname member of
# `struct ptrace_lwpinfo'.
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 8368fea0423..4ffdf2d61ff 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1487,6 +1487,26 @@ if test "$gdb_cv_have_pt_getdbregs" = yes; then
[Define if sys/ptrace.h defines the PT_GETDBREGS request.])
fi
+# See if <asm/termios.h> provides the BOTHER request.
+AC_MSG_CHECKING(for PT_GETDBREGS)
+AC_CACHE_VAL(
+ [gdb_cv_have_termios_bother],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include <asm/termios.h>],
+ [BOTHER; TCGETS2;]
+ )],
+ [gdb_cv_have_termios_bother=yes],
+ [gdb_cv_have_termios_bother=no]
+ )]
+)
+AC_MSG_RESULT($gdb_cv_have_termios_bother)
+if test "$gdb_cv_have_termios_bother" = yes; then
+ AC_DEFINE(HAVE_TERMIOS_BOTHER, 1,
+ [Define if asm/termios.h defines the BOTHER request.])
+fi
+
+
# See if <sys/ptrace.h> supports LWP names on FreeBSD
# Older FreeBSD versions don't have the pl_tdname member of
# `struct ptrace_lwpinfo'.
diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c
index 02845aa938b..fe6ca3f0b94 100644
--- a/gdb/ser-unix.c
+++ b/gdb/ser-unix.c
@@ -30,6 +30,22 @@
#include "gdbsupport/gdb_select.h"
#include "cli/cli-cmds.h"
#include "gdbsupport/filestuff.h"
+#if HAVE_TERMIOS_BOTHER || __APPLE__
+#include <sys/ioctl.h>
+#endif
+#if __APPLE__
+#include <IOKit/serial/ioss.h>
+#ifdef IOSSIOSPEED
+#define HAVE_APPLE_IOSSIOSPEED
+#endif
+#endif
+#if HAVE_TERMIOS_BOTHER
+/* Workaround to resolve conflicting declarations of termios
+ * in <asm/termbits.h> and <termios.h */
+#define termios asmtermios
+#include <asm/termbits.h>
+#undef termios
+#endif
#include <termios.h>
#include "gdbsupport/scoped_ignore_sigttou.h"
@@ -289,10 +305,28 @@ baudtab[] =
4800, B4800
}
,
+#ifdef B7200
+ {
+ 7200, B7200
+ }
+ ,
+#endif
{
9600, B9600
}
,
+#ifdef B14400
+ {
+ 14400, B14400
+ }
+ ,
+#endif
+#ifdef B28800
+ {
+ 28800, B28800
+ }
+ ,
+#endif
{
19200, B19200
}
@@ -307,6 +341,12 @@ baudtab[] =
}
,
#endif
+#ifdef B76800
+ {
+ 76800, B76800
+ }
+ ,
+#endif
#ifdef B115200
{
115200, B115200
@@ -412,6 +452,7 @@ rate_to_code (int rate)
/* check if it is in between valid values. */
if (rate < baudtab[i].rate)
{
+#if !(HAVE_TERMIOS_BOTHER || HAVE_APPLE_IOSSIOSPEED)
if (i)
{
error (_("Invalid baud rate %d. "
@@ -423,21 +464,27 @@ rate_to_code (int rate)
error (_("Invalid baud rate %d. Minimum value is %d."),
rate, baudtab[0].rate);
}
+#else
+ return -1;
+#endif
}
}
}
-
+
+#if !(HAVE_TERMIOS_BOTHER || HAVE_APPLE_IOSSIOSPEED)
/* The requested speed was too large. */
error (_("Invalid baud rate %d. Maximum value is %d."),
rate, baudtab[i - 1].rate);
+#else
+ return -1;
+#endif
}
static void
-hardwire_setbaudrate (struct serial *scb, int rate)
+set_baudcode_baudrate (struct serial *scb, int baud_code)
{
struct hardwire_ttystate state;
- int baud_code = rate_to_code (rate);
-
+
if (get_tty_state (scb, &state))
perror_with_name ("could not get tty state");
@@ -448,6 +495,53 @@ hardwire_setbaudrate (struct serial *scb, int rate)
perror_with_name ("could not set tty state");
}
+static void
+set_custom_baudrate (int fd, int rate)
+{
+#if HAVE_TERMIOS_BOTHER
+ struct termios2 tio;
+
+ if (ioctl (fd, TCGETS2, &tio) < 0)
+ {
+ error (_("Can not set custom baud rate %d. Error is %d (TCGETS2)."),
+ rate, errno);
+ }
+ tio.c_cflag &= ~CBAUD;
+ tio.c_cflag |= BOTHER;
+ tio.c_ispeed = rate;
+ tio.c_ospeed = rate;
+ if (ioctl (fd, TCSETS2, &tio) < 0)
+ {
+ error (_("Can not set custom baud rate %d. Error is %d (TCSETS2)."),
+ rate, errno);
+ }
+
+#elif HAVE_APPLE_IOSSIOSPEED
+ if (ioctl (fd, IOSSIOSPEED, &rate) < 0)
+ {
+ error (_("Can not set custom baud rate %d. Error is %d."),
+ rate, errno);
+ }
+#endif
+}
+
+static void
+hardwire_setbaudrate (struct serial *scb, int rate)
+{
+ int baud_code = rate_to_code (rate);
+
+ if (baud_code < 0)
+ {
+ /* The baud rate code was not found.
+ Try to set a custom baud rate. */
+ set_custom_baudrate (scb->fd, rate);
+ }
+ else
+ {
+ set_baudcode_baudrate (scb, baud_code);
+ }
+}
+
static int
hardwire_setstopbits (struct serial *scb, int num)
{
--
2.43.0
More information about the Gdb-patches
mailing list