2002-06-25 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>

* 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.
This commit is contained in:
Joel Sherrill
2002-06-27 21:25:14 +00:00
parent bbcfe5f2d9
commit 9e633f58da
28 changed files with 2396 additions and 4 deletions

View File

@@ -1,3 +1,15 @@
2002-06-25 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
* 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.
2002-06-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* wrapup/Makefile.am: Don't preinstall libmisc.a.

View File

@@ -5,7 +5,7 @@
ACLOCAL_AMFLAGS = -I ../../../aclocal
SUBDIRS = capture cpuuse devnull dummy dumpbuf monitor mw-fb shell \
rtmonuse stackchk untar wrapup
rtmonuse serdbg stackchk untar wrapup
EXTRA_DIST = README

View File

@@ -38,6 +38,7 @@ dummy/Makefile
dumpbuf/Makefile
monitor/Makefile
rtmonuse/Makefile
serdbg/Makefile
stackchk/Makefile
capture/Makefile
untar/Makefile

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,47 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
include_rtemsdir = $(includedir)/rtems
LIBNAME = libserdbg-tmp
LIB = $(ARCH)/$(LIBNAME).a
C_FILES = serdbg.c serdbgio.c termios_printk.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
noinst_HEADERS =
include_HEADERS = serdbgcnf.h serdbg.h termios_printk_cnf.h \
termios_printk.h
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
$(PROJECT_INCLUDE):
@$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
#
# (OPTIONAL) Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
PREINSTALL_FILES = $(PROJECT_INCLUDE) \
$(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = README serdbg.c serdbgio.c serdbgcnf.h serdbg.h \
termios_printk.c termios_printk.h termios_printk_cnf.h
include $(top_srcdir)/../../../automake/local.am

138
c/src/libmisc/serdbg/README Normal file
View File

@@ -0,0 +1,138 @@
#
# $Id$
#
This directory contains three useful packages related to the termios I/O
system:
PACKAGE SERDBGIO
================
"serdbgio" provides the "serial gdb" standard I/O functions "getDebugChar"
and "putDebugChar" for any device driver supporting polled termios mode.
The initialization function "serdbg_open" opens the v.24 port intended
for the serial debug connection, and sets the desired baud rate. The
"getDebugChar" and "putDebugChar" functions then interact with the
corresponding driver using the calls intended for polled termios
operation.
Specification for the debug device, baud rate and other parameters is
done in a global structure of type "serdbg_conf_t". A configuration
mechanism quite similar to the overall RTEMS configuration is available.
PACKAGE SERDBG
==============
"serdbg" provides a means to optionally initialize and/or start a
serial gdb session as soon as possible, this means as soon as all
drivers have been initialized. The serial debug I/O functions can
either be integrated as special routines of the BSP drivers, or using
the package "serdbgio"
PACKAGE TERMIOS_PRINTK
======================
"termios_printk" provides a standard output function suitable to use
with "printk". It uses the same technique as serdbgio, hooking the
interface between a polled device driver and the termios system.
REQUIREMENTS
============
- These two packages can be used with any polled termios device
driver.
- For standard initialization, they need a modified "bsppost.c"
to perform the initialization calls.
USAGE
=====
For using these packages add the following to your "init" module or
your "system.h" file (Note: most macro settings fall back to a
default, if not set.):
/*
* CONFIGURE_USE_SERDBG
* set this macro, if you want to connect gdb over a serial line
* when set, the debug stub will be connected after driver
* initialization in "bsppost.c"
*/
#define CONFIGURE_USE_SERDBG
/*
* CONFIGURE_SERDBG_SKIP_INIT_BKPT
* set this macro, if you do not want the gdb interface to wait for a
* debugger connection directly after initialization
* If you set this macro, the gdb stub will only hook various
* exception vectors when called from "bsppost.c".
*/
/* #define CONFIGURE_SERDBG_SKIP_INIT_BKPT */
/*
* CONFIGURE_SERDBG_USE_POLLED_TERMIOS
* set this macro, if you want "serdbgio" to provide the I/O
* functions for the serial gdb connection
*/
#define CONFIGURE_SERDBG_USE_POLLED_TERMIOS
/*
* CONFIGURE_SERDBG_DEVNAME
* use this macro to specify the serial device to use
* for "serdbgio".
* Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
*/
#define CONFIGURE_SERDBG_DEVNAME "/dev/tty03"
/*
* CONFIGURE_SERDBG_BAUDRATE
* use this macro to specify the baud rate to use
* for "serdbgio".
* Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
*/
#define CONFIGURE_SERDBG_BAUDRATE 57600
/*
* CONFIGURE_SERDBG_CALLOUT
* use this macro to specify a routine that will called during I/O polling
* Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
* This function of type "void pollfnc(void)" can be used for e.g.
* tickling a watchdog
*/
/* #define CONFIGURE_SERDBG_CALLOUT tickle_my_watchdog_fnc */
#include <serdbgcnf.h>
/*
* CONFIGURE_USE_TERMIOS_PRINTK
* set this macro, if you want printk output to be sent to a serial
* driver using the polled termios interface
* when set, the printk output function will be connected after driver
* initialization in "bsppost.c"
*/
#define CONFIGURE_USE_TERMIOS_PRINTK
/*
* CONFIGURE_TERMIOS_PRINTK_DEVNAME
* use this macro to specify the serial device to use
* for printk output.
* Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
*/
#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
/*
* CONFIGURE_TERMIOS_PRINTK_BAUDRATE
* use this macro to specify the baudrate to use
* for printk output.
* Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
*/
#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
/*
* CONFIGURE_TERMIOS_PRINTK_CALLOUT
* use this macro to specify a routine that will called during I/O polling
* This function of type "void pollfnc(void)" can be used for e.g.
* tickling a watchdog
*/
/* #define CONFIGURE_TERMIOS_PRINTK_CALLOUT tickle_my_watchdog_fnc */
#include <termios_printk_cnf.h>

View File

@@ -0,0 +1,90 @@
/*===============================================================*\
| Project: RTEMS remote gdb over serial line |
+-----------------------------------------------------------------+
| File: serdbg.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file contains intialization and utility functions to add |
| a gdb remote debug stub to an RTEMS system |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 04.04.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <serdbg.h>
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int serdbg_init_dbg
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| initialize remote gdb session over serial line |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
void
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| rtems_status_code |
\*=========================================================================*/
{
static boolean is_initialized = FALSE;
rtems_status_code rc = RTEMS_SUCCESSFUL;
extern void set_debug_traps(void);
extern void breakpoint(void);
if (is_initialized) {
return RTEMS_SUCCESSFUL;
}
is_initialized = TRUE;
/*
* try to open serial device
*/
if (rc == RTEMS_SUCCESSFUL) {
if ((serdbg_conf.open_io != NULL) &&
(0 > serdbg_conf.open_io(serdbg_conf.devname,serdbg_conf.baudrate))) {
fprintf(stderr,
"remote_gdb_init: cannot open device %s "
"for gdb connection:%s\n",serdbg_conf.devname,strerror(errno));
rc = RTEMS_IO_ERROR;
}
}
/*
* initialize gdb stub
*/
if (rc == RTEMS_SUCCESSFUL) {
set_debug_traps();
}
/*
* now activate gdb stub
*/
if ((rc == RTEMS_SUCCESSFUL) &&
!serdbg_conf.skip_init_bkpt) {
breakpoint();
}
/*
* return to original function
* this may be already unter gdb control
*/
return rc;
}

View File

@@ -0,0 +1,174 @@
/*===============================================================*\
| Project: RTEMS remote gdb over serial line |
+-----------------------------------------------------------------+
| File: serdbg.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| a gdb remote debug stub to an RTEMS system |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 04.04.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _SERDBG_H
#define _SERDBG_H
#include <rtems.h>
#include <termios.h>
typedef struct {
unsigned32 baudrate; /* debug baud rate, e.g. 57600 */
void (*callout)(void); /* callout pointer during polling */
int (*open_io)(const char *dev_name,unsigned32 baudrate); /* I/O open fnc */
const char *devname; /* debug device, e.g. "/dev/tty01" */
unsigned8 skip_init_bkpt; /* if TRUE, do not stop when initializing */
} serdbg_conf_t;
/*
* must be defined in init module...
*/
extern serdbg_conf_t serdbg_conf;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void putDebugChar
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| send character to remote debugger |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
char c /* char to send */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int getDebugChar
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| get character from remote debugger |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
void /* <none> */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void serdbg_exceptionHandler
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| hook directly to an exception vector |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
int vecnum, /* vector index to hook at */
void *vector /* address of handler function */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int serdbg_init
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| initialize remote gdb session over serial line |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
void
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| rtems_status_code |
\*=========================================================================*/
/*
* stuff from serdbgio.c
*/
/*=========================================================================*\
| 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 |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void putDebugChar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int getDebugChar
/*-------------------------------------------------------------------------*\
| Purpose: |
| wait for one character from serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
void /* none */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| received character |
\*=========================================================================*/
#endif /* _SERDBG_H */

