From 9e633f58da0e7a5e07da0becdd81b43ab2ea227c Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 27 Jun 2002 21:25:14 +0000 Subject: 2002-06-25 Thomas Doerfler * With the addition of serdbg, the standard polled I/O functions for gdbstub and/or printk are optionally routed to any termios-aware device driver, that supports polled mode. See libmisc/serdbg/README. * serdbg/Makefile.am, serdbg/README, serdbg/serdbg.c, serdbg/serdbg.h, serdbg/serdbgcnf.h, serdbg/serdbgio.c, serdbg/termios_printk.c, serdbg/termios_printk.h, serdbg/termios_printk_cnf.h, serdbg/.cvsignore: New files. * configure.ac, Makefile.am, wrapup/Makefile.am: Modified to reflect addition. --- cpukit/libmisc/serdbg/serdbgio.c | 252 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 cpukit/libmisc/serdbg/serdbgio.c (limited to 'cpukit/libmisc/serdbg/serdbgio.c') diff --git a/cpukit/libmisc/serdbg/serdbgio.c b/cpukit/libmisc/serdbg/serdbgio.c new file mode 100644 index 0000000000..d44fa7f9fa --- /dev/null +++ b/cpukit/libmisc/serdbg/serdbgio.c @@ -0,0 +1,252 @@ +/*===============================================================*\ +| File: serdbgio.c | ++-----------------------------------------------------------------+ +| Copyright (c) 2002 IMD | +| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler | +| Hebststr. 8, 82178 Puchheim, Germany | +| | +| The license and distribution terms for this file may be | +| found in the file LICENSE in this distribution or at | +| http://www.OARcorp.com/rtems/license.html. | +| all rights reserved | ++-----------------------------------------------------------------+ +| TERMIOS serial gdb interface support | +| the functions in this file allow the standard gdb stubs like | +| "m68k-stub.c" to access any serial interfaces that work with | +| RTEMS termios in polled mode | +| | ++-----------------------------------------------------------------+ +| date history ID | +| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | +| 10.05.02 creation doe | +|*****************************************************************| +|* $Id$ + * +|*****************************************************************| +\*===============================================================*/ + +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* + * internal variables + */ +int serdbg_fd = -1; +struct rtems_termios_tty *serdbg_tty; + +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int serdbg_open + +/*-------------------------------------------------------------------------*\ +| Purpose: | +| try to open given serial debug port | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ +( + const char *dev_name, /* name of device to open */ + unsigned32 baudrate /* baud rate to use */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| 0 on success, -1 and errno otherwise | +\*=========================================================================*/ +{ + boolean err_occurred = FALSE; + rtems_libio_t *iop = NULL; + struct termios act_termios; + tcflag_t baudcode = B0; + +#define FD_STORE_CNT 3 + int fd_store[FD_STORE_CNT]; + int fd_store_used = 0; + + /* + * translate baudrate into baud code + */ + switch(baudrate) { + case 50: baudcode = B50; break; + case 75: baudcode = B75; break; + case 110: baudcode = B110; break; + case 134: baudcode = B134; break; + case 150: baudcode = B150; break; + case 200: baudcode = B200; break; + case 300: baudcode = B300; break; + case 600: baudcode = B600; break; + case 1200: baudcode = B1200; break; + case 1800: baudcode = B1800; break; + case 2400: baudcode = B2400; break; + case 4800: baudcode = B4800; break; + case 9600: baudcode = B9600; break; + case 19200: baudcode = B19200; break; + case 38400: baudcode = B38400; break; + case 57600: baudcode = B57600; break; + case 115200: baudcode = B115200; break; + case 230400: baudcode = B230400; break; + case 460800: baudcode = B460800; break; + default : err_occurred = TRUE; errno = EINVAL; break; + } + + /* + * open device for serdbg operation + * skip any fds that are between 0..2, because they are + * reserved for stdin/out/err + */ + if (!err_occurred && + (dev_name != NULL) && + (dev_name[0] != '\0')) { + do { + serdbg_fd = open(dev_name,O_RDWR); + if (serdbg_fd < 0) { + err_occurred = TRUE; + } + else { + if (serdbg_fd < 3) { + if (fd_store_used >= FD_STORE_CNT) { + err_occurred = TRUE; + } + else { + fd_store[fd_store_used++] = serdbg_fd; + } + } + } + } while (!err_occurred && + (serdbg_fd < 3)); + } + /* + * close any fds, that have been placed in fd_store + * so fd 0..2 are reusable again + */ + while (--fd_store_used >= 0) { + close(fd_store[fd_store_used]); + } + + /* + * capture tty structure + */ + if (!err_occurred) { + iop = &rtems_libio_iops[serdbg_fd]; + serdbg_tty = iop->data1; + } + /* + * set device baudrate + * (and transp mode, this is not really needed) + * ... + */ + /* + * ... get fd settings + */ + if (!err_occurred && + (0 != tcgetattr(serdbg_fd,&act_termios))) { + err_occurred = TRUE; + } + if (!err_occurred) { + act_termios.c_iflag + &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + act_termios.c_oflag + &= ~OPOST; + + act_termios.c_lflag + &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + + cfsetospeed(&act_termios,baudcode); + cfsetispeed(&act_termios,baudcode); + + if (0 != tcsetattr(serdbg_fd,TCSANOW,&act_termios)) { + err_occurred = TRUE; + } + } + return (err_occurred + ? -1 + : 0); +} + +void putDebugChar(char c) __attribute__ ((__weak__)); +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +void putDebugChar +/*-------------------------------------------------------------------------*\ +| Purpose: | +| send one character to serial port | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ +( + char c /* character to print */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| | +\*=========================================================================*/ +{ + /* + * call serdbg polling callout, if available + */ + if (serdbg_conf.callout != NULL) { + serdbg_conf.callout(); + } + /* + * check, whether debug serial port is available + */ + if ((serdbg_tty != NULL) && + (serdbg_tty->device.write != NULL)) { + /* + * send character to debug serial port + */ + serdbg_tty->device.write(serdbg_tty->minor,&c,1); + } +} + +int getDebugChar(void) __attribute__ ((__weak__)); +/*=========================================================================*\ +| Function: | +\*-------------------------------------------------------------------------*/ +int getDebugChar +/*-------------------------------------------------------------------------*\ +| Purpose: | +| wait for one character from serial port | ++---------------------------------------------------------------------------+ +| Input Parameters: | +\*-------------------------------------------------------------------------*/ +( + void /* none */ +) +/*-------------------------------------------------------------------------*\ +| Return Value: | +| received character | +\*=========================================================================*/ +{ + int c = -1; + /* + * check, whether debug serial port is available + */ + if ((serdbg_tty != NULL) && + (serdbg_tty->device.pollRead != NULL)) { + do { + /* + * call serdbg polling callout, if available + */ + if (serdbg_conf.callout != NULL) { + serdbg_conf.callout(); + } + /* + * get character from debug serial port + */ + c = serdbg_tty->device.pollRead(serdbg_tty->minor); + } while (c < 0); + } + return c; +} + -- cgit v1.2.3