View File

@@ -0,0 +1,81 @@
/*===============================================================*\
| Project: RTEMS configure remote gdb over serial line |
+-----------------------------------------------------------------+
| File: serdbgcnf.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| a gdb remote debug stub to an RTEMS system |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _SERDBGCNF_H
#define _SERDBGCNF_H
#include "serdbg.h"
#ifdef CONFIGURE_INIT
/*
* fallback for baud rate to use
*/
#ifndef CONFIGURE_SERDBG_BAUDRATE
#define CONFIGURE_SERDBG_BAUDRATE 9600
#endif
/*
* fallback for device name to use
*/
#ifndef CONFIGURE_SERDBG_DEVNAME
#define CONFIGURE_SERDBG_DEVNAME "/dev/tty01"
#endif
/*
* fill in serdbg_conf structure
*/
serdbg_conf_t serdbg_conf = {
CONFIGURE_SERDBG_BAUDRATE,
#ifdef CONFIGURE_SERDBG_CALLOUT
CONFIGURE_SERDBG_CALLOUT,
#else
NULL,
#endif
#ifdef CONFIGURE_SERDBG_USE_POLLED_TERMIOS
serdbg_open,
#else
NULL,
#endif
CONFIGURE_SERDBG_DEVNAME,
#ifdef CONFIGURE_SERDBG_SKIP_INIT_BKPT
TRUE,
#else
FALSE,
#endif
};
int serdbg_init(void) {
#ifdef CONFIGURE_USE_SERDBG
extern int serdbg_init_dbg(void);
return serdbg_init_dbg();
#else
return 0;
#endif
}
#endif /* CONFIGURE_INIT */
#endif /* _SERDBGCNF_H */

View File

@@ -0,0 +1,252 @@
/*===============================================================*\
| File: serdbgio.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| Hebststr. 8, 82178 Puchheim, Germany |
| <Thomas.Doerfler@imd-systems.de> |
| 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 <rtems.h>
#include <rtems/libio_.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <serdbg.h>
/*
* 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: |
| <none> |
\*=========================================================================*/
{
/*
* 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;
}

View File

@@ -0,0 +1,233 @@
/*===============================================================*\
| File: termios_printk.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| Hebststr. 8, 82178 Puchheim, Germany |
| <Thomas.Doerfler@imd-systems.de> |
| 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 printk support |
| this module performs low-level printk output using |
| a polled termios driver |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
|*****************************************************************|
|* $Id$
*
|*****************************************************************|
\*===============================================================*/
#include <rtems.h>
#include <rtems/libio_.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <rtems/bspIo.h>
#include <termios_printk.h>
/*
* internal variables
*/
int termios_printk_fd = -1;
struct rtems_termios_tty *termios_printk_tty;
static void _termios_printk_null_char( char c ) {return;}
BSP_output_char_function_type BSP_output_char = _termios_printk_null_char;
BSP_polling_getchar_function_type BSP_poll_char;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void termios_printk_outputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
{
static const char cr = '\r';
/*
* check, whether printk serial port is available
*/
if ((termios_printk_tty != NULL) &&
(termios_printk_tty->device.write != NULL)) {
/*
* call termios_printk polling callout, if available
*/
if (termios_printk_conf.callout != NULL) {
termios_printk_conf.callout();
}
/*
* send character to debug serial port
*/
if (c == '\n') {
termios_printk_tty->device.write(termios_printk_tty->minor,&cr,1);
}
termios_printk_tty->device.write(termios_printk_tty->minor,&c,1);
}
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
char termios_printk_inputchar
/*-------------------------------------------------------------------------*\
| 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 ((termios_printk_tty != NULL) &&
(termios_printk_tty->device.pollRead != NULL)) {
do {
/*
* call termios_printk polling callout, if available
*/
if (termios_printk_conf.callout != NULL) {
termios_printk_conf.callout();
}
/*
* get character from debug serial port
*/
c = termios_printk_tty->device.pollRead(termios_printk_tty->minor);
} while (c < 0);
}
return c;
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int termios_printk_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;
if (termios_printk_fd >= 0) {
/*
* already initialized
*/
return 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
*/
if (!err_occurred &&
(dev_name != NULL) &&
(dev_name[0] != '\0')) {
termios_printk_fd = open(dev_name,O_RDWR);
if (termios_printk_fd < 0) {
err_occurred = TRUE;
}
}
/*
* capture tty structure
*/
if (!err_occurred) {
iop = &rtems_libio_iops[termios_printk_fd];
termios_printk_tty = iop->data1;
}
/*
* set device baudrate
* (and transp mode, this is not really needed)
* ...
*/
/*
* ... get fd settings
*/
if (!err_occurred &&
(0 != tcgetattr(termios_printk_fd,&act_termios))) {
err_occurred = TRUE;
}
if (!err_occurred) {
cfsetospeed(&act_termios,baudcode);
cfsetispeed(&act_termios,baudcode);
if (0 != tcsetattr(termios_printk_fd,TCSANOW,&act_termios)) {
err_occurred = TRUE;
}
}
if (!err_occurred) {
BSP_output_char = termios_printk_outputchar;
BSP_poll_char = termios_printk_inputchar;
}
return (err_occurred
? -1
: 0);
}

View File

@@ -0,0 +1,95 @@
/*===============================================================*\
| Project: RTEMS remote gdb over serial line |
+-----------------------------------------------------------------+
| File: termios_printk.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| printk polled output via termios polled drivers |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.04.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _TERMIOS_PRINTK_H
#define _TERMIOS_PRINTK_H
#include <rtems.h>
#include <termios.h>
typedef struct {
unsigned32 baudrate; /* debug baud rate, e.g. 57600 */
void (*callout)(void); /* callout pointer during polling */
const char *devname; /* debug device, e.g. "/dev/tty01" */
} termios_printk_conf_t;
/*
* must be defined in init module...
*/
extern termios_printk_conf_t termios_printk_conf;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void termios_printk_outputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
char termios_printk_inputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| wait for one character from serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
void /* none */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| received character |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int termios_printk_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 |
\*=========================================================================*/
#endif /* _TERMIOS_PRINTK_H */

View File

@@ -0,0 +1,70 @@
/*===============================================================*\
| Project: RTEMS configure remote gdb over serial line |
+-----------------------------------------------------------------+
| File: termios_printk_cnf.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| printk support via polled termios |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _TERMIOS_PRINTK_CNF_H
#define _TERMIOS_PRINTK_CNF_H
#include "termios_printk.h"
#ifdef CONFIGURE_INIT
/*
* fallback for baud rate to use
*/
#ifndef CONFIGURE_TERMIOS_PRINTK_BAUDRATE
#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
#endif
/*
* fallback for device name to use
*/
#ifndef CONFIGURE_TERMIOS_PRINTK_DEVNAME
#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
#endif
#ifdef CONFIGURE_USE_TERMIOS_PRINTK
/*
* fill in termios_printk_conf structure
*/
termios_printk_conf_t termios_printk_conf = {
CONFIGURE_TERMIOS_PRINTK_BAUDRATE,
#ifdef CONFIGURE_TERMIOS_PRINTK_CALLOUT
CONFIGURE_TERMIOS_PRINTK_CALLOUT,
#else
NULL,
#endif
CONFIGURE_TERMIOS_PRINTK_DEVNAME,
};
#endif
int termios_printk_init(void) {
#ifdef CONFIGURE_USE_TERMIOS_PRINTK
return termios_printk_open(termios_printk_conf.devname,
termios_printk_conf.baudrate);
#else
return 0;
#endif
}
#endif /* CONFIGURE_INIT */
#endif /* _TERMIOS_PRINTK_CNF_H */

View File

@@ -15,7 +15,8 @@ TMP_LIBS = ../monitor/$(ARCH)/libmonitor-tmp.a \
../cpuuse/$(ARCH)/libcpuuse-tmp.a ../rtmonuse/$(ARCH)/librtmonuse-tmp.a \
../shell/$(ARCH)/libshell-tmp.a ../dumpbuf/$(ARCH)/libdumpbuf-tmp.a \
../devnull/$(ARCH)/libdevnull-tmp.a ../dummy/$(ARCH)/libdummy-tmp.a \
../mw-fb/$(ARCH)/libmw-fb-tmp.a ../capture/$(ARCH)/libcapture-tmp.a
../mw-fb/$(ARCH)/libmw-fb-tmp.a ../capture/$(ARCH)/libcapture-tmp.a \
../serdbg/$(ARCH)/libserdbg-tmp.a
#
# (OPTIONAL) Add local stuff here using +=

View File

@@ -1,3 +1,15 @@
2002-06-25 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
* 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.
2002-06-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* wrapup/Makefile.am: Don't preinstall libmisc.a.

View File

@@ -5,7 +5,7 @@
ACLOCAL_AMFLAGS = -I ../../../aclocal
SUBDIRS = capture cpuuse devnull dummy dumpbuf monitor mw-fb shell \
rtmonuse stackchk untar wrapup
rtmonuse serdbg stackchk untar wrapup
EXTRA_DIST = README

View File

@@ -38,6 +38,7 @@ dummy/Makefile
dumpbuf/Makefile
monitor/Makefile
rtmonuse/Makefile
serdbg/Makefile
stackchk/Makefile
capture/Makefile
untar/Makefile

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,47 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
include_rtemsdir = $(includedir)/rtems
LIBNAME = libserdbg-tmp
LIB = $(ARCH)/$(LIBNAME).a
C_FILES = serdbg.c serdbgio.c termios_printk.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
noinst_HEADERS =
include_HEADERS = serdbgcnf.h serdbg.h termios_printk_cnf.h \
termios_printk.h
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
$(PROJECT_INCLUDE):
@$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
#
# (OPTIONAL) Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
PREINSTALL_FILES = $(PROJECT_INCLUDE) \
$(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = README serdbg.c serdbgio.c serdbgcnf.h serdbg.h \
termios_printk.c termios_printk.h termios_printk_cnf.h
include $(top_srcdir)/../../../automake/local.am

View File

@@ -0,0 +1,138 @@
#
# $Id$
#
This directory contains three useful packages related to the termios I/O
system:
PACKAGE SERDBGIO
================
"serdbgio" provides the "serial gdb" standard I/O functions "getDebugChar"
and "putDebugChar" for any device driver supporting polled termios mode.
The initialization function "serdbg_open" opens the v.24 port intended
for the serial debug connection, and sets the desired baud rate. The
"getDebugChar" and "putDebugChar" functions then interact with the
corresponding driver using the calls intended for polled termios
operation.
Specification for the debug device, baud rate and other parameters is
done in a global structure of type "serdbg_conf_t". A configuration
mechanism quite similar to the overall RTEMS configuration is available.
PACKAGE SERDBG
==============
"serdbg" provides a means to optionally initialize and/or start a
serial gdb session as soon as possible, this means as soon as all
drivers have been initialized. The serial debug I/O functions can
either be integrated as special routines of the BSP drivers, or using
the package "serdbgio"
PACKAGE TERMIOS_PRINTK
======================
"termios_printk" provides a standard output function suitable to use
with "printk". It uses the same technique as serdbgio, hooking the
interface between a polled device driver and the termios system.
REQUIREMENTS
============
- These two packages can be used with any polled termios device
driver.
- For standard initialization, they need a modified "bsppost.c"
to perform the initialization calls.
USAGE
=====
For using these packages add the following to your "init" module or
your "system.h" file (Note: most macro settings fall back to a
default, if not set.):
/*
* CONFIGURE_USE_SERDBG
* set this macro, if you want to connect gdb over a serial line
* when set, the debug stub will be connected after driver
* initialization in "bsppost.c"
*/
#define CONFIGURE_USE_SERDBG
/*
* CONFIGURE_SERDBG_SKIP_INIT_BKPT
* set this macro, if you do not want the gdb interface to wait for a
* debugger connection directly after initialization
* If you set this macro, the gdb stub will only hook various
* exception vectors when called from "bsppost.c".
*/
/* #define CONFIGURE_SERDBG_SKIP_INIT_BKPT */
/*
* CONFIGURE_SERDBG_USE_POLLED_TERMIOS
* set this macro, if you want "serdbgio" to provide the I/O
* functions for the serial gdb connection
*/
#define CONFIGURE_SERDBG_USE_POLLED_TERMIOS
/*
* CONFIGURE_SERDBG_DEVNAME
* use this macro to specify the serial device to use
* for "serdbgio".
* Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
*/
#define CONFIGURE_SERDBG_DEVNAME "/dev/tty03"
/*
* CONFIGURE_SERDBG_BAUDRATE
* use this macro to specify the baud rate to use
* for "serdbgio".
* Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
*/
#define CONFIGURE_SERDBG_BAUDRATE 57600
/*
* CONFIGURE_SERDBG_CALLOUT
* use this macro to specify a routine that will called during I/O polling
* Only used, when CONFIGURE_SERDBG_USE_POLLED_TERMIOS is set
* This function of type "void pollfnc(void)" can be used for e.g.
* tickling a watchdog
*/
/* #define CONFIGURE_SERDBG_CALLOUT tickle_my_watchdog_fnc */
#include <serdbgcnf.h>
/*
* CONFIGURE_USE_TERMIOS_PRINTK
* set this macro, if you want printk output to be sent to a serial
* driver using the polled termios interface
* when set, the printk output function will be connected after driver
* initialization in "bsppost.c"
*/
#define CONFIGURE_USE_TERMIOS_PRINTK
/*
* CONFIGURE_TERMIOS_PRINTK_DEVNAME
* use this macro to specify the serial device to use
* for printk output.
* Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
*/
#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
/*
* CONFIGURE_TERMIOS_PRINTK_BAUDRATE
* use this macro to specify the baudrate to use
* for printk output.
* Only used, when CONFIGURE_USE_TERMIOS_PRINTK is set
*/
#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
/*
* CONFIGURE_TERMIOS_PRINTK_CALLOUT
* use this macro to specify a routine that will called during I/O polling
* This function of type "void pollfnc(void)" can be used for e.g.
* tickling a watchdog
*/
/* #define CONFIGURE_TERMIOS_PRINTK_CALLOUT tickle_my_watchdog_fnc */
#include <termios_printk_cnf.h>

View File

@@ -0,0 +1,90 @@
/*===============================================================*\
| Project: RTEMS remote gdb over serial line |
+-----------------------------------------------------------------+
| File: serdbg.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file contains intialization and utility functions to add |
| a gdb remote debug stub to an RTEMS system |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 04.04.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <serdbg.h>
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int serdbg_init_dbg
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| initialize remote gdb session over serial line |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
void
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| rtems_status_code |
\*=========================================================================*/
{
static boolean is_initialized = FALSE;
rtems_status_code rc = RTEMS_SUCCESSFUL;
extern void set_debug_traps(void);
extern void breakpoint(void);
if (is_initialized) {
return RTEMS_SUCCESSFUL;
}
is_initialized = TRUE;
/*
* try to open serial device
*/
if (rc == RTEMS_SUCCESSFUL) {
if ((serdbg_conf.open_io != NULL) &&
(0 > serdbg_conf.open_io(serdbg_conf.devname,serdbg_conf.baudrate))) {
fprintf(stderr,
"remote_gdb_init: cannot open device %s "
"for gdb connection:%s\n",serdbg_conf.devname,strerror(errno));
rc = RTEMS_IO_ERROR;
}
}
/*
* initialize gdb stub
*/
if (rc == RTEMS_SUCCESSFUL) {
set_debug_traps();
}
/*
* now activate gdb stub
*/
if ((rc == RTEMS_SUCCESSFUL) &&
!serdbg_conf.skip_init_bkpt) {
breakpoint();
}
/*
* return to original function
* this may be already unter gdb control
*/
return rc;
}

View File

@@ -0,0 +1,174 @@
/*===============================================================*\
| Project: RTEMS remote gdb over serial line |
+-----------------------------------------------------------------+
| File: serdbg.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| a gdb remote debug stub to an RTEMS system |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 04.04.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _SERDBG_H
#define _SERDBG_H
#include <rtems.h>
#include <termios.h>
typedef struct {
unsigned32 baudrate; /* debug baud rate, e.g. 57600 */
void (*callout)(void); /* callout pointer during polling */
int (*open_io)(const char *dev_name,unsigned32 baudrate); /* I/O open fnc */
const char *devname; /* debug device, e.g. "/dev/tty01" */
unsigned8 skip_init_bkpt; /* if TRUE, do not stop when initializing */
} serdbg_conf_t;
/*
* must be defined in init module...
*/
extern serdbg_conf_t serdbg_conf;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void putDebugChar
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| send character to remote debugger |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
char c /* char to send */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int getDebugChar
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| get character from remote debugger |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
void /* <none> */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void serdbg_exceptionHandler
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| hook directly to an exception vector |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
int vecnum, /* vector index to hook at */
void *vector /* address of handler function */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int serdbg_init
(
/*-------------------------------------------------------------------------*\
| Purpose: |
| initialize remote gdb session over serial line |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
void
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| rtems_status_code |
\*=========================================================================*/
/*
* stuff from serdbgio.c
*/
/*=========================================================================*\
| 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 |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void putDebugChar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int getDebugChar
/*-------------------------------------------------------------------------*\
| Purpose: |
| wait for one character from serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
void /* none */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| received character |
\*=========================================================================*/
#endif /* _SERDBG_H */

View File

@@ -0,0 +1,81 @@
/*===============================================================*\
| Project: RTEMS configure remote gdb over serial line |
+-----------------------------------------------------------------+
| File: serdbgcnf.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| a gdb remote debug stub to an RTEMS system |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _SERDBGCNF_H
#define _SERDBGCNF_H
#include "serdbg.h"
#ifdef CONFIGURE_INIT
/*
* fallback for baud rate to use
*/
#ifndef CONFIGURE_SERDBG_BAUDRATE
#define CONFIGURE_SERDBG_BAUDRATE 9600
#endif
/*
* fallback for device name to use
*/
#ifndef CONFIGURE_SERDBG_DEVNAME
#define CONFIGURE_SERDBG_DEVNAME "/dev/tty01"
#endif
/*
* fill in serdbg_conf structure
*/
serdbg_conf_t serdbg_conf = {
CONFIGURE_SERDBG_BAUDRATE,
#ifdef CONFIGURE_SERDBG_CALLOUT
CONFIGURE_SERDBG_CALLOUT,
#else
NULL,
#endif
#ifdef CONFIGURE_SERDBG_USE_POLLED_TERMIOS
serdbg_open,
#else
NULL,
#endif
CONFIGURE_SERDBG_DEVNAME,
#ifdef CONFIGURE_SERDBG_SKIP_INIT_BKPT
TRUE,
#else
FALSE,
#endif
};
int serdbg_init(void) {
#ifdef CONFIGURE_USE_SERDBG
extern int serdbg_init_dbg(void);
return serdbg_init_dbg();
#else
return 0;
#endif
}
#endif /* CONFIGURE_INIT */
#endif /* _SERDBGCNF_H */

View File

@@ -0,0 +1,252 @@
/*===============================================================*\
| File: serdbgio.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| Hebststr. 8, 82178 Puchheim, Germany |
| <Thomas.Doerfler@imd-systems.de> |
| 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 <rtems.h>
#include <rtems/libio_.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <serdbg.h>
/*
* 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: |
| <none> |
\*=========================================================================*/
{
/*
* 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;
}

View File

@@ -0,0 +1,233 @@
/*===============================================================*\
| File: termios_printk.c |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| Hebststr. 8, 82178 Puchheim, Germany |
| <Thomas.Doerfler@imd-systems.de> |
| 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 printk support |
| this module performs low-level printk output using |
| a polled termios driver |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
|*****************************************************************|
|* $Id$
*
|*****************************************************************|
\*===============================================================*/
#include <rtems.h>
#include <rtems/libio_.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <rtems/termiostypes.h>
#include <rtems/bspIo.h>
#include <termios_printk.h>
/*
* internal variables
*/
int termios_printk_fd = -1;
struct rtems_termios_tty *termios_printk_tty;
static void _termios_printk_null_char( char c ) {return;}
BSP_output_char_function_type BSP_output_char = _termios_printk_null_char;
BSP_polling_getchar_function_type BSP_poll_char;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void termios_printk_outputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
)
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
{
static const char cr = '\r';
/*
* check, whether printk serial port is available
*/
if ((termios_printk_tty != NULL) &&
(termios_printk_tty->device.write != NULL)) {
/*
* call termios_printk polling callout, if available
*/
if (termios_printk_conf.callout != NULL) {
termios_printk_conf.callout();
}
/*
* send character to debug serial port
*/
if (c == '\n') {
termios_printk_tty->device.write(termios_printk_tty->minor,&cr,1);
}
termios_printk_tty->device.write(termios_printk_tty->minor,&c,1);
}
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
char termios_printk_inputchar
/*-------------------------------------------------------------------------*\
| 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 ((termios_printk_tty != NULL) &&
(termios_printk_tty->device.pollRead != NULL)) {
do {
/*
* call termios_printk polling callout, if available
*/
if (termios_printk_conf.callout != NULL) {
termios_printk_conf.callout();
}
/*
* get character from debug serial port
*/
c = termios_printk_tty->device.pollRead(termios_printk_tty->minor);
} while (c < 0);
}
return c;
}
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int termios_printk_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;
if (termios_printk_fd >= 0) {
/*
* already initialized
*/
return 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
*/
if (!err_occurred &&
(dev_name != NULL) &&
(dev_name[0] != '\0')) {
termios_printk_fd = open(dev_name,O_RDWR);
if (termios_printk_fd < 0) {
err_occurred = TRUE;
}
}
/*
* capture tty structure
*/
if (!err_occurred) {
iop = &rtems_libio_iops[termios_printk_fd];
termios_printk_tty = iop->data1;
}
/*
* set device baudrate
* (and transp mode, this is not really needed)
* ...
*/
/*
* ... get fd settings
*/
if (!err_occurred &&
(0 != tcgetattr(termios_printk_fd,&act_termios))) {
err_occurred = TRUE;
}
if (!err_occurred) {
cfsetospeed(&act_termios,baudcode);
cfsetispeed(&act_termios,baudcode);
if (0 != tcsetattr(termios_printk_fd,TCSANOW,&act_termios)) {
err_occurred = TRUE;
}
}
if (!err_occurred) {
BSP_output_char = termios_printk_outputchar;
BSP_poll_char = termios_printk_inputchar;
}
return (err_occurred
? -1
: 0);
}

View File

@@ -0,0 +1,95 @@
/*===============================================================*\
| Project: RTEMS remote gdb over serial line |
+-----------------------------------------------------------------+
| File: termios_printk.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| printk polled output via termios polled drivers |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.04.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _TERMIOS_PRINTK_H
#define _TERMIOS_PRINTK_H
#include <rtems.h>
#include <termios.h>
typedef struct {
unsigned32 baudrate; /* debug baud rate, e.g. 57600 */
void (*callout)(void); /* callout pointer during polling */
const char *devname; /* debug device, e.g. "/dev/tty01" */
} termios_printk_conf_t;
/*
* must be defined in init module...
*/
extern termios_printk_conf_t termios_printk_conf;
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
void termios_printk_outputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| send one character to serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
char c /* character to print */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| <none> |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
char termios_printk_inputchar
/*-------------------------------------------------------------------------*\
| Purpose: |
| wait for one character from serial port |
+---------------------------------------------------------------------------+
| Input Parameters: |
\*-------------------------------------------------------------------------*/
(
void /* none */
);
/*-------------------------------------------------------------------------*\
| Return Value: |
| received character |
\*=========================================================================*/
/*=========================================================================*\
| Function: |
\*-------------------------------------------------------------------------*/
int termios_printk_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 |
\*=========================================================================*/
#endif /* _TERMIOS_PRINTK_H */

View File

@@ -0,0 +1,70 @@
/*===============================================================*\
| Project: RTEMS configure remote gdb over serial line |
+-----------------------------------------------------------------+
| File: termios_printk_cnf.h |
+-----------------------------------------------------------------+
| Copyright (c) 2002 IMD |
| Ingenieurbuero fuer Microcomputertechnik Th. Doerfler |
| <Thomas.Doerfler@imd-systems.de> |
| all rights reserved |
+-----------------------------------------------------------------+
| this file declares intialization functions to add |
| printk support via polled termios |
| |
+-----------------------------------------------------------------+
| date history ID |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 13.05.02 creation doe |
\*===============================================================*/
/*
* $Id$
*/
#ifndef _TERMIOS_PRINTK_CNF_H
#define _TERMIOS_PRINTK_CNF_H
#include "termios_printk.h"
#ifdef CONFIGURE_INIT
/*
* fallback for baud rate to use
*/
#ifndef CONFIGURE_TERMIOS_PRINTK_BAUDRATE
#define CONFIGURE_TERMIOS_PRINTK_BAUDRATE 9600
#endif
/*
* fallback for device name to use
*/
#ifndef CONFIGURE_TERMIOS_PRINTK_DEVNAME
#define CONFIGURE_TERMIOS_PRINTK_DEVNAME "/dev/console"
#endif
#ifdef CONFIGURE_USE_TERMIOS_PRINTK
/*
* fill in termios_printk_conf structure
*/
termios_printk_conf_t termios_printk_conf = {
CONFIGURE_TERMIOS_PRINTK_BAUDRATE,
#ifdef CONFIGURE_TERMIOS_PRINTK_CALLOUT
CONFIGURE_TERMIOS_PRINTK_CALLOUT,
#else
NULL,
#endif
CONFIGURE_TERMIOS_PRINTK_DEVNAME,
};
#endif
int termios_printk_init(void) {
#ifdef CONFIGURE_USE_TERMIOS_PRINTK
return termios_printk_open(termios_printk_conf.devname,
termios_printk_conf.baudrate);
#else
return 0;
#endif
}
#endif /* CONFIGURE_INIT */
#endif /* _TERMIOS_PRINTK_CNF_H */

View File

@@ -15,7 +15,8 @@ TMP_LIBS = ../monitor/$(ARCH)/libmonitor-tmp.a \
../cpuuse/$(ARCH)/libcpuuse-tmp.a ../rtmonuse/$(ARCH)/librtmonuse-tmp.a \
../shell/$(ARCH)/libshell-tmp.a ../dumpbuf/$(ARCH)/libdumpbuf-tmp.a \
../devnull/$(ARCH)/libdevnull-tmp.a ../dummy/$(ARCH)/libdummy-tmp.a \
../mw-fb/$(ARCH)/libmw-fb-tmp.a ../capture/$(ARCH)/libcapture-tmp.a
../mw-fb/$(ARCH)/libmw-fb-tmp.a ../capture/$(ARCH)/libcapture-tmp.a \
../serdbg/$(ARCH)/libserdbg-tmp.a
#
# (OPTIONAL) Add local stuff here using +=