forked from Imagelibrary/rtems
2002-12-12 Ralf Corsepius <corsepius@faw.uni-ulm.de>
* .cvsignore: Moved to rtems/cpukit/libmisc. * ChangeLog: Moved to rtems/cpukit/libmisc. * Makefile.am: Moved to rtems/cpukit/libmisc. * README: Moved to rtems/cpukit/libmisc. * configure.ac: Moved to rtems/cpukit/libmisc. * capture/Makefile.am: Moved to rtems/cpukit/libmisc. * capture/README: Moved to rtems/cpukit/libmisc. * capture/capture-cli.c: Moved to rtems/cpukit/libmisc. * capture/capture-cli.h: Moved to rtems/cpukit/libmisc. * capture/capture.c: Moved to rtems/cpukit/libmisc. * capture/capture.h: Moved to rtems/cpukit/libmisc. * cpuuse/Makefile.am: Moved to rtems/cpukit/libmisc. * cpuuse/README: Moved to rtems/cpukit/libmisc. * cpuuse/cpuuse.c: Moved to rtems/cpukit/libmisc. * cpuuse/cpuuse.h: Moved to rtems/cpukit/libmisc. * devnull/.cvsignore: Moved to rtems/cpukit/libmisc. * devnull/Makefile.am: Moved to rtems/cpukit/libmisc. * devnull/devnull.c: Moved to rtems/cpukit/libmisc. * devnull/devnull.h: Moved to rtems/cpukit/libmisc. * dummy/.cvsignore: Moved to rtems/cpukit/libmisc. * dummy/Makefile.am: Moved to rtems/cpukit/libmisc. * dummy/README: Moved to rtems/cpukit/libmisc. * dummy/dummy.c: Moved to rtems/cpukit/libmisc. * dumpbuf/.cvsignore: Moved to rtems/cpukit/libmisc. * dumpbuf/Makefile.am: Moved to rtems/cpukit/libmisc. * dumpbuf/dumpbuf.c: Moved to rtems/cpukit/libmisc. * dumpbuf/dumpbuf.h: Moved to rtems/cpukit/libmisc. * monitor/.cvsignore: Moved to rtems/cpukit/libmisc. * monitor/Makefile.am: Moved to rtems/cpukit/libmisc. * monitor/README: Moved to rtems/cpukit/libmisc. * monitor/mon-command.c: Moved to rtems/cpukit/libmisc. * monitor/mon-config.c: Moved to rtems/cpukit/libmisc. * monitor/mon-dname.c: Moved to rtems/cpukit/libmisc. * monitor/mon-driver.c: Moved to rtems/cpukit/libmisc. * monitor/mon-extension.c: Moved to rtems/cpukit/libmisc. * monitor/mon-itask.c: Moved to rtems/cpukit/libmisc. * monitor/mon-manager.c: Moved to rtems/cpukit/libmisc. * monitor/mon-monitor.c: Moved to rtems/cpukit/libmisc. * monitor/mon-mpci.c: Moved to rtems/cpukit/libmisc. * monitor/mon-object.c: Moved to rtems/cpukit/libmisc. * monitor/mon-prmisc.c: Moved to rtems/cpukit/libmisc. * monitor/mon-queue.c: Moved to rtems/cpukit/libmisc. * monitor/mon-server.c: Moved to rtems/cpukit/libmisc. * monitor/mon-symbols.c: Moved to rtems/cpukit/libmisc. * monitor/mon-task.c: Moved to rtems/cpukit/libmisc. * monitor/monitor.h: Moved to rtems/cpukit/libmisc. * monitor/symbols.h: Moved to rtems/cpukit/libmisc. * mw-fb/.cvsignore: Moved to rtems/cpukit/libmisc. * mw-fb/Makefile.am: Moved to rtems/cpukit/libmisc. * mw-fb/mw_fb.c: Moved to rtems/cpukit/libmisc. * mw-fb/mw_fb.h: Moved to rtems/cpukit/libmisc. * mw-fb/mw_uid.c: Moved to rtems/cpukit/libmisc. * mw-fb/mw_uid.h: Moved to rtems/cpukit/libmisc. * rtmonuse/.cvsignore: Moved to rtems/cpukit/libmisc. * rtmonuse/Makefile.am: Moved to rtems/cpukit/libmisc. * rtmonuse/rtmonuse.c: Moved to rtems/cpukit/libmisc. * rtmonuse/rtmonuse.h: Moved to rtems/cpukit/libmisc. * serdbg/.cvsignore: Moved to rtems/cpukit/libmisc. * serdbg/Makefile.am: Moved to rtems/cpukit/libmisc. * serdbg/README: Moved to rtems/cpukit/libmisc. * serdbg/serdbg.c: Moved to rtems/cpukit/libmisc. * serdbg/serdbg.h: Moved to rtems/cpukit/libmisc. * serdbg/serdbgcnf.h: Moved to rtems/cpukit/libmisc. * serdbg/serdbgio.c: Moved to rtems/cpukit/libmisc. * serdbg/termios_printk.c: Moved to rtems/cpukit/libmisc. * serdbg/termios_printk.h: Moved to rtems/cpukit/libmisc. * serdbg/termios_printk_cnf.h: Moved to rtems/cpukit/libmisc. * shell/.cvsignore: Moved to rtems/cpukit/libmisc. * shell/Makefile.am: Moved to rtems/cpukit/libmisc. * shell/README: Moved to rtems/cpukit/libmisc. * shell/cmds.c: Moved to rtems/cpukit/libmisc. * shell/shell.c: Moved to rtems/cpukit/libmisc. * shell/shell.h: Moved to rtems/cpukit/libmisc. * stackchk/.cvsignore: Moved to rtems/cpukit/libmisc. * stackchk/Makefile.am: Moved to rtems/cpukit/libmisc. * stackchk/README: Moved to rtems/cpukit/libmisc. * stackchk/check.c: Moved to rtems/cpukit/libmisc. * stackchk/internal.h: Moved to rtems/cpukit/libmisc. * stackchk/stackchk.h: Moved to rtems/cpukit/libmisc. * untar/.cvsignore: Moved to rtems/cpukit/libmisc. * untar/Makefile.am: Moved to rtems/cpukit/libmisc. * untar/README: Moved to rtems/cpukit/libmisc. * untar/untar.c: Moved to rtems/cpukit/libmisc. * untar/untar.h: Moved to rtems/cpukit/libmisc. * wrapup/.cvsignore: Moved to rtems/cpukit/libmisc. * wrapup/Makefile.am: Moved to rtems/cpukit/libmisc.
This commit is contained in:
@@ -1,535 +0,0 @@
|
|||||||
2002-12-12 Ralf Corsepius <corsepius@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* .cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* ChangeLog: Moved to rtems/cpukit/libmisc.
|
|
||||||
* Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* configure.ac: Moved to rtems/cpukit/libmisc.
|
|
||||||
* capture/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* capture/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* capture/capture-cli.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* capture/capture-cli.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* capture/capture.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* capture/capture.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* cpuuse/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* cpuuse/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* cpuuse/cpuuse.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* cpuuse/cpuuse.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* devnull/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* devnull/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* devnull/devnull.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* devnull/devnull.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dummy/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dummy/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dummy/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dummy/dummy.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dumpbuf/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dumpbuf/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dumpbuf/dumpbuf.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* dumpbuf/dumpbuf.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-command.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-config.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-dname.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-driver.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-extension.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-itask.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-manager.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-monitor.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-mpci.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-object.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-prmisc.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-queue.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-server.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-symbols.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/mon-task.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/monitor.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* monitor/symbols.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* mw-fb/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* mw-fb/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* mw-fb/mw_fb.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* mw-fb/mw_fb.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* mw-fb/mw_uid.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* mw-fb/mw_uid.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* rtmonuse/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* rtmonuse/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* rtmonuse/rtmonuse.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* rtmonuse/rtmonuse.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/serdbg.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/serdbg.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/serdbgcnf.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/serdbgio.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/termios_printk.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/termios_printk.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* serdbg/termios_printk_cnf.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* shell/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* shell/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* shell/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* shell/cmds.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* shell/shell.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* shell/shell.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* stackchk/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* stackchk/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* stackchk/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* stackchk/check.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* stackchk/internal.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* stackchk/stackchk.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* untar/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* untar/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
* untar/README: Moved to rtems/cpukit/libmisc.
|
|
||||||
* untar/untar.c: Moved to rtems/cpukit/libmisc.
|
|
||||||
* untar/untar.h: Moved to rtems/cpukit/libmisc.
|
|
||||||
* wrapup/.cvsignore: Moved to rtems/cpukit/libmisc.
|
|
||||||
* wrapup/Makefile.am: Moved to rtems/cpukit/libmisc.
|
|
||||||
|
|
||||||
2002-12-10 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP.
|
|
||||||
|
|
||||||
2002-12-10 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* capture/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* cpuuse/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* devnull/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* dummy/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* dumpbuf/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* monitor/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* mw-fb/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* rtmonuse/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* serdbg/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* shell/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* stackchk/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* untar/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
* wrapup/Makefile.am: Don't include @RTEMS_BSP@.cfg.
|
|
||||||
|
|
||||||
2002-12-02 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* stackchk/check.c: Better handling of task name.
|
|
||||||
|
|
||||||
2002-11-15 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* monitor/mon-commands.c: Removed warnings for RTEMS_UNIX.
|
|
||||||
|
|
||||||
2002-11-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* capture/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* serdbg/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* serdbg/serdbgio.c: Add #include <unistd.h>.
|
|
||||||
* shell/Makefile.am: Add RTEMS_LIBSHELL conditional.
|
|
||||||
* wrapup/Makefile.am: Add RTEMS_LIBSHELL conditional.
|
|
||||||
* configure.ac: Check for stdio assignments.
|
|
||||||
Add RTEMS_LIBSHELL conditional.
|
|
||||||
|
|
||||||
2002-11-01 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* stackchk/check.c: Removed warnings.
|
|
||||||
|
|
||||||
2002-10-31 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* stackchk/check.c: Removed warning.
|
|
||||||
|
|
||||||
2002-10-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* monitor/mon-command.c: Don't build rtems_monitor_line_editor for
|
|
||||||
RTEMS_UNIX to avoid gcc warning.
|
|
||||||
|
|
||||||
2002-10-24 Fabrizio Pirovano <pirovano.thysys@tiscalinet.it>
|
|
||||||
|
|
||||||
* capture/capture.c, monitor/mon-manager.c, stackchk/check.c:
|
|
||||||
Patch to remove problems introduced by object name rework.
|
|
||||||
|
|
||||||
2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* .cvsignore: Reformat.
|
|
||||||
Add autom4te*cache.
|
|
||||||
Remove autom4te.cache.
|
|
||||||
|
|
||||||
2002-08-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* shell/shell.c: #include <time.h>
|
|
||||||
* wrapup/Makefile.am: Eliminate LIBNAME.
|
|
||||||
|
|
||||||
2002-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* capture/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* cpuuse/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* devnull/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* dummy/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* dumpbuf/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* monitor/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* mw-fb/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* rtmonuse/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* serdbg/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* shell/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* stackchk/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
* untar/Makefile.am: Use .$(OBJEXT) instead of .o.
|
|
||||||
|
|
||||||
2002-08-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* shell/Makefile.am: Remove shell.h from EXTRA_DIST.
|
|
||||||
|
|
||||||
2002-08-01 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* cpuuse/cpuuse.c (CPU_usage_Dump) : Corrected so it honors when an
|
|
||||||
object name is raw versus being a string.
|
|
||||||
|
|
||||||
2002-07-30 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* stackchk/check.c: Don't reference the RTEMS allocated interrupt
|
|
||||||
stack if the port doesn't configure using it.
|
|
||||||
|
|
||||||
2002-07-24 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* wrapup/Makefile.am: Temporarily don't include serdbg since it
|
|
||||||
causes some BSPs to not link "main(){}" as required by autoconf.
|
|
||||||
|
|
||||||
2002-07-20 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* capture/capture.c: include <string.h> for memset.
|
|
||||||
* capture/capture-cli.c: include <string.h> for memset.
|
|
||||||
|
|
||||||
2002-07-01 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* capture/capture-cli.c, cpuuse/cpuuse.c, monitor/mon-monitor.c,
|
|
||||||
monitor/mon-object.c, monitor/monitor.h: Corrected use of
|
|
||||||
_Objects_Information_table now that it is a two dimensional
|
|
||||||
array based upon API and class. In addition, in the monitor,
|
|
||||||
corrected an error which occured when a target has 64 bit pointers.
|
|
||||||
|
|
||||||
2002-07-01 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* stackchk/check.c: Corrected use of
|
|
||||||
_Objects_Information_table now that it is a two dimensional
|
|
||||||
array based upon API and class.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
2002-05-24 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* configure.ac, Makefile.am: Remove references to rootfs.
|
|
||||||
|
|
||||||
2002-05-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* rootfs/.cvsignore: Remove.
|
|
||||||
* rootfs/Makefile.am: Remove.
|
|
||||||
* rootfs/mkrootfs.h: Remove.
|
|
||||||
* rootfs/mkrootfs.c: Remove.
|
|
||||||
* configure.ac: Remove rootfs and NETWORKING macros.
|
|
||||||
* wrapup/Makefile.am: Remove rootfs and HAS_NETWORKING.
|
|
||||||
|
|
||||||
2002-05-16 Chris Johns <ccj@acm.org>
|
|
||||||
|
|
||||||
* Per PR194, added the Capture engine.
|
|
||||||
* capture/Makefile.am, capture/README, capture/capture-cli.c,
|
|
||||||
capture/capture-cli.h, capture/capture.c, capture/capture.h,
|
|
||||||
capture/.cvsignore: New files.
|
|
||||||
* Makefile.am, configure.ac, wrapup/Makefile.am: Modified to
|
|
||||||
reflect addition.
|
|
||||||
|
|
||||||
2001-05-14 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* dummy/Makefile.am, wrapup/Makefile.am: Fixed to generate
|
|
||||||
a library of the same name.
|
|
||||||
|
|
||||||
2002-03-20 Chris Johns <ccj@acm.org>
|
|
||||||
|
|
||||||
* monitor/mon-command.c: Per PR192 the RTEMS monitor makes everything
|
|
||||||
lowercase. The capture engine need to set triggers or watches on task
|
|
||||||
with uppercase names.
|
|
||||||
Also stop the monitor repeating command when enter is pressed.
|
|
||||||
|
|
||||||
2002-04-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* monitor/mon-monitor.c: Replace done with return (gcc3).
|
|
||||||
|
|
||||||
2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* configure.ac:
|
|
||||||
AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
|
|
||||||
AM_INIT_AUTOMAKE([no-define foreign 1.6]).
|
|
||||||
* Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* cpuuse/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* devnull/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* dummy/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* dumpbuf/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* monitor/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* mw-fb/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* rootfs/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* rtmonuse/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* shell/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* stackchk/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* untar/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
* wrapup/Makefile.am: Remove AUTOMAKE_OPTIONS.
|
|
||||||
|
|
||||||
2002-03-20 Chris Johns <ccj@acm.org>
|
|
||||||
|
|
||||||
* PR148.
|
|
||||||
* monitor/mon-prmisc.c: Fixed to print task states correctly.
|
|
||||||
|
|
||||||
2002-01-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* shell/shell.c: Remove #undef __STRICT_ANSI__.
|
|
||||||
|
|
||||||
2002-01-07 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* rootfs/Makefile.am: Use include_rtems_HEADERS instead of H_FILES.
|
|
||||||
|
|
||||||
2002-01-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* mw-fb/mw_uid.c: Apply rtems_set_errno_and_return_minus_one.
|
|
||||||
|
|
||||||
2001-10-12 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* rootfs/mkrootfs.c, rootfs/mkrootfs.h: Fixed typo.
|
|
||||||
|
|
||||||
2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* .cvsignore: Add autom4te.cache for autoconf > 2.52.
|
|
||||||
* configure.in: Remove.
|
|
||||||
* configure.ac: New file, generated from configure.in by autoupdate.
|
|
||||||
|
|
||||||
2001-09-28 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* dummy/dummy.c: Now a useful configuration that starts main().
|
|
||||||
* wrapup/Makefile.am: Include a base level configuration in
|
|
||||||
RTEMS library.
|
|
||||||
|
|
||||||
2001-09-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* untar/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* monitor/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* shell/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* devnull/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* dumpbuf/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* mw-fb/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* stackchk/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* rtmonuse/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* cpuuse/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
* rootfs/Makefile.am: Use 'PREINSTALL_FILES ='.
|
|
||||||
|
|
||||||
2001-09-27 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* ChangeLog: Fixed typo in date.
|
|
||||||
|
|
||||||
2001-09-21 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* configure.in, rootfs/Makefile.am: Added conditional to make sure
|
|
||||||
rootfs does not get built with networking is disabled. Also
|
|
||||||
added include of compile.am to rootfs/Makefile.am.
|
|
||||||
* wrapup/Makefile.am: Added rootfs conditionally if networking enabled.
|
|
||||||
|
|
||||||
2001-09-19 Chris Johns <ccj@acm.org>
|
|
||||||
|
|
||||||
* Added support for populating the initial "root" filesystem
|
|
||||||
with information obtained via the DHCP response.
|
|
||||||
* rootfs: New directory.
|
|
||||||
* rootfs/.cvsignore, rootfs/Makefile.am, rootfs/mkrootfs.c,
|
|
||||||
rootfs/mkrootfs.h: New files.
|
|
||||||
* configure.in, Makefile.am: Modified to reflect addition.
|
|
||||||
|
|
||||||
2001-09-14 Fernando Ruiz <fernando.ruiz@ctv.es>
|
|
||||||
|
|
||||||
* shell/shell.c: Don't close file it wasn't open.
|
|
||||||
|
|
||||||
2001-09-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* aclocal/canonical-target-name.m4: Use AC_CANONICAL_TARGET instead
|
|
||||||
of AC_CANONICAL_SYSTEM.
|
|
||||||
* aclocal/config-subdirs.m4: Use AS_MKDIR_P instead of
|
|
||||||
mkinstalldirs and mkdir.
|
|
||||||
* aclocal/target.m4: Obsolete RTEMS_OUTPUT_BUILD_SUBDIRS,
|
|
||||||
hack RTEMS_CONFIG_BUILD_SUBDIRS, introduce
|
|
||||||
_RTEMS_OUTPUT_BUILD_SUBDIRS.
|
|
||||||
|
|
||||||
2001-09-14 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* ChangeLog: Fixed some mistakes.
|
|
||||||
|
|
||||||
2001-09-14 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* ChangeLog: Fixed some mistakes.
|
|
||||||
|
|
||||||
2001-09-14 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* aclocal/canonical-target-name.m4: Use AC_CANONICAL_TARGET instead
|
|
||||||
of AC_CANONICAL_SYSTEM.
|
|
||||||
* aclocal/config-subdirs.m4: Use AS_MKDIR_P instead of
|
|
||||||
mkinstalldirs and mkdir.
|
|
||||||
* aclocal/target.m4: Obsolete RTEMS_OUTPUT_BUILD_SUBDIRS,
|
|
||||||
hack RTEMS_CONFIG_BUILD_SUBDIRS, introduce
|
|
||||||
_RTEMS_OUTPUT_BUILD_SUBDIRS.
|
|
||||||
|
|
||||||
2001-09-14 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* ChangeLog: Fixed some mistakes.
|
|
||||||
|
|
||||||
2001-09-14 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* ChangeLog: Fixed some mistakes.
|
|
||||||
|
|
||||||
2001-09-13 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* devnull/devnull.c: Eliminate warning.
|
|
||||||
|
|
||||||
2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>
|
|
||||||
|
|
||||||
* shell/pty.c: Moved to libnetworking/rtems_telnetd.
|
|
||||||
|
|
||||||
2001-08-09 Fernando-Ruiz Casas <correo@fernando-ruiz.com>
|
|
||||||
|
|
||||||
* shell/Makefile.am, shell/README, shell/cmds.c, shell/shell.c,
|
|
||||||
shell/shell.h: Updates.
|
|
||||||
|
|
||||||
2001-08-09 Keith Outwater <vac4050@cae597.rsc.raytheon.com>
|
|
||||||
|
|
||||||
* monitor/mon-command.c: Add support for partial command matching.
|
|
||||||
The monitor used to have this functionality before it was overhauled
|
|
||||||
to support addition of user commands.
|
|
||||||
|
|
||||||
2001-06-14 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* shell/telnetd.c, shell/telnetd.h: Moved to
|
|
||||||
libnetworking/rtems_servers so the network stack to address network
|
|
||||||
depenendency.
|
|
||||||
* shell/Makefile.am: Modified to reflect above.
|
|
||||||
|
|
||||||
2001-05-25 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* shell/cmds.c: Removed code from inappropriate source.
|
|
||||||
|
|
||||||
2000-05-24 Fernando Ruiz Casas <fernando.ruiz@ctv.es>
|
|
||||||
|
|
||||||
* monitor/mon-prmisc.c: Correct print line.
|
|
||||||
* shell/Makefile.am: Added new file telnetd.c.
|
|
||||||
* shell/telnetd.c, shell/telnetd.h, shell/pty.c: New files.
|
|
||||||
* shell/shell.c, shell/cmds.c, shell/shell.h: Numerous improvments:
|
|
||||||
- The shell_init has a new parameter 'forever' because in
|
|
||||||
/dev/console you need that this process runs forever but in
|
|
||||||
tcp/ip not. (respawn?)
|
|
||||||
- A new task for every session opened trought tcp/ip telnet client.
|
|
||||||
(the chargen,daytime and more are possible of implementation but
|
|
||||||
I ask me if they are necesary)
|
|
||||||
- Exit from the session delete the task and when the client fails too.
|
|
||||||
- More cmds have been implemented. (very reduced version of these)
|
|
||||||
umask, chmod, id, whoami, rm, cat, ...
|
|
||||||
- A reduced line edit has been implemented.
|
|
||||||
Ctrl-C abort the input,
|
|
||||||
Ctrl-d in the first position gives EOF (logout).
|
|
||||||
'\b' and DEL makes the rubout operation.
|
|
||||||
I think that readline() for every session spents a lot of resources.
|
|
||||||
|
|
||||||
2001-04-28 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* shell/cmds.c, shell/shell.c: Remove fileno-hacks.
|
|
||||||
* monitor/mon-symbols.c: Remove #undef __STRICT_ANSI__.
|
|
||||||
|
|
||||||
2001-04-20 Fernando Ruiz Casas <correo@fernando-ruiz.com>
|
|
||||||
|
|
||||||
* Added initial shell functionality.
|
|
||||||
* Makefile.am, configure.in, wrapup/Makefile.am:
|
|
||||||
* shell/.cvsignore, shell/Makefile.am, shell/README,
|
|
||||||
shell/cmds.c, shell/shell.c, shell/shell.h: New files.
|
|
||||||
|
|
||||||
2001-04-20 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* devnull/devnull.c (null_initialize): Added check to
|
|
||||||
ensure that the driver is only initialized once. Otherwise,
|
|
||||||
it will abort when the device /dev/null is present.
|
|
||||||
(null_write): Do not dereference a NULL pointer.
|
|
||||||
|
|
||||||
2001-02-06 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* monitor/mon-command.c: Use #if defined(RTEMS_UNIX).
|
|
||||||
|
|
||||||
2001-02-03 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* untar/Makefile.am, monitor/Makefile.am, dummy/Makefile.am,
|
|
||||||
devnull/Makefile.am, dumpbuf/Makefile.am, mw-fb/Makefile.am,
|
|
||||||
stackchk/Makefile.am, rtmonuse/Makefile.am, cpuuse/Makefile.am:
|
|
||||||
Apply include_*HEADERS instead of H_FILES.
|
|
||||||
|
|
||||||
2001-01-05 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* devnull: New addition. Moved from libcpu/sh.
|
|
||||||
* devnull/devnull.c, devnull/devnull.h, devnull/.cvsignore,
|
|
||||||
devnull/Makefile.am: New files.
|
|
||||||
* Makefile.am, configure.in, wrapup/Makefile.am: Modified to reflect
|
|
||||||
addition of above.
|
|
||||||
|
|
||||||
2000-11-30 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* mw-fb/mw_uid.c: Removed unnecessary dependency on <bsp.h>.
|
|
||||||
|
|
||||||
2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.
|
|
||||||
|
|
||||||
2000-11-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* Makefile.am: Switch to ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal.
|
|
||||||
|
|
||||||
2000-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* Makefile.am: ACLOCAL_AMFLAGS= -I $(RTEMS_TOPdir)/macros.
|
|
||||||
Switch to GNU canonicalization.
|
|
||||||
|
|
||||||
2000-09-28 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* monitor/mon-driver.c: Accounted for addition of "_entry" to
|
|
||||||
fields in rtems_driver_address_table.
|
|
||||||
|
|
||||||
2000-09-04 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
|
|
||||||
|
|
||||||
* cpuuse/Makefile.am, dummy/Makefile.am, dumpbuf/Makefile.am,
|
|
||||||
monitor/Makefile.am, rtmonuse/Makefile.am, stackchk/Makefile.am,
|
|
||||||
untar/Makefile.am, wrapup/Makefile.am, mw-fb/Makefile.am:
|
|
||||||
Include compile.am.
|
|
||||||
|
|
||||||
2000-08-30 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* Many files: Moved posix/include/rtems/posix/seterr.h to
|
|
||||||
score/include/rtems/seterr.h so it would be available within
|
|
||||||
all APIs.
|
|
||||||
|
|
||||||
2000-08-30 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* mw-fb/.cvsignore: New file.
|
|
||||||
|
|
||||||
2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
|
|
||||||
|
|
||||||
* Added generic Micro FrameBuffer interface for MicroWindows.
|
|
||||||
This interface allows MicroWindows to under RTEMS. A sample
|
|
||||||
driver has been developed for the pc386 BSP. See
|
|
||||||
pc386/fb_vga.c as a sample.
|
|
||||||
* Added Uniform Input Device interface for MicroWindows.
|
|
||||||
See PC386 bsp for sample drivers for mouse and keyboard (console).
|
|
||||||
* mw-bf: New directory.
|
|
||||||
* Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb.
|
|
||||||
* mw-fb/Makefile.am: New file.
|
|
||||||
* mw-fb/mw_fb.c: New file.
|
|
||||||
* mw-fb/mw_fb.h: New file.
|
|
||||||
* mw-fb/mw_uid.c: New file.
|
|
||||||
* mw-fb/mw_uid.h: New file.
|
|
||||||
|
|
||||||
2000-08-10 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
|
|
||||||
* ChangeLog: New file.
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I ../../../aclocal
|
|
||||||
|
|
||||||
SUBDIRS = capture cpuuse devnull dummy dumpbuf monitor mw-fb shell \
|
|
||||||
rtmonuse serdbg stackchk untar wrapup
|
|
||||||
|
|
||||||
EXTRA_DIST = README
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/subdirs.am
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
This directory contains for the "miscellaneous" library. Currently
|
|
||||||
this library contains a number of useful support libraries:
|
|
||||||
|
|
||||||
+ Task Stack Overflow Checker
|
|
||||||
+ Workspace Consistency Checker
|
|
||||||
+ Task Execution Time Monitor
|
|
||||||
+ Period Statistics Monitor
|
|
||||||
+ Debug Monitor
|
|
||||||
|
|
||||||
The following ideas have been mentioned for items which could go
|
|
||||||
in this library, but this list is not all inclusive:
|
|
||||||
|
|
||||||
+ there are no outstanding suggestions.
|
|
||||||
|
|
||||||
The intent of this library is to provide a home for useful utility routines
|
|
||||||
which are dependent upon RTEMS.
|
|
||||||
|
|
||||||
--joel
|
|
||||||
16 Sept 97
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libcapture-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = capture.c capture-cli.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = capture.h capture-cli.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README capture.c capture-cli.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
RTEMS Performance Monitoring and Measurement Framework
|
|
||||||
|
|
||||||
Copyright 2002 Chris Johns (ccj@acm.org)
|
|
||||||
23 April 2002
|
|
||||||
|
|
||||||
This directory contains the source code for the performance monitoring and
|
|
||||||
measurement framework. It is more commonly know as the capture engine.
|
|
||||||
|
|
||||||
The capture engine is in an early phase of development. Please review the Status
|
|
||||||
section of this document for the current status.
|
|
||||||
|
|
||||||
Performance.
|
|
||||||
|
|
||||||
The capture engine is designed to not effect the system it is
|
|
||||||
monitoring. Resources such as memory are used as well as a small performance
|
|
||||||
hit in task creation, deletion and context switch. The overhead is small and
|
|
||||||
will not be noticed unless the system is operating close to the performance
|
|
||||||
limit of the target.
|
|
||||||
|
|
||||||
Structure.
|
|
||||||
|
|
||||||
The capture engine is implemented in a couple of layers. This lowest layer is
|
|
||||||
the capture engine. Its interface is in the file 'capture.h'. Typically this
|
|
||||||
interface is directly used unless you are implementing a target interface. The
|
|
||||||
user interface is via a target interface.
|
|
||||||
|
|
||||||
Command Line Interface (CLI).
|
|
||||||
|
|
||||||
This is a target interface that provides a number of user commands via the
|
|
||||||
RTEMS monitor. To use you need to provide the following in your
|
|
||||||
application initialisation:
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
#include <rtems/capture-cli.h>
|
|
||||||
|
|
||||||
rtems_monitor_init (0);
|
|
||||||
rtems_capture_cli_init (0);
|
|
||||||
|
|
||||||
Check the file capture-cli.h for documentation of the interface. The parameter
|
|
||||||
is a pointer to your board support package's time stamp handler. The time stamp
|
|
||||||
handler is yet to be tested so it is recommended this is left as 0, unless you
|
|
||||||
wish to test this part of the engine.
|
|
||||||
|
|
||||||
The commands are:
|
|
||||||
|
|
||||||
copen - Open the capture engine.
|
|
||||||
cclose - Close the capture engine.
|
|
||||||
cenable - Enable the capture engine.
|
|
||||||
cdisable - Disable the capture engine.
|
|
||||||
ctlist - List the tasks known to the capture engine.
|
|
||||||
ctload - Display the current load (sort of top).
|
|
||||||
cwlist - List the watch and trigger controls.
|
|
||||||
cwadd - Add a watch.
|
|
||||||
cwdel - Delete a watch.
|
|
||||||
cwctl - Enable or disable a watch.
|
|
||||||
cwglob - Enable or disable the global watch.
|
|
||||||
cwceil - Set the watch ceiling.
|
|
||||||
cwfloor - Set the watch floor.
|
|
||||||
ctrace - Dump the trace records.
|
|
||||||
ctrig - Define a trigger.
|
|
||||||
|
|
||||||
Open
|
|
||||||
|
|
||||||
usage: copen [-i] size
|
|
||||||
|
|
||||||
Open the capture engine. The size parameter is the size of the capture engine
|
|
||||||
trace buffer. A single record hold a single event, for example a task create or
|
|
||||||
a context in or out. The option '-i' will enable the capture engine after it is
|
|
||||||
opened.
|
|
||||||
|
|
||||||
Close
|
|
||||||
|
|
||||||
usage: cclose
|
|
||||||
|
|
||||||
Close the capture engine and release all resources held by the capture engine.
|
|
||||||
|
|
||||||
Enable
|
|
||||||
|
|
||||||
usage: cenable
|
|
||||||
|
|
||||||
Enable the capture engine if it has been opened.
|
|
||||||
|
|
||||||
Disable
|
|
||||||
|
|
||||||
usage: cdisable
|
|
||||||
|
|
||||||
Disable the capture engine. The enable and disable commands provide a means of
|
|
||||||
removing the overhead of the capture engine from the context switch. This may
|
|
||||||
be needed when testing if it is felt the capture engines overhead is effecting
|
|
||||||
the system.
|
|
||||||
|
|
||||||
Task List
|
|
||||||
|
|
||||||
usage: ctlist
|
|
||||||
|
|
||||||
List the tasks the capture engine knows about. This may contain tasks that have
|
|
||||||
been deleted.
|
|
||||||
|
|
||||||
Task Load
|
|
||||||
|
|
||||||
usage: ctload
|
|
||||||
|
|
||||||
List the tasks in the order of load in a similar way top does on Unix. The
|
|
||||||
command sends ANSI terminal codes. You press enter to stop the update. The
|
|
||||||
update period is fixed at 5 seconds. The output looks like:
|
|
||||||
|
|
||||||
Press ENTER to exit.
|
|
||||||
|
|
||||||
PID NAME RPRI CPRI STATE %CPU %STK FLGS EXEC TIME
|
|
||||||
04010001 IDLE 255 255 READY 96.012% 0% a-----g 1
|
|
||||||
08010009 CPlt 1 1 READY 3.815% 15% a------ 0
|
|
||||||
08010003 ntwk 20 20 Wevnt 0.072% 0% at----g 0
|
|
||||||
08010004 CSr0 20 20 Wevnt 0.041% 0% at----g 0
|
|
||||||
08010001 main 250 250 DELAY 0.041% 0% a-----g 0
|
|
||||||
08010008 test 100 100 Wevnt 0.000% 20% at-T-+g 0
|
|
||||||
08010007 test 100 100 Wevnt 0.000% 0% at-T-+g 0
|
|
||||||
08010005 CSt0 20 20 Wevnt 0.000% 0% at----g 0
|
|
||||||
08010006 RMON 1 1 Wsem 0.000% 0% a------ 0
|
|
||||||
|
|
||||||
There are 7 flags and from left to right are:
|
|
||||||
|
|
||||||
1) 'a' the task is active, and 'd' the task has been deleted.
|
|
||||||
2) 't' the task has been traced.
|
|
||||||
3) 'F' the task has a from (TO_ANY) trigger.
|
|
||||||
4) 'T' the task has a to (FROM_ANY) trigger.
|
|
||||||
5) 'E' the task has an edge (FROM_TO) trigger.
|
|
||||||
6) '+' the task as a watch control attached, 'w' a watch is enabled.
|
|
||||||
7) 'g' the task is part of a global trigger.
|
|
||||||
|
|
||||||
The %STK is the percentage of stack used by a task. Currently only tasks
|
|
||||||
created while the capture engine is enabled can be monitored.
|
|
||||||
|
|
||||||
The RPRI is the real priority. This is the priority set for the task. The
|
|
||||||
current priority is the executing priority that may reflect a level set as a
|
|
||||||
result of priority inversion.
|
|
||||||
|
|
||||||
Watch List
|
|
||||||
|
|
||||||
usage: cwlist
|
|
||||||
|
|
||||||
This command lists the watch and trigger controls the capture engine has. A
|
|
||||||
control is a structure used by the capture engine to determine if a task is
|
|
||||||
watched or triggers capturing.
|
|
||||||
|
|
||||||
Watch Add
|
|
||||||
|
|
||||||
usage: cwadd [task name] [id]
|
|
||||||
|
|
||||||
Add a watch for a task. You can provide a name or id or both. A name will cause
|
|
||||||
all tasks with that name to have the watch added. An id results in a watch
|
|
||||||
being for a specific task.
|
|
||||||
|
|
||||||
Using a name is useful when the task is not yet created.
|
|
||||||
|
|
||||||
Watch Delete
|
|
||||||
|
|
||||||
usage: cwdel [task name] [id]
|
|
||||||
|
|
||||||
Delete a watch that has been added.
|
|
||||||
|
|
||||||
Watch Control
|
|
||||||
|
|
||||||
usage: cwctl [task name] [id] on/off
|
|
||||||
|
|
||||||
Enable or disable a watch. The name and id parameters are the same as the watch
|
|
||||||
add command.
|
|
||||||
|
|
||||||
Global Watch
|
|
||||||
|
|
||||||
usage: cwglob on/off
|
|
||||||
|
|
||||||
Enable or disable the global watch. A global watch is an easy way to enable
|
|
||||||
watches for all tasks with real priorities between the watch ceiling and floor
|
|
||||||
priorities.
|
|
||||||
|
|
||||||
Watch Priority Ceiling
|
|
||||||
|
|
||||||
usage: cwceil priority
|
|
||||||
|
|
||||||
Set the watch priority ceiling. All tasks with a priority less than the ceiling
|
|
||||||
priority are not watched. This allow you to ignore high priority system and
|
|
||||||
driver tasks.
|
|
||||||
|
|
||||||
Watch Priority Floor
|
|
||||||
|
|
||||||
usage: cwfloor priority
|
|
||||||
|
|
||||||
Set the watch priority floor. All tasks with a priority greater than the floor
|
|
||||||
priority level are not watched. This allows you to remove tasks such as IDLE
|
|
||||||
from being monitored.
|
|
||||||
|
|
||||||
Trace
|
|
||||||
|
|
||||||
usage: ctrace [-c] [-r records]
|
|
||||||
|
|
||||||
Dump the trace record. The option '-c' will output the records in comma
|
|
||||||
separated variables (CSV). The '-r' option controls the number of records
|
|
||||||
dumped. This can help stop the command looping for-ever.
|
|
||||||
|
|
||||||
Trigger
|
|
||||||
|
|
||||||
usage: ctrig type [from name] [from id] [to name] [to id]
|
|
||||||
|
|
||||||
Set a trigger. The types of triggers are :
|
|
||||||
|
|
||||||
from : trigger on a context switch from a task
|
|
||||||
to : trigger on a context switch to a task
|
|
||||||
edge : trigger on a context switch from a task to a task
|
|
||||||
|
|
||||||
The from and to trigger types requires a task name or task id or both be
|
|
||||||
provided. The edge requires a from name and/or id and a to name and/or id be
|
|
||||||
provided.
|
|
||||||
|
|
||||||
Flush
|
|
||||||
|
|
||||||
usage: cflush [-n]
|
|
||||||
|
|
||||||
Flush the trace record. The option '-n' stops the capture engine be
|
|
||||||
primed. This means an exising trigger state will not be cleared and tracing
|
|
||||||
will continue.
|
|
||||||
|
|
||||||
Status.
|
|
||||||
|
|
||||||
The following is a list of outstanding issues or bugs.
|
|
||||||
|
|
||||||
1) The capture engine does not scan the existing list of tasks in the kernel
|
|
||||||
when initialised. This means tasks that exist but are not active are not
|
|
||||||
seen. Not sure how to implement this one.
|
|
||||||
|
|
||||||
2) The blocking read of trace records has not been completely implemented or
|
|
||||||
tested. This will wait until I complete the csv support for the cli for a
|
|
||||||
serial UI or the tcp server is implemented.
|
|
||||||
|
|
||||||
3) Task control block clean up is not implemented. The control block should be
|
|
||||||
dumped to the trace buffer. This requires extended record formats. This can
|
|
||||||
be implemented using an event flag to indicate an extended record follows
|
|
||||||
the trace record. This would allow a task delete record to be directly
|
|
||||||
followed by the task information.
|
|
||||||
|
|
||||||
4) Complete csv (comma separated variable) support for the CLI.
|
|
||||||
|
|
||||||
5) Implement a tcp server interface.
|
|
||||||
|
|
||||||
6) Complete the capture engine API documentation.
|
|
||||||
|
|
||||||
7) Test the user supplied time stamp handler.
|
|
||||||
|
|
||||||
8) Task name support is only for the rtems_name type. This means the only the
|
|
||||||
classic API tasks are currently supported. Partial support for the different
|
|
||||||
task names is provided how-ever this is not clean and does not support the
|
|
||||||
variable length task name such as found in the POSIX tasks.
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
$Id$
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright Objective Design Systems Pty Ltd, 2002
|
|
||||||
All rights reserved Objective Design Systems Pty Ltd, 2002
|
|
||||||
Chris Johns (ccj@acm.org)
|
|
||||||
|
|
||||||
COPYRIGHT (c) 1989-1998.
|
|
||||||
On-Line Applications Research Corporation (OAR).
|
|
||||||
|
|
||||||
The license and distribution terms for this file may be
|
|
||||||
found in the file LICENSE in this distribution.
|
|
||||||
|
|
||||||
This software with is provided ``as is'' and with NO WARRANTY.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
RTEMS Performance Monitoring and Measurement Framework.
|
|
||||||
|
|
||||||
This is the Target Interface Command Line Interface. You need
|
|
||||||
start the RTEMS monitor.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CAPTURE_CLI_H_
|
|
||||||
#define __CAPTURE_CLI_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rtems/capture.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_cli_init
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function initialises the command line interface to the capture
|
|
||||||
* engine.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_cli_init (rtems_capture_timestamp timestamp);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,869 +0,0 @@
|
|||||||
/*
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
$Id$
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright Objective Design Systems Pty Ltd, 2002
|
|
||||||
All rights reserved Objective Design Systems Pty Ltd, 2002
|
|
||||||
Chris Johns (ccj@acm.org)
|
|
||||||
|
|
||||||
COPYRIGHT (c) 1989-1998.
|
|
||||||
On-Line Applications Research Corporation (OAR).
|
|
||||||
|
|
||||||
The license and distribution terms for this file may be
|
|
||||||
found in the file LICENSE in this distribution.
|
|
||||||
|
|
||||||
This software with is provided ``as is'' and with NO WARRANTY.
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
RTEMS Performance Monitoring and Measurement Framework.
|
|
||||||
|
|
||||||
This is the Capture Engine component.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CAPTURE_H_
|
|
||||||
#define __CAPTURE_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The number of tasks in a trigger group.
|
|
||||||
*/
|
|
||||||
#define RTEMS_CAPTURE_TRIGGER_TASKS (32)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_t
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* RTEMS control holds the trigger and watch configuration for a group of
|
|
||||||
* tasks with the same name.
|
|
||||||
*/
|
|
||||||
typedef struct rtems_capture_control_s
|
|
||||||
{
|
|
||||||
rtems_name name;
|
|
||||||
rtems_id id;
|
|
||||||
rtems_unsigned32 flags;
|
|
||||||
rtems_name from[RTEMS_CAPTURE_TRIGGER_TASKS];
|
|
||||||
rtems_id from_id[RTEMS_CAPTURE_TRIGGER_TASKS];
|
|
||||||
struct rtems_capture_control_s* next;
|
|
||||||
} rtems_capture_control_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Control flags.
|
|
||||||
*/
|
|
||||||
#define RTEMS_CAPTURE_WATCH (1 << 0)
|
|
||||||
#define RTEMS_CAPTURE_FROM_ANY (1 << 1)
|
|
||||||
#define RTEMS_CAPTURE_TO_ANY (1 << 2)
|
|
||||||
#define RTEMS_CAPTURE_FROM_TO (1 << 3)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_t
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* RTEMS capture control provdes the information about a task, along
|
|
||||||
* with its trigger state. The control is referenced by each
|
|
||||||
* capture record. This is* information neeed by the decoder. The
|
|
||||||
* capture record cannot assume the task will exist when the record is
|
|
||||||
* dumped via the target interface so task info needed for tracing is
|
|
||||||
* copied and held here.
|
|
||||||
*
|
|
||||||
* The inline heper functions provide more details about the info
|
|
||||||
* contained in this structure.
|
|
||||||
*
|
|
||||||
* Note, the tracer code exploits the fact an rtems_name is a
|
|
||||||
* 32bit value.
|
|
||||||
*/
|
|
||||||
typedef struct rtems_capture_task_s
|
|
||||||
{
|
|
||||||
rtems_name name;
|
|
||||||
rtems_id id;
|
|
||||||
rtems_unsigned32 flags;
|
|
||||||
rtems_tcb* tcb;
|
|
||||||
rtems_unsigned32 in;
|
|
||||||
rtems_unsigned32 out;
|
|
||||||
rtems_task_priority start_priority;
|
|
||||||
rtems_unsigned32 stack_size;
|
|
||||||
rtems_unsigned32 stack_clean;
|
|
||||||
rtems_unsigned32 ticks;
|
|
||||||
rtems_unsigned32 tick_offset;
|
|
||||||
rtems_unsigned32 ticks_in;
|
|
||||||
rtems_unsigned32 tick_offset_in;
|
|
||||||
rtems_unsigned32 last_ticks;
|
|
||||||
rtems_unsigned32 last_tick_offset;
|
|
||||||
rtems_capture_control_t* control;
|
|
||||||
struct rtems_capture_task_s* next;
|
|
||||||
} rtems_capture_task_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Task flags.
|
|
||||||
*/
|
|
||||||
#define RTEMS_CAPTURE_TRACED (1 << 0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_record_t
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* RTEMS capture record. This is a record that is written into
|
|
||||||
* the buffer. The events includes the priority of the task
|
|
||||||
* at the time of the context switch.
|
|
||||||
*/
|
|
||||||
typedef struct rtems_capture_record_s
|
|
||||||
{
|
|
||||||
rtems_capture_task_t* task;
|
|
||||||
rtems_unsigned32 events;
|
|
||||||
rtems_unsigned32 ticks;
|
|
||||||
rtems_unsigned32 tick_offset;
|
|
||||||
} rtems_capture_record_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The capture record event flags.
|
|
||||||
*/
|
|
||||||
#define RTEMS_CAPTURE_REAL_PRI_EVENT_MASK (0x000000ff)
|
|
||||||
#define RTEMS_CAPTURE_CURR_PRI_EVENT_MASK (0x0000ff00)
|
|
||||||
#define RTEMS_CAPTURE_REAL_PRIORITY_EVENT (0)
|
|
||||||
#define RTEMS_CAPTURE_CURR_PRIORITY_EVENT (8)
|
|
||||||
#define RTEMS_CAPTURE_EVENT_START (16)
|
|
||||||
#define RTEMS_CAPTURE_CREATED_BY_EVENT (1 << 16)
|
|
||||||
#define RTEMS_CAPTURE_CREATED_EVENT (1 << 17)
|
|
||||||
#define RTEMS_CAPTURE_STARTED_BY_EVENT (1 << 18)
|
|
||||||
#define RTEMS_CAPTURE_STARTED_EVENT (1 << 19)
|
|
||||||
#define RTEMS_CAPTURE_RESTARTED_BY_EVENT (1 << 20)
|
|
||||||
#define RTEMS_CAPTURE_RESTARTED_EVENT (1 << 21)
|
|
||||||
#define RTEMS_CAPTURE_DELETED_BY_EVENT (1 << 22)
|
|
||||||
#define RTEMS_CAPTURE_DELETED_EVENT (1 << 23)
|
|
||||||
#define RTEMS_CAPTURE_BEGIN_EVENT (1 << 24)
|
|
||||||
#define RTEMS_CAPTURE_EXITTED_EVENT (1 << 25)
|
|
||||||
#define RTEMS_CAPTURE_SWITCHED_OUT_EVENT (1 << 26)
|
|
||||||
#define RTEMS_CAPTURE_SWITCHED_IN_EVENT (1 << 27)
|
|
||||||
#define RTEMS_CAPTURE_TIMESTAMP (1 << 28)
|
|
||||||
#define RTEMS_CAPTURE_EVENT_END (28)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_trigger_t
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* The types of triggers that exist. FIXME: add more here.
|
|
||||||
*/
|
|
||||||
typedef enum rtems_capture_trigger_t
|
|
||||||
{
|
|
||||||
rtems_capture_to_any,
|
|
||||||
rtems_capture_from_any,
|
|
||||||
rtems_capture_from_to
|
|
||||||
} rtems_capture_trigger_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_timestamp
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This defines the callout handler to obtain a time stamp. The
|
|
||||||
* value returned is time count since the last read.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef void (*rtems_capture_timestamp)
|
|
||||||
(rtems_unsigned32* ticks, rtems_unsigned32* micro);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_open
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function initialises the realtime trace manager allocating the capture
|
|
||||||
* buffer. It is assumed we have a working heap at stage of initialisation.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_open (rtems_unsigned32 size,
|
|
||||||
rtems_capture_timestamp timestamp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_close
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function shutdowns the tracer and release any claimed
|
|
||||||
* resources.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_close ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function allows control of tracing at a global level.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_control (rtems_boolean enable);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_flush
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function flushes the trace buffer. The prime parameter allows the
|
|
||||||
* capture engine to also be primed again.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_flush (rtems_boolean prime);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_add
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function defines a watch for a specific task given a name. A watch
|
|
||||||
* causes it to be traced either in or out of context. The watch can be
|
|
||||||
* optionally enabled or disabled with the set routine. It is disabled by
|
|
||||||
* default.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_watch_add (rtems_name name, rtems_id id);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_del
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function removes a watch for a specific task given a name. The task
|
|
||||||
* description will still exist if referenced by a trace record in the trace
|
|
||||||
* buffer or a global watch is defined.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_watch_del (rtems_name name, rtems_id id);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_set
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function allows control of a watch. The watch can be enabled or
|
|
||||||
* disabled.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_watch_ctrl (rtems_name name, rtems_id id, rtems_boolean enable);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_global
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function allows control of a global watch. The watch can be enabled or
|
|
||||||
* disabled. A global watch configures all tasks below the ceiling and above
|
|
||||||
* the floor to be traced.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_watch_global (rtems_boolean enable);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_global_on
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the global watch state.
|
|
||||||
*/
|
|
||||||
rtems_boolean
|
|
||||||
rtems_capture_watch_global_on ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_ceiling
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function sets a watch ceiling. Tasks at or greating that the
|
|
||||||
* ceiling priority are not watched. This is a simple way to monitor
|
|
||||||
* an application and exclude system tasks running at a higher
|
|
||||||
* priority level.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_watch_ceiling (rtems_task_priority ceiling);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_get_ceiling
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function gets the watch ceiling.
|
|
||||||
*/
|
|
||||||
rtems_task_priority
|
|
||||||
rtems_capture_watch_get_ceiling ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_floor
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function sets a watch floor. Tasks at or less that the
|
|
||||||
* floor priority are not watched. This is a simple way to monitor
|
|
||||||
* an application and exclude system tasks running at a lower
|
|
||||||
* priority level.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_watch_floor (rtems_task_priority floor);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_watch_get_floor
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function gets the watch floor.
|
|
||||||
*/
|
|
||||||
rtems_task_priority
|
|
||||||
rtems_capture_watch_get_floor ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_set_trigger
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function sets an edge trigger. Left is the left side of
|
|
||||||
* the edge and right is right side of the edge. The trigger type
|
|
||||||
* can be -
|
|
||||||
*
|
|
||||||
* FROM_ANY : a switch from any task to the right side of the edge.
|
|
||||||
* TO_ANY : a switch from the left side of the edge to any task.
|
|
||||||
* FROM_TO : a switch from the left side of the edge to the right
|
|
||||||
* side of the edge.
|
|
||||||
*
|
|
||||||
* This set trigger routine will create a trace control for the
|
|
||||||
* target task. The task list is searched and any existing tasks
|
|
||||||
* are linked to the new control.
|
|
||||||
*
|
|
||||||
* We can have a number of tasks that have the same name so we
|
|
||||||
* search using names. This means a number of tasks can be
|
|
||||||
* linked to single control.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_set_trigger (rtems_name from,
|
|
||||||
rtems_id from_id,
|
|
||||||
rtems_name to,
|
|
||||||
rtems_id to_id,
|
|
||||||
rtems_capture_trigger_t trigger);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_read
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function reads a number of records from the capture buffer.
|
|
||||||
* The user can optionally block and wait until the buffer as a
|
|
||||||
* specific number of records available or a specific time has
|
|
||||||
* elasped.
|
|
||||||
*
|
|
||||||
* The function returns the number of record that is has that are
|
|
||||||
* in a continous block of memory. If the number of available records
|
|
||||||
* wrap then only those records are provided. This removes the need for
|
|
||||||
* caller to be concerned about buffer wrappings. If the number of
|
|
||||||
* requested records cannot be met due to the wrapping of the records
|
|
||||||
* less than the specified number will be returned.
|
|
||||||
*
|
|
||||||
* The user must release the records. This is achieved with a call to
|
|
||||||
* rtems_capture_release. Calls this function without a release will
|
|
||||||
* result in at least the same number of records being released.
|
|
||||||
*
|
|
||||||
* The 'threshold' parameter is the number of records that must be
|
|
||||||
* captured before returning. If a timeout period is specified (non-0)
|
|
||||||
* any captured records will be returned. These parameters stop
|
|
||||||
* thrashing occuring for a small number of records, yet allows
|
|
||||||
* a user configured latiency to be applied for single events.
|
|
||||||
*
|
|
||||||
* The 'timeout' parameter is in micro-seconds. A value of 0 will disable
|
|
||||||
* the timeout.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_read (rtems_unsigned32 threshold,
|
|
||||||
rtems_unsigned32 timeout,
|
|
||||||
rtems_unsigned32* read,
|
|
||||||
rtems_capture_record_t** recs);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_release
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function releases the requested number of record slots back
|
|
||||||
* to the capture engine. The count must match the number read.
|
|
||||||
*/
|
|
||||||
rtems_status_code
|
|
||||||
rtems_capture_release (rtems_unsigned32 count);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_tick_time
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the tick period in micro-seconds.
|
|
||||||
*/
|
|
||||||
rtems_unsigned32
|
|
||||||
rtems_capture_tick_time ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_tick_time
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the tick period in micro-seconds.
|
|
||||||
*/
|
|
||||||
rtems_unsigned32
|
|
||||||
rtems_capture_tick_time ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_event_text
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns a string for an event based on the bit in the
|
|
||||||
* event. The functions takes the bit offset as a number not the bit
|
|
||||||
* set in a bit map.
|
|
||||||
*/
|
|
||||||
const char*
|
|
||||||
rtems_capture_event_text (int event);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_get_task_list
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the head of the list of tasks that the
|
|
||||||
* capture engine has detected.
|
|
||||||
*/
|
|
||||||
rtems_capture_task_t*
|
|
||||||
rtems_capture_get_task_list ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_next_task
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the pointer to the next task in the list. The
|
|
||||||
* pointer NULL terminates the list.
|
|
||||||
*/
|
|
||||||
static inline rtems_capture_task_t*
|
|
||||||
rtems_capture_next_task (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_valid
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns true if the task control block points to
|
|
||||||
* a valid task.
|
|
||||||
*/
|
|
||||||
static inline rtems_boolean
|
|
||||||
rtems_capture_task_valid (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->tcb != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_id
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task id.
|
|
||||||
*/
|
|
||||||
static inline rtems_id
|
|
||||||
rtems_capture_task_id (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_state
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task state.
|
|
||||||
*/
|
|
||||||
static inline States_Control
|
|
||||||
rtems_capture_task_state (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
if (rtems_capture_task_valid (task))
|
|
||||||
return task->tcb->current_state;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_name
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task name.
|
|
||||||
*/
|
|
||||||
static inline rtems_name
|
|
||||||
rtems_capture_task_name (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_flags
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task flags.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_flags (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_control
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task control if present.
|
|
||||||
*/
|
|
||||||
static inline rtems_capture_control_t*
|
|
||||||
rtems_capture_task_control (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->control;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_control_flags
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task control flags if a control is present.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_control_flags (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
if (!task->control)
|
|
||||||
return 0;
|
|
||||||
return task->control->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_switched_in
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the number of times the task has
|
|
||||||
* been switched into context.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_switched_in (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->in;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_switched_out
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the number of times the task has
|
|
||||||
* been switched out of context.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_switched_out (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_curr_priority
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the tasks start priority. The tracer needs this
|
|
||||||
* to track where the task's priority goes.
|
|
||||||
*/
|
|
||||||
static inline rtems_task_priority
|
|
||||||
rtems_capture_task_start_priority (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->start_priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_real_priority
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the tasks real priority.
|
|
||||||
*/
|
|
||||||
static inline rtems_task_priority
|
|
||||||
rtems_capture_task_real_priority (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
if (rtems_capture_task_valid (task))
|
|
||||||
return task->tcb->real_priority;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_curr_priority
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the tasks current priority.
|
|
||||||
*/
|
|
||||||
static inline rtems_task_priority
|
|
||||||
rtems_capture_task_curr_priority (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
if (rtems_capture_task_valid (task))
|
|
||||||
return task->tcb->current_priority;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_stack_usage
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function updates the stack usage. The task control block
|
|
||||||
* is updated.
|
|
||||||
*/
|
|
||||||
rtems_unsigned32
|
|
||||||
rtems_capture_task_stack_usage (rtems_capture_task_t* task);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_stack_size
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the task's stack size.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_stack_size (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->stack_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_stack_used
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the amount of stack used.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_stack_used (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->stack_size - task->stack_clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_ticks
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the current execution time as ticks.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_ticks (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->ticks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_tick_offset
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the current execution time tick offset.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_tick_offset (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
return task->tick_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_time
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the current execution time.
|
|
||||||
*/
|
|
||||||
static inline unsigned long long
|
|
||||||
rtems_capture_task_time (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
unsigned long long t = task->ticks;
|
|
||||||
return (t * rtems_capture_tick_time ()) + task->tick_offset;;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_delta_time
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the execution time as a different between the
|
|
||||||
* last time the detla time was and now.
|
|
||||||
*/
|
|
||||||
static inline unsigned long long
|
|
||||||
rtems_capture_task_delta_time (rtems_capture_task_t* task)
|
|
||||||
{
|
|
||||||
unsigned long long t = task->ticks - task->last_ticks;
|
|
||||||
rtems_unsigned32 o = task->tick_offset - task->last_tick_offset;
|
|
||||||
|
|
||||||
task->last_ticks = task->ticks;
|
|
||||||
task->last_tick_offset = task->tick_offset;
|
|
||||||
|
|
||||||
return (t * rtems_capture_tick_time ()) + o;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_task_count
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the number of tasks the capture
|
|
||||||
* engine knows about.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_task_count ()
|
|
||||||
{
|
|
||||||
rtems_capture_task_t* task = rtems_capture_get_task_list ();
|
|
||||||
rtems_unsigned32 count = 0;
|
|
||||||
|
|
||||||
while (task)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
task = rtems_capture_next_task (task);
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_get_control_list
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the head of the list of controls in the
|
|
||||||
* capture engine.
|
|
||||||
*/
|
|
||||||
rtems_capture_control_t*
|
|
||||||
rtems_capture_get_control_list ();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_next_control
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the pointer to the next control in the list. The
|
|
||||||
* pointer NULL terminates the list.
|
|
||||||
*/
|
|
||||||
static inline rtems_capture_control_t*
|
|
||||||
rtems_capture_next_control (rtems_capture_control_t* control)
|
|
||||||
{
|
|
||||||
return control->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_id
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the control id.
|
|
||||||
*/
|
|
||||||
static inline rtems_id
|
|
||||||
rtems_capture_control_id (rtems_capture_control_t* control)
|
|
||||||
{
|
|
||||||
return control->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_name
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the control name.
|
|
||||||
*/
|
|
||||||
static inline rtems_name
|
|
||||||
rtems_capture_control_name (rtems_capture_control_t* control)
|
|
||||||
{
|
|
||||||
return control->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_flags
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the control flags.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_control_flags (rtems_capture_control_t* control)
|
|
||||||
{
|
|
||||||
return control->flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_from_name
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the control from task name.
|
|
||||||
*/
|
|
||||||
static inline rtems_name
|
|
||||||
rtems_capture_control_from_name (rtems_capture_control_t* control, int from)
|
|
||||||
{
|
|
||||||
if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
|
|
||||||
return control->from[from];
|
|
||||||
return control->from[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_from_id
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the control from task id.
|
|
||||||
*/
|
|
||||||
static inline rtems_id
|
|
||||||
rtems_capture_control_from_id (rtems_capture_control_t* control, int from)
|
|
||||||
{
|
|
||||||
if (from < RTEMS_CAPTURE_TRIGGER_TASKS)
|
|
||||||
return control->from_id[from];
|
|
||||||
return control->from_id[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_capture_control_count
|
|
||||||
*
|
|
||||||
* DESCRIPTION:
|
|
||||||
*
|
|
||||||
* This function returns the number of controls the capture
|
|
||||||
* engine has.
|
|
||||||
*/
|
|
||||||
static inline rtems_unsigned32
|
|
||||||
rtems_capture_control_count ()
|
|
||||||
{
|
|
||||||
rtems_capture_control_t* control = rtems_capture_get_control_list ();
|
|
||||||
rtems_unsigned32 count = 0;
|
|
||||||
|
|
||||||
while (control)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
control = rtems_capture_next_control (control);
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
## Process this file with autoconf to produce a configure script.
|
|
||||||
##
|
|
||||||
## $Id$
|
|
||||||
|
|
||||||
AC_PREREQ(2.52)
|
|
||||||
AC_INIT([rtems-c-src-libmisc],[_RTEMS_VERSION],[rtems-bugs@OARcorp.com])
|
|
||||||
AC_CONFIG_SRCDIR([dumpbuf])
|
|
||||||
RTEMS_TOP(../../..)
|
|
||||||
AC_CONFIG_AUX_DIR(../../..)
|
|
||||||
|
|
||||||
RTEMS_CANONICAL_TARGET_CPU
|
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([no-define foreign 1.6])
|
|
||||||
AM_MAINTAINER_MODE
|
|
||||||
|
|
||||||
RTEMS_ENABLE_BARE
|
|
||||||
|
|
||||||
RTEMS_ENV_RTEMSBSP
|
|
||||||
RTEMS_CHECK_CPU
|
|
||||||
RTEMS_CANONICAL_HOST
|
|
||||||
|
|
||||||
RTEMS_PROJECT_ROOT
|
|
||||||
|
|
||||||
RTEMS_PROG_CC_FOR_TARGET
|
|
||||||
RTEMS_CANONICALIZE_TOOLS
|
|
||||||
|
|
||||||
RTEMS_CHECK_MULTIPROCESSING(RTEMS_BSP)
|
|
||||||
|
|
||||||
AM_CONDITIONAL(HAS_MP,test "$HAS_MP" = "yes")
|
|
||||||
|
|
||||||
# shell/* wants to assign file descriptors to stdio file descriptors.
|
|
||||||
AC_MSG_CHECKING([for assignable stdio])
|
|
||||||
AC_COMPILE_IFELSE(
|
|
||||||
[AC_LANG_PROGRAM(
|
|
||||||
[#include <stdio.h>],
|
|
||||||
[stdin = fopen("/tmp", "r")])],
|
|
||||||
[HAVE_ASSIGNABLE_STDIO=yes],
|
|
||||||
[HAVE_ASSIGNABLE_STDIO=no])
|
|
||||||
AC_MSG_RESULT([$HAVE_ASSIGNABLE_STDIO])
|
|
||||||
|
|
||||||
AM_CONDITIONAL([RTEMS_LIBSHELL],[test x"$HAVE_ASSIGNABLE_STDIO" = x"yes"])
|
|
||||||
|
|
||||||
# Explicitly list all Makefiles here
|
|
||||||
AC_CONFIG_FILES([Makefile
|
|
||||||
cpuuse/Makefile
|
|
||||||
shell/Makefile
|
|
||||||
devnull/Makefile
|
|
||||||
dummy/Makefile
|
|
||||||
dumpbuf/Makefile
|
|
||||||
monitor/Makefile
|
|
||||||
rtmonuse/Makefile
|
|
||||||
serdbg/Makefile
|
|
||||||
stackchk/Makefile
|
|
||||||
capture/Makefile
|
|
||||||
untar/Makefile
|
|
||||||
mw-fb/Makefile
|
|
||||||
wrapup/Makefile
|
|
||||||
])
|
|
||||||
AC_OUTPUT
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libcpuuse-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = cpuuse.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = cpuuse.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README cpuuse.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
This directory contains a stack bounds checker. It provides two
|
|
||||||
primary features:
|
|
||||||
|
|
||||||
+ check for stack overflow at each context switch
|
|
||||||
+ provides an educated guess at each task's stack usage
|
|
||||||
|
|
||||||
The stack overflow check at context switch works by looking for
|
|
||||||
a 16 byte pattern at the logical end of the stack to be corrupted.
|
|
||||||
The "guesser" assumes that the entire stack was prefilled with a known
|
|
||||||
pattern and assumes that the pattern is still in place if the memory
|
|
||||||
has not been used as a stack.
|
|
||||||
|
|
||||||
Both of these can be fooled by pushing large holes onto the stack
|
|
||||||
and not writing to them... or (much more unlikely) writing the
|
|
||||||
magic patterns into memory.
|
|
||||||
|
|
||||||
This code has not been extensively tested. It is provided as a tool
|
|
||||||
for RTEMS users to catch the most common mistake in multitasking
|
|
||||||
systems ... too little stack space. Suggestions and comments are appreciated.
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
1. Stack usage information is questionable on CPUs which push
|
|
||||||
large holes on stack.
|
|
||||||
|
|
||||||
2. The stack checker has a tendency to generate a fault when
|
|
||||||
trying to print the helpful diagnostic message. If it comes
|
|
||||||
out, congratulations. If not, then the variable Stack_check_Blown_task
|
|
||||||
contains a pointer to the TCB of the offending task. This
|
|
||||||
is usually enough to go on.
|
|
||||||
|
|
||||||
FUTURE:
|
|
||||||
|
|
||||||
1. Determine how/if gcc will generate stack probe calls and support that.
|
|
||||||
|
|
||||||
2. Get accurate stack usage numbers on i960.. it pushes very large
|
|
||||||
holes on the stack.
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* CPU Usage Reporter
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999. 1996.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include <rtems/cpuuse.h>
|
|
||||||
|
|
||||||
unsigned32 CPU_usage_Ticks_at_last_reset;
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* CPU_usage_Dump
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CPU_usage_Dump( void )
|
|
||||||
{
|
|
||||||
unsigned32 i;
|
|
||||||
unsigned32 api_index;
|
|
||||||
Thread_Control *the_thread;
|
|
||||||
Objects_Information *information;
|
|
||||||
unsigned32 u32_name;
|
|
||||||
char name[5];
|
|
||||||
unsigned32 total_units = 0;
|
|
||||||
|
|
||||||
for ( api_index = 1 ;
|
|
||||||
api_index <= OBJECTS_APIS_LAST ;
|
|
||||||
api_index++ ) {
|
|
||||||
if ( !_Objects_Information_table[ api_index ] )
|
|
||||||
continue;
|
|
||||||
information = _Objects_Information_table[ api_index ][ 1 ];
|
|
||||||
if ( information ) {
|
|
||||||
for ( i=1 ; i <= information->maximum ; i++ ) {
|
|
||||||
the_thread = (Thread_Control *)information->local_table[ i ];
|
|
||||||
|
|
||||||
if ( the_thread )
|
|
||||||
total_units += the_thread->ticks_executed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("CPU Usage by thread\n");
|
|
||||||
#if defined(unix) || ( CPU_HARDWARE_FP == TRUE )
|
|
||||||
printf( " ID NAME TICKS PERCENT\n" );
|
|
||||||
#else
|
|
||||||
printf( " ID NAME TICKS\n" );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for ( api_index = 1 ;
|
|
||||||
api_index <= OBJECTS_APIS_LAST ;
|
|
||||||
api_index++ ) {
|
|
||||||
if ( !_Objects_Information_table[ api_index ] )
|
|
||||||
continue;
|
|
||||||
information = _Objects_Information_table[ api_index ][ 1 ];
|
|
||||||
if ( information ) {
|
|
||||||
for ( i=1 ; i <= information->maximum ; i++ ) {
|
|
||||||
the_thread = (Thread_Control *)information->local_table[ i ];
|
|
||||||
|
|
||||||
if ( !the_thread )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( information->is_string )
|
|
||||||
u32_name = *(unsigned32 *)the_thread->Object.name;
|
|
||||||
else
|
|
||||||
u32_name = (unsigned32)the_thread->Object.name;
|
|
||||||
|
|
||||||
name[ 0 ] = (u32_name >> 24) & 0xff;
|
|
||||||
name[ 1 ] = (u32_name >> 16) & 0xff;
|
|
||||||
name[ 2 ] = (u32_name >> 8) & 0xff;
|
|
||||||
name[ 3 ] = (u32_name >> 0) & 0xff;
|
|
||||||
name[ 4 ] = '\0';
|
|
||||||
|
|
||||||
if ( !isprint(name[0]) ) name[0] = '*';
|
|
||||||
if ( !isprint(name[1]) ) name[1] = '*';
|
|
||||||
if ( !isprint(name[2]) ) name[2] = '*';
|
|
||||||
if ( !isprint(name[3]) ) name[3] = '*';
|
|
||||||
|
|
||||||
#if defined(unix) || ( CPU_HARDWARE_FP == TRUE )
|
|
||||||
printf( "0x%08x %4s %8d %5.3f\n",
|
|
||||||
the_thread->Object.id,
|
|
||||||
name,
|
|
||||||
the_thread->ticks_executed,
|
|
||||||
(total_units) ?
|
|
||||||
(double)the_thread->ticks_executed / (double)total_units :
|
|
||||||
(double)total_units
|
|
||||||
);
|
|
||||||
#else
|
|
||||||
printf( "0x%08x %4s %8d\n",
|
|
||||||
the_thread->Object.id,
|
|
||||||
name,
|
|
||||||
the_thread->ticks_executed
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"\nTicks since last reset = %d\n",
|
|
||||||
_Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset
|
|
||||||
);
|
|
||||||
printf( "\nTotal Units = %d\n", total_units );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* CPU_usage_Reset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CPU_usage_Reset( void )
|
|
||||||
{
|
|
||||||
unsigned32 i;
|
|
||||||
unsigned32 api_index;
|
|
||||||
Thread_Control *the_thread;
|
|
||||||
Objects_Information *information;
|
|
||||||
|
|
||||||
CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot;
|
|
||||||
|
|
||||||
for ( api_index = 1 ;
|
|
||||||
api_index <= OBJECTS_APIS_LAST ;
|
|
||||||
api_index++ ) {
|
|
||||||
if ( !_Objects_Information_table[ api_index ] )
|
|
||||||
continue;
|
|
||||||
information = _Objects_Information_table[ api_index ][ 1 ];
|
|
||||||
if ( information ) {
|
|
||||||
for ( i=1 ; i <= information->maximum ; i++ ) {
|
|
||||||
the_thread = (Thread_Control *)information->local_table[ i ];
|
|
||||||
|
|
||||||
if ( !the_thread )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
the_thread->ticks_executed = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/* cpuuse.h
|
|
||||||
*
|
|
||||||
* This include file contains information necessary to utilize
|
|
||||||
* and install the cpu usage reporting mechanism.
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999. 1996.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CPU_USE_h
|
|
||||||
#define __CPU_USE_h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CPU_usage_Dump
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CPU_usage_Dump( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* CPU_usage_Reset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CPU_usage_Reset( void );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* end of include file */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libdevnull-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = devnull.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = devnull.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = devnull.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
/* /dev/null
|
|
||||||
*
|
|
||||||
* Derived from rtems' stub driver.
|
|
||||||
*
|
|
||||||
* Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-2000.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/devnull.h>
|
|
||||||
#include <rtems/libio.h>
|
|
||||||
|
|
||||||
/* null_initialize
|
|
||||||
*
|
|
||||||
* This routine is the null device driver init routine.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* major - device major number
|
|
||||||
* minor - device minor number
|
|
||||||
* pargp - pointer to parameter block
|
|
||||||
*
|
|
||||||
* Output parameters:
|
|
||||||
* rval - NULL_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_unsigned32 NULL_major;
|
|
||||||
static char initialized;
|
|
||||||
|
|
||||||
rtems_device_driver null_initialize(
|
|
||||||
rtems_device_major_number major,
|
|
||||||
rtems_device_minor_number minor,
|
|
||||||
void *pargp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_device_driver status;
|
|
||||||
|
|
||||||
if ( !initialized ) {
|
|
||||||
initialized = 1;
|
|
||||||
|
|
||||||
status = rtems_io_register_name(
|
|
||||||
"/dev/null",
|
|
||||||
major,
|
|
||||||
(rtems_device_minor_number) 0
|
|
||||||
);
|
|
||||||
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
rtems_fatal_error_occurred(status);
|
|
||||||
|
|
||||||
NULL_major = major;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* null_open
|
|
||||||
*
|
|
||||||
* This routine is the null device driver open routine.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* major - device major number
|
|
||||||
* minor - device minor number
|
|
||||||
* pargb - pointer to open parameter block
|
|
||||||
*
|
|
||||||
* Output parameters:
|
|
||||||
* rval - NULL_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_device_driver null_open(
|
|
||||||
rtems_device_major_number major,
|
|
||||||
rtems_device_minor_number minor,
|
|
||||||
void *pargp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NULL_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* null_close
|
|
||||||
*
|
|
||||||
* This routine is the null device driver close routine.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* major - device major number
|
|
||||||
* minor - device minor number
|
|
||||||
* pargb - pointer to close parameter block
|
|
||||||
*
|
|
||||||
* Output parameters:
|
|
||||||
* rval - NULL_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_device_driver null_close(
|
|
||||||
rtems_device_major_number major,
|
|
||||||
rtems_device_minor_number minor,
|
|
||||||
void *pargp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NULL_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* null_read
|
|
||||||
*
|
|
||||||
* This routine is the null device driver read routine.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* major - device major number
|
|
||||||
* minor - device minor number
|
|
||||||
* pargp - pointer to read parameter block
|
|
||||||
*
|
|
||||||
* Output parameters:
|
|
||||||
* rval - NULL_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_device_driver null_read(
|
|
||||||
rtems_device_major_number major,
|
|
||||||
rtems_device_minor_number minor,
|
|
||||||
void *pargp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NULL_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* null_write
|
|
||||||
*
|
|
||||||
* This routine is the null device driver write routine.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* major - device major number
|
|
||||||
* minor - device minor number
|
|
||||||
* pargp - pointer to write parameter block
|
|
||||||
*
|
|
||||||
* Output parameters:
|
|
||||||
* rval - NULL_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_device_driver null_write(
|
|
||||||
rtems_device_major_number major,
|
|
||||||
rtems_device_minor_number minor,
|
|
||||||
void *pargp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *) pargp;
|
|
||||||
|
|
||||||
if ( rw_args )
|
|
||||||
rw_args->bytes_moved = rw_args->count;
|
|
||||||
|
|
||||||
return NULL_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* null_control
|
|
||||||
*
|
|
||||||
* This routine is the null device driver control routine.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* major - device major number
|
|
||||||
* minor - device minor number
|
|
||||||
* pargp - pointer to cntrl parameter block
|
|
||||||
*
|
|
||||||
* Output parameters:
|
|
||||||
* rval - NULL_SUCCESSFUL
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_device_driver null_control(
|
|
||||||
rtems_device_major_number major,
|
|
||||||
rtems_device_minor_number minor,
|
|
||||||
void *pargp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NULL_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/* devnull.h
|
|
||||||
*
|
|
||||||
* Null device driver, derived from rtems' stub driver.
|
|
||||||
*
|
|
||||||
* Author: Ralf Corsepius (corsepiu@faw.uni-ulm.de)
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-2000.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __NULL_DRIVER_h
|
|
||||||
#define __NULL_DRIVER_h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEVNULL_DRIVER_TABLE_ENTRY \
|
|
||||||
{ null_initialize, null_open, null_close, null_read, \
|
|
||||||
null_write, null_control }
|
|
||||||
|
|
||||||
#define NULL_SUCCESSFUL RTEMS_SUCCESSFUL
|
|
||||||
|
|
||||||
rtems_device_driver null_initialize(
|
|
||||||
rtems_device_major_number,
|
|
||||||
rtems_device_minor_number,
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
rtems_device_driver null_open(
|
|
||||||
rtems_device_major_number,
|
|
||||||
rtems_device_minor_number,
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
rtems_device_driver null_close(
|
|
||||||
rtems_device_major_number,
|
|
||||||
rtems_device_minor_number,
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
rtems_device_driver null_read(
|
|
||||||
rtems_device_major_number,
|
|
||||||
rtems_device_minor_number,
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
rtems_device_driver null_write(
|
|
||||||
rtems_device_major_number,
|
|
||||||
rtems_device_minor_number,
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
rtems_device_driver null_control(
|
|
||||||
rtems_device_major_number,
|
|
||||||
rtems_device_minor_number,
|
|
||||||
void *
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* end of include file */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
LIBNAME = libdummy-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = dummy.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
TMPINSTALL_FILES += $(PROJECT_RELEASE)/lib/$(PGMNAME)$(LIB_VARIANT).rel
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README dummy.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
dummy.rel
|
|
||||||
=========
|
|
||||||
|
|
||||||
A relocatible objects which contains a dummy configuration for RTEMS.
|
|
||||||
|
|
||||||
Helps linking standard c-program code with RTEMS, which shall *not* be run
|
|
||||||
on a target, such as configure script code fragments generated by autoconf's
|
|
||||||
AC_TRY_LINK.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
tar xzvf somepkg.tar.gz
|
|
||||||
cd somepkg
|
|
||||||
|
|
||||||
LDFLAGS=/usr/local/rtems/<cpu>-rtems/<bsp>/lib/dummy.rel \
|
|
||||||
CC="<cpu>-rtems-gcc \
|
|
||||||
-B/usr/local/rtems/<cpu>-rtems/<bsp>/lib/ -specs bsp_specs -qrtems" \
|
|
||||||
CC_FOR_BUILD="gcc" \
|
|
||||||
configure --host=<cpu>-rtems --build=i686-pc-linux-gnu
|
|
||||||
make
|
|
||||||
|
|
||||||
History:
|
|
||||||
Starting dummy.c with a copy of rtems-19990528/c/src/tests/samples/minimum/init.c
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/* Init
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Input parameters: NONE
|
|
||||||
*
|
|
||||||
* Output parameters: NONE
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
rtems_task Init(
|
|
||||||
rtems_task_argument ignored
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int main( int, char **, char **);
|
|
||||||
|
|
||||||
/* configuration information */
|
|
||||||
|
|
||||||
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
|
|
||||||
#define CONFIGURE_MAXIMUM_TASKS 10
|
|
||||||
#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
|
|
||||||
#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 20
|
|
||||||
#define CONFIGURE_INIT_TASK_ENTRY_POINT (void *)main
|
|
||||||
|
|
||||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
|
||||||
#define CONFIGURE_INIT
|
|
||||||
|
|
||||||
#include <confdefs.h>
|
|
||||||
|
|
||||||
/* global variables */
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libdumpbuf-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = dumpbuf.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = dumpbuf.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = dumpbuf.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* COPYRIGHT (c) 1997.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may in
|
|
||||||
* the file LICENSE in this distribution or at
|
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <rtems/dumpbuf.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Put the body below Dump_Buffer so it won't get inlined.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void Dump_Line(
|
|
||||||
unsigned char *buffer,
|
|
||||||
int length
|
|
||||||
);
|
|
||||||
|
|
||||||
void Dump_Buffer(
|
|
||||||
unsigned char *buffer,
|
|
||||||
int length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
int i, mod, max;
|
|
||||||
|
|
||||||
if ( !length ) return;
|
|
||||||
|
|
||||||
mod = length % 16;
|
|
||||||
|
|
||||||
max = length - mod;
|
|
||||||
|
|
||||||
for ( i=0 ; i<max ; i+=16 )
|
|
||||||
Dump_Line( &buffer[ i ], 16 );
|
|
||||||
|
|
||||||
if ( mod )
|
|
||||||
Dump_Line( &buffer[ max ], mod );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Dump_Line(
|
|
||||||
unsigned char *buffer,
|
|
||||||
int length
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
int i;
|
|
||||||
char line_buffer[120];
|
|
||||||
|
|
||||||
line_buffer[0] = '\0';
|
|
||||||
|
|
||||||
for( i=0 ; i<length ; i++ )
|
|
||||||
sprintf( line_buffer, "%s%02x ", line_buffer, buffer[ i ] );
|
|
||||||
|
|
||||||
for( ; i<16 ; i++ )
|
|
||||||
strcat( line_buffer, " " );
|
|
||||||
|
|
||||||
strcat( line_buffer, "|" );
|
|
||||||
for( i=0 ; i<length ; i++ )
|
|
||||||
sprintf( line_buffer, "%s%c", line_buffer,
|
|
||||||
isprint( buffer[ i ] ) ? buffer[ i ] : '.' );
|
|
||||||
|
|
||||||
for( ; i<16 ; i++ )
|
|
||||||
strcat( line_buffer, " " );
|
|
||||||
|
|
||||||
strcat( line_buffer, "|\n" );
|
|
||||||
|
|
||||||
printf( line_buffer );
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* COPYRIGHT (c) 1997.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* The license and distribution terms for this file may in
|
|
||||||
* the file LICENSE in this distribution or at
|
|
||||||
* http://www.OARcorp.com/rtems/license.html.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DUMP_BUFFER_h
|
|
||||||
#define __DUMP_BUFFER_h
|
|
||||||
|
|
||||||
void Dump_Buffer(
|
|
||||||
unsigned char *buffer,
|
|
||||||
int length
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* end of include file */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libmonitor-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
# We only build multiprocessing related files if HAS_MP was defined
|
|
||||||
MP_C_FILES = mon-mpci.c
|
|
||||||
|
|
||||||
C_FILES = mon-command.c mon-symbols.c mon-prmisc.c mon-monitor.c \
|
|
||||||
mon-object.c mon-server.c mon-task.c mon-queue.c mon-driver.c \
|
|
||||||
mon-dname.c mon-itask.c mon-extension.c mon-manager.c mon-config.c
|
|
||||||
|
|
||||||
if HAS_MP
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT)) $(MP_C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
else
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
endif
|
|
||||||
|
|
||||||
include_rtems_HEADERS = monitor.h symbols.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README mon-command.c mon-config.c mon-dname.c mon-driver.c \
|
|
||||||
mon-extension.c mon-itask.c mon-manager.c mon-monitor.c mon-mpci.c \
|
|
||||||
mon-object.c mon-prmisc.c mon-queue.c mon-server.c mon-symbols.c \
|
|
||||||
mon-task.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
monitor task
|
|
||||||
|
|
||||||
The monitor task is an optional task that knows about RTEMS
|
|
||||||
data structures and can print out information about them.
|
|
||||||
It is a work-in-progress and needs many more commands, but
|
|
||||||
is useful now.
|
|
||||||
|
|
||||||
The monitor works best when it is the highest priority task,
|
|
||||||
so all your other tasks should ideally be at some priority
|
|
||||||
greater than 1.
|
|
||||||
|
|
||||||
To use the monitor:
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
rtems_monitor_init(0);
|
|
||||||
|
|
||||||
The parameter to rtems_monitor_init() tells the monitor whether
|
|
||||||
to suspend itself on startup. A value of 0 causes the monitor
|
|
||||||
to immediately enter command mode; a non-zero value causes the
|
|
||||||
monitor to suspend itself after creation and wait for explicit
|
|
||||||
wakeup.
|
|
||||||
|
|
||||||
|
|
||||||
rtems_monitor_wakeup();
|
|
||||||
|
|
||||||
wakes up a suspended monitor and causes it to reenter command mode.
|
|
||||||
|
|
||||||
Monitor commands
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The monitor prompt is 'rtems> '.
|
|
||||||
Can abbreviate commands to "uniquity"
|
|
||||||
There is a 'help' command. Here is the output from various
|
|
||||||
help commands:
|
|
||||||
|
|
||||||
Commands (may be abbreviated)
|
|
||||||
|
|
||||||
help -- get this message or command specific help
|
|
||||||
task -- show task information
|
|
||||||
queue -- show message queue information
|
|
||||||
symbol -- show entries from symbol table
|
|
||||||
pause -- pause monitor for a specified number of ticks
|
|
||||||
fatal -- invoke a fatal RTEMS error
|
|
||||||
|
|
||||||
task [id [id ...] ]
|
|
||||||
display information about the specified tasks.
|
|
||||||
Default is to display information about all tasks on this node
|
|
||||||
|
|
||||||
queue [id [id ... ] ]
|
|
||||||
display information about the specified message queues
|
|
||||||
Default is to display information about all queues on this node
|
|
||||||
|
|
||||||
symbol [ symbolname [symbolname ... ] ]
|
|
||||||
display value associated with specified symbol.
|
|
||||||
Defaults to displaying all known symbols.
|
|
||||||
|
|
||||||
pause [ticks]
|
|
||||||
monitor goes to "sleep" for specified ticks (default is 1)
|
|
||||||
monitor will resume at end of period or if explicitly awakened
|
|
||||||
|
|
||||||
fatal [status]
|
|
||||||
Invoke 'rtems_fatal_error_occurred' with 'status'
|
|
||||||
(default is RTEMS_INTERNAL_ERROR)
|
|
||||||
|
|
||||||
continue
|
|
||||||
put the monitor to sleep waiting for an explicit wakeup from the
|
|
||||||
program running.
|
|
||||||
|
|
||||||
|
|
||||||
Sample output from 'task' command
|
|
||||||
---------------------------------
|
|
||||||
|
|
||||||
rtems> task
|
|
||||||
ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
00010001 UI1 2 READY P:T:nA NONE15: 0x40606348
|
|
||||||
00010002 RMON 1 READY nP NONE15: 0x40604110
|
|
||||||
|
|
||||||
'RMON' is the monitor itself, so we have 1 "user" task.
|
|
||||||
Its modes are P:T:nA which translate to:
|
|
||||||
|
|
||||||
preemptable
|
|
||||||
timesliced
|
|
||||||
no ASRS
|
|
||||||
|
|
||||||
It has no events.
|
|
||||||
It has a notepad value for notepad 15 which is 0x40606348
|
|
||||||
(this is the libc thread state)
|
|
||||||
|
|
||||||
@@ -1,733 +0,0 @@
|
|||||||
/*
|
|
||||||
* Command parsing routines for RTEMS monitor
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 2001-01-30 KJO (vac4050@cae597.rsc.raytheon.com):
|
|
||||||
* Fixed rtems_monitor_command_lookup() to accept partial
|
|
||||||
* commands to uniqeness. Added support for setting
|
|
||||||
* the monitor prompt via an environment variable:
|
|
||||||
* RTEMS_MONITOR_PROMPT
|
|
||||||
*
|
|
||||||
* CCJ: 26-3-2000, adding command history and command line
|
|
||||||
* editing. This code is donated from My Right Boot and not
|
|
||||||
* covered by GPL, only the RTEMS license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Some key labels to define special keys.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define KEYS_EXTENDED (0x8000)
|
|
||||||
#define KEYS_NORMAL_MASK (0x00ff)
|
|
||||||
#define KEYS_INS (0)
|
|
||||||
#define KEYS_DEL (1)
|
|
||||||
#define KEYS_UARROW (2)
|
|
||||||
#define KEYS_DARROW (3)
|
|
||||||
#define KEYS_LARROW (4)
|
|
||||||
#define KEYS_RARROW (5)
|
|
||||||
#define KEYS_HOME (6)
|
|
||||||
#define KEYS_END (7)
|
|
||||||
#define KEYS_F1 (8)
|
|
||||||
#define KEYS_F2 (9)
|
|
||||||
#define KEYS_F3 (10)
|
|
||||||
#define KEYS_F4 (11)
|
|
||||||
#define KEYS_F5 (12)
|
|
||||||
#define KEYS_F6 (13)
|
|
||||||
#define KEYS_F7 (14)
|
|
||||||
#define KEYS_F8 (15)
|
|
||||||
#define KEYS_F9 (16)
|
|
||||||
#define KEYS_F10 (17)
|
|
||||||
|
|
||||||
#define RTEMS_COMMAND_BUFFER_SIZE (75)
|
|
||||||
|
|
||||||
static char monitor_prompt[32];
|
|
||||||
#ifndef RTEMS_UNIX
|
|
||||||
static char buffer[RTEMS_COMMAND_BUFFER_SIZE];
|
|
||||||
static int pos;
|
|
||||||
static int logged_in;
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* History data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RTEMS_COMMAND_HISTORIES (20)
|
|
||||||
|
|
||||||
#ifndef RTEMS_UNIX
|
|
||||||
static char history_buffer[RTEMS_COMMAND_HISTORIES][RTEMS_COMMAND_BUFFER_SIZE];
|
|
||||||
static int history_pos[RTEMS_COMMAND_HISTORIES];
|
|
||||||
static int history;
|
|
||||||
static int history_next;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Translation tables. Not sure if this is the best way to
|
|
||||||
* handle this, how-ever I wish to avoid the overhead of
|
|
||||||
* including a more complete and standard environment such
|
|
||||||
* as ncurses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct translation_table
|
|
||||||
{
|
|
||||||
char expecting;
|
|
||||||
struct translation_table *branch;
|
|
||||||
unsigned int key;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct translation_table trans_two[] =
|
|
||||||
{
|
|
||||||
{ '~', 0, KEYS_INS },
|
|
||||||
{ 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct translation_table trans_three[] =
|
|
||||||
{
|
|
||||||
{ '~', 0, KEYS_DEL },
|
|
||||||
{ 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct translation_table trans_tab_csi[] =
|
|
||||||
{
|
|
||||||
{ '2', trans_two, 0 },
|
|
||||||
{ '3', trans_three, 0 },
|
|
||||||
{ 'A', 0, KEYS_UARROW },
|
|
||||||
{ 'B', 0, KEYS_DARROW },
|
|
||||||
{ 'D', 0, KEYS_LARROW },
|
|
||||||
{ 'C', 0, KEYS_RARROW },
|
|
||||||
{ 'F', 0, KEYS_END },
|
|
||||||
{ 'H', 0, KEYS_HOME },
|
|
||||||
{ 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct translation_table trans_tab_O[] =
|
|
||||||
{
|
|
||||||
{ '1', 0, KEYS_F1 },
|
|
||||||
{ '2', 0, KEYS_F2 },
|
|
||||||
{ '3', 0, KEYS_F3 },
|
|
||||||
{ '4', 0, KEYS_F4 },
|
|
||||||
{ '5', 0, KEYS_F5 },
|
|
||||||
{ '6', 0, KEYS_F6 },
|
|
||||||
{ '7', 0, KEYS_F7 },
|
|
||||||
{ '8', 0, KEYS_F8 },
|
|
||||||
{ '9', 0, KEYS_F9 },
|
|
||||||
{ ':', 0, KEYS_F10 },
|
|
||||||
{ 'P', 0, KEYS_F1 },
|
|
||||||
{ 'Q', 0, KEYS_F2 },
|
|
||||||
{ 'R', 0, KEYS_F3 },
|
|
||||||
{ 'S', 0, KEYS_F4 },
|
|
||||||
{ 'T', 0, KEYS_F5 },
|
|
||||||
{ 'U', 0, KEYS_F6 },
|
|
||||||
{ 'V', 0, KEYS_F7 },
|
|
||||||
{ 'W', 0, KEYS_F8 },
|
|
||||||
{ 'X', 0, KEYS_F9 },
|
|
||||||
{ 'Y', 0, KEYS_F10 },
|
|
||||||
{ 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct translation_table trans_tab[] =
|
|
||||||
{
|
|
||||||
{ '[', trans_tab_csi, 0 }, /* CSI command sequences */
|
|
||||||
{ 'O', trans_tab_O, 0 }, /* O are the fuction keys */
|
|
||||||
{ 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform a basic tranlation for some ANSI/VT100 key codes.
|
|
||||||
* This code could do with a timeout on the ESC as it is
|
|
||||||
* now lost from the input stream. It is not* used by the
|
|
||||||
* line editor below so considiered not worth the effort.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
rtems_monitor_getchar (
|
|
||||||
)
|
|
||||||
{
|
|
||||||
struct translation_table *translation = 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
char c = getchar ();
|
|
||||||
if (c == 27)
|
|
||||||
translation = trans_tab;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If no translation happing just pass through
|
|
||||||
* and return the key.
|
|
||||||
*/
|
|
||||||
if (translation)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Scan the current table for the key, and if found
|
|
||||||
* see if this key is a fork. If so follow it and
|
|
||||||
* wait else return the extended key.
|
|
||||||
*/
|
|
||||||
int index = 0;
|
|
||||||
int branched = 0;
|
|
||||||
while ((translation[index].expecting != '\0') ||
|
|
||||||
(translation[index].key != '\0'))
|
|
||||||
{
|
|
||||||
if (translation[index].expecting == c)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* A branch is take if more keys are to come.
|
|
||||||
*/
|
|
||||||
if (translation[index].branch == 0)
|
|
||||||
return KEYS_EXTENDED | translation[index].key;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
translation = translation[index].branch;
|
|
||||||
branched = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Who knows what these keys are, just drop them.
|
|
||||||
*/
|
|
||||||
if (!branched)
|
|
||||||
translation = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef RTEMS_UNIX
|
|
||||||
/*
|
|
||||||
* The line editor with history.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
rtems_monitor_line_editor (
|
|
||||||
char *command
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int repeating = 0;
|
|
||||||
|
|
||||||
memset (buffer, 0, RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
history = history_next;
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
if (!logged_in)
|
|
||||||
printf ("\nMonitor ready, press enter to login.\n\n");
|
|
||||||
else
|
|
||||||
printf ("%s $ ", monitor_prompt);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
unsigned int extended_key = rtems_monitor_getchar ();
|
|
||||||
char c = extended_key & KEYS_NORMAL_MASK;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make the extended_key usable as a boolean.
|
|
||||||
*/
|
|
||||||
extended_key &= ~KEYS_NORMAL_MASK;
|
|
||||||
|
|
||||||
if (!extended_key && !logged_in)
|
|
||||||
{
|
|
||||||
if (c == '\n')
|
|
||||||
{
|
|
||||||
logged_in = 1;
|
|
||||||
/*
|
|
||||||
* The prompt has changed from `>' to `$' to help know
|
|
||||||
* which version of the monitor code people are using.
|
|
||||||
*/
|
|
||||||
printf("%s $ ", monitor_prompt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (extended_key)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case KEYS_END:
|
|
||||||
printf (buffer + pos);
|
|
||||||
pos = (int) strlen (buffer);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYS_HOME:
|
|
||||||
printf ("\r%s $ ", monitor_prompt);
|
|
||||||
pos = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYS_LARROW:
|
|
||||||
if (pos > 0)
|
|
||||||
{
|
|
||||||
pos--;
|
|
||||||
putchar ('\b');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYS_RARROW:
|
|
||||||
if ((pos < RTEMS_COMMAND_BUFFER_SIZE) && (buffer[pos] != '\0'))
|
|
||||||
{
|
|
||||||
putchar (buffer[pos]);
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYS_UARROW:
|
|
||||||
/*
|
|
||||||
* If we are moving up the histories then we need to save the working
|
|
||||||
* buffer.
|
|
||||||
*/
|
|
||||||
if (history)
|
|
||||||
{
|
|
||||||
int end;
|
|
||||||
int bs;
|
|
||||||
if (history == history_next)
|
|
||||||
{
|
|
||||||
memcpy (history_buffer[history_next], buffer,
|
|
||||||
RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
history_pos[history_next] = pos;
|
|
||||||
}
|
|
||||||
history--;
|
|
||||||
memcpy (buffer, history_buffer[history],
|
|
||||||
RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
pos = history_pos[history];
|
|
||||||
printf ("\r%*c", RTEMS_COMMAND_BUFFER_SIZE, ' ');
|
|
||||||
printf ("\r%s $ %s", monitor_prompt, buffer);
|
|
||||||
end = (int) strlen (buffer);
|
|
||||||
for (bs = 0; bs < (end - pos); bs++)
|
|
||||||
putchar ('\b');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYS_DARROW:
|
|
||||||
if (history < history_next)
|
|
||||||
{
|
|
||||||
int end;
|
|
||||||
int bs;
|
|
||||||
history++;
|
|
||||||
memcpy (buffer, history_buffer[history],
|
|
||||||
RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
pos = history_pos[history];
|
|
||||||
printf ("\r%*c", RTEMS_COMMAND_BUFFER_SIZE, ' ');
|
|
||||||
printf ("\r%s $ %s", monitor_prompt, buffer);
|
|
||||||
end = (int) strlen (buffer);
|
|
||||||
for (bs = 0; bs < (end - pos); bs++)
|
|
||||||
putchar ('\b');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEYS_DEL:
|
|
||||||
if (buffer[pos] != '\0')
|
|
||||||
{
|
|
||||||
int end;
|
|
||||||
int bs;
|
|
||||||
strcpy (&buffer[pos], &buffer[pos + 1]);
|
|
||||||
printf ("\r%s $ %s", monitor_prompt, buffer);
|
|
||||||
end = (int) strlen (buffer);
|
|
||||||
for (bs = 0; bs < (end - pos); bs++)
|
|
||||||
putchar ('\b');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\b':
|
|
||||||
case '\x7e':
|
|
||||||
case '\x7f':
|
|
||||||
if (pos > 0)
|
|
||||||
{
|
|
||||||
int bs;
|
|
||||||
pos--;
|
|
||||||
strcpy (buffer + pos, buffer + pos + 1);
|
|
||||||
printf ("\b%s \b", buffer + pos);
|
|
||||||
for (bs = 0; bs < ((int) strlen (buffer) - pos); bs++)
|
|
||||||
putchar ('\b');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\n':
|
|
||||||
/*
|
|
||||||
* Process the command.
|
|
||||||
*/
|
|
||||||
printf ("\n");
|
|
||||||
repeating = 1;
|
|
||||||
/*
|
|
||||||
* Only process the history if we have a command and
|
|
||||||
*a history.
|
|
||||||
*/
|
|
||||||
if (strlen (buffer))
|
|
||||||
{
|
|
||||||
if (history_next && (history == history_next))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Do not place the last command into the history
|
|
||||||
*if the same.
|
|
||||||
*/
|
|
||||||
if (strcmp (history_buffer[history_next - 1], buffer))
|
|
||||||
repeating = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
repeating = 0;
|
|
||||||
}
|
|
||||||
if (!repeating)
|
|
||||||
{
|
|
||||||
memcpy (history_buffer[history_next], buffer,
|
|
||||||
RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
history_pos[history_next] = pos;
|
|
||||||
if (history_next < (RTEMS_COMMAND_HISTORIES - 1))
|
|
||||||
history_next++;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memmove (history_buffer[0], history_buffer[1],
|
|
||||||
RTEMS_COMMAND_BUFFER_SIZE * (RTEMS_COMMAND_HISTORIES - 1));
|
|
||||||
memmove (&history_pos[0], &history_pos[1],
|
|
||||||
sizeof (history_pos[0]) * (RTEMS_COMMAND_HISTORIES - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_ENTER_REPEATS
|
|
||||||
if (history_next)
|
|
||||||
memcpy (buffer, history_buffer[history_next - 1],
|
|
||||||
RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
memmove (command, buffer, RTEMS_COMMAND_BUFFER_SIZE);
|
|
||||||
return repeating;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if ((pos < (RTEMS_COMMAND_BUFFER_SIZE - 1)) &&
|
|
||||||
(c >= ' ') && (c <= 'z'))
|
|
||||||
{
|
|
||||||
int end;
|
|
||||||
end = strlen (buffer);
|
|
||||||
if ((pos < end) && (end < RTEMS_COMMAND_BUFFER_SIZE))
|
|
||||||
{
|
|
||||||
int ch, bs;
|
|
||||||
for (ch = end + 1; ch > pos; ch--)
|
|
||||||
buffer[ch] = buffer[ch - 1];
|
|
||||||
printf (buffer + pos);
|
|
||||||
for (bs = 0; bs < (end - pos + 1); bs++)
|
|
||||||
putchar ('\b');
|
|
||||||
}
|
|
||||||
buffer[pos++] = c;
|
|
||||||
if (pos > end)
|
|
||||||
buffer[pos] = '\0';
|
|
||||||
putchar (c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* make_argv(cp): token-count
|
|
||||||
* Break up the command line in 'cp' into global argv[] and argc (return
|
|
||||||
* value).
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
rtems_monitor_make_argv(
|
|
||||||
char *cp,
|
|
||||||
int *argc_p,
|
|
||||||
char **argv)
|
|
||||||
{
|
|
||||||
int argc = 0;
|
|
||||||
|
|
||||||
while ((cp = strtok(cp, " \t\n\r")))
|
|
||||||
{
|
|
||||||
argv[argc++] = cp;
|
|
||||||
cp = (char *) NULL;
|
|
||||||
}
|
|
||||||
argv[argc] = (char *) NULL; /* end of argv */
|
|
||||||
|
|
||||||
return *argc_p = argc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read and break up a monitor command
|
|
||||||
*
|
|
||||||
* We have to loop on the gets call, since it will return NULL under UNIX
|
|
||||||
* RTEMS when we get a signal (eg: SIGALRM).
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
rtems_monitor_command_read(char *command,
|
|
||||||
int *argc,
|
|
||||||
char **argv)
|
|
||||||
{
|
|
||||||
char *env_prompt;
|
|
||||||
|
|
||||||
env_prompt = getenv("RTEMS_MONITOR_PROMPT");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* put node number in the prompt if we are multiprocessing
|
|
||||||
*/
|
|
||||||
if (!rtems_configuration_get_user_multiprocessing_table ())
|
|
||||||
sprintf (monitor_prompt, "%s",
|
|
||||||
(env_prompt == NULL) ? MONITOR_PROMPT: env_prompt);
|
|
||||||
else if (rtems_monitor_default_node != rtems_monitor_node)
|
|
||||||
sprintf (monitor_prompt, "%d-%s-%d", rtems_monitor_node,
|
|
||||||
(env_prompt == NULL) ? MONITOR_PROMPT : env_prompt,
|
|
||||||
rtems_monitor_default_node);
|
|
||||||
else
|
|
||||||
sprintf (monitor_prompt, "%d-%s", rtems_monitor_node,
|
|
||||||
(env_prompt == NULL) ? MONITOR_PROMPT : env_prompt);
|
|
||||||
|
|
||||||
#if defined(RTEMS_UNIX)
|
|
||||||
/* RTEMS on unix gets so many interrupt system calls this is hosed */
|
|
||||||
printf ("%s> ", monitor_prompt);
|
|
||||||
fflush (stdout);
|
|
||||||
while (gets(command) == (char *) 0)
|
|
||||||
;
|
|
||||||
#else
|
|
||||||
rtems_monitor_line_editor (command);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return rtems_monitor_make_argv (command, argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look up a command in a command table
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_monitor_command_entry_t *
|
|
||||||
rtems_monitor_command_lookup(
|
|
||||||
rtems_monitor_command_entry_t *table,
|
|
||||||
int argc,
|
|
||||||
char **argv
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int command_length;
|
|
||||||
rtems_monitor_command_entry_t *found_it = NULL;
|
|
||||||
|
|
||||||
command_length = strlen (argv[0]);
|
|
||||||
|
|
||||||
if ((table == 0) || (argv[0] == 0))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
while (table)
|
|
||||||
{
|
|
||||||
if (table->command)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check for ambiguity
|
|
||||||
*/
|
|
||||||
if (!strncmp (table->command, argv[0], command_length))
|
|
||||||
{
|
|
||||||
if (found_it)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
found_it = table;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
table = table->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* No ambiguity (the possible partial command was unique after all)
|
|
||||||
*/
|
|
||||||
if (found_it)
|
|
||||||
{
|
|
||||||
if (table->command_function == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return found_it;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_show_help (
|
|
||||||
rtems_monitor_command_entry_t *help_cmd,
|
|
||||||
int max_cmd_len
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#define MAX_HELP_LINE_LENGTH (75 - max_cmd_len - 2)
|
|
||||||
|
|
||||||
if (help_cmd && help_cmd->command)
|
|
||||||
{
|
|
||||||
const char *help = help_cmd->usage;
|
|
||||||
int help_len = strlen (help);
|
|
||||||
int spaces = max_cmd_len - strlen (help_cmd->command);
|
|
||||||
int show_this_line = 0;
|
|
||||||
int line_one = 1;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
printf ("%s", help_cmd->command);
|
|
||||||
|
|
||||||
if (help_len == 0)
|
|
||||||
{
|
|
||||||
printf (" - No help associated.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (help_len)
|
|
||||||
{
|
|
||||||
printf ("%*c", spaces, ' ');
|
|
||||||
|
|
||||||
if (line_one)
|
|
||||||
printf (" - ");
|
|
||||||
|
|
||||||
spaces = max_cmd_len + 2;
|
|
||||||
line_one = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* See if greater then the line length if so, work back
|
|
||||||
* from the end for a space, tab or lf or cr.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (help_len > MAX_HELP_LINE_LENGTH)
|
|
||||||
{
|
|
||||||
for (show_this_line = MAX_HELP_LINE_LENGTH - 1;
|
|
||||||
show_this_line;
|
|
||||||
show_this_line--)
|
|
||||||
if ((help[show_this_line] == ' ') ||
|
|
||||||
(help[show_this_line] == '\n') ||
|
|
||||||
(help[show_this_line] == '\r'))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If show_this_line is 0, it is a very long word !!
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (show_this_line == 0)
|
|
||||||
show_this_line = MAX_HELP_LINE_LENGTH - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
show_this_line = help_len;
|
|
||||||
|
|
||||||
for (c = 0; c < show_this_line; c++)
|
|
||||||
if ((help[c] == '\r') || (help[c] == '\n'))
|
|
||||||
show_this_line = c;
|
|
||||||
else
|
|
||||||
putchar (help[c]);
|
|
||||||
|
|
||||||
printf ("\n");
|
|
||||||
|
|
||||||
help += show_this_line;
|
|
||||||
help_len -= show_this_line;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Move past the line feeds or what ever else is being skipped.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (help_len)
|
|
||||||
{
|
|
||||||
if ((*help != '\r') && (*help != '\n'))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (*help != ' ')
|
|
||||||
{
|
|
||||||
help++;
|
|
||||||
help_len--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
help++;
|
|
||||||
help_len--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_command_usage(
|
|
||||||
rtems_monitor_command_entry_t *table,
|
|
||||||
char *command_string
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_command_entry_t *command = table;
|
|
||||||
int max_cmd_len = 0;
|
|
||||||
|
|
||||||
/* if first entry in table is a usage, then print it out */
|
|
||||||
|
|
||||||
if (command_string && (*command_string != '\0'))
|
|
||||||
{
|
|
||||||
char *argv[2];
|
|
||||||
|
|
||||||
argv[0] = command_string;
|
|
||||||
argv[1] = 0;
|
|
||||||
|
|
||||||
command = rtems_monitor_command_lookup (table, 1, argv);
|
|
||||||
|
|
||||||
if (command)
|
|
||||||
rtems_monitor_show_help (command, strlen (command_string));
|
|
||||||
else
|
|
||||||
printf ("Unrecognised command; try just 'help'\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Find the largest command size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (command)
|
|
||||||
{
|
|
||||||
int len = strlen (command->command);
|
|
||||||
|
|
||||||
if (len > max_cmd_len)
|
|
||||||
max_cmd_len = len;
|
|
||||||
|
|
||||||
command = command->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_cmd_len++;
|
|
||||||
|
|
||||||
command = table;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now some nice formatting for the help.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (command)
|
|
||||||
{
|
|
||||||
rtems_monitor_show_help (command, max_cmd_len);
|
|
||||||
command = command->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_help_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int arg;
|
|
||||||
rtems_monitor_command_entry_t *command;
|
|
||||||
|
|
||||||
command = (rtems_monitor_command_entry_t *) command_arg;
|
|
||||||
|
|
||||||
if (argc == 1)
|
|
||||||
rtems_monitor_command_usage(command, 0);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (arg = 1; argv[arg]; arg++)
|
|
||||||
rtems_monitor_command_usage(command, argv[arg]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS Config display support
|
|
||||||
*
|
|
||||||
* TODO
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h> /* strtoul() */
|
|
||||||
|
|
||||||
#define DATACOL 15
|
|
||||||
#define CONTCOL DATACOL /* continued col */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill in entire monitor config table
|
|
||||||
* for sending to a remote monitor or printing on the local system
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_config_canonical(
|
|
||||||
rtems_monitor_config_t *canonical_config,
|
|
||||||
void *config_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_configuration_table *c = (rtems_configuration_table *) config_void;
|
|
||||||
rtems_api_configuration_table *r = c->RTEMS_api_configuration;
|
|
||||||
|
|
||||||
canonical_config->work_space_start = c->work_space_start;
|
|
||||||
canonical_config->work_space_size = c->work_space_size;
|
|
||||||
canonical_config->maximum_tasks = r->maximum_tasks;
|
|
||||||
canonical_config->maximum_timers = r->maximum_timers;
|
|
||||||
canonical_config->maximum_semaphores = r->maximum_semaphores;
|
|
||||||
canonical_config->maximum_message_queues = r->maximum_message_queues;
|
|
||||||
canonical_config->maximum_partitions = r->maximum_partitions;
|
|
||||||
canonical_config->maximum_regions = r->maximum_regions;
|
|
||||||
canonical_config->maximum_ports = r->maximum_ports;
|
|
||||||
canonical_config->maximum_periods = r->maximum_periods;
|
|
||||||
canonical_config->maximum_extensions = c->maximum_extensions;
|
|
||||||
canonical_config->microseconds_per_tick = c->microseconds_per_tick;
|
|
||||||
canonical_config->ticks_per_timeslice = c->ticks_per_timeslice;
|
|
||||||
canonical_config->number_of_initialization_tasks = r->number_of_initialization_tasks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is easy, since there is only 1 (altho we could get them from
|
|
||||||
* other nodes...)
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_config_next(
|
|
||||||
void *object_info,
|
|
||||||
rtems_monitor_config_t *canonical_config,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_configuration_table *c = _Configuration_Table;
|
|
||||||
int n = rtems_get_index(*next_id);
|
|
||||||
|
|
||||||
if (n >= 1)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
*next_id += 1;
|
|
||||||
return (void *) c;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
*next_id = RTEMS_OBJECT_ID_FINAL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_config_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
INITIAL (startup) Configuration Info\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_config_dump(
|
|
||||||
rtems_monitor_config_t *monitor_config,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
length = 0;
|
|
||||||
length += printf("WORKSPACE");
|
|
||||||
length += rtems_monitor_pad(DATACOL, length);
|
|
||||||
length += printf("start: 0x%x; size: 0x%x\n",
|
|
||||||
(unsigned32) monitor_config->work_space_start,
|
|
||||||
monitor_config->work_space_size);
|
|
||||||
|
|
||||||
length = 0;
|
|
||||||
length += printf("TIME");
|
|
||||||
length += rtems_monitor_pad(DATACOL, length);
|
|
||||||
length += printf("usec/tick: %d; tick/timeslice: %d; tick/sec: %d\n",
|
|
||||||
monitor_config->microseconds_per_tick,
|
|
||||||
monitor_config->ticks_per_timeslice,
|
|
||||||
1000000 / monitor_config->microseconds_per_tick);
|
|
||||||
|
|
||||||
length = 0;
|
|
||||||
length += printf("MAXIMUMS");
|
|
||||||
length += rtems_monitor_pad(DATACOL, length);
|
|
||||||
length += printf("tasks: %d; timers: %d; sems: %d; que's: %d; ext's: %d\n",
|
|
||||||
monitor_config->maximum_tasks,
|
|
||||||
monitor_config->maximum_timers,
|
|
||||||
monitor_config->maximum_semaphores,
|
|
||||||
monitor_config->maximum_message_queues,
|
|
||||||
monitor_config->maximum_extensions);
|
|
||||||
length = 0;
|
|
||||||
length += rtems_monitor_pad(CONTCOL, length);
|
|
||||||
length += printf("partitions: %d; regions: %d; ports: %d; periods: %d\n",
|
|
||||||
monitor_config->maximum_partitions,
|
|
||||||
monitor_config->maximum_regions,
|
|
||||||
monitor_config->maximum_ports,
|
|
||||||
monitor_config->maximum_periods);
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS monitor driver names support.
|
|
||||||
*
|
|
||||||
* There are 2 "driver" things the monitor knows about.
|
|
||||||
*
|
|
||||||
* 1. Regular RTEMS drivers.
|
|
||||||
* This is a table indexed by major device number and
|
|
||||||
* containing driver entry points only.
|
|
||||||
*
|
|
||||||
* 2. Driver name table.
|
|
||||||
* A separate table of names for drivers.
|
|
||||||
* The table converts driver names to a major number
|
|
||||||
* as index into the driver table and a minor number
|
|
||||||
* for an argument to driver.
|
|
||||||
*
|
|
||||||
* Drivers are displayed with 'driver' command.
|
|
||||||
* Names are displayed with 'dname' command.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h> /* strtoul() */
|
|
||||||
#include <string.h> /* strncpy() */
|
|
||||||
|
|
||||||
#define DATACOL 15
|
|
||||||
#define CONTCOL DATACOL /* continued col */
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_dname_canonical(
|
|
||||||
rtems_monitor_dname_t *canonical_dname,
|
|
||||||
void *dname_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_driver_name_t *np = (rtems_driver_name_t *) dname_void;
|
|
||||||
|
|
||||||
(void) strncpy(canonical_dname->name_string, np->device_name, sizeof(canonical_dname->name_string));
|
|
||||||
canonical_dname->major = np->major;
|
|
||||||
canonical_dname->minor = np->minor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_dname_next(
|
|
||||||
void *object_information,
|
|
||||||
rtems_monitor_dname_t *canonical_dname,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_unsigned32 n = rtems_get_index(*next_id);
|
|
||||||
rtems_driver_name_t *table = _IO_Driver_name_table;
|
|
||||||
rtems_driver_name_t *np = 0;
|
|
||||||
|
|
||||||
/* XXX should we be using _IO_Number_of_devices */
|
|
||||||
for (np = table + n ; n<_IO_Number_of_devices; n++, np++)
|
|
||||||
if (np->device_name)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
*next_id = RTEMS_OBJECT_ID_FINAL;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
done:
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dummy up a fake id and name for this item
|
|
||||||
*/
|
|
||||||
|
|
||||||
canonical_dname->id = n;
|
|
||||||
canonical_dname->name = rtems_build_name('-', '-', '-', '-');
|
|
||||||
|
|
||||||
*next_id += 1;
|
|
||||||
return np;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_dname_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
Major:Minor Name\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_dname_dump(
|
|
||||||
rtems_monitor_dname_t *monitor_dname,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(6, length);
|
|
||||||
length += rtems_monitor_dump_hex(monitor_dname->major);
|
|
||||||
length += printf(":");
|
|
||||||
length += rtems_monitor_dump_hex(monitor_dname->minor);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(16, length);
|
|
||||||
length += printf("%.*s",
|
|
||||||
(int) sizeof(monitor_dname->name_string),
|
|
||||||
(char *) monitor_dname->name_string);
|
|
||||||
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS monitor IO (device drivers) support
|
|
||||||
*
|
|
||||||
* There are 2 "driver" things the monitor knows about.
|
|
||||||
*
|
|
||||||
* 1. Regular RTEMS drivers.
|
|
||||||
* This is a table indexed by major device number and
|
|
||||||
* containing driver entry points only.
|
|
||||||
*
|
|
||||||
* 2. Driver name table.
|
|
||||||
* A separate table of names for drivers.
|
|
||||||
* The table converts driver names to a major number
|
|
||||||
* as index into the driver table and a minor number
|
|
||||||
* for an argument to driver.
|
|
||||||
*
|
|
||||||
* Drivers are displayed with 'driver' command.
|
|
||||||
* Names are displayed with 'name' command.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h> /* strtoul() */
|
|
||||||
|
|
||||||
#define DATACOL 15
|
|
||||||
#define CONTCOL DATACOL /* continued col */
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_driver_canonical(
|
|
||||||
rtems_monitor_driver_t *canonical_driver,
|
|
||||||
void *driver_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_driver_address_table *d = (rtems_driver_address_table *) driver_void;
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->initialization,
|
|
||||||
(void *) d->initialization_entry);
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
|
|
||||||
(void *) d->open_entry);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
|
|
||||||
(void *) d->close_entry);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
|
|
||||||
(void *) d->read_entry);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
|
|
||||||
(void *) d->write_entry);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
|
|
||||||
(void *) d->control_entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_driver_next(
|
|
||||||
void *object_info,
|
|
||||||
rtems_monitor_driver_t *canonical_driver,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_configuration_table *c = _Configuration_Table;
|
|
||||||
rtems_unsigned32 n = rtems_get_index(*next_id);
|
|
||||||
|
|
||||||
if (n >= c->number_of_device_drivers)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dummy up a fake id and name for this item
|
|
||||||
*/
|
|
||||||
|
|
||||||
canonical_driver->id = n;
|
|
||||||
canonical_driver->name = rtems_build_name('-', '-', '-', '-');
|
|
||||||
|
|
||||||
*next_id += 1;
|
|
||||||
return (void *) (c->Device_driver_table + n);
|
|
||||||
|
|
||||||
failed:
|
|
||||||
*next_id = RTEMS_OBJECT_ID_FINAL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_driver_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
Major Entry points\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_driver_dump(
|
|
||||||
rtems_monitor_driver_t *monitor_driver,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
length += printf(" %d", monitor_driver->id);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(13, length);
|
|
||||||
length += printf("init: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_driver->initialization, verbose);
|
|
||||||
length += printf("; control: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_driver->control, verbose);
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(13, length);
|
|
||||||
|
|
||||||
length += printf("open: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_driver->open, verbose);
|
|
||||||
length += printf("; close: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_driver->close, verbose);
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(13, length);
|
|
||||||
|
|
||||||
length += printf("read: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_driver->read, verbose);
|
|
||||||
length += printf("; write: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_driver->write, verbose);
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS Monitor extension support
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_extension_canonical(
|
|
||||||
rtems_monitor_extension_t *canonical_extension,
|
|
||||||
void *extension_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Extension_Control *rtems_extension = (Extension_Control *) extension_void;
|
|
||||||
rtems_extensions_table *e = &rtems_extension->Extension.Callouts;
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_create,
|
|
||||||
(void *) e->thread_create);
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_start,
|
|
||||||
(void *) e->thread_start);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_restart,
|
|
||||||
(void *) e->thread_restart);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_delete,
|
|
||||||
(void *) e->thread_delete);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_tswitch,
|
|
||||||
(void *) e->thread_switch);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_begin,
|
|
||||||
(void *) e->thread_begin);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_exitted,
|
|
||||||
(void *) e->thread_exitted);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->e_fatal,
|
|
||||||
(void *) e->fatal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_extension_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
ID NAME\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dump out the canonical form
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_extension_dump(
|
|
||||||
rtems_monitor_extension_t *monitor_extension,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_id(monitor_extension->id);
|
|
||||||
length += rtems_monitor_pad(11, length);
|
|
||||||
length += rtems_monitor_dump_name(monitor_extension->name);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(18, length);
|
|
||||||
length += printf("create: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_create, verbose);
|
|
||||||
length += printf("; start: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_start, verbose);
|
|
||||||
length += printf("; restart: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_restart, verbose);
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(18, length);
|
|
||||||
length += printf("delete: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_delete, verbose);
|
|
||||||
length += printf("; switch: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_tswitch, verbose);
|
|
||||||
length += printf("; begin: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_begin, verbose);
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(18, length);
|
|
||||||
length += printf("exitted: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_exitted, verbose);
|
|
||||||
length += printf("; fatal: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_extension->e_fatal, verbose);
|
|
||||||
length += printf("\n");
|
|
||||||
length = 0;
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS Monitor init task support
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* As above, but just for init tasks
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
rtems_monitor_init_task_canonical(
|
|
||||||
rtems_monitor_init_task_t *canonical_itask,
|
|
||||||
void *itask_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_initialization_tasks_table *rtems_itask = itask_void;
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_itask->entry,
|
|
||||||
(void *) rtems_itask->entry_point);
|
|
||||||
|
|
||||||
canonical_itask->argument = rtems_itask->argument;
|
|
||||||
canonical_itask->stack_size = rtems_itask->stack_size;
|
|
||||||
canonical_itask->priority = rtems_itask->initial_priority;
|
|
||||||
canonical_itask->modes = rtems_itask->mode_set;
|
|
||||||
canonical_itask->attributes = rtems_itask->attribute_set;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_init_task_next(
|
|
||||||
void *object_info,
|
|
||||||
rtems_monitor_init_task_t *canonical_init_task,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_configuration_table *c = _Configuration_Table;
|
|
||||||
rtems_initialization_tasks_table *itask;
|
|
||||||
rtems_unsigned32 n = rtems_get_index(*next_id);
|
|
||||||
|
|
||||||
if (n >= c->RTEMS_api_configuration->number_of_initialization_tasks)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
itask = c->RTEMS_api_configuration->User_initialization_tasks_table + n;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* dummy up a fake id and name for this item
|
|
||||||
*/
|
|
||||||
|
|
||||||
canonical_init_task->id = n;
|
|
||||||
canonical_init_task->name = itask->name;
|
|
||||||
|
|
||||||
*next_id += 1;
|
|
||||||
return (void *) itask;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
*next_id = RTEMS_OBJECT_ID_FINAL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_init_task_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
# NAME ENTRY ARGUMENT PRIO MODES ATTRIBUTES STACK SIZE\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_init_task_dump(
|
|
||||||
rtems_monitor_init_task_t *monitor_itask,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_itask->id);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(7, length);
|
|
||||||
length += rtems_monitor_dump_name(monitor_itask->name);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(14, length);
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_itask->entry, verbose);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(25, length);
|
|
||||||
length += printf("%d [0x%x]", monitor_itask->argument, monitor_itask->argument);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(39, length);
|
|
||||||
length += rtems_monitor_dump_priority(monitor_itask->priority);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(46, length);
|
|
||||||
length += rtems_monitor_dump_modes(monitor_itask->modes);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(54, length);
|
|
||||||
length += rtems_monitor_dump_attributes(monitor_itask->attributes);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(66, length);
|
|
||||||
length += printf("%d [0x%x]", monitor_itask->stack_size, monitor_itask->stack_size);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS Monitor "manager" support.
|
|
||||||
* Used to traverse object (chain) lists and print them out.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "next" routine for all objects that are RTEMS manager objects
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_manager_next(
|
|
||||||
void *table_void,
|
|
||||||
void *canonical,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Objects_Information *table = table_void;
|
|
||||||
rtems_monitor_generic_t *copy;
|
|
||||||
Objects_Control *object = 0;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When we are called, it must be local
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( ! _Objects_Is_local_id(*next_id))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
object = _Objects_Get_next(table, *next_id, &location, next_id);
|
|
||||||
|
|
||||||
if (object)
|
|
||||||
{
|
|
||||||
copy = (rtems_monitor_generic_t *) canonical;
|
|
||||||
copy->id = object->id;
|
|
||||||
if(table->is_string)
|
|
||||||
_Objects_Copy_name_raw(object->name, ©->name, sizeof(copy->name));
|
|
||||||
else
|
|
||||||
_Objects_Copy_name_raw(&object->name, ©->name, sizeof(copy->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,603 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS monitor main body
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* add stuff to RTEMS api
|
|
||||||
* rtems_get_name(id)
|
|
||||||
* rtems_get_type(id)
|
|
||||||
* rtems_build_id(node, type, num)
|
|
||||||
* Add a command to dump out info about an arbitrary id when
|
|
||||||
* types are added to id's
|
|
||||||
* rtems> id idnum
|
|
||||||
* idnum: node n, object: whatever, id: whatever
|
|
||||||
* allow id's to be specified as n:t:id, where 'n:t' is optional
|
|
||||||
* should have a separate monitor FILE stream (ala the debugger)
|
|
||||||
* remote request/response stuff should be cleaned up
|
|
||||||
* maybe we can use real rpc??
|
|
||||||
* 'info' command to print out:
|
|
||||||
* interrupt stack location, direction and size
|
|
||||||
* floating point config stuff
|
|
||||||
* interrupt config stuff
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
/* set by trap handler */
|
|
||||||
extern rtems_tcb *debugger_interrupted_task;
|
|
||||||
extern rtems_context *debugger_interrupted_task_context;
|
|
||||||
extern rtems_unsigned32 debugger_trap;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Various id's for the monitor
|
|
||||||
* They need to be public variables for access by other agencies
|
|
||||||
* such as debugger and remote servers'
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_id rtems_monitor_task_id;
|
|
||||||
|
|
||||||
unsigned32 rtems_monitor_node; /* our node number */
|
|
||||||
unsigned32 rtems_monitor_default_node; /* current default for commands */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The rtems symbol table
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_symbol_table_t *rtems_monitor_symbols;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User registered commands.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_monitor_command_entry_t rtems_registered_commands;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The top-level commands
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_monitor_command_entry_t rtems_monitor_commands[] = {
|
|
||||||
{ "config",
|
|
||||||
"Show the system configuration.",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_CONFIG,
|
|
||||||
&rtems_monitor_commands[1],
|
|
||||||
},
|
|
||||||
{ "itask",
|
|
||||||
"List init tasks for the system",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_INIT_TASK,
|
|
||||||
&rtems_monitor_commands[2],
|
|
||||||
},
|
|
||||||
{ "mpci",
|
|
||||||
"Show the MPCI system configuration, if configured.",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_MPCI,
|
|
||||||
&rtems_monitor_commands[3],
|
|
||||||
},
|
|
||||||
{ "pause",
|
|
||||||
"Monitor goes to \"sleep\" for specified ticks (default is 1). "
|
|
||||||
"Monitor will resume at end of period or if explicitly awakened\n"
|
|
||||||
" pause [ticks]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_pause_cmd,
|
|
||||||
0,
|
|
||||||
&rtems_monitor_commands[4],
|
|
||||||
},
|
|
||||||
{ "continue",
|
|
||||||
"Put the monitor to sleep waiting for an explicit wakeup from the "
|
|
||||||
"program running.\n",
|
|
||||||
0,
|
|
||||||
rtems_monitor_continue_cmd,
|
|
||||||
0,
|
|
||||||
&rtems_monitor_commands[5],
|
|
||||||
},
|
|
||||||
{ "go",
|
|
||||||
"Alias for 'continue'",
|
|
||||||
0,
|
|
||||||
rtems_monitor_continue_cmd,
|
|
||||||
0,
|
|
||||||
&rtems_monitor_commands[6],
|
|
||||||
},
|
|
||||||
{ "node",
|
|
||||||
"Specify default node number for commands that take id's.\n"
|
|
||||||
" node [ node number ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_node_cmd,
|
|
||||||
0,
|
|
||||||
&rtems_monitor_commands[7],
|
|
||||||
},
|
|
||||||
{ "symbol",
|
|
||||||
"Display value associated with specified symbol. "
|
|
||||||
"Defaults to displaying all known symbols.\n"
|
|
||||||
" symbol [ symbolname [symbolname ... ] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_symbol_cmd,
|
|
||||||
#if defined(RTEMS_CPU_HAS_16_BIT_ADDRESSES)
|
|
||||||
0, /* XXX find a way to fix the compile time error on h8 */
|
|
||||||
#else
|
|
||||||
(rtems_monitor_command_arg_t) &rtems_monitor_symbols,
|
|
||||||
#endif
|
|
||||||
&rtems_monitor_commands[8],
|
|
||||||
},
|
|
||||||
{ "extension",
|
|
||||||
"Display information about specified extensions. "
|
|
||||||
"Default is to display information about all extensions on this node.\n"
|
|
||||||
" extension [id [id ...] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_EXTENSION,
|
|
||||||
&rtems_monitor_commands[9],
|
|
||||||
},
|
|
||||||
{ "task",
|
|
||||||
"Display information about the specified tasks. "
|
|
||||||
"Default is to display information about all tasks on this node.\n"
|
|
||||||
" task [id [id ...] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_TASK,
|
|
||||||
&rtems_monitor_commands[10],
|
|
||||||
},
|
|
||||||
{ "queue",
|
|
||||||
"Display information about the specified message queues. "
|
|
||||||
"Default is to display information about all queues on this node.\n"
|
|
||||||
" queue [id [id ... ] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_QUEUE,
|
|
||||||
&rtems_monitor_commands[11],
|
|
||||||
},
|
|
||||||
{ "object",
|
|
||||||
"Display information about specified RTEMS objects. "
|
|
||||||
"Object id's must include 'type' information. "
|
|
||||||
"(which may normally be defaulted)\n"
|
|
||||||
" object [id [id ...] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_INVALID,
|
|
||||||
&rtems_monitor_commands[12],
|
|
||||||
},
|
|
||||||
{ "driver",
|
|
||||||
"Display the RTEMS device driver table.\n"
|
|
||||||
" driver [ major [ major ... ] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_DRIVER,
|
|
||||||
&rtems_monitor_commands[13],
|
|
||||||
},
|
|
||||||
{ "dname",
|
|
||||||
"Displays information about named drivers.\n",
|
|
||||||
0,
|
|
||||||
rtems_monitor_object_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_MONITOR_OBJECT_DNAME,
|
|
||||||
&rtems_monitor_commands[14],
|
|
||||||
},
|
|
||||||
{ "exit",
|
|
||||||
"Invoke 'rtems_fatal_error_occurred' with 'status' "
|
|
||||||
"(default is RTEMS_SUCCESSFUL)\n"
|
|
||||||
" exit [status]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_fatal_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_SUCCESSFUL,
|
|
||||||
&rtems_monitor_commands[15],
|
|
||||||
},
|
|
||||||
{ "fatal",
|
|
||||||
"'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n"
|
|
||||||
" fatal [status]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_fatal_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_TASK_EXITTED, /* exit value */
|
|
||||||
&rtems_monitor_commands[16],
|
|
||||||
},
|
|
||||||
{ "quit",
|
|
||||||
"Alias for 'exit'\n",
|
|
||||||
0,
|
|
||||||
rtems_monitor_fatal_cmd,
|
|
||||||
(rtems_monitor_command_arg_t) RTEMS_SUCCESSFUL, /* exit value */
|
|
||||||
&rtems_monitor_commands[17],
|
|
||||||
},
|
|
||||||
{ "help",
|
|
||||||
"Provide information about commands. "
|
|
||||||
"Default is show basic command summary.\n"
|
|
||||||
"help [ command [ command ] ]",
|
|
||||||
0,
|
|
||||||
rtems_monitor_help_cmd,
|
|
||||||
#if defined(RTEMS_CPU_HAS_16_BIT_ADDRESSES)
|
|
||||||
0, /* XXX find a way to fix the compile time error on h8 */
|
|
||||||
#else
|
|
||||||
(rtems_monitor_command_arg_t) rtems_monitor_commands,
|
|
||||||
#endif
|
|
||||||
&rtems_monitor_commands[18],
|
|
||||||
},
|
|
||||||
#ifdef CPU_INVOKE_DEBUGGER
|
|
||||||
{ "debugger",
|
|
||||||
"Enter the debugger, if possible. "
|
|
||||||
"A continue from the debugger will return to the monitor.\n",
|
|
||||||
0,
|
|
||||||
rtems_monitor_debugger_cmd,
|
|
||||||
0,
|
|
||||||
&rtems_monitor_commands[19],
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
{ 0, 0, 0, 0, 0, &rtems_registered_commands },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
rtems_status_code
|
|
||||||
rtems_monitor_suspend(rtems_interval timeout)
|
|
||||||
{
|
|
||||||
rtems_event_set event_set;
|
|
||||||
rtems_status_code status;
|
|
||||||
|
|
||||||
status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
|
|
||||||
RTEMS_DEFAULT_OPTIONS,
|
|
||||||
timeout,
|
|
||||||
&event_set);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_wakeup(void)
|
|
||||||
{
|
|
||||||
rtems_status_code status;
|
|
||||||
|
|
||||||
status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_debugger_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#ifdef CPU_INVOKE_DEBUGGER
|
|
||||||
CPU_INVOKE_DEBUGGER;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_pause_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (argc == 1)
|
|
||||||
rtems_monitor_suspend(1);
|
|
||||||
else
|
|
||||||
rtems_monitor_suspend(strtoul(argv[1], 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_fatal_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (argc == 1)
|
|
||||||
rtems_fatal_error_occurred(command_arg);
|
|
||||||
else
|
|
||||||
rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_continue_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_node_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 new_node = rtems_monitor_default_node;
|
|
||||||
|
|
||||||
switch (argc)
|
|
||||||
{
|
|
||||||
case 1: /* no node, just set back to ours */
|
|
||||||
new_node = rtems_monitor_node;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
new_node = strtoul(argv[1], 0, 0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("invalid syntax, try 'help node'\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((new_node >= 1) &&
|
|
||||||
_Configuration_MP_table &&
|
|
||||||
(new_node <= _Configuration_MP_table->maximum_nodes))
|
|
||||||
rtems_monitor_default_node = new_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: rtems_monitor_symbols_loadup
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Create and load the monitor's symbol table.
|
|
||||||
* We are reading the output format of 'gnm' which looks like this:
|
|
||||||
*
|
|
||||||
* 400a7068 ? _Rate_monotonic_Information
|
|
||||||
* 400a708c ? _Thread_Dispatch_disable_level
|
|
||||||
* 400a7090 ? _Configuration_Table
|
|
||||||
*
|
|
||||||
* We ignore the type field.
|
|
||||||
*
|
|
||||||
* Side Effects:
|
|
||||||
* Creates and fills in 'rtems_monitor_symbols' table
|
|
||||||
*
|
|
||||||
* TODO
|
|
||||||
* there should be a BSP #define or something like that
|
|
||||||
* to do this; Assuming stdio is crazy.
|
|
||||||
* Someday this should know BFD
|
|
||||||
* Maybe we could get objcopy to just copy the symbol areas
|
|
||||||
* and copy that down.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_symbols_loadup(void)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
char buffer[128];
|
|
||||||
|
|
||||||
if (rtems_monitor_symbols)
|
|
||||||
rtems_symbol_table_destroy(rtems_monitor_symbols);
|
|
||||||
|
|
||||||
rtems_monitor_symbols = rtems_symbol_table_create(10);
|
|
||||||
if (rtems_monitor_symbols == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
fp = fopen("symbols", "r");
|
|
||||||
|
|
||||||
if (fp == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (fgets(buffer, sizeof(buffer) - 1, fp))
|
|
||||||
{
|
|
||||||
char *symbol;
|
|
||||||
char *value;
|
|
||||||
char *ignored_type;
|
|
||||||
|
|
||||||
value = strtok(buffer, " \t\n");
|
|
||||||
ignored_type = strtok(0, " \t\n");
|
|
||||||
symbol = strtok(0, " \t\n");
|
|
||||||
|
|
||||||
if (symbol && ignored_type && value)
|
|
||||||
{
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
sp = rtems_symbol_create(rtems_monitor_symbols,
|
|
||||||
symbol,
|
|
||||||
(rtems_unsigned32) strtoul(value, 0, 16));
|
|
||||||
if (sp == 0)
|
|
||||||
{
|
|
||||||
printf("could not define symbol '%s'\n", symbol);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("parsing error on '%s'\n", buffer);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* User registered commands.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
rtems_monitor_insert_cmd (
|
|
||||||
rtems_monitor_command_entry_t *command
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_command_entry_t *p = rtems_registered_commands.next;
|
|
||||||
|
|
||||||
command->next = 0;
|
|
||||||
|
|
||||||
if (rtems_registered_commands.next)
|
|
||||||
{
|
|
||||||
for (; p->next; p = p->next)
|
|
||||||
{
|
|
||||||
if (STREQ(command->command, p->command))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
p->next = command;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rtems_registered_commands.next = command;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
rtems_monitor_erase_cmd (
|
|
||||||
rtems_monitor_command_entry_t *command
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_command_entry_t *p;
|
|
||||||
rtems_monitor_command_entry_t **p_prev = &rtems_registered_commands.next;
|
|
||||||
|
|
||||||
if (rtems_registered_commands.next)
|
|
||||||
{
|
|
||||||
for (p = rtems_registered_commands.next; p->next; p = p->next)
|
|
||||||
{
|
|
||||||
if (STREQ(command->command, p->command))
|
|
||||||
{
|
|
||||||
*p_prev = p->next;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
p_prev = &p->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Main monitor command loop
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_task(
|
|
||||||
rtems_task_argument monitor_flags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_tcb *debugee = 0;
|
|
||||||
rtems_context *rp;
|
|
||||||
rtems_context_fp *fp;
|
|
||||||
char command_buffer[513];
|
|
||||||
int argc;
|
|
||||||
char *argv[64];
|
|
||||||
boolean verbose = FALSE;
|
|
||||||
struct termios term;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make the stdin stream characte not line based.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (tcgetattr (STDIN_FILENO, &term) < 0)
|
|
||||||
{
|
|
||||||
printf("rtems-monitor: cannot get terminal attributes.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* No echo, no canonical processing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
term.c_lflag &= ~(ECHO | ICANON | IEXTEN);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* No sigint on BREAK, CR-to-NL off, input parity off,
|
|
||||||
* don't strip 8th bit on input, output flow control off
|
|
||||||
*/
|
|
||||||
|
|
||||||
term.c_lflag &= ~(INPCK | ISTRIP | IXON);
|
|
||||||
term.c_cc[VMIN] = 1;
|
|
||||||
term.c_cc[VTIME] = 0;
|
|
||||||
|
|
||||||
if (tcsetattr (STDIN_FILENO, TCSANOW, &term) < 0)
|
|
||||||
{
|
|
||||||
printf("cannot set terminal attributes\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (monitor_flags & RTEMS_MONITOR_SUSPEND)
|
|
||||||
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
extern rtems_tcb * _Thread_Executing;
|
|
||||||
rtems_monitor_command_entry_t *command;
|
|
||||||
|
|
||||||
debugee = _Thread_Executing;
|
|
||||||
rp = &debugee->Registers;
|
|
||||||
#if (CPU_HARDWARE_FP == TRUE) || (CPU_SOFTWARE_FP == TRUE)
|
|
||||||
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
|
|
||||||
#else
|
|
||||||
fp = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
|
|
||||||
continue;
|
|
||||||
if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
|
|
||||||
argc,
|
|
||||||
argv)) == 0)
|
|
||||||
{
|
|
||||||
/* no command */
|
|
||||||
printf("Unrecognised command; try 'help'\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
command->command_function(argc, argv, command->command_arg, verbose);
|
|
||||||
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_kill(void)
|
|
||||||
{
|
|
||||||
if (rtems_monitor_task_id)
|
|
||||||
rtems_task_delete(rtems_monitor_task_id);
|
|
||||||
rtems_monitor_task_id = 0;
|
|
||||||
|
|
||||||
rtems_monitor_server_kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_init(
|
|
||||||
unsigned32 monitor_flags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_status_code status;
|
|
||||||
|
|
||||||
rtems_monitor_kill();
|
|
||||||
|
|
||||||
status = rtems_task_create(RTEMS_MONITOR_NAME,
|
|
||||||
1,
|
|
||||||
RTEMS_MINIMUM_STACK_SIZE * 2,
|
|
||||||
RTEMS_INTERRUPT_LEVEL(0),
|
|
||||||
RTEMS_DEFAULT_ATTRIBUTES,
|
|
||||||
&rtems_monitor_task_id);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "could not create monitor task");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
|
|
||||||
rtems_monitor_default_node = rtems_monitor_node;
|
|
||||||
|
|
||||||
rtems_monitor_symbols_loadup();
|
|
||||||
|
|
||||||
if (monitor_flags & RTEMS_MONITOR_GLOBAL)
|
|
||||||
rtems_monitor_server_init(monitor_flags);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start the monitor task itself
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = rtems_task_start(rtems_monitor_task_id,
|
|
||||||
rtems_monitor_task,
|
|
||||||
monitor_flags);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "could not start monitor");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS MPCI Config display support
|
|
||||||
*
|
|
||||||
* TODO
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h> /* strtoul() */
|
|
||||||
|
|
||||||
#define DATACOL 15
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill in entire monitor config table
|
|
||||||
* for sending to a remote monitor or printing on the local system
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_mpci_canonical(
|
|
||||||
rtems_monitor_mpci_t *canonical_mpci,
|
|
||||||
void *config_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_configuration_table *c = _Configuration_Table;
|
|
||||||
rtems_multiprocessing_table *m;
|
|
||||||
rtems_mpci_table *mt;
|
|
||||||
|
|
||||||
m = c->User_multiprocessing_table;
|
|
||||||
if (m == 0)
|
|
||||||
return;
|
|
||||||
mt = m->User_mpci_table;
|
|
||||||
|
|
||||||
canonical_mpci->node = m->node;
|
|
||||||
canonical_mpci->maximum_nodes = m->maximum_nodes;
|
|
||||||
canonical_mpci->maximum_global_objects = m->maximum_global_objects;
|
|
||||||
canonical_mpci->maximum_proxies = m->maximum_proxies;
|
|
||||||
|
|
||||||
canonical_mpci->default_timeout = mt->default_timeout;
|
|
||||||
canonical_mpci->maximum_packet_size = mt->maximum_packet_size;
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->initialization,
|
|
||||||
(void *) mt->initialization);
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->get_packet,
|
|
||||||
(void *) mt->get_packet);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->return_packet,
|
|
||||||
(void *) mt->return_packet);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->send_packet,
|
|
||||||
(void *) mt->send_packet);
|
|
||||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->receive_packet,
|
|
||||||
(void *) mt->receive_packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is easy, since there is only 1 (altho we could get them from
|
|
||||||
* other nodes...)
|
|
||||||
*/
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_mpci_next(
|
|
||||||
void *object_info,
|
|
||||||
rtems_monitor_mpci_t *canonical_mpci,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_configuration_table *c = _Configuration_Table;
|
|
||||||
int n = rtems_get_index(*next_id);
|
|
||||||
|
|
||||||
if (n >= 1)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
if ( ! c->User_multiprocessing_table)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
*next_id += 1;
|
|
||||||
return (void *) c;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
*next_id = RTEMS_OBJECT_ID_FINAL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_mpci_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
max max max default max\n\
|
|
||||||
node nodes globals proxies timeout pktsize\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_mpci_dump(
|
|
||||||
rtems_monitor_mpci_t *monitor_mpci,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(2, length);
|
|
||||||
length += printf(" %d", monitor_mpci->node);
|
|
||||||
length += rtems_monitor_pad(11, length);
|
|
||||||
length += printf("%d", monitor_mpci->maximum_nodes);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(18, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_global_objects);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(28, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_proxies);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(37, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_mpci->default_timeout);
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(46, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_mpci->maximum_packet_size);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
length = 0;
|
|
||||||
length += rtems_monitor_pad(DATACOL, length);
|
|
||||||
|
|
||||||
length += printf("init: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_mpci->initialization, verbose);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
length = 0;
|
|
||||||
length += rtems_monitor_pad(DATACOL, length);
|
|
||||||
|
|
||||||
length += printf("get: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_mpci->get_packet, verbose);
|
|
||||||
length += printf("; return: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_mpci->return_packet, verbose);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
length = 0;
|
|
||||||
length += rtems_monitor_pad(DATACOL, length);
|
|
||||||
|
|
||||||
length += printf("send: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_mpci->send_packet, verbose);
|
|
||||||
length += printf("; receive: ");
|
|
||||||
length += rtems_monitor_symbol_dump(&monitor_mpci->receive_packet, verbose);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
@@ -1,383 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS Monitor "object" support.
|
|
||||||
*
|
|
||||||
* Used to traverse object lists and print them out.
|
|
||||||
* An object can be an RTEMS object (chain based stuff) or
|
|
||||||
* a "misc" object such as a device driver.
|
|
||||||
*
|
|
||||||
* Each object has its own file in this directory (eg: extension.c)
|
|
||||||
* That file provides routines to convert a "native" structure
|
|
||||||
* to its canonical form, print a canonical structure, etc.
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* should allow for non-numeric id's???
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h> /* strtoul() */
|
|
||||||
#include <string.h> /* memcpy() */
|
|
||||||
|
|
||||||
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add:
|
|
||||||
* next
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_monitor_object_info_t rtems_monitor_object_info[] =
|
|
||||||
{
|
|
||||||
{ RTEMS_MONITOR_OBJECT_CONFIG,
|
|
||||||
(void *) 0,
|
|
||||||
sizeof(rtems_monitor_config_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_config_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_config_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_config_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_config_dump,
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_MPCI,
|
|
||||||
(void *) 0,
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
sizeof(rtems_monitor_mpci_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_mpci_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_mpci_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_mpci_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_mpci_dump,
|
|
||||||
#else
|
|
||||||
0,
|
|
||||||
(rtems_monitor_object_next_fn) 0,
|
|
||||||
(rtems_monitor_object_canonical_fn) 0,
|
|
||||||
(rtems_monitor_object_dump_header_fn) 0,
|
|
||||||
(rtems_monitor_object_dump_fn) 0,
|
|
||||||
#endif
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_INIT_TASK,
|
|
||||||
(void *) 0,
|
|
||||||
sizeof(rtems_monitor_init_task_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_init_task_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_init_task_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_init_task_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_init_task_dump,
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_TASK,
|
|
||||||
(void *) &_RTEMS_tasks_Information,
|
|
||||||
sizeof(rtems_monitor_task_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_task_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_task_dump,
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_QUEUE,
|
|
||||||
(void *) &_Message_queue_Information,
|
|
||||||
sizeof(rtems_monitor_queue_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_queue_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_queue_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_queue_dump,
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_EXTENSION,
|
|
||||||
(void *) &_Extension_Information,
|
|
||||||
sizeof(rtems_monitor_extension_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_manager_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_extension_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_extension_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_extension_dump,
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_DRIVER,
|
|
||||||
(void *) 0,
|
|
||||||
sizeof(rtems_monitor_driver_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_driver_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_driver_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_driver_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_driver_dump,
|
|
||||||
},
|
|
||||||
{ RTEMS_MONITOR_OBJECT_DNAME,
|
|
||||||
/* XXX now that the driver name table is allocated from the */
|
|
||||||
/* XXX Workspace, this does not work */
|
|
||||||
(void *) 0,
|
|
||||||
/* (void *) _IO_Driver_name_table, */
|
|
||||||
sizeof(rtems_monitor_dname_t),
|
|
||||||
(rtems_monitor_object_next_fn) rtems_monitor_dname_next,
|
|
||||||
(rtems_monitor_object_canonical_fn) rtems_monitor_dname_canonical,
|
|
||||||
(rtems_monitor_object_dump_header_fn) rtems_monitor_dname_dump_header,
|
|
||||||
(rtems_monitor_object_dump_fn) rtems_monitor_dname_dump,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allow id's to be specified without the node number or
|
|
||||||
* type for convenience.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_id
|
|
||||||
rtems_monitor_id_fixup(
|
|
||||||
rtems_id id,
|
|
||||||
unsigned32 default_node,
|
|
||||||
rtems_monitor_object_type_t type
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 node;
|
|
||||||
|
|
||||||
node = rtems_get_node(id);
|
|
||||||
if (node == 0)
|
|
||||||
{
|
|
||||||
if (rtems_get_class(id) != OBJECTS_NO_CLASS)
|
|
||||||
type = rtems_get_class(id);
|
|
||||||
|
|
||||||
id = _Objects_Build_id(
|
|
||||||
OBJECTS_CLASSIC_API, type, default_node, rtems_get_index(id));
|
|
||||||
}
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rtems_monitor_object_info_t *
|
|
||||||
rtems_monitor_object_lookup(
|
|
||||||
rtems_monitor_object_type_t type
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_object_info_t *p;
|
|
||||||
for (p = &rtems_monitor_object_info[0];
|
|
||||||
p < &rtems_monitor_object_info[NUMELEMS(rtems_monitor_object_info)];
|
|
||||||
p++)
|
|
||||||
{
|
|
||||||
if (p->type == type)
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_id
|
|
||||||
rtems_monitor_object_canonical_next_remote(
|
|
||||||
rtems_monitor_object_type_t type,
|
|
||||||
rtems_id id,
|
|
||||||
void *canonical
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_id next_id;
|
|
||||||
rtems_status_code status;
|
|
||||||
rtems_monitor_server_request_t request;
|
|
||||||
rtems_monitor_server_response_t response;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Send request
|
|
||||||
*/
|
|
||||||
|
|
||||||
request.command = RTEMS_MONITOR_SERVER_CANONICAL;
|
|
||||||
request.argument0 = (unsigned32) type;
|
|
||||||
request.argument1 = (unsigned32) id;
|
|
||||||
|
|
||||||
status = rtems_monitor_server_request(rtems_get_node(id), &request, &response);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* process response
|
|
||||||
*/
|
|
||||||
|
|
||||||
next_id = (rtems_id) response.result0;
|
|
||||||
if (next_id != RTEMS_OBJECT_ID_FINAL)
|
|
||||||
(void) memcpy(canonical, &response.payload, response.result1);
|
|
||||||
|
|
||||||
return next_id;
|
|
||||||
|
|
||||||
failed:
|
|
||||||
return RTEMS_OBJECT_ID_FINAL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rtems_id
|
|
||||||
rtems_monitor_object_canonical_next(
|
|
||||||
rtems_monitor_object_info_t *info,
|
|
||||||
rtems_id id,
|
|
||||||
void *canonical
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_id next_id;
|
|
||||||
void *raw_item;
|
|
||||||
|
|
||||||
if ( ! _Objects_Is_local_id(id))
|
|
||||||
next_id = rtems_monitor_object_canonical_next_remote(info->type,
|
|
||||||
id,
|
|
||||||
canonical);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next_id = id;
|
|
||||||
|
|
||||||
raw_item = (void *) info->next(info->object_information,
|
|
||||||
canonical,
|
|
||||||
&next_id);
|
|
||||||
|
|
||||||
if (raw_item)
|
|
||||||
{
|
|
||||||
info->canonical(canonical, raw_item);
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return next_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* this is routine server invokes locally to get the type
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_id
|
|
||||||
rtems_monitor_object_canonical_get(
|
|
||||||
rtems_monitor_object_type_t type,
|
|
||||||
rtems_id id,
|
|
||||||
void *canonical,
|
|
||||||
unsigned32 *size_p
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_object_info_t *info;
|
|
||||||
rtems_id next_id;
|
|
||||||
|
|
||||||
*size_p = 0;
|
|
||||||
|
|
||||||
info = rtems_monitor_object_lookup(type);
|
|
||||||
|
|
||||||
if (info == 0)
|
|
||||||
return RTEMS_OBJECT_ID_FINAL;
|
|
||||||
|
|
||||||
next_id = rtems_monitor_object_canonical_next(info, id, canonical);
|
|
||||||
*size_p = info->size;
|
|
||||||
|
|
||||||
return next_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_object_dump_1(
|
|
||||||
rtems_monitor_object_info_t *info,
|
|
||||||
rtems_id id,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_id next_id;
|
|
||||||
rtems_monitor_union_t canonical;
|
|
||||||
|
|
||||||
if ((next_id = rtems_monitor_object_canonical_next(
|
|
||||||
info,
|
|
||||||
id,
|
|
||||||
&canonical)) != RTEMS_OBJECT_ID_FINAL)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If the one we actually got is the one we wanted, then
|
|
||||||
* print it out.
|
|
||||||
* For ones that have an id field, this works fine,
|
|
||||||
* for all others, always dump it out.
|
|
||||||
*
|
|
||||||
* HACK: the way we determine whether there is an id is a hack.
|
|
||||||
*
|
|
||||||
* by the way: the reason we try to not have an id, is that some
|
|
||||||
* of the canonical structures are almost too big for shared
|
|
||||||
* memory driver (eg: mpci)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((info->next != rtems_monitor_manager_next) ||
|
|
||||||
(id == canonical.generic.id))
|
|
||||||
info->dump(&canonical, verbose);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_object_dump_all(
|
|
||||||
rtems_monitor_object_info_t *info,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_id next_id;
|
|
||||||
rtems_monitor_union_t canonical;
|
|
||||||
|
|
||||||
next_id = RTEMS_OBJECT_ID_INITIAL(OBJECTS_CLASSIC_API, info->type, rtems_monitor_default_node);
|
|
||||||
|
|
||||||
while ((next_id = rtems_monitor_object_canonical_next(
|
|
||||||
info,
|
|
||||||
next_id,
|
|
||||||
&canonical)) != RTEMS_OBJECT_ID_FINAL)
|
|
||||||
{
|
|
||||||
info->dump(&canonical, verbose);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_object_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int arg;
|
|
||||||
rtems_monitor_object_info_t *info = 0;
|
|
||||||
rtems_monitor_object_type_t type = (rtems_monitor_object_type_t) command_arg;
|
|
||||||
|
|
||||||
/* what is the default type? */
|
|
||||||
type = (rtems_monitor_object_type_t) command_arg;
|
|
||||||
|
|
||||||
if (argc == 1)
|
|
||||||
{
|
|
||||||
if (type == RTEMS_MONITOR_OBJECT_INVALID)
|
|
||||||
{
|
|
||||||
printf("A type must be specified to \"dump all\"\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = rtems_monitor_object_lookup(type);
|
|
||||||
if (info == 0)
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
if (info->dump_header)
|
|
||||||
info->dump_header(verbose);
|
|
||||||
rtems_monitor_object_dump_all(info, verbose);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned32 default_node = rtems_monitor_default_node;
|
|
||||||
rtems_monitor_object_type_t last_type = RTEMS_MONITOR_OBJECT_INVALID;
|
|
||||||
rtems_id id;
|
|
||||||
|
|
||||||
for (arg=1; argv[arg]; arg++)
|
|
||||||
{
|
|
||||||
id = (rtems_id) strtoul(argv[arg], 0, 16);
|
|
||||||
id = rtems_monitor_id_fixup(id, default_node, type);
|
|
||||||
type = (rtems_monitor_object_type_t) rtems_get_class(id);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Allow the item type to change in the middle
|
|
||||||
* of the command. If the type changes, then
|
|
||||||
* just dump out a new header and keep on going.
|
|
||||||
*/
|
|
||||||
if (type != last_type)
|
|
||||||
{
|
|
||||||
info = rtems_monitor_object_lookup(type);
|
|
||||||
if (info == 0)
|
|
||||||
goto not_found;
|
|
||||||
|
|
||||||
if (info->dump_header)
|
|
||||||
info->dump_header(verbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info == 0)
|
|
||||||
{
|
|
||||||
not_found: printf("Invalid or unsupported type %d\n", type);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_monitor_object_dump_1(info, id, verbose);
|
|
||||||
|
|
||||||
default_node = rtems_get_node(id);
|
|
||||||
|
|
||||||
last_type = type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -1,264 +0,0 @@
|
|||||||
/*
|
|
||||||
* Print misc stuff for the monitor dump routines
|
|
||||||
* Each routine returns the number of characters it output.
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <rtems/assoc.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_separator(void)
|
|
||||||
{
|
|
||||||
printf("------------------------------------------------------------------------------\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_pad(
|
|
||||||
unsigned32 destination_column,
|
|
||||||
unsigned32 current_column
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int pad_length;
|
|
||||||
|
|
||||||
if (destination_column <= current_column)
|
|
||||||
pad_length = 1;
|
|
||||||
else
|
|
||||||
pad_length = destination_column - current_column;
|
|
||||||
|
|
||||||
return printf("%*s", pad_length, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_char(rtems_unsigned8 ch)
|
|
||||||
{
|
|
||||||
if (isprint(ch))
|
|
||||||
return printf("%c", ch);
|
|
||||||
else
|
|
||||||
return printf("%02x", ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_decimal(unsigned32 num)
|
|
||||||
{
|
|
||||||
return printf("%4d", num);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_hex(unsigned32 num)
|
|
||||||
{
|
|
||||||
return printf("0x%x", num);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_assoc_bitfield(
|
|
||||||
rtems_assoc_t *ap,
|
|
||||||
char *separator,
|
|
||||||
unsigned32 value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 b;
|
|
||||||
unsigned32 length = 0;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
for (b = 1; b; b <<= 1)
|
|
||||||
if (b & value)
|
|
||||||
{
|
|
||||||
if (length)
|
|
||||||
length += printf("%s", separator);
|
|
||||||
|
|
||||||
name = rtems_assoc_name_by_local(ap, b);
|
|
||||||
|
|
||||||
if (name)
|
|
||||||
length += printf("%s", name);
|
|
||||||
else
|
|
||||||
length += printf("0x%x", b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_id(rtems_id id)
|
|
||||||
{
|
|
||||||
return printf("%08x", id);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_name(rtems_name name)
|
|
||||||
{
|
|
||||||
unsigned32 i;
|
|
||||||
unsigned32 length = 0;
|
|
||||||
union {
|
|
||||||
unsigned32 ui;
|
|
||||||
char c[4];
|
|
||||||
} u;
|
|
||||||
|
|
||||||
u.ui = (rtems_unsigned32) name;
|
|
||||||
|
|
||||||
#if (CPU_BIG_ENDIAN == TRUE)
|
|
||||||
for (i=0; i<sizeof(u.c); i++)
|
|
||||||
length += rtems_monitor_dump_char(u.c[i]);
|
|
||||||
#else
|
|
||||||
for (i=0; i<sizeof(u.c); i++)
|
|
||||||
length += rtems_monitor_dump_char(u.c[sizeof(u.c)-1-i]);
|
|
||||||
#endif
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_priority(rtems_task_priority priority)
|
|
||||||
{
|
|
||||||
return printf("%3d", priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
rtems_assoc_t rtems_monitor_state_assoc[] = {
|
|
||||||
{ "DORM", STATES_DORMANT },
|
|
||||||
{ "SUSP", STATES_SUSPENDED },
|
|
||||||
{ "TRANS", STATES_TRANSIENT },
|
|
||||||
{ "DELAY", STATES_DELAYING },
|
|
||||||
{ "Wbuf", STATES_WAITING_FOR_BUFFER },
|
|
||||||
{ "Wseg", STATES_WAITING_FOR_SEGMENT },
|
|
||||||
{ "Wmsg" , STATES_WAITING_FOR_MESSAGE },
|
|
||||||
{ "Wevnt", STATES_WAITING_FOR_EVENT },
|
|
||||||
{ "Wsem", STATES_WAITING_FOR_SEMAPHORE },
|
|
||||||
{ "Wtime", STATES_WAITING_FOR_TIME },
|
|
||||||
{ "Wrpc", STATES_WAITING_FOR_RPC_REPLY },
|
|
||||||
{ "Wmutex", STATES_WAITING_FOR_MUTEX },
|
|
||||||
{ "Wcvar", STATES_WAITING_FOR_CONDITION_VARIABLE },
|
|
||||||
{ "Wjatx", STATES_WAITING_FOR_JOIN_AT_EXIT },
|
|
||||||
{ "Wsig", STATES_WAITING_FOR_SIGNAL },
|
|
||||||
{ "WRATE", STATES_WAITING_FOR_PERIOD },
|
|
||||||
{ "Wisig", STATES_INTERRUPTIBLE_BY_SIGNAL },
|
|
||||||
{ 0, 0, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_state(States_Control state)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
if (state == STATES_READY) /* assoc doesn't deal with this as it is 0 */
|
|
||||||
length += printf("READY");
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_state_assoc,
|
|
||||||
":",
|
|
||||||
state);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_assoc_t rtems_monitor_attribute_assoc[] = {
|
|
||||||
{ "FL", RTEMS_FLOATING_POINT },
|
|
||||||
{ "GL", RTEMS_GLOBAL },
|
|
||||||
{ "PR", RTEMS_PRIORITY },
|
|
||||||
{ "BI", RTEMS_BINARY_SEMAPHORE },
|
|
||||||
{ "IN", RTEMS_INHERIT_PRIORITY },
|
|
||||||
{ 0, 0, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_attributes(rtems_attribute attributes)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
if (attributes == RTEMS_DEFAULT_ATTRIBUTES) /* value is 0 */
|
|
||||||
length += printf("DEFAULT");
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_attribute_assoc,
|
|
||||||
":",
|
|
||||||
attributes);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_assoc_t rtems_monitor_modes_assoc[] = {
|
|
||||||
{ "nP", RTEMS_NO_PREEMPT },
|
|
||||||
{ "T", RTEMS_TIMESLICE },
|
|
||||||
{ "nA", RTEMS_NO_ASR },
|
|
||||||
{ 0, 0, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_modes(rtems_mode modes)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
if (modes == RTEMS_DEFAULT_MODES) /* value is 0 */
|
|
||||||
length += printf("P:T:nA");
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_modes_assoc,
|
|
||||||
":",
|
|
||||||
modes);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_assoc_t rtems_monitor_events_assoc[] = {
|
|
||||||
{ "0", RTEMS_EVENT_0 },
|
|
||||||
{ "1", RTEMS_EVENT_1 },
|
|
||||||
{ "2", RTEMS_EVENT_2 },
|
|
||||||
{ "3", RTEMS_EVENT_3 },
|
|
||||||
{ "4", RTEMS_EVENT_4 },
|
|
||||||
{ "5", RTEMS_EVENT_5 },
|
|
||||||
{ "6", RTEMS_EVENT_6 },
|
|
||||||
{ "7", RTEMS_EVENT_7 },
|
|
||||||
{ "8", RTEMS_EVENT_8 },
|
|
||||||
{ "9", RTEMS_EVENT_9 },
|
|
||||||
{ "10", RTEMS_EVENT_10 },
|
|
||||||
{ "11", RTEMS_EVENT_11 },
|
|
||||||
{ "12", RTEMS_EVENT_12 },
|
|
||||||
{ "13", RTEMS_EVENT_13 },
|
|
||||||
{ "14", RTEMS_EVENT_14 },
|
|
||||||
{ "15", RTEMS_EVENT_15 },
|
|
||||||
{ "16", RTEMS_EVENT_16 },
|
|
||||||
{ "17", RTEMS_EVENT_17 },
|
|
||||||
{ "18", RTEMS_EVENT_18 },
|
|
||||||
{ "19", RTEMS_EVENT_19 },
|
|
||||||
{ "20", RTEMS_EVENT_20 },
|
|
||||||
{ "21", RTEMS_EVENT_21 },
|
|
||||||
{ "22", RTEMS_EVENT_22 },
|
|
||||||
{ "23", RTEMS_EVENT_23 },
|
|
||||||
{ "24", RTEMS_EVENT_24 },
|
|
||||||
{ "25", RTEMS_EVENT_25 },
|
|
||||||
{ "26", RTEMS_EVENT_26 },
|
|
||||||
{ "27", RTEMS_EVENT_27 },
|
|
||||||
{ "28", RTEMS_EVENT_28 },
|
|
||||||
{ "29", RTEMS_EVENT_29 },
|
|
||||||
{ "30", RTEMS_EVENT_30 },
|
|
||||||
{ "31", RTEMS_EVENT_31 },
|
|
||||||
{ 0, 0, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_events(rtems_event_set events)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
if (events == EVENT_SETS_NONE_PENDING) /* value is 0 */
|
|
||||||
length += printf("NONE");
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_assoc_bitfield(rtems_monitor_events_assoc,
|
|
||||||
":",
|
|
||||||
events);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_dump_notepad(unsigned32 *notepad)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i < RTEMS_NUMBER_NOTEPADS; i++)
|
|
||||||
if (notepad[i])
|
|
||||||
length += printf("%d: 0x%x ", i, notepad[i]);
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_queue_canonical(
|
|
||||||
rtems_monitor_queue_t *canonical_queue,
|
|
||||||
void *queue_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Message_queue_Control *rtems_queue = (Message_queue_Control *) queue_void;
|
|
||||||
|
|
||||||
canonical_queue->attributes = rtems_queue->attribute_set;
|
|
||||||
canonical_queue->maximum_message_size = rtems_queue->message_queue.maximum_message_size;
|
|
||||||
canonical_queue->maximum_pending_messages = rtems_queue->message_queue.maximum_pending_messages;
|
|
||||||
canonical_queue->number_of_pending_messages = rtems_queue->message_queue.number_of_pending_messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_queue_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
ID NAME ATTRIBUTES PEND MAXPEND MAXSIZE\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dump out the "next" queue indicated by 'id'.
|
|
||||||
* Returns next one to check.
|
|
||||||
* Returns RTEMS_OBJECT_ID_FINAL when all done
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_queue_dump(
|
|
||||||
rtems_monitor_queue_t *monitor_queue,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_id(monitor_queue->id);
|
|
||||||
length += rtems_monitor_pad(11, length);
|
|
||||||
length += rtems_monitor_dump_name(monitor_queue->name);
|
|
||||||
length += rtems_monitor_pad(19, length);
|
|
||||||
length += rtems_monitor_dump_attributes(monitor_queue->attributes);
|
|
||||||
length += rtems_monitor_pad(31, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_queue->number_of_pending_messages);
|
|
||||||
length += rtems_monitor_pad(39, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_queue->maximum_pending_messages);
|
|
||||||
length += rtems_monitor_pad(48, length);
|
|
||||||
length += rtems_monitor_dump_decimal(monitor_queue->maximum_message_size);
|
|
||||||
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
@@ -1,303 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS monitor server (handles requests for info from RTEMS monitors
|
|
||||||
* running on other nodes)
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Various id's for the server
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_id rtems_monitor_server_task_id;
|
|
||||||
rtems_id rtems_monitor_server_request_queue_id; /* our server */
|
|
||||||
rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */
|
|
||||||
rtems_id rtems_monitor_server_response_queue_id; /* our server */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Send a request to a server task
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_status_code
|
|
||||||
rtems_monitor_server_request(
|
|
||||||
unsigned32 server_node,
|
|
||||||
rtems_monitor_server_request_t *request,
|
|
||||||
rtems_monitor_server_response_t *response
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_id server_id;
|
|
||||||
rtems_status_code status;
|
|
||||||
unsigned32 size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* What is id of monitor on target node?
|
|
||||||
* Look it up if we don't know it yet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
server_id = rtems_monitor_server_request_queue_ids[server_node];
|
|
||||||
if (server_id == 0)
|
|
||||||
{
|
|
||||||
status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME,
|
|
||||||
server_node,
|
|
||||||
&server_id);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "ident of remote server failed");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_monitor_server_request_queue_ids[server_node] = server_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
request->return_id = rtems_monitor_server_response_queue_id;
|
|
||||||
|
|
||||||
status = rtems_message_queue_send(server_id, request, sizeof(*request));
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "monitor server request send failed");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Await response, if requested
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (response)
|
|
||||||
{
|
|
||||||
status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id,
|
|
||||||
response,
|
|
||||||
&size,
|
|
||||||
RTEMS_WAIT,
|
|
||||||
100);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "server did not respond");
|
|
||||||
|
|
||||||
/* maybe server task was restarted; look it up again next time */
|
|
||||||
rtems_monitor_server_request_queue_ids[server_node] = 0;
|
|
||||||
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response->command != RTEMS_MONITOR_SERVER_RESPONSE)
|
|
||||||
{
|
|
||||||
status = RTEMS_INCORRECT_STATE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* monitor server task
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_server_task(
|
|
||||||
rtems_task_argument monitor_flags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_monitor_server_request_t request;
|
|
||||||
rtems_monitor_server_response_t response;
|
|
||||||
rtems_status_code status;
|
|
||||||
unsigned32 size;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
status = rtems_message_queue_receive(
|
|
||||||
rtems_monitor_server_request_queue_id,
|
|
||||||
&request,
|
|
||||||
&size,
|
|
||||||
RTEMS_WAIT,
|
|
||||||
(rtems_interval) 0);
|
|
||||||
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "monitor server msg queue receive error");
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != sizeof(request))
|
|
||||||
{
|
|
||||||
rtems_error(0, "monitor server bad size on receive");
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (request.command)
|
|
||||||
{
|
|
||||||
case RTEMS_MONITOR_SERVER_CANONICAL:
|
|
||||||
{
|
|
||||||
rtems_monitor_object_type_t object_type;
|
|
||||||
rtems_id id;
|
|
||||||
rtems_id next_id;
|
|
||||||
|
|
||||||
object_type = (rtems_monitor_object_type_t) request.argument0;
|
|
||||||
id = (rtems_id) request.argument1;
|
|
||||||
next_id = rtems_monitor_object_canonical_get(object_type,
|
|
||||||
id,
|
|
||||||
&response.payload,
|
|
||||||
&size);
|
|
||||||
|
|
||||||
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
|
|
||||||
response.result0 = next_id;
|
|
||||||
response.result1 = size;
|
|
||||||
|
|
||||||
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
|
|
||||||
payload))
|
|
||||||
|
|
||||||
status = rtems_message_queue_send(request.return_id,
|
|
||||||
&response,
|
|
||||||
size + SERVER_OVERHEAD);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "response send failed");
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
rtems_error(0, "invalid command to monitor server: %d", request.command);
|
|
||||||
goto failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
failed:
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Kill off any old server
|
|
||||||
* Not sure if this is useful, but it doesn't help
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_server_kill(void)
|
|
||||||
{
|
|
||||||
if (rtems_monitor_server_task_id)
|
|
||||||
rtems_task_delete(rtems_monitor_server_task_id);
|
|
||||||
rtems_monitor_server_task_id = 0;
|
|
||||||
|
|
||||||
if (rtems_monitor_server_request_queue_id)
|
|
||||||
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
|
|
||||||
rtems_monitor_server_request_queue_ids = 0;
|
|
||||||
|
|
||||||
if (rtems_monitor_server_response_queue_id)
|
|
||||||
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
|
|
||||||
rtems_monitor_server_response_queue_id = 0;
|
|
||||||
|
|
||||||
if (rtems_monitor_server_request_queue_ids)
|
|
||||||
free(rtems_monitor_server_request_queue_ids);
|
|
||||||
rtems_monitor_server_request_queue_ids = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_server_init(
|
|
||||||
unsigned32 monitor_flags
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_status_code status;
|
|
||||||
|
|
||||||
if (_System_state_Is_multiprocessing &&
|
|
||||||
(_Configuration_MP_table->maximum_nodes > 1))
|
|
||||||
{
|
|
||||||
unsigned32 maximum_nodes = _Configuration_MP_table->maximum_nodes;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create the msg que our server will listen
|
|
||||||
* Since we only get msgs from other RTEMS monitors, we just
|
|
||||||
* need reserve space for 1 msg from each node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = rtems_message_queue_create(
|
|
||||||
RTEMS_MONITOR_QUEUE_NAME,
|
|
||||||
maximum_nodes,
|
|
||||||
sizeof(rtems_monitor_server_request_t),
|
|
||||||
RTEMS_GLOBAL,
|
|
||||||
&rtems_monitor_server_request_queue_id);
|
|
||||||
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "could not create monitor server message queue");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create the msg que our responses will come on
|
|
||||||
* Since monitor just does one thing at a time, we only need 1 item
|
|
||||||
* message queue.
|
|
||||||
*/
|
|
||||||
|
|
||||||
status = rtems_message_queue_create(
|
|
||||||
RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
|
|
||||||
1, /* depth */
|
|
||||||
sizeof(rtems_monitor_server_response_t),
|
|
||||||
RTEMS_GLOBAL,
|
|
||||||
&rtems_monitor_server_response_queue_id);
|
|
||||||
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "could not create monitor response message queue");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* need an id for queue of each other server we might talk to */
|
|
||||||
/* indexed by node, so add 1 to maximum_nodes */
|
|
||||||
rtems_monitor_server_request_queue_ids =
|
|
||||||
(rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id));
|
|
||||||
(void) memset(rtems_monitor_server_request_queue_ids,
|
|
||||||
0,
|
|
||||||
(maximum_nodes + 1) * sizeof(rtems_id));
|
|
||||||
|
|
||||||
rtems_monitor_server_request_queue_ids[rtems_monitor_node] =
|
|
||||||
rtems_monitor_server_request_queue_id;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* create the server task
|
|
||||||
*/
|
|
||||||
status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME,
|
|
||||||
1,
|
|
||||||
0 /* default stack */,
|
|
||||||
RTEMS_INTERRUPT_LEVEL(0),
|
|
||||||
RTEMS_DEFAULT_ATTRIBUTES,
|
|
||||||
&rtems_monitor_server_task_id);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "could not create monitor server task");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start the server task
|
|
||||||
*/
|
|
||||||
status = rtems_task_start(rtems_monitor_server_task_id,
|
|
||||||
rtems_monitor_server_task,
|
|
||||||
monitor_flags);
|
|
||||||
if (status != RTEMS_SUCCESSFUL)
|
|
||||||
{
|
|
||||||
rtems_error(status, "could not start monitor server");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
@@ -1,482 +0,0 @@
|
|||||||
/*
|
|
||||||
* File: symbols.c
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Symbol table manager for the RTEMS monitor.
|
|
||||||
* These routines may be used by other system resources also.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
#include <rtems/symbols.h>
|
|
||||||
|
|
||||||
|
|
||||||
rtems_symbol_table_t *
|
|
||||||
rtems_symbol_table_create()
|
|
||||||
{
|
|
||||||
rtems_symbol_table_t *table;
|
|
||||||
|
|
||||||
table = (rtems_symbol_table_t *) malloc(sizeof(rtems_symbol_table_t));
|
|
||||||
memset((void *) table, 0, sizeof(*table));
|
|
||||||
|
|
||||||
table->growth_factor = 30; /* 30 percent */
|
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_symbol_table_destroy(rtems_symbol_table_t *table)
|
|
||||||
{
|
|
||||||
rtems_symbol_string_block_t *p, *pnext;
|
|
||||||
|
|
||||||
if (table)
|
|
||||||
{
|
|
||||||
if (table->addresses)
|
|
||||||
(void) free(table->addresses);
|
|
||||||
table->addresses = 0;
|
|
||||||
p = table->string_buffer_head;
|
|
||||||
while (p)
|
|
||||||
{
|
|
||||||
pnext = p->next;
|
|
||||||
free(p);
|
|
||||||
p = pnext;
|
|
||||||
}
|
|
||||||
table->string_buffer_head = 0;
|
|
||||||
table->string_buffer_current = 0;
|
|
||||||
|
|
||||||
free(table);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_symbol_t *
|
|
||||||
rtems_symbol_create(
|
|
||||||
rtems_symbol_table_t *table,
|
|
||||||
char *name,
|
|
||||||
rtems_unsigned32 value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int symbol_length;
|
|
||||||
size_t newsize;
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
|
|
||||||
symbol_length = strlen(name) + 1; /* include '\000' in length */
|
|
||||||
|
|
||||||
/* need to grow the table? */
|
|
||||||
if (table->next >= table->size)
|
|
||||||
{
|
|
||||||
if (table->size == 0)
|
|
||||||
newsize = 100;
|
|
||||||
else
|
|
||||||
newsize = table->size + (table->size / (100 / table->growth_factor));
|
|
||||||
|
|
||||||
table->addresses = (rtems_symbol_t *) realloc((void *) table->addresses, newsize * sizeof(rtems_symbol_t));
|
|
||||||
if (table->addresses == 0) /* blew it; lost orig */
|
|
||||||
goto failed;
|
|
||||||
table->size = newsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = &table->addresses[table->next];
|
|
||||||
sp->value = value;
|
|
||||||
|
|
||||||
/* Have to add it to string pool */
|
|
||||||
/* need to grow pool? */
|
|
||||||
|
|
||||||
if ((table->string_buffer_head == 0) ||
|
|
||||||
(table->strings_next + symbol_length) >= SYMBOL_STRING_BLOCK_SIZE)
|
|
||||||
{
|
|
||||||
rtems_symbol_string_block_t *p;
|
|
||||||
|
|
||||||
p = (rtems_symbol_string_block_t *) malloc(sizeof(rtems_symbol_string_block_t));
|
|
||||||
if (p == 0)
|
|
||||||
goto failed;
|
|
||||||
p->next = 0;
|
|
||||||
if (table->string_buffer_head == 0)
|
|
||||||
table->string_buffer_head = p;
|
|
||||||
else
|
|
||||||
table->string_buffer_current->next = p;
|
|
||||||
table->string_buffer_current = p;
|
|
||||||
|
|
||||||
table->strings_next = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp->name = table->string_buffer_current->buffer + table->strings_next;
|
|
||||||
(void) strcpy(sp->name, name);
|
|
||||||
|
|
||||||
table->strings_next += symbol_length;
|
|
||||||
table->sorted = 0;
|
|
||||||
table->next++;
|
|
||||||
|
|
||||||
return sp;
|
|
||||||
|
|
||||||
/* XXX Not sure what to do here. We've possibly destroyed the initial
|
|
||||||
symbol table due to realloc failure */
|
|
||||||
failed:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Qsort entry point for compare by address
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int
|
|
||||||
rtems_symbol_compare(const void *e1,
|
|
||||||
const void *e2)
|
|
||||||
{
|
|
||||||
rtems_symbol_t *s1, *s2;
|
|
||||||
s1 = (rtems_symbol_t *) e1;
|
|
||||||
s2 = (rtems_symbol_t *) e2;
|
|
||||||
|
|
||||||
if (s1->value < s2->value)
|
|
||||||
return -1;
|
|
||||||
if (s1->value > s2->value)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sort the symbol table using qsort
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
rtems_symbol_sort(rtems_symbol_table_t *table)
|
|
||||||
{
|
|
||||||
qsort((void *) table->addresses, (size_t) table->next,
|
|
||||||
sizeof(rtems_symbol_t), rtems_symbol_compare);
|
|
||||||
table->sorted = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search the symbol table by address
|
|
||||||
* This code based on CYGNUS newlib bsearch, but changed
|
|
||||||
* to allow for finding closest symbol <= key
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_symbol_t *
|
|
||||||
rtems_symbol_value_lookup(
|
|
||||||
rtems_symbol_table_t *table,
|
|
||||||
rtems_unsigned32 value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
rtems_symbol_t *base;
|
|
||||||
rtems_symbol_t *best = 0;
|
|
||||||
rtems_unsigned32 distance;
|
|
||||||
rtems_unsigned32 best_distance = ~0;
|
|
||||||
rtems_unsigned32 elements;
|
|
||||||
|
|
||||||
if (table == 0)
|
|
||||||
table = rtems_monitor_symbols;
|
|
||||||
|
|
||||||
if ((table == 0) || (table->size == 0))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (table->sorted == 0)
|
|
||||||
rtems_symbol_sort(table);
|
|
||||||
|
|
||||||
base = table->addresses;
|
|
||||||
elements = table->next;
|
|
||||||
|
|
||||||
while (elements)
|
|
||||||
{
|
|
||||||
sp = base + (elements / 2);
|
|
||||||
if (value < sp->value)
|
|
||||||
elements /= 2;
|
|
||||||
else if (value > sp->value)
|
|
||||||
{
|
|
||||||
distance = value - sp->value;
|
|
||||||
if (distance < best_distance)
|
|
||||||
{
|
|
||||||
best_distance = distance;
|
|
||||||
best = sp;
|
|
||||||
}
|
|
||||||
base = sp + 1;
|
|
||||||
elements = (elements / 2) - (elements % 2 ? 0 : 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value == base->value)
|
|
||||||
return base;
|
|
||||||
|
|
||||||
return best;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search the symbol table for the exact matching address.
|
|
||||||
* If the symbol table has already been sorted, then
|
|
||||||
* call the regular symbol value lookup, however, it it
|
|
||||||
* has not yet been sorted, search it sequentially.
|
|
||||||
* This routine is primarily used for low level symbol
|
|
||||||
* lookups (eg. from exception handler and interrupt routines)
|
|
||||||
* where the penality of sorted is not wanted and where
|
|
||||||
* an exact match is needed such that symbol table order
|
|
||||||
* is not important.
|
|
||||||
*/
|
|
||||||
const rtems_symbol_t *
|
|
||||||
rtems_symbol_value_lookup_exact(
|
|
||||||
rtems_symbol_table_t *table,
|
|
||||||
rtems_unsigned32 value
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_unsigned32 s;
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
|
|
||||||
if (table == 0)
|
|
||||||
{
|
|
||||||
table = rtems_monitor_symbols;
|
|
||||||
if (table == 0)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table->sorted)
|
|
||||||
{
|
|
||||||
sp = rtems_symbol_value_lookup(table, value);
|
|
||||||
if ( rtems_symbol_value(sp) == value )
|
|
||||||
return sp;
|
|
||||||
else
|
|
||||||
return NULL; /* not an exact match */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
|
|
||||||
{
|
|
||||||
if ( sp->value == value )
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Search the symbol table by string name (case independent)
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_symbol_t *
|
|
||||||
rtems_symbol_name_lookup(
|
|
||||||
rtems_symbol_table_t *table,
|
|
||||||
char *name
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_unsigned32 s;
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
|
|
||||||
if (table == 0)
|
|
||||||
{
|
|
||||||
table = rtems_monitor_symbols;
|
|
||||||
if (table == 0)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
|
|
||||||
{
|
|
||||||
if ( strcasecmp(sp->name, name) == 0 )
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
rtems_monitor_symbol_next(
|
|
||||||
void *object_info,
|
|
||||||
rtems_monitor_symbol_t *canonical,
|
|
||||||
rtems_id *next_id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_symbol_table_t *table;
|
|
||||||
rtems_unsigned32 n = rtems_get_index(*next_id);
|
|
||||||
|
|
||||||
table = *(rtems_symbol_table_t **) object_info;
|
|
||||||
if (table == 0)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
if (n >= table->next)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
/* NOTE: symbols do not have id and name fields */
|
|
||||||
|
|
||||||
if (table->sorted == 0)
|
|
||||||
rtems_symbol_sort(table);
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
|
|
||||||
*next_id += 1;
|
|
||||||
return (void *) (table->addresses + n);
|
|
||||||
|
|
||||||
failed:
|
|
||||||
*next_id = RTEMS_OBJECT_ID_FINAL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_symbol_canonical(
|
|
||||||
rtems_monitor_symbol_t *canonical_symbol,
|
|
||||||
rtems_symbol_t *sp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
canonical_symbol->value = sp->value;
|
|
||||||
canonical_symbol->offset = 0;
|
|
||||||
strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_symbol_canonical_by_name(
|
|
||||||
rtems_monitor_symbol_t *canonical_symbol,
|
|
||||||
char *name
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
|
|
||||||
sp = rtems_symbol_name_lookup(0, name);
|
|
||||||
|
|
||||||
canonical_symbol->value = sp ? sp->value : 0;
|
|
||||||
|
|
||||||
strncpy(canonical_symbol->name, name, sizeof(canonical_symbol->name));
|
|
||||||
canonical_symbol->offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_symbol_canonical_by_value(
|
|
||||||
rtems_monitor_symbol_t *canonical_symbol,
|
|
||||||
void *value_void_p
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 value = (unsigned32) value_void_p;
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
|
|
||||||
sp = rtems_symbol_value_lookup(0, value);
|
|
||||||
if (sp)
|
|
||||||
{
|
|
||||||
canonical_symbol->value = sp->value;
|
|
||||||
canonical_symbol->offset = value - sp->value;
|
|
||||||
strncpy(canonical_symbol->name, sp->name, sizeof(canonical_symbol->name));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
canonical_symbol->value = value;
|
|
||||||
canonical_symbol->offset = 0;
|
|
||||||
canonical_symbol->name[0] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned32
|
|
||||||
rtems_monitor_symbol_dump(
|
|
||||||
rtems_monitor_symbol_t *canonical_symbol,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 length = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* print the name if it exists AND if value is non-zero
|
|
||||||
* Ie: don't print some garbage symbol for address 0
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (canonical_symbol->name[0] && (canonical_symbol->value != 0))
|
|
||||||
{
|
|
||||||
if (canonical_symbol->offset == 0)
|
|
||||||
length += printf("%.*s",
|
|
||||||
(int) sizeof(canonical_symbol->name),
|
|
||||||
canonical_symbol->name);
|
|
||||||
else
|
|
||||||
length += printf("<%.*s+0x%x>",
|
|
||||||
(int) sizeof(canonical_symbol->name),
|
|
||||||
canonical_symbol->name,
|
|
||||||
canonical_symbol->offset);
|
|
||||||
if (verbose)
|
|
||||||
length += printf(" [0x%x]", canonical_symbol->value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
length += printf("[0x%x]", canonical_symbol->value);
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_symbol_dump_all(
|
|
||||||
rtems_symbol_table_t *table,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_unsigned32 s;
|
|
||||||
rtems_symbol_t *sp;
|
|
||||||
|
|
||||||
if (table == 0)
|
|
||||||
{
|
|
||||||
table = rtems_monitor_symbols;
|
|
||||||
if (table == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table->sorted == 0)
|
|
||||||
rtems_symbol_sort(table);
|
|
||||||
|
|
||||||
for (s = 0, sp = table->addresses; s < table->next; s++, sp++)
|
|
||||||
{
|
|
||||||
rtems_monitor_symbol_t canonical_symbol;
|
|
||||||
|
|
||||||
rtems_monitor_symbol_canonical(&canonical_symbol, sp);
|
|
||||||
rtems_monitor_symbol_dump(&canonical_symbol, TRUE);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 'symbol' command
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_symbol_cmd(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int arg;
|
|
||||||
rtems_symbol_table_t *table;
|
|
||||||
|
|
||||||
table = *(rtems_symbol_table_t **) command_arg;
|
|
||||||
if (table == 0)
|
|
||||||
{
|
|
||||||
table = rtems_monitor_symbols;
|
|
||||||
if (table == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Use object command to dump out whole symbol table
|
|
||||||
*/
|
|
||||||
if (argc == 1)
|
|
||||||
rtems_monitor_symbol_dump_all(table, verbose);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rtems_monitor_symbol_t canonical_symbol;
|
|
||||||
|
|
||||||
for (arg=1; argv[arg]; arg++)
|
|
||||||
{
|
|
||||||
rtems_monitor_symbol_canonical_by_name(&canonical_symbol, argv[arg]);
|
|
||||||
rtems_monitor_symbol_dump(&canonical_symbol, verbose);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS Monitor task support
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h> /* memcpy() */
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_task_canonical(
|
|
||||||
rtems_monitor_task_t *canonical_task,
|
|
||||||
void *thread_void
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Thread_Control *rtems_thread = (Thread_Control *) thread_void;
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
|
|
||||||
api = rtems_thread->API_Extensions[ THREAD_API_RTEMS ];
|
|
||||||
|
|
||||||
canonical_task->entry = rtems_thread->Start.entry_point;
|
|
||||||
canonical_task->argument = rtems_thread->Start.numeric_argument;
|
|
||||||
canonical_task->stack = rtems_thread->Start.Initial_stack.area;
|
|
||||||
canonical_task->stack_size = rtems_thread->Start.Initial_stack.size;
|
|
||||||
canonical_task->priority = rtems_thread->current_priority;
|
|
||||||
canonical_task->state = rtems_thread->current_state;
|
|
||||||
canonical_task->wait_id = rtems_thread->Wait.id;
|
|
||||||
canonical_task->events = api->pending_events;
|
|
||||||
|
|
||||||
/* XXX modes and attributes only exist in the RTEMS API .. */
|
|
||||||
/* XXX not directly in the core thread.. they will have to be derived */
|
|
||||||
/* XXX if they are important enough to include anymore. */
|
|
||||||
canonical_task->modes = 0; /* XXX FIX ME.... rtems_thread->current_modes; */
|
|
||||||
canonical_task->attributes = 0 /* XXX FIX ME rtems_thread->API_Extensions[ THREAD_API_RTEMS ]->attribute_set */;
|
|
||||||
(void) memcpy(canonical_task->notepad, api ->Notepads, sizeof(canonical_task->notepad));
|
|
||||||
/* XXX more to fix */
|
|
||||||
/*
|
|
||||||
(void) memcpy(&canonical_task->wait_args, &rtems_thread->Wait.Extra, sizeof(canonical_task->wait_args));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_task_dump_header(
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
printf("\
|
|
||||||
ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES\n");
|
|
||||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
|
||||||
0 1 2 3 4 5 6 7 */
|
|
||||||
|
|
||||||
rtems_monitor_separator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
rtems_monitor_task_dump(
|
|
||||||
rtems_monitor_task_t *monitor_task,
|
|
||||||
boolean verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int length = 0;
|
|
||||||
|
|
||||||
length += rtems_monitor_dump_id(monitor_task->id);
|
|
||||||
length += rtems_monitor_pad(11, length);
|
|
||||||
length += rtems_monitor_dump_name(monitor_task->name);
|
|
||||||
length += rtems_monitor_pad(18, length);
|
|
||||||
length += rtems_monitor_dump_priority(monitor_task->priority);
|
|
||||||
length += rtems_monitor_pad(24, length);
|
|
||||||
length += rtems_monitor_dump_state(monitor_task->state);
|
|
||||||
length += rtems_monitor_pad(31, length);
|
|
||||||
length += rtems_monitor_dump_modes(monitor_task->modes);
|
|
||||||
length += rtems_monitor_pad(39, length);
|
|
||||||
length += rtems_monitor_dump_events(monitor_task->events);
|
|
||||||
if (monitor_task->wait_id)
|
|
||||||
{
|
|
||||||
length += rtems_monitor_pad(47, length);
|
|
||||||
length += rtems_monitor_dump_id(monitor_task->wait_id);
|
|
||||||
length += rtems_monitor_pad(57, length);
|
|
||||||
length += rtems_monitor_dump_hex(monitor_task->wait_args);
|
|
||||||
}
|
|
||||||
|
|
||||||
length += rtems_monitor_pad(65, length);
|
|
||||||
length += rtems_monitor_dump_notepad(monitor_task->notepad);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,458 +0,0 @@
|
|||||||
/*
|
|
||||||
* File: monitor.h
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* The RTEMS monitor task include file.
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __MONITOR_H
|
|
||||||
#define __MONITOR_H
|
|
||||||
|
|
||||||
#include <rtems/symbols.h>
|
|
||||||
#include <rtems/error.h> /* rtems_error() */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Monitor types are derived from rtems object classes
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
RTEMS_MONITOR_OBJECT_INVALID = OBJECTS_NO_CLASS,
|
|
||||||
RTEMS_MONITOR_OBJECT_TASK = OBJECTS_RTEMS_TASKS,
|
|
||||||
RTEMS_MONITOR_OBJECT_EXTENSION = OBJECTS_RTEMS_EXTENSIONS,
|
|
||||||
RTEMS_MONITOR_OBJECT_QUEUE = OBJECTS_RTEMS_MESSAGE_QUEUES,
|
|
||||||
RTEMS_MONITOR_OBJECT_SEMAPHORE = OBJECTS_RTEMS_SEMAPHORES,
|
|
||||||
RTEMS_MONITOR_OBJECT_PARTITION = OBJECTS_RTEMS_PARTITIONS,
|
|
||||||
RTEMS_MONITOR_OBJECT_REGION = OBJECTS_RTEMS_REGIONS,
|
|
||||||
RTEMS_MONITOR_OBJECT_PORT = OBJECTS_RTEMS_PORTS,
|
|
||||||
|
|
||||||
/* following monitor objects are not known to RTEMS, but
|
|
||||||
* we like to have "types" for them anyway */
|
|
||||||
|
|
||||||
RTEMS_MONITOR_OBJECT_DRIVER = OBJECTS_RTEMS_CLASSES_LAST+1,
|
|
||||||
RTEMS_MONITOR_OBJECT_DNAME,
|
|
||||||
RTEMS_MONITOR_OBJECT_CONFIG,
|
|
||||||
RTEMS_MONITOR_OBJECT_INIT_TASK,
|
|
||||||
RTEMS_MONITOR_OBJECT_MPCI,
|
|
||||||
RTEMS_MONITOR_OBJECT_SYMBOL
|
|
||||||
} rtems_monitor_object_type_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rtems_monitor_init() flags
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RTEMS_MONITOR_SUSPEND 0x0001 /* suspend monitor on startup */
|
|
||||||
#define RTEMS_MONITOR_GLOBAL 0x0002 /* monitor should be global */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Public interfaces for RTEMS data structures monitor is aware of.
|
|
||||||
* These are only used by the monitor.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* All the canonical objects that correspond to RTEMS managed "objects"
|
|
||||||
* must have an identical first portion with 'id' and 'name' fields.
|
|
||||||
*
|
|
||||||
* Others do not have that restriction, even tho we would like them to.
|
|
||||||
* This is because some of the canonical structures are almost too big
|
|
||||||
* for shared memory driver (eg: mpci) and we are nickel and diming it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Type of a pointer that may be a symbol
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MONITOR_SYMBOL_LEN 20
|
|
||||||
typedef struct {
|
|
||||||
char name[MONITOR_SYMBOL_LEN];
|
|
||||||
unsigned32 value;
|
|
||||||
unsigned32 offset;
|
|
||||||
} rtems_monitor_symbol_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id;
|
|
||||||
rtems_name name;
|
|
||||||
/* end of common portion */
|
|
||||||
} rtems_monitor_generic_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Task
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id;
|
|
||||||
rtems_name name;
|
|
||||||
/* end of common portion */
|
|
||||||
Thread_Entry entry;
|
|
||||||
unsigned32 argument;
|
|
||||||
void *stack;
|
|
||||||
unsigned32 stack_size;
|
|
||||||
rtems_task_priority priority;
|
|
||||||
States_Control state;
|
|
||||||
rtems_event_set events;
|
|
||||||
rtems_mode modes;
|
|
||||||
rtems_attribute attributes;
|
|
||||||
unsigned32 notepad[RTEMS_NUMBER_NOTEPADS];
|
|
||||||
rtems_id wait_id;
|
|
||||||
unsigned32 wait_args;
|
|
||||||
} rtems_monitor_task_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Init task
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id; /* not really an id */
|
|
||||||
rtems_name name;
|
|
||||||
/* end of common portion */
|
|
||||||
rtems_monitor_symbol_t entry;
|
|
||||||
unsigned32 argument;
|
|
||||||
unsigned32 stack_size;
|
|
||||||
rtems_task_priority priority;
|
|
||||||
rtems_mode modes;
|
|
||||||
rtems_attribute attributes;
|
|
||||||
} rtems_monitor_init_task_t;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Message queue
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id;
|
|
||||||
rtems_name name;
|
|
||||||
/* end of common portion */
|
|
||||||
rtems_attribute attributes;
|
|
||||||
unsigned32 number_of_pending_messages;
|
|
||||||
unsigned32 maximum_pending_messages;
|
|
||||||
unsigned32 maximum_message_size;
|
|
||||||
} rtems_monitor_queue_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extension
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id;
|
|
||||||
rtems_name name;
|
|
||||||
/* end of common portion */
|
|
||||||
rtems_monitor_symbol_t e_create;
|
|
||||||
rtems_monitor_symbol_t e_start;
|
|
||||||
rtems_monitor_symbol_t e_restart;
|
|
||||||
rtems_monitor_symbol_t e_delete;
|
|
||||||
rtems_monitor_symbol_t e_tswitch;
|
|
||||||
rtems_monitor_symbol_t e_begin;
|
|
||||||
rtems_monitor_symbol_t e_exitted;
|
|
||||||
rtems_monitor_symbol_t e_fatal;
|
|
||||||
} rtems_monitor_extension_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Device driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id; /* not really an id (should be tho) */
|
|
||||||
rtems_name name; /* ditto */
|
|
||||||
/* end of common portion */
|
|
||||||
rtems_monitor_symbol_t initialization; /* initialization procedure */
|
|
||||||
rtems_monitor_symbol_t open; /* open request procedure */
|
|
||||||
rtems_monitor_symbol_t close; /* close request procedure */
|
|
||||||
rtems_monitor_symbol_t read; /* read request procedure */
|
|
||||||
rtems_monitor_symbol_t write; /* write request procedure */
|
|
||||||
rtems_monitor_symbol_t control; /* special functions procedure */
|
|
||||||
} rtems_monitor_driver_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id; /* not used for drivers (yet) */
|
|
||||||
rtems_name name; /* not used for drivers (yet) */
|
|
||||||
/* end of common portion */
|
|
||||||
unsigned32 major;
|
|
||||||
unsigned32 minor;
|
|
||||||
char name_string[64];
|
|
||||||
} rtems_monitor_dname_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* System config
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *work_space_start;
|
|
||||||
unsigned32 work_space_size;
|
|
||||||
unsigned32 maximum_tasks;
|
|
||||||
unsigned32 maximum_timers;
|
|
||||||
unsigned32 maximum_semaphores;
|
|
||||||
unsigned32 maximum_message_queues;
|
|
||||||
unsigned32 maximum_partitions;
|
|
||||||
unsigned32 maximum_regions;
|
|
||||||
unsigned32 maximum_ports;
|
|
||||||
unsigned32 maximum_periods;
|
|
||||||
unsigned32 maximum_extensions;
|
|
||||||
unsigned32 microseconds_per_tick;
|
|
||||||
unsigned32 ticks_per_timeslice;
|
|
||||||
unsigned32 number_of_initialization_tasks;
|
|
||||||
} rtems_monitor_config_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MPCI config
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
typedef struct {
|
|
||||||
unsigned32 node; /* local node number */
|
|
||||||
unsigned32 maximum_nodes; /* maximum # nodes in system */
|
|
||||||
unsigned32 maximum_global_objects; /* maximum # global objects */
|
|
||||||
unsigned32 maximum_proxies; /* maximum # proxies */
|
|
||||||
|
|
||||||
unsigned32 default_timeout; /* in ticks */
|
|
||||||
unsigned32 maximum_packet_size;
|
|
||||||
rtems_monitor_symbol_t initialization;
|
|
||||||
rtems_monitor_symbol_t get_packet;
|
|
||||||
rtems_monitor_symbol_t return_packet;
|
|
||||||
rtems_monitor_symbol_t send_packet;
|
|
||||||
rtems_monitor_symbol_t receive_packet;
|
|
||||||
} rtems_monitor_mpci_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The generic canonical information union
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
rtems_monitor_generic_t generic;
|
|
||||||
rtems_monitor_task_t task;
|
|
||||||
rtems_monitor_queue_t queue;
|
|
||||||
rtems_monitor_extension_t extension;
|
|
||||||
rtems_monitor_driver_t driver;
|
|
||||||
rtems_monitor_dname_t dname;
|
|
||||||
rtems_monitor_config_t config;
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
rtems_monitor_mpci_t mpci;
|
|
||||||
#endif
|
|
||||||
rtems_monitor_init_task_t itask;
|
|
||||||
} rtems_monitor_union_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Support for talking to other monitors
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Names of other monitors
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define RTEMS_MONITOR_NAME (rtems_build_name('R', 'M', 'O', 'N'))
|
|
||||||
#define RTEMS_MONITOR_SERVER_NAME (rtems_build_name('R', 'M', 'S', 'V'))
|
|
||||||
#define RTEMS_MONITOR_QUEUE_NAME (rtems_build_name('R', 'M', 'S', 'Q'))
|
|
||||||
#define RTEMS_MONITOR_RESPONSE_QUEUE_NAME (rtems_build_name('R', 'M', 'R', 'Q'))
|
|
||||||
|
|
||||||
#define RTEMS_MONITOR_SERVER_RESPONSE 0x0001
|
|
||||||
#define RTEMS_MONITOR_SERVER_CANONICAL 0x0002
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned32 command;
|
|
||||||
rtems_id return_id;
|
|
||||||
unsigned32 argument0;
|
|
||||||
unsigned32 argument1;
|
|
||||||
unsigned32 argument2;
|
|
||||||
unsigned32 argument3;
|
|
||||||
unsigned32 argument4;
|
|
||||||
unsigned32 argument5;
|
|
||||||
} rtems_monitor_server_request_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned32 command;
|
|
||||||
unsigned32 result0;
|
|
||||||
unsigned32 result1;
|
|
||||||
rtems_monitor_union_t payload;
|
|
||||||
} rtems_monitor_server_response_t;
|
|
||||||
|
|
||||||
extern rtems_id rtems_monitor_task_id;
|
|
||||||
|
|
||||||
extern unsigned32 rtems_monitor_node; /* our node number */
|
|
||||||
extern unsigned32 rtems_monitor_default_node; /* current default for commands */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Monitor command function and table entry
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct rtems_monitor_command_entry_s rtems_monitor_command_entry_t;
|
|
||||||
|
|
||||||
typedef void ( *rtems_monitor_command_function_t )(
|
|
||||||
int argc,
|
|
||||||
char **argv,
|
|
||||||
unsigned32 command_arg,
|
|
||||||
boolean verbose
|
|
||||||
);
|
|
||||||
|
|
||||||
#if defined(__mips64)
|
|
||||||
typedef unsigned64 rtems_monitor_command_arg_t;
|
|
||||||
#else
|
|
||||||
typedef unsigned32 rtems_monitor_command_arg_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct rtems_monitor_command_entry_s {
|
|
||||||
char *command; /* command name */
|
|
||||||
char *usage; /* usage string for the command */
|
|
||||||
unsigned32 arguments_required; /* # of required args */
|
|
||||||
rtems_monitor_command_function_t command_function;
|
|
||||||
/* Some argument for the command */
|
|
||||||
rtems_monitor_command_arg_t command_arg;
|
|
||||||
struct rtems_monitor_command_entry_s *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void *(*rtems_monitor_object_next_fn)(void *, void *, rtems_id *);
|
|
||||||
typedef void (*rtems_monitor_object_canonical_fn)(void *, void *);
|
|
||||||
typedef void (*rtems_monitor_object_dump_header_fn)(boolean);
|
|
||||||
typedef void (*rtems_monitor_object_dump_fn)(void *, boolean);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_monitor_object_type_t type;
|
|
||||||
void *object_information;
|
|
||||||
int size; /* of canonical object */
|
|
||||||
rtems_monitor_object_next_fn next;
|
|
||||||
rtems_monitor_object_canonical_fn canonical;
|
|
||||||
rtems_monitor_object_dump_header_fn dump_header;
|
|
||||||
rtems_monitor_object_dump_fn dump;
|
|
||||||
} rtems_monitor_object_info_t;
|
|
||||||
|
|
||||||
|
|
||||||
/* monitor.c */
|
|
||||||
void rtems_monitor_kill(void);
|
|
||||||
void rtems_monitor_init(unsigned32);
|
|
||||||
void rtems_monitor_wakeup(void);
|
|
||||||
void rtems_monitor_pause_cmd(int, char **, unsigned32, boolean);
|
|
||||||
void rtems_monitor_fatal_cmd(int, char **, unsigned32, boolean);
|
|
||||||
void rtems_monitor_continue_cmd(int, char **, unsigned32, boolean);
|
|
||||||
void rtems_monitor_debugger_cmd(int, char **, unsigned32, boolean);
|
|
||||||
void rtems_monitor_node_cmd(int, char **, unsigned32, boolean);
|
|
||||||
void rtems_monitor_symbols_loadup(void);
|
|
||||||
int rtems_monitor_insert_cmd(rtems_monitor_command_entry_t *);
|
|
||||||
int rtems_monitor_erase_cmd(rtems_monitor_command_entry_t *);
|
|
||||||
|
|
||||||
void rtems_monitor_task(rtems_task_argument);
|
|
||||||
|
|
||||||
/* server.c */
|
|
||||||
void rtems_monitor_server_kill(void);
|
|
||||||
rtems_status_code rtems_monitor_server_request(unsigned32, rtems_monitor_server_request_t *, rtems_monitor_server_response_t *);
|
|
||||||
void rtems_monitor_server_task(rtems_task_argument);
|
|
||||||
void rtems_monitor_server_init(unsigned32);
|
|
||||||
|
|
||||||
/* command.c */
|
|
||||||
int rtems_monitor_make_argv(char *, int *, char **);
|
|
||||||
int rtems_monitor_command_read(char *, int *, char **);
|
|
||||||
rtems_monitor_command_entry_t *rtems_monitor_command_lookup(
|
|
||||||
rtems_monitor_command_entry_t * table, int argc, char **argv);
|
|
||||||
void rtems_monitor_command_usage(rtems_monitor_command_entry_t *, char *);
|
|
||||||
void rtems_monitor_help_cmd(int, char **, unsigned32, boolean);
|
|
||||||
|
|
||||||
/* prmisc.c */
|
|
||||||
void rtems_monitor_separator(void);
|
|
||||||
unsigned32 rtems_monitor_pad(unsigned32 dest_col, unsigned32 curr_col);
|
|
||||||
unsigned32 rtems_monitor_dump_char(unsigned8 ch);
|
|
||||||
unsigned32 rtems_monitor_dump_decimal(unsigned32 num);
|
|
||||||
unsigned32 rtems_monitor_dump_hex(unsigned32 num);
|
|
||||||
unsigned32 rtems_monitor_dump_id(rtems_id id);
|
|
||||||
unsigned32 rtems_monitor_dump_name(rtems_name name);
|
|
||||||
unsigned32 rtems_monitor_dump_priority(rtems_task_priority priority);
|
|
||||||
unsigned32 rtems_monitor_dump_state(States_Control state);
|
|
||||||
unsigned32 rtems_monitor_dump_modes(rtems_mode modes);
|
|
||||||
unsigned32 rtems_monitor_dump_attributes(rtems_attribute attributes);
|
|
||||||
unsigned32 rtems_monitor_dump_events(rtems_event_set events);
|
|
||||||
unsigned32 rtems_monitor_dump_notepad(unsigned32 *notepad);
|
|
||||||
|
|
||||||
/* object.c */
|
|
||||||
rtems_id rtems_monitor_id_fixup(rtems_id, unsigned32, rtems_monitor_object_type_t);
|
|
||||||
rtems_id rtems_monitor_object_canonical_get(rtems_monitor_object_type_t, rtems_id, void *, unsigned32 *size_p);
|
|
||||||
rtems_id rtems_monitor_object_canonical_next(rtems_monitor_object_info_t *, rtems_id, void *);
|
|
||||||
void *rtems_monitor_object_next(void *, void *, rtems_id, rtems_id *);
|
|
||||||
rtems_id rtems_monitor_object_canonical(rtems_id, void *);
|
|
||||||
void rtems_monitor_object_cmd(int, char **, unsigned32, boolean);
|
|
||||||
|
|
||||||
/* manager.c */
|
|
||||||
void *rtems_monitor_manager_next(void *, void *, rtems_id *);
|
|
||||||
|
|
||||||
/* config.c */
|
|
||||||
void rtems_monitor_config_canonical(rtems_monitor_config_t *, void *);
|
|
||||||
void *rtems_monitor_config_next(void *, rtems_monitor_config_t *, rtems_id *);
|
|
||||||
void rtems_monitor_config_dump_header(boolean);
|
|
||||||
void rtems_monitor_config_dump(rtems_monitor_config_t *, boolean verbose);
|
|
||||||
|
|
||||||
/* mpci.c */
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
void rtems_monitor_mpci_canonical(rtems_monitor_mpci_t *, void *);
|
|
||||||
void *rtems_monitor_mpci_next(void *, rtems_monitor_mpci_t *, rtems_id *);
|
|
||||||
void rtems_monitor_mpci_dump_header(boolean);
|
|
||||||
void rtems_monitor_mpci_dump(rtems_monitor_mpci_t *, boolean verbose);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* itask.c */
|
|
||||||
void rtems_monitor_init_task_canonical(rtems_monitor_init_task_t *, void *);
|
|
||||||
void *rtems_monitor_init_task_next(void *, rtems_monitor_init_task_t *, rtems_id *);
|
|
||||||
void rtems_monitor_init_task_dump_header(boolean);
|
|
||||||
void rtems_monitor_init_task_dump(rtems_monitor_init_task_t *, boolean verbose);
|
|
||||||
|
|
||||||
/* extension.c */
|
|
||||||
void rtems_monitor_extension_canonical(rtems_monitor_extension_t *, void *);
|
|
||||||
void rtems_monitor_extension_dump_header(boolean verbose);
|
|
||||||
void rtems_monitor_extension_dump(rtems_monitor_extension_t *, boolean);
|
|
||||||
|
|
||||||
/* task.c */
|
|
||||||
void rtems_monitor_task_canonical(rtems_monitor_task_t *, void *);
|
|
||||||
void rtems_monitor_task_dump_header(boolean verbose);
|
|
||||||
void rtems_monitor_task_dump(rtems_monitor_task_t *, boolean);
|
|
||||||
|
|
||||||
/* queue.c */
|
|
||||||
void rtems_monitor_queue_canonical(rtems_monitor_queue_t *, void *);
|
|
||||||
void rtems_monitor_queue_dump_header(boolean verbose);
|
|
||||||
void rtems_monitor_queue_dump(rtems_monitor_queue_t *, boolean);
|
|
||||||
|
|
||||||
/* driver.c */
|
|
||||||
void *rtems_monitor_driver_next(void *, rtems_monitor_driver_t *, rtems_id *);
|
|
||||||
void rtems_monitor_driver_canonical(rtems_monitor_driver_t *, void *);
|
|
||||||
void rtems_monitor_driver_dump_header(boolean);
|
|
||||||
void rtems_monitor_driver_dump(rtems_monitor_driver_t *, boolean);
|
|
||||||
|
|
||||||
/* dname.c */
|
|
||||||
void *rtems_monitor_dname_next(void *, rtems_monitor_dname_t *, rtems_id *);
|
|
||||||
void rtems_monitor_dname_canonical(rtems_monitor_dname_t *, void *);
|
|
||||||
void rtems_monitor_dname_dump_header(boolean);
|
|
||||||
void rtems_monitor_dname_dump(rtems_monitor_dname_t *, boolean);
|
|
||||||
|
|
||||||
/* symbols.c */
|
|
||||||
rtems_symbol_table_t *rtems_symbol_table_create();
|
|
||||||
void rtems_symbol_table_destroy(rtems_symbol_table_t *table);
|
|
||||||
|
|
||||||
rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *, char *, unsigned32);
|
|
||||||
rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *, unsigned32);
|
|
||||||
const rtems_symbol_t *rtems_symbol_value_lookup_exact(rtems_symbol_table_t *, unsigned32);
|
|
||||||
rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *, char *);
|
|
||||||
void *rtems_monitor_symbol_next(void *object_info, rtems_monitor_symbol_t *, rtems_id *);
|
|
||||||
void rtems_monitor_symbol_canonical(rtems_monitor_symbol_t *, rtems_symbol_t *);
|
|
||||||
void rtems_monitor_symbol_canonical_by_name(rtems_monitor_symbol_t *, char *);
|
|
||||||
void rtems_monitor_symbol_canonical_by_value(rtems_monitor_symbol_t *, void *);
|
|
||||||
unsigned32 rtems_monitor_symbol_dump(rtems_monitor_symbol_t *, boolean);
|
|
||||||
void rtems_monitor_symbol_cmd(int, char **, unsigned32, boolean);
|
|
||||||
|
|
||||||
|
|
||||||
extern rtems_symbol_table_t *rtems_monitor_symbols;
|
|
||||||
|
|
||||||
#ifndef MONITOR_PROMPT
|
|
||||||
#define MONITOR_PROMPT "rtems" /* will have '> ' appended */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
|
|
||||||
|
|
||||||
|
|
||||||
#define STREQ(a,b) (strcmp(a,b) == 0)
|
|
||||||
#define STRNEQ(a,b,n) (strncmp(a,b,n) == 0)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! __MONITOR_H */
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* RTEMS monitor symbol table functions
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Entry points for symbol table routines.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _INCLUDE_SYMBOLS_H
|
|
||||||
#define _INCLUDE_SYMBOLS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_unsigned32 value;
|
|
||||||
char *name;
|
|
||||||
} rtems_symbol_t;
|
|
||||||
|
|
||||||
#define SYMBOL_STRING_BLOCK_SIZE 4080
|
|
||||||
typedef struct rtems_symbol_string_block_s {
|
|
||||||
struct rtems_symbol_string_block_s *next;
|
|
||||||
char buffer[SYMBOL_STRING_BLOCK_SIZE];
|
|
||||||
} rtems_symbol_string_block_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
|
|
||||||
rtems_unsigned32 sorted; /* are symbols sorted right now? */
|
|
||||||
rtems_unsigned32 growth_factor; /* % to grow by when needed */
|
|
||||||
rtems_unsigned32 next; /* next symbol slot to use when adding */
|
|
||||||
rtems_unsigned32 size; /* max # of symbols */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Symbol list -- sorted by address (when we do a lookup)
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_symbol_t *addresses; /* symbol array by address */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* String pool, unsorted, a list of blocks of string data
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_symbol_string_block_t *string_buffer_head;
|
|
||||||
rtems_symbol_string_block_t *string_buffer_current;
|
|
||||||
rtems_unsigned32 strings_next; /* next byte to use in this block */
|
|
||||||
|
|
||||||
} rtems_symbol_table_t;
|
|
||||||
|
|
||||||
#define rtems_symbol_name(sp) ((sp)->name)
|
|
||||||
#define rtems_symbol_value(sp) ((sp)->value)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ! _INCLUDE_SYMBOLS_H */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libmw-fb-tmp
|
|
||||||
LIB = ${ARCH}/${LIBNAME}.a
|
|
||||||
|
|
||||||
C_FILES = mw_fb.c mw_uid.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=${ARCH}/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = mw_fb.h mw_uid.h
|
|
||||||
|
|
||||||
SRCS = $(C_FILES)
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
${LIB}: ${OBJS}
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: ${ARCH} $(PREINSTALL_FILES) $(LIB) $(TMPINSTALL_FILES)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = $(C_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/*
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// $Header$
|
|
||||||
//
|
|
||||||
// Copyright (c) 2000 - Rosimildo da Silva
|
|
||||||
//
|
|
||||||
// MODULE DESCRIPTION:
|
|
||||||
// Wrapper API around the ioctls calls for the Micro FrameBuffer
|
|
||||||
// interface for Embedded Systems
|
|
||||||
//
|
|
||||||
// All functions returns 0 on success. Any other value should be
|
|
||||||
// decoded as an error. A list of errors will be created over time.
|
|
||||||
//
|
|
||||||
// MODIFICATION/HISTORY:
|
|
||||||
//
|
|
||||||
// $Log$
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <rtems/mw_fb.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function returns the information regarding the display.
|
|
||||||
* It is called just after the driver be opened to get all needed
|
|
||||||
* information about the driver. No change in the mode of operation
|
|
||||||
* of the driver is done with this call.
|
|
||||||
*/
|
|
||||||
int ufb_get_screen_info( int fd, struct fb_screeninfo *info )
|
|
||||||
{
|
|
||||||
return ioctl( fd, FB_SCREENINFO, ( void *)info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the mode of the graphics subsystem
|
|
||||||
*/
|
|
||||||
int ufb_get_mode( int fd, int *mode )
|
|
||||||
{
|
|
||||||
struct fb_exec_function exec;
|
|
||||||
exec.func_no = FB_FUNC_GET_MODE;
|
|
||||||
exec.param = ( void *)mode;
|
|
||||||
return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the current collor pallete
|
|
||||||
*/
|
|
||||||
int ufb_get_palette( int fd, struct fb_cmap *color )
|
|
||||||
{
|
|
||||||
return ioctl( fd, FB_GETPALETTE, ( void *)color );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the current collor pallete
|
|
||||||
*/
|
|
||||||
int ufb_set_palette( int fd, struct fb_cmap *color )
|
|
||||||
{
|
|
||||||
return ioctl( fd, FB_SETPALETTE, ( void *)color );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Does all necessary initialization to put the device in
|
|
||||||
* graphics mode
|
|
||||||
*/
|
|
||||||
int ufb_enter_graphics( int fd, int mode )
|
|
||||||
{
|
|
||||||
struct fb_exec_function exec;
|
|
||||||
exec.func_no = FB_FUNC_ENTER_GRAPHICS;
|
|
||||||
exec.param = ( void *)mode;
|
|
||||||
return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch the device back to the default mode of operation.
|
|
||||||
* In most cases it put the device back to plain text mode.
|
|
||||||
*/
|
|
||||||
int ufb_exit_graphics( int fd )
|
|
||||||
{
|
|
||||||
struct fb_exec_function exec;
|
|
||||||
exec.func_no = FB_FUNC_EXIT_GRAPHICS;
|
|
||||||
exec.param = 0;
|
|
||||||
return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tell the driver that the "virtual buffer" is dirty, and an update
|
|
||||||
* of it to the real device, maybe a serial/parallel LCD or whatever
|
|
||||||
* is required
|
|
||||||
*/
|
|
||||||
int ufb_buffer_is_dirty( int fd )
|
|
||||||
{
|
|
||||||
struct fb_exec_function exec;
|
|
||||||
exec.func_no = FB_FUNC_IS_DIRTY;
|
|
||||||
exec.param = 0;
|
|
||||||
return ioctl( fd, FB_EXEC_FUNCTION , ( void *)&exec );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function maps the physical ( kernel mode ) address of the framebuffer device
|
|
||||||
* and maps it to the user space address.
|
|
||||||
*/
|
|
||||||
int ufb_mmap_to_user_space( int fd, void **fb_addr, void *physical_addr, unsigned long size )
|
|
||||||
{
|
|
||||||
#ifdef __rtems__
|
|
||||||
/* RTEMS runs in ring 0, and there is no distinction between
|
|
||||||
user space and kernel space, so we just return the same
|
|
||||||
pointer to the caller.
|
|
||||||
*/
|
|
||||||
*fb_addr = physical_addr;
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
/* other kernels might want to map it to the user space,
|
|
||||||
maybe using mmap()
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function unmaps memory of the FB from the user's space
|
|
||||||
*/
|
|
||||||
int ufb_unmmap_from_user_space( int fd, void *addr )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// $Header$
|
|
||||||
//
|
|
||||||
// Copyright (c) 2000 - Rosimildo da Silva
|
|
||||||
//
|
|
||||||
// MODULE DESCRIPTION:
|
|
||||||
// Micro FrameBuffer interface for Embedded Systems.
|
|
||||||
//
|
|
||||||
// MODIFICATION/HISTORY:
|
|
||||||
//
|
|
||||||
// $Log$
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
#ifndef _MW_FB_H
|
|
||||||
#define _MW_FB_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ioctls
|
|
||||||
0x46 is 'F' */
|
|
||||||
#define FB_SCREENINFO 0x4601
|
|
||||||
#define FB_GETPALETTE 0x4602
|
|
||||||
#define FB_SETPALETTE 0x4603
|
|
||||||
#define FB_EXEC_FUNCTION 0x4604
|
|
||||||
|
|
||||||
|
|
||||||
#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
|
|
||||||
#define FB_TYPE_PLANES 1 /* Non interleaved planes */
|
|
||||||
#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
|
|
||||||
#define FB_TYPE_TEXT 3 /* Text/attributes */
|
|
||||||
#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
|
|
||||||
#define FB_TYPE_VIRTUAL_BUFFER 5 /* Virtual Buffer */
|
|
||||||
|
|
||||||
|
|
||||||
#define FB_VISUAL_MONO01 0 /* Monochr. 1=Black 0=White */
|
|
||||||
#define FB_VISUAL_MONO10 1 /* Monochr. 1=White 0=Black */
|
|
||||||
#define FB_VISUAL_TRUECOLOR 2 /* True color */
|
|
||||||
#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
|
|
||||||
#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
|
|
||||||
#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
|
|
||||||
|
|
||||||
#define FB_ACCEL_NONE 0 /* no hardware accelerator */
|
|
||||||
|
|
||||||
/* no dependency on any other header file */
|
|
||||||
typedef unsigned long __u32;
|
|
||||||
typedef unsigned short __u16;
|
|
||||||
|
|
||||||
struct fb_screeninfo {
|
|
||||||
__u32 xres; /* visible resolution */
|
|
||||||
__u32 yres;
|
|
||||||
__u32 bits_per_pixel; /* guess what */
|
|
||||||
__u32 line_length; /* number of chars per line */
|
|
||||||
volatile char *smem_start; /* Start of frame buffer mem */
|
|
||||||
/* (physical address) */
|
|
||||||
__u32 smem_len; /* Length of frame buffer mem */
|
|
||||||
__u32 type; /* see FB_TYPE_* */
|
|
||||||
__u32 visual; /* see FB_VISUAL_* */
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fb_cmap {
|
|
||||||
__u32 start; /* First entry */
|
|
||||||
__u32 len; /* Number of entries */
|
|
||||||
__u16 *red; /* Red values */
|
|
||||||
__u16 *green;
|
|
||||||
__u16 *blue;
|
|
||||||
__u16 *transp; /* transparency, can be NULL */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* type of function to be executed at the driver level */
|
|
||||||
#define FB_FUNC_ENTER_GRAPHICS 0
|
|
||||||
#define FB_FUNC_EXIT_GRAPHICS 1
|
|
||||||
#define FB_FUNC_IS_DIRTY 2
|
|
||||||
#define FB_FUNC_GET_MODE 3
|
|
||||||
|
|
||||||
struct fb_exec_function
|
|
||||||
{
|
|
||||||
int func_no;
|
|
||||||
void *param;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Micro Framebuffer API Wrapper */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function returns the information regarding the display.
|
|
||||||
* It is called just after the driver be opened to get all needed
|
|
||||||
* information about the driver. No change in the mode of operation
|
|
||||||
* of the driver is done with this call.
|
|
||||||
*/
|
|
||||||
extern int ufb_get_screen_info( int fd, struct fb_screeninfo *info );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the mode of the graphics subsystem
|
|
||||||
*/
|
|
||||||
extern int ufb_get_mode( int fd, int *mode );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the current collor pallete
|
|
||||||
*/
|
|
||||||
extern int ufb_get_palette( int fd, struct fb_cmap *color );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the current collor pallete
|
|
||||||
*/
|
|
||||||
extern int ufb_set_palette( int fd, struct fb_cmap *color );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Does all necessary initialization to put the device in
|
|
||||||
* graphics mode
|
|
||||||
*/
|
|
||||||
extern int ufb_enter_graphics( int fd, int mode );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch the device back to the default mode of operation.
|
|
||||||
* In most cases it put the device back to plain text mode.
|
|
||||||
*/
|
|
||||||
extern int ufb_exit_graphics( int fd );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tell the driver that the "virtual buffer" is dirty, and an update
|
|
||||||
* of it to the real device, maybe a serial/parallel LCD or whatever
|
|
||||||
* is required
|
|
||||||
*/
|
|
||||||
extern int ufb_buffer_is_dirty( int fd );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function maps the physical ( kernel mode ) address of the framebuffer device
|
|
||||||
* and maps it to the user space address.
|
|
||||||
*/
|
|
||||||
int ufb_mmap_to_user_space( int fd, void **fb_addr, void *physical_addr, unsigned long size );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function unmaps memory of the FB from the user's space
|
|
||||||
*/
|
|
||||||
int ufb_unmmap_from_user_space( int fd, void *addr );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _MW_FB_H */
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
/*
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// $Header$
|
|
||||||
//
|
|
||||||
// Copyright (c) 2000 - Rosimildo da Silva
|
|
||||||
//
|
|
||||||
// MODULE DESCRIPTION:
|
|
||||||
// This module implements the input devices interface used by MicroWindows
|
|
||||||
// in an embedded system environment.
|
|
||||||
// It uses the RTEMS message queue as the repository for the messages posted
|
|
||||||
// by the devices registered.
|
|
||||||
//
|
|
||||||
// MODIFICATION/HISTORY:
|
|
||||||
//
|
|
||||||
// $Log$
|
|
||||||
// Revision 1.3 2000/11/30 14:36:46 joel
|
|
||||||
// 2000-11-30 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
//
|
|
||||||
// * mw-fb/mw_uid.c: Removed unnecessary dependency on <bsp.h>.
|
|
||||||
//
|
|
||||||
// Revision 1.2 2000/08/30 17:12:55 joel
|
|
||||||
// 2000-08-30 Joel Sherrill <joel@OARcorp.com>
|
|
||||||
//
|
|
||||||
// * Many files: Moved posix/include/rtems/posix/seterr.h to
|
|
||||||
// score/include/rtems/seterr.h so it would be available within
|
|
||||||
// all APIs.
|
|
||||||
//
|
|
||||||
// Revision 1.1 2000/08/30 08:21:24 joel
|
|
||||||
// 2000-08-26 Rosimildo da Silva <rdasilva@connecttel.com>
|
|
||||||
//
|
|
||||||
// * Added generic Micro FrameBuffer interface for MicroWindows.
|
|
||||||
// This interface allows MicroWindows to under RTEMS. A sample
|
|
||||||
// driver has been developed for the pc386 BSP. See
|
|
||||||
// pc386/fb_vga.c as a sample.
|
|
||||||
// * Added Uniform Input Device interface for MicroWindows.
|
|
||||||
// See PC386 bsp for sample drivers for mouse and keyboard (console).
|
|
||||||
// * mw-bf: New directory.
|
|
||||||
// * Makefile.am, configure.in, wrapup/Makefile.am: Account for mw-fb.
|
|
||||||
// * mw-fb/Makefile.am: New file.
|
|
||||||
// * mw-fb/mw_fb.c: New file.
|
|
||||||
// * mw-fb/mw_fb.h: New file.
|
|
||||||
// * mw-fb/mw_uid.c: New file.
|
|
||||||
// * mw-fb/mw_uid.h: New file.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
#include <rtems/mw_uid.h>
|
|
||||||
#include <rtems/seterr.h>
|
|
||||||
|
|
||||||
static rtems_id queue_id = 0;
|
|
||||||
static int open_count = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
#define MW_DEBUG_ON 1
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* open a message queue with the kernel */
|
|
||||||
int uid_open_queue( const char *q_name, int flags, size_t max_msgs )
|
|
||||||
{
|
|
||||||
static rtems_name queue_name;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For the first device calling this function we would create the queue.
|
|
||||||
* It is assumed that this call is done at initialization, and no concerns
|
|
||||||
* regarding multi-threading is taken in consideration here.
|
|
||||||
*/
|
|
||||||
if( !open_count )
|
|
||||||
{
|
|
||||||
rtems_status_code status;
|
|
||||||
queue_name = rtems_build_name( q_name[0],
|
|
||||||
q_name[1],
|
|
||||||
q_name[2],
|
|
||||||
q_name[3] );
|
|
||||||
status = rtems_message_queue_create( queue_name,
|
|
||||||
max_msgs,
|
|
||||||
sizeof( struct MW_UID_MESSAGE ),
|
|
||||||
RTEMS_FIFO | RTEMS_LOCAL,
|
|
||||||
&queue_id );
|
|
||||||
if( status != RTEMS_SUCCESSFUL )
|
|
||||||
{
|
|
||||||
#ifdef MW_DEBUG_ON
|
|
||||||
printk( "UID_Queue: error creating queue: %d\n", status );
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#ifdef MW_DEBUG_ON
|
|
||||||
printk( "UID_Queue: id=%X\n", queue_id );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
open_count++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* close message queue */
|
|
||||||
int uid_close_queue( void )
|
|
||||||
{
|
|
||||||
if( open_count == 1 )
|
|
||||||
{
|
|
||||||
rtems_message_queue_delete( queue_id );
|
|
||||||
queue_id = 0;
|
|
||||||
}
|
|
||||||
open_count--;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reads for a message from the device */
|
|
||||||
int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout )
|
|
||||||
{
|
|
||||||
rtems_status_code status;
|
|
||||||
rtems_unsigned32 size = 0;
|
|
||||||
unsigned long micro_secs = timeout*1000;
|
|
||||||
int wait = ( timeout != 0 );
|
|
||||||
|
|
||||||
status = rtems_message_queue_receive( queue_id,
|
|
||||||
(void*)m,
|
|
||||||
&size,
|
|
||||||
wait ? RTEMS_WAIT : RTEMS_NO_WAIT,
|
|
||||||
TOD_MICROSECONDS_TO_TICKS(micro_secs ) );
|
|
||||||
|
|
||||||
if( status == RTEMS_SUCCESSFUL )
|
|
||||||
{
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
else if( ( status == RTEMS_UNSATISFIED ) || ( status == RTEMS_TIMEOUT ) )
|
|
||||||
{
|
|
||||||
/* this macro returns -1 */
|
|
||||||
rtems_set_errno_and_return_minus_one( ETIMEDOUT );
|
|
||||||
}
|
|
||||||
/* Here we have one error condition */
|
|
||||||
#ifdef MW_DEBUG_ON
|
|
||||||
printk( "UID_Queue: error reading queue: %d\n", status );
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* add a message to the queue of events. This method cna be used to
|
|
||||||
* simulate hardware events, and it can be very handy during development
|
|
||||||
* a new interface.
|
|
||||||
*/
|
|
||||||
int uid_send_message( struct MW_UID_MESSAGE *m )
|
|
||||||
{
|
|
||||||
rtems_status_code status;
|
|
||||||
status = rtems_message_queue_send( queue_id, ( void * )m,
|
|
||||||
sizeof( struct MW_UID_MESSAGE ) );
|
|
||||||
return status == RTEMS_SUCCESSFUL ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* register the device to insert events to the message
|
|
||||||
* queue named as the value passed in q_name
|
|
||||||
*/
|
|
||||||
int uid_register_device( int fd, const char *q_name )
|
|
||||||
{
|
|
||||||
return ioctl( fd, MW_UID_REGISTER_DEVICE, q_name );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* tell this device to stop adding events to the queue */
|
|
||||||
int uid_unregister_device( int fd )
|
|
||||||
{
|
|
||||||
return ioctl( fd, MW_UID_UNREGISTER_DEVICE, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the keyboard */
|
|
||||||
int uid_set_kbd_mode( int fd, int mode, int *old_mode )
|
|
||||||
{
|
|
||||||
if (ioctl( fd, MV_KDGKBMODE, old_mode) < 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ioctl(fd, MV_KDSKBMODE, mode ) < 0 )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// $Header$
|
|
||||||
//
|
|
||||||
// Copyright (c) 2000 - Rosimildo da Silva
|
|
||||||
//
|
|
||||||
// MODULE DESCRIPTION:
|
|
||||||
// This module defines the interface for input devices used by MicroWindows
|
|
||||||
// in an embedded system environment.
|
|
||||||
//
|
|
||||||
// MODIFICATION/HISTORY:
|
|
||||||
//
|
|
||||||
// $Log$
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
#ifndef _MW_UID_H
|
|
||||||
#define _MW_UID_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 0x41XX -- IOCLT functions for the Micro Input Devices commands */
|
|
||||||
#define MW_UID_REGISTER_DEVICE 0x4100
|
|
||||||
#define MW_UID_UNREGISTER_DEVICE 0x4101
|
|
||||||
|
|
||||||
|
|
||||||
/* devices supported by MicroWindows */
|
|
||||||
enum MW_INPUT_DEVICE_TYPE
|
|
||||||
{
|
|
||||||
MV_UID_INVALID = 0,
|
|
||||||
MV_UID_REL_POS = 1, /* mouse */
|
|
||||||
MV_UID_ABS_POS = 2, /* touch-screen */
|
|
||||||
MV_UID_KBD = 3, /* keyboard */
|
|
||||||
MV_UID_TIMER = 4 /* timer -- not used */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* matching MicroWindows */
|
|
||||||
#define MV_BUTTON_RIGHT 0x01
|
|
||||||
#define MV_BUTTON_CENTER 0x02
|
|
||||||
#define MV_BUTTON_LEFT 0x04
|
|
||||||
|
|
||||||
/* modifiers of the keyboard type devices */
|
|
||||||
#define MV_KEY_MODIFIER_SHIFT_DOWN 0x10
|
|
||||||
#define MV_KEY_MODIFIER_ALT_DOWN 0x20
|
|
||||||
|
|
||||||
/* indication of the LEDS */
|
|
||||||
#define MV_KEY_MODIFIER_CAPS_ON 0x04
|
|
||||||
#define MV_KEY_MODIFIER_NUN_LOCK_ON 0x02
|
|
||||||
#define MV_KEY_SCROLL_LOCK_ON 0x01
|
|
||||||
|
|
||||||
/* keyboard modes -- default ASCII */
|
|
||||||
#define MV_KEY_MODE_ASCII 0x01
|
|
||||||
/*
|
|
||||||
* This mode one event is sent when a key is pressed,
|
|
||||||
* and another one is send when a key is released.
|
|
||||||
*/
|
|
||||||
#define MV_KEY_MODE_SCANCODE 0x00
|
|
||||||
|
|
||||||
|
|
||||||
/* these defines match with the linux keyboard range
|
|
||||||
for ioctls functions for the keyboard interface.
|
|
||||||
0x4BXX --- keyboard related functions
|
|
||||||
*/
|
|
||||||
#define MV_KDGKBMODE 0x4B44 /* gets current keyboard mode */
|
|
||||||
#define MV_KDSKBMODE 0x4B45 /* sets current keyboard mode */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Message generated by input devices controlled by MicroWindows.
|
|
||||||
*/
|
|
||||||
struct MW_UID_MESSAGE
|
|
||||||
{
|
|
||||||
enum MW_INPUT_DEVICE_TYPE type; /* device type */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
/* fired when keyboard events are raised */
|
|
||||||
struct kbd_t {
|
|
||||||
unsigned short code; /* keycode or scancode */
|
|
||||||
unsigned char modifiers; /* key modifiers */
|
|
||||||
unsigned char mode; /* current Kbd mode */
|
|
||||||
} kbd;
|
|
||||||
|
|
||||||
/* fired when position events are raised, mouse, touch screen, etc */
|
|
||||||
struct pos_t {
|
|
||||||
unsigned short btns; /* indicates which buttons are pressed */
|
|
||||||
short x; /* x location */
|
|
||||||
short y; /* y location */
|
|
||||||
short z; /* z location, 0 for 2D */
|
|
||||||
} pos;
|
|
||||||
|
|
||||||
/* fired by a timer device periodically */
|
|
||||||
struct timer_t {
|
|
||||||
unsigned long frt; /* free running timer */
|
|
||||||
unsigned long seq; /* sequence number */
|
|
||||||
} tmr;
|
|
||||||
|
|
||||||
} m;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* API for creating/closing/accessing the message queue used by the micro
|
|
||||||
* input device interface. All functions in this interface returns a
|
|
||||||
* zero ( 0 ) on success. One exception for that is the "read" routine
|
|
||||||
* that returns the number of bytes read. Negaive numbers indicate errors
|
|
||||||
*
|
|
||||||
* The implementation of the message queue for RTEMS uses a POSIX message
|
|
||||||
* queue interface. It should be very portable among systems with a POSIX
|
|
||||||
* support.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* creates the message queue that holds events from the input devices */
|
|
||||||
extern int uid_open_queue( const char *q_name, int flags, size_t max_msgs );
|
|
||||||
|
|
||||||
/* closes message queue */
|
|
||||||
extern int uid_close_queue( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* reads a message from the queue. It waits up to the specified
|
|
||||||
* timeout in mili-seconds.
|
|
||||||
*/
|
|
||||||
extern int uid_read_message( struct MW_UID_MESSAGE *m, unsigned long timeout );
|
|
||||||
|
|
||||||
/* write a message to the queue */
|
|
||||||
extern int uid_write_message( struct MW_UID_MESSAGE *m );
|
|
||||||
|
|
||||||
|
|
||||||
/* register device to insert data to the queue */
|
|
||||||
extern int uid_register_device( int fd, const char *q_name );
|
|
||||||
|
|
||||||
/* unregister device to stop adding messages to the queue */
|
|
||||||
extern int uid_unregister_device( int fd );
|
|
||||||
|
|
||||||
/* set the keyboard */
|
|
||||||
extern int uid_set_kbd_mode( int fd, int mode, int *old_mode );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _MW_UID_H */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = librtmonuse-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = rtmonuse.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = rtmonuse.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = rtmonuse.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <rtems/rtmonuse.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_id id;
|
|
||||||
unsigned32 count;
|
|
||||||
unsigned32 missed_count;
|
|
||||||
unsigned32 min_cpu_time;
|
|
||||||
unsigned32 max_cpu_time;
|
|
||||||
unsigned32 total_cpu_time;
|
|
||||||
unsigned32 min_wall_time;
|
|
||||||
unsigned32 max_wall_time;
|
|
||||||
unsigned32 total_wall_time;
|
|
||||||
} Period_usage_t;
|
|
||||||
|
|
||||||
Period_usage_t *Period_usage_Information;
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Period_usage_Initialize
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Period_usage_Initialize( void )
|
|
||||||
{
|
|
||||||
int maximum;
|
|
||||||
|
|
||||||
maximum = _Configuration_Table->RTEMS_api_configuration->maximum_periods;
|
|
||||||
|
|
||||||
Period_usage_Information = malloc( sizeof(Period_usage_t) * (maximum+1) );
|
|
||||||
|
|
||||||
Period_usage_Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Period_usage_Reset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Period_usage_Reset( void )
|
|
||||||
{
|
|
||||||
unsigned32 i;
|
|
||||||
Period_usage_t *the_usage;
|
|
||||||
|
|
||||||
for ( i=0 ;
|
|
||||||
i<_Configuration_Table->RTEMS_api_configuration->maximum_periods ;
|
|
||||||
i++ ) {
|
|
||||||
the_usage = &Period_usage_Information[ i ];
|
|
||||||
|
|
||||||
the_usage->count = 0;
|
|
||||||
the_usage->missed_count = 0;
|
|
||||||
the_usage->min_cpu_time = 0xFFFFFFFF;
|
|
||||||
the_usage->max_cpu_time = 0;
|
|
||||||
the_usage->total_cpu_time = 0;
|
|
||||||
the_usage->min_wall_time = 0xFFFFFFFF;
|
|
||||||
the_usage->max_wall_time = 0;
|
|
||||||
the_usage->total_wall_time = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Period_usage_Update
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Period_usage_Update(
|
|
||||||
rtems_id id
|
|
||||||
)
|
|
||||||
{
|
|
||||||
rtems_rate_monotonic_period_status rm_status;
|
|
||||||
rtems_status_code status;
|
|
||||||
Period_usage_t *the_usage;
|
|
||||||
|
|
||||||
assert( Period_usage_Information );
|
|
||||||
|
|
||||||
status = rtems_rate_monotonic_get_status( id, &rm_status );
|
|
||||||
assert( status == RTEMS_SUCCESSFUL );
|
|
||||||
|
|
||||||
the_usage = &Period_usage_Information[ rtems_get_index( id ) ];
|
|
||||||
|
|
||||||
the_usage->id = id;
|
|
||||||
the_usage->count++;
|
|
||||||
if ( rm_status.state == RATE_MONOTONIC_EXPIRED )
|
|
||||||
the_usage->missed_count++;
|
|
||||||
the_usage->total_cpu_time += rm_status.ticks_executed_since_last_period;
|
|
||||||
the_usage->total_wall_time += rm_status.ticks_since_last_period;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update CPU time
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( rm_status.ticks_executed_since_last_period < the_usage->min_cpu_time )
|
|
||||||
the_usage->min_cpu_time = rm_status.ticks_executed_since_last_period;
|
|
||||||
|
|
||||||
if ( rm_status.ticks_executed_since_last_period > the_usage->max_cpu_time )
|
|
||||||
the_usage->max_cpu_time = rm_status.ticks_executed_since_last_period;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Update Wall time
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( rm_status.ticks_since_last_period < the_usage->min_wall_time )
|
|
||||||
the_usage->min_wall_time = rm_status.ticks_since_last_period;
|
|
||||||
|
|
||||||
if ( rm_status.ticks_since_last_period > the_usage->max_wall_time )
|
|
||||||
the_usage->max_wall_time = rm_status.ticks_since_last_period;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Period_usage_Dump
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Period_usage_Dump( void )
|
|
||||||
{
|
|
||||||
unsigned32 i;
|
|
||||||
Period_usage_t *the_usage;
|
|
||||||
Rate_monotonic_Control *the_period;
|
|
||||||
unsigned32 u32_name;
|
|
||||||
char name[5];
|
|
||||||
|
|
||||||
if ( !Period_usage_Information ) {
|
|
||||||
printf( "Period statistics library is not initialized\n" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf( "Period information by period\n" );
|
|
||||||
printf( " ID OWNER PERIODS MISSED CPU TIME WALL TIME\n" );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RTEMS does not use an index of zero for object ids.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for ( i=1 ;
|
|
||||||
i<_Configuration_Table->RTEMS_api_configuration->maximum_periods ;
|
|
||||||
i++ ) {
|
|
||||||
the_usage = &Period_usage_Information[ i ];
|
|
||||||
if ( the_usage->count == 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
the_period =
|
|
||||||
(Rate_monotonic_Control *)_Rate_monotonic_Information.local_table[ i ];
|
|
||||||
|
|
||||||
if ( the_period->owner )
|
|
||||||
u32_name = *(unsigned32 *)the_period->owner->Object.name;
|
|
||||||
else
|
|
||||||
u32_name = rtems_build_name(' ', ' ', ' ', ' ');
|
|
||||||
|
|
||||||
name[ 0 ] = (u32_name >> 24) & 0xff;
|
|
||||||
name[ 1 ] = (u32_name >> 16) & 0xff;
|
|
||||||
name[ 2 ] = (u32_name >> 8) & 0xff;
|
|
||||||
name[ 3 ] = (u32_name >> 0) & 0xff;
|
|
||||||
name[ 4 ] = '\0';
|
|
||||||
|
|
||||||
printf(
|
|
||||||
"0x%08x %4s %6d %3d %d/%d/%5.2f %d/%d/%3.2f\n",
|
|
||||||
the_usage->id,
|
|
||||||
name,
|
|
||||||
the_usage->count,
|
|
||||||
the_usage->missed_count,
|
|
||||||
the_usage->min_cpu_time,
|
|
||||||
the_usage->max_cpu_time,
|
|
||||||
(double) the_usage->total_cpu_time / (double) the_usage->count,
|
|
||||||
the_usage->min_wall_time,
|
|
||||||
the_usage->max_wall_time,
|
|
||||||
(double) the_usage->total_wall_time / (double) the_usage->count
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __RATE_MONOTONIC_USAGE_h
|
|
||||||
#define __RATE_MONOTONIC_USAGE_h
|
|
||||||
|
|
||||||
void Period_usage_Initialize( void );
|
|
||||||
|
|
||||||
void Period_usage_Reset( void );
|
|
||||||
|
|
||||||
void Period_usage_Update(
|
|
||||||
rtems_id id
|
|
||||||
);
|
|
||||||
|
|
||||||
void Period_usage_Dump( void );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
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)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
noinst_HEADERS =
|
|
||||||
include_HEADERS = serdbgcnf.h serdbg.h termios_printk_cnf.h \
|
|
||||||
termios_printk.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
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
|
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
#
|
|
||||||
# $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>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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 */
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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 */
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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 <unistd.h> /* close */
|
|
||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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);
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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 */
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*===============================================================*\
|
|
||||||
| 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 */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libshell-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = cmds.c shell.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
if RTEMS_LIBSHELL
|
|
||||||
include_rtems_HEADERS = shell.h
|
|
||||||
endif
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
if RTEMS_LIBSHELL
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README shell.c cmds.c shell.h
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
This directory contains a shell user extension
|
|
||||||
primary features:
|
|
||||||
|
|
||||||
+ create a user shell terminal task.
|
|
||||||
|
|
||||||
This code has not been extensively tested. It is provided as a tool
|
|
||||||
for RTEMS users to open more shell terminal.
|
|
||||||
Suggestions and comments are appreciated.
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
1. printf() & getchar() works but you can't use
|
|
||||||
0,1,2 like fildes. You need to use fileno(stdin),fileno(stdout),...
|
|
||||||
|
|
||||||
2. You only need a termios dev to start a new session, add your new commands
|
|
||||||
and enjoy it.
|
|
||||||
|
|
||||||
3. Telnetd daemon uses this (browse libnetworking/rtems_telnetd)
|
|
||||||
Enjoy it.
|
|
||||||
|
|
||||||
FUTURE:
|
|
||||||
|
|
||||||
1. Adding new commands in cmds.c to give file manegement to shell.
|
|
||||||
@@ -1,524 +0,0 @@
|
|||||||
/*
|
|
||||||
* Author: Fernando RUIZ CASAS
|
|
||||||
*
|
|
||||||
* Work: fernando.ruiz@ctv.es
|
|
||||||
* Home: correo@fernando-ruiz.com
|
|
||||||
*
|
|
||||||
* This file is inspired in rtems_monitor & Chris John MyRightBoot
|
|
||||||
*
|
|
||||||
* But I want to make it more user friendly
|
|
||||||
* A 'monitor' command is added to adapt the call rtems monitor commands
|
|
||||||
* at my call procedure
|
|
||||||
*
|
|
||||||
* TODO: A lot of improvements of course.
|
|
||||||
* cp, mv, ...
|
|
||||||
* hexdump,
|
|
||||||
*
|
|
||||||
* More? Say me it, please...
|
|
||||||
*
|
|
||||||
* The BSP Specific are not welcome here.
|
|
||||||
*
|
|
||||||
* C&S welcome...
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <grp.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/monitor.h>
|
|
||||||
#include <rtems/score/tod.h>
|
|
||||||
|
|
||||||
#include <imfs.h>
|
|
||||||
#include <rtems/shell.h>
|
|
||||||
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
- str to int "0xaffe" "0b010010" "0123" "192939"
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
int str2int(char * s) {
|
|
||||||
int sign=1;
|
|
||||||
int base=10;
|
|
||||||
int value=0;
|
|
||||||
int digit;
|
|
||||||
if (!s) return 0;
|
|
||||||
if (*s) {
|
|
||||||
if (*s=='-') {
|
|
||||||
sign=-1;
|
|
||||||
s++;
|
|
||||||
if (!*s) return 0;
|
|
||||||
};
|
|
||||||
if (*s=='0') {
|
|
||||||
s++;
|
|
||||||
switch(*s) {
|
|
||||||
case 'x':
|
|
||||||
case 'X':s++;
|
|
||||||
base=16;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':s++;
|
|
||||||
base=2;
|
|
||||||
break;
|
|
||||||
default :base=8;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
while (*s) {
|
|
||||||
switch(*s) {
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':digit=*s-'0';
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
case 'D':
|
|
||||||
case 'E':
|
|
||||||
case 'F':digit=*s-'A'+10;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
case 'b':
|
|
||||||
case 'c':
|
|
||||||
case 'd':
|
|
||||||
case 'e':
|
|
||||||
case 'f':digit=*s-'a'+10;
|
|
||||||
break;
|
|
||||||
default:return value*sign;
|
|
||||||
};
|
|
||||||
if (digit>base) return value*sign;
|
|
||||||
value=value*base+digit;
|
|
||||||
s++;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
return value*sign;
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------*
|
|
||||||
* RAM MEMORY COMMANDS
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define mdump_adr (current_shell_env->mdump_adr) /* static value */
|
|
||||||
|
|
||||||
int main_mdump(int argc,char * argv[]) {
|
|
||||||
unsigned char n,m,max=0;
|
|
||||||
int adr=mdump_adr;
|
|
||||||
unsigned char * pb;
|
|
||||||
if (argc>1) adr=str2int(argv[1]);
|
|
||||||
if (argc>2) max=str2int(argv[2]);
|
|
||||||
max/=16;
|
|
||||||
if (!max) max=20;
|
|
||||||
for (m=0;m<max;m++) {
|
|
||||||
printf("0x%08X ",adr);
|
|
||||||
pb=(unsigned char*) adr;
|
|
||||||
for (n=0;n<16;n++)
|
|
||||||
printf("%02X%c",pb[n],n==7?'-':' ');
|
|
||||||
for (n=0;n<16;n++) {
|
|
||||||
printf("%c",isprint(pb[n])?pb[n]:'.');
|
|
||||||
};
|
|
||||||
printf("\n");
|
|
||||||
adr+=16;
|
|
||||||
};
|
|
||||||
mdump_adr=adr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
int main_mwdump(int argc,char * argv[]) {
|
|
||||||
unsigned char n,m,max=0;
|
|
||||||
int adr=mdump_adr;
|
|
||||||
unsigned short * pw;
|
|
||||||
if (argc>1) adr=str2int(argv[1]);
|
|
||||||
if (argc>2) max=str2int(argv[2]);
|
|
||||||
max/=16;
|
|
||||||
if (!max) max=20;
|
|
||||||
for (m=0;m<max;m++) {
|
|
||||||
printf("0x%08X ",adr);
|
|
||||||
pw=(unsigned short*) adr;
|
|
||||||
for (n=0;n<8;n++)
|
|
||||||
printf("%02X %02X%c",pw[n]/0x100,pw[n]%0x100,n==3?'-':' ');
|
|
||||||
for (n=0;n<8;n++) {
|
|
||||||
printf("%c",isprint(pw[n]/0x100)?pw[n]/0x100:'.');
|
|
||||||
printf("%c",isprint(pw[n]%0x100)?pw[n]%0x100:'.');
|
|
||||||
};
|
|
||||||
printf("\n");
|
|
||||||
adr+=16;
|
|
||||||
};
|
|
||||||
mdump_adr=adr;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
int main_medit(int argc,char * argv[]) {
|
|
||||||
unsigned char * pb;
|
|
||||||
int n,i;
|
|
||||||
if (argc<3) {
|
|
||||||
printf("too few arguments\n");
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
pb=(unsigned char*)str2int(argv[1]);
|
|
||||||
i=2;
|
|
||||||
n=0;
|
|
||||||
while (i<=argc) {
|
|
||||||
pb[n++]=str2int(argv[i++])%0x100;
|
|
||||||
}
|
|
||||||
mdump_adr=(int)pb;
|
|
||||||
return main_mdump(0,NULL);
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
int main_mfill(int argc,char * argv[]) {
|
|
||||||
int adr;
|
|
||||||
int size;
|
|
||||||
unsigned char value;
|
|
||||||
if (argc<4) {
|
|
||||||
printf("too few arguments\n");
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
adr =str2int(argv[1]);
|
|
||||||
size =str2int(argv[2]);
|
|
||||||
value=str2int(argv[3])%0x100;
|
|
||||||
memset((unsigned char*)adr,size,value);
|
|
||||||
mdump_adr=adr;
|
|
||||||
return main_mdump(0,NULL);
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
int main_mmove(int argc,char * argv[]) {
|
|
||||||
int src;
|
|
||||||
int dst;
|
|
||||||
int size;
|
|
||||||
if (argc<4) {
|
|
||||||
printf("too few arguments\n");
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
dst =str2int(argv[1]);
|
|
||||||
src =str2int(argv[2]);
|
|
||||||
size =str2int(argv[3]);
|
|
||||||
memcpy((unsigned char*)dst,(unsigned char*)src,size);
|
|
||||||
mdump_adr=dst;
|
|
||||||
return main_mdump(0,NULL);
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------*/
|
|
||||||
#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
|
|
||||||
int main_malloc_dump(int argc,char * argv[]) {
|
|
||||||
void malloc_dump(void);
|
|
||||||
malloc_dump();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Reset. Assumes that the watchdog is present.
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int main_reset (int argc, char **argv)
|
|
||||||
{
|
|
||||||
rtems_interrupt_level level;
|
|
||||||
printf ("Waiting for watchdog ... ");
|
|
||||||
tcdrain(fileno(stdout));
|
|
||||||
|
|
||||||
rtems_interrupt_disable (level);
|
|
||||||
for (;;)
|
|
||||||
;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* Alias. make an alias
|
|
||||||
*----------------------------------------------------------------------------*/
|
|
||||||
int main_alias (int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc<3) {
|
|
||||||
printf("too few arguments\n");
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
if (!shell_alias_cmd(argv[1],argv[2])) {
|
|
||||||
printf("unable to make an alias(%s,%s)\n",argv[1],argv[2]);
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*
|
|
||||||
* Directory commands
|
|
||||||
*-----------------------------------------------------------*/
|
|
||||||
int main_ls(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char * fname;
|
|
||||||
DIR *dirp;
|
|
||||||
struct dirent *dp;
|
|
||||||
struct stat stat_buf;
|
|
||||||
struct passwd * pwd;
|
|
||||||
struct group * grp;
|
|
||||||
char * user;
|
|
||||||
char * group;
|
|
||||||
char sbuf[256];
|
|
||||||
char nbuf[1024];
|
|
||||||
int n,size;
|
|
||||||
|
|
||||||
fname=".";
|
|
||||||
if (argc>1) fname=argv[1];
|
|
||||||
|
|
||||||
if ((dirp = opendir(fname)) == NULL)
|
|
||||||
{
|
|
||||||
printf("%s: No such file or directory.\n", fname);
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
n=0;
|
|
||||||
size=0;
|
|
||||||
while ((dp = readdir(dirp)) != NULL)
|
|
||||||
{
|
|
||||||
strcpy(nbuf,fname);
|
|
||||||
if (nbuf[strlen(nbuf)-1]!='/') strcat(nbuf,"/");
|
|
||||||
strcat(nbuf,dp->d_name); /* always the fullpathname. Avoid ftpd problem.*/
|
|
||||||
if (stat(nbuf, &stat_buf) == 0)
|
|
||||||
{ /* AWFUL buts works...*/
|
|
||||||
strftime(sbuf,sizeof(sbuf)-1,"%b %d %H:%M",gmtime(&stat_buf.st_atime));
|
|
||||||
pwd=getpwuid(stat_buf.st_uid);
|
|
||||||
user=pwd?pwd->pw_name:"nouser";
|
|
||||||
grp=getgrgid(stat_buf.st_gid);
|
|
||||||
group=grp?grp->gr_name:"nogrp";
|
|
||||||
printf("%c%c%c%c%c%c%c%c%c%c %3d %6.6s %6.6s %11d %s %s%c\n",
|
|
||||||
(S_ISLNK(stat_buf.st_mode)?('l'):
|
|
||||||
(S_ISDIR(stat_buf.st_mode)?('d'):('-'))),
|
|
||||||
(stat_buf.st_mode & S_IRUSR)?('r'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IWUSR)?('w'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IXUSR)?('x'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IRGRP)?('r'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IWGRP)?('w'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IXGRP)?('x'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IROTH)?('r'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IWOTH)?('w'):('-'),
|
|
||||||
(stat_buf.st_mode & S_IXOTH)?('x'):('-'),
|
|
||||||
(int)stat_buf.st_nlink,
|
|
||||||
user,group,
|
|
||||||
(int)stat_buf.st_size,
|
|
||||||
sbuf,
|
|
||||||
dp->d_name,
|
|
||||||
S_ISDIR(stat_buf.st_mode)?'/':' ');
|
|
||||||
n++;
|
|
||||||
size+=stat_buf.st_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("%d files %d bytes occupied\n",n,size);
|
|
||||||
closedir(dirp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_pwd (int argc, char *argv[]) {
|
|
||||||
char dir[1024];
|
|
||||||
getcwd(dir,1024);
|
|
||||||
printf("%s\n",dir);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_chdir (int argc, char *argv[]) {
|
|
||||||
char *dir;
|
|
||||||
dir="/";
|
|
||||||
if (argc>1) dir=argv[1];
|
|
||||||
if (chdir(dir)) {
|
|
||||||
printf("chdir to '%s' failed:%s\n",dir,strerror(errno));
|
|
||||||
return errno;
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_mkdir (int argc, char *argv[]) {
|
|
||||||
char *dir;
|
|
||||||
int n;
|
|
||||||
n=1;
|
|
||||||
while (n<argc) {
|
|
||||||
dir=argv[n++];
|
|
||||||
if (mkdir(dir,S_IRWXU|S_IRWXG|S_IRWXO)) {
|
|
||||||
printf("mkdir '%s' failed:%s\n",dir,strerror(errno));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_rmdir (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
char *dir;
|
|
||||||
int n;
|
|
||||||
n=1;
|
|
||||||
while (n<argc) {
|
|
||||||
dir=argv[n++];
|
|
||||||
if (rmdir(dir)) printf("rmdir '%s' failed:%s\n",dir,strerror(errno));
|
|
||||||
};
|
|
||||||
return errno;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_chroot(int argc,char * argv[]) {
|
|
||||||
char * new_root="/";
|
|
||||||
if (argc==2) new_root=argv[1];
|
|
||||||
if (chroot(new_root)<0) {
|
|
||||||
printf("error %s:chroot(%s);\n",strerror(errno),new_root);
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_cat (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
n=1;
|
|
||||||
while (n<argc) cat_file(stdout,argv[n++]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_rm (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
n=1;
|
|
||||||
while (n<argc) {
|
|
||||||
if (unlink(argv[n])) {
|
|
||||||
printf("error %s:rm %s\n",strerror(errno),argv[n]);
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
n++;
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
/* date - print time and date */
|
|
||||||
|
|
||||||
int main_date(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
time_t t;
|
|
||||||
time(&t);
|
|
||||||
printf("%s", ctime(&t));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_logoff(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
printf("logoff from the system...");
|
|
||||||
current_shell_env->exit_shell=TRUE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_tty (int argc,char *argv[])
|
|
||||||
{
|
|
||||||
printf("%s\n",ttyname(fileno(stdin)));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_whoami(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
struct passwd * pwd;
|
|
||||||
pwd=getpwuid(getuid());
|
|
||||||
printf("%s\n",pwd?pwd->pw_name:"nobody");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_id (int argc,char *argv[])
|
|
||||||
{
|
|
||||||
struct passwd * pwd;
|
|
||||||
struct group * grp;
|
|
||||||
pwd=getpwuid(getuid());
|
|
||||||
grp=getgrgid(getgid());
|
|
||||||
printf("uid=%d(%s),gid=%d(%s),",
|
|
||||||
getuid(),pwd?pwd->pw_name:"",
|
|
||||||
getgid(),grp?grp->gr_name:"");
|
|
||||||
pwd=getpwuid(geteuid());
|
|
||||||
grp=getgrgid(getegid());
|
|
||||||
printf("euid=%d(%s),egid=%d(%s)\n",
|
|
||||||
geteuid(),pwd?pwd->pw_name:"",
|
|
||||||
getegid(),grp?grp->gr_name:"");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_umask(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
mode_t msk=umask(0);
|
|
||||||
if (argc == 2) msk=str2int(argv[1]);
|
|
||||||
umask(msk);
|
|
||||||
msk=umask(0);
|
|
||||||
printf("0%o\n",msk);
|
|
||||||
umask(msk);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
int main_chmod(int argc,char *argv[])
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
mode_t mode;
|
|
||||||
if (argc > 2){
|
|
||||||
mode=str2int(argv[1])&0777;
|
|
||||||
n=2;
|
|
||||||
while (n<argc) chmod(argv[n++],mode);
|
|
||||||
};
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*
|
|
||||||
* with this you can call at all the rtems monitor commands.
|
|
||||||
* Not all work fine but you can show the rtems status and more.
|
|
||||||
*-----------------------------------------------------------*/
|
|
||||||
int main_monitor(int argc,char * argv[]) {
|
|
||||||
rtems_monitor_command_entry_t *command;
|
|
||||||
extern rtems_monitor_command_entry_t rtems_monitor_commands[];
|
|
||||||
rtems_task_ident(RTEMS_SELF,0,&rtems_monitor_task_id);
|
|
||||||
rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
|
|
||||||
rtems_monitor_default_node = rtems_monitor_node;
|
|
||||||
if ((command=rtems_monitor_command_lookup(rtems_monitor_commands,argc,argv)))
|
|
||||||
command->command_function(argc, argv, command->command_arg, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
void register_cmds(void) {
|
|
||||||
rtems_monitor_command_entry_t *command;
|
|
||||||
extern rtems_monitor_command_entry_t rtems_monitor_commands[];
|
|
||||||
/* monitor topic */
|
|
||||||
command=rtems_monitor_commands;
|
|
||||||
while (command) {
|
|
||||||
if (strcmp("exit",command->command)) /*Exclude EXIT (alias quit)*/
|
|
||||||
shell_add_cmd(command->command,"monitor",
|
|
||||||
command->usage ,main_monitor);
|
|
||||||
command=command->next;
|
|
||||||
};
|
|
||||||
/* dir[ectories] topic */
|
|
||||||
shell_add_cmd ("ls" ,"dir","ls [dir] # list files in the directory" ,main_ls );
|
|
||||||
shell_add_cmd ("chdir" ,"dir","chdir [dir] # change the current directory",main_chdir);
|
|
||||||
shell_add_cmd ("rmdir" ,"dir","rmdir dir # remove directory" ,main_rmdir);
|
|
||||||
shell_add_cmd ("mkdir" ,"dir","mkdir dir # make a directory" ,main_mkdir);
|
|
||||||
shell_add_cmd ("pwd" ,"dir","pwd # print work directory" ,main_pwd );
|
|
||||||
shell_add_cmd ("chroot","dir","chroot [dir] # change the root directory" ,main_chroot);
|
|
||||||
shell_add_cmd ("cat" ,"dir","cat n1 [n2 [n3...]]# show the ascii contents",main_cat );
|
|
||||||
shell_add_cmd ("rm" ,"dir","rm n1 [n2 [n3...]]# remove files" ,main_rm );
|
|
||||||
shell_add_cmd ("chmod" ,"dir","chmod 0777 n1 n2... #change filemode" ,main_chmod);
|
|
||||||
|
|
||||||
shell_alias_cmd("ls" ,"dir");
|
|
||||||
shell_alias_cmd("chdir" ,"cd");
|
|
||||||
|
|
||||||
/* misc. topic */
|
|
||||||
shell_add_cmd ("logoff","misc","logoff from the system" ,main_logoff);
|
|
||||||
shell_alias_cmd("logoff","exit");
|
|
||||||
shell_add_cmd ("date" ,"misc","date" ,main_date);
|
|
||||||
shell_add_cmd ("reset","misc","reset the BSP" ,main_reset);
|
|
||||||
shell_add_cmd ("alias","misc","alias old new" ,main_alias);
|
|
||||||
shell_add_cmd ("tty" ,"misc","show ttyname" ,main_tty );
|
|
||||||
shell_add_cmd ("whoami","misc","show current user" ,main_whoami);
|
|
||||||
shell_add_cmd ("id" ,"misc","show uid,gid,euid,egid" ,main_id );
|
|
||||||
shell_add_cmd ("umask" ,"misc","umask [new_umask]" ,main_umask );
|
|
||||||
|
|
||||||
|
|
||||||
/* memory topic */
|
|
||||||
shell_add_cmd ("mdump","mem" ,"mdump [adr [size]]" ,main_mdump);
|
|
||||||
shell_add_cmd ("wdump","mem" ,"wdump [adr [size]]" ,main_mwdump);
|
|
||||||
shell_add_cmd ("medit","mem" ,"medit adr value [value ...]" ,main_medit);
|
|
||||||
shell_add_cmd ("mfill","mem" ,"mfill adr size value" ,main_mfill);
|
|
||||||
shell_add_cmd ("mmove","mem" ,"mmove dst src size" ,main_mmove);
|
|
||||||
#ifdef MALLOC_STATS /* /rtems/s/src/lib/libc/malloc.c */
|
|
||||||
shell_add_cmd ("malloc","mem","mem show memory malloc'ed" ,main_mem);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
@@ -1,682 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Instantatiate a new terminal shell.
|
|
||||||
*
|
|
||||||
* Author:
|
|
||||||
*
|
|
||||||
* WORK: fernando.ruiz@ctv.es
|
|
||||||
* HOME: correo@fernando-ruiz.com
|
|
||||||
*
|
|
||||||
* Thanks at:
|
|
||||||
* Chris John
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <rtems/error.h>
|
|
||||||
#include <rtems/libio.h>
|
|
||||||
#include <rtems/libio_.h>
|
|
||||||
#include <rtems/system.h>
|
|
||||||
#include <rtems/shell.h>
|
|
||||||
|
|
||||||
#include <termios.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* This is a stupidity but is cute.
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
rtems_unsigned32 new_rtems_name(char * rtems_name) {
|
|
||||||
static char b[5];
|
|
||||||
sprintf(b,"%-4.4s",rtems_name);
|
|
||||||
return rtems_build_name(b[0],b[1],b[2],b[3]);
|
|
||||||
}
|
|
||||||
/* **************************************************************
|
|
||||||
* common linked list of shell commands.
|
|
||||||
* Because the help report is very long
|
|
||||||
* I have a topic for each command.
|
|
||||||
* Help list the topics
|
|
||||||
* help [topic] list the commands for the topic
|
|
||||||
* help [command] help for the command
|
|
||||||
* Can you see help rtems monitor report?
|
|
||||||
* ************************************************************** */
|
|
||||||
|
|
||||||
struct shell_topic_tt;
|
|
||||||
typedef struct shell_topic_tt shell_topic_t;
|
|
||||||
|
|
||||||
struct shell_topic_tt {
|
|
||||||
char * topic;
|
|
||||||
shell_topic_t * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static shell_cmd_t * shell_first_cmd;
|
|
||||||
static shell_topic_t * shell_first_topic;
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* Using Chain I can reuse the rtems code.
|
|
||||||
* I am more comfortable with this, sorry.
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
shell_topic_t * shell_lookup_topic(char * topic) {
|
|
||||||
shell_topic_t * shell_topic;
|
|
||||||
shell_topic=shell_first_topic;
|
|
||||||
while (shell_topic) {
|
|
||||||
if (!strcmp(shell_topic->topic,topic)) return shell_topic;
|
|
||||||
shell_topic=shell_topic->next;
|
|
||||||
};
|
|
||||||
return (shell_topic_t *) NULL;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- */
|
|
||||||
shell_topic_t * shell_add_topic(char * topic) {
|
|
||||||
shell_topic_t * current,*aux;
|
|
||||||
if (!shell_first_topic) {
|
|
||||||
aux=malloc(sizeof(shell_topic_t));
|
|
||||||
aux->topic=topic;
|
|
||||||
aux->next=(shell_topic_t*)NULL;
|
|
||||||
return shell_first_topic=aux;
|
|
||||||
} else {
|
|
||||||
current=shell_first_topic;
|
|
||||||
if (!strcmp(topic,current->topic)) return current;
|
|
||||||
while (current->next) {
|
|
||||||
if (!strcmp(topic,current->next->topic)) return current->next;
|
|
||||||
current=current->next;
|
|
||||||
};
|
|
||||||
aux=malloc(sizeof(shell_topic_t));
|
|
||||||
aux->topic=topic;
|
|
||||||
aux->next=(shell_topic_t*)NULL;
|
|
||||||
current->next=aux;
|
|
||||||
return aux;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- */
|
|
||||||
shell_cmd_t * shell_lookup_cmd(char * cmd) {
|
|
||||||
shell_cmd_t * shell_cmd;
|
|
||||||
shell_cmd=shell_first_cmd;
|
|
||||||
while (shell_cmd) {
|
|
||||||
if (!strcmp(shell_cmd->name,cmd)) return shell_cmd;
|
|
||||||
shell_cmd=shell_cmd->next;
|
|
||||||
};
|
|
||||||
return (shell_cmd_t *) NULL;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- */
|
|
||||||
shell_cmd_t * shell_add_cmd(char * cmd,
|
|
||||||
char * topic,
|
|
||||||
char * usage,
|
|
||||||
shell_command_t command) {
|
|
||||||
int shell_help(int argc,char * argv[]);
|
|
||||||
shell_cmd_t * shell_cmd,*shell_pvt;
|
|
||||||
if (!shell_first_cmd) {
|
|
||||||
shell_first_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t));
|
|
||||||
shell_first_cmd->name ="help";
|
|
||||||
shell_first_cmd->topic ="help";
|
|
||||||
shell_first_cmd->usage ="help [topic] # list of usage of commands";
|
|
||||||
shell_first_cmd->command=shell_help;
|
|
||||||
shell_first_cmd->alias =(shell_cmd_t *) NULL;
|
|
||||||
shell_first_cmd->next =(shell_cmd_t *) NULL;
|
|
||||||
shell_add_topic(shell_first_cmd->topic);
|
|
||||||
register_cmds();
|
|
||||||
};
|
|
||||||
if (!cmd) return (shell_cmd_t *) NULL;
|
|
||||||
if (!command) return (shell_cmd_t *) NULL;
|
|
||||||
shell_cmd=(shell_cmd_t *) malloc(sizeof(shell_cmd_t));
|
|
||||||
shell_cmd->name =cmd;
|
|
||||||
shell_cmd->topic =topic;
|
|
||||||
shell_cmd->usage =usage;
|
|
||||||
shell_cmd->command=command;
|
|
||||||
shell_cmd->alias =(shell_cmd_t *) NULL;
|
|
||||||
shell_cmd->next =(shell_cmd_t *) NULL;
|
|
||||||
shell_add_topic(shell_cmd->topic);
|
|
||||||
shell_pvt=shell_first_cmd;
|
|
||||||
while (shell_pvt->next) shell_pvt=shell_pvt->next;
|
|
||||||
return shell_pvt->next=shell_cmd;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* you can make an alias for every command.
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
shell_cmd_t * shell_alias_cmd(char * cmd, char * alias) {
|
|
||||||
shell_cmd_t * shell_cmd,* shell_aux;
|
|
||||||
shell_aux=(shell_cmd_t *) NULL;
|
|
||||||
if (alias) {
|
|
||||||
if ((shell_aux=shell_lookup_cmd(alias))!=NULL) {
|
|
||||||
return NULL;
|
|
||||||
};
|
|
||||||
if ((shell_cmd=shell_lookup_cmd(cmd))!=NULL) {
|
|
||||||
shell_aux=shell_add_cmd(alias,shell_cmd->topic,
|
|
||||||
shell_cmd->usage,shell_cmd->command);
|
|
||||||
if (shell_aux) shell_aux->alias=shell_cmd;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
return shell_aux;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* Poor but enough..
|
|
||||||
* TODO: Redirection capture. "" evaluate, ... C&S welcome.
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
int shell_make_args(char * cmd,
|
|
||||||
int * pargc,
|
|
||||||
char * argv[]) {
|
|
||||||
int argc=0;
|
|
||||||
while ((cmd=strtok(cmd," \t\r\n"))!=NULL) {
|
|
||||||
argv[argc++]=cmd;
|
|
||||||
cmd=(char*)NULL;
|
|
||||||
};
|
|
||||||
argv[argc]=(char*)NULL;
|
|
||||||
return *pargc=argc;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* show the help for one command.
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
int shell_help_cmd(shell_cmd_t * shell_cmd) {
|
|
||||||
char * pc;
|
|
||||||
int col,line;
|
|
||||||
printf("%-10.10s -",shell_cmd->name);
|
|
||||||
col=12;
|
|
||||||
line=1;
|
|
||||||
if (shell_cmd->alias) {
|
|
||||||
printf("is an <alias> for command '%s'",shell_cmd->alias->name);
|
|
||||||
} else
|
|
||||||
if (shell_cmd->usage) {
|
|
||||||
pc=shell_cmd->usage;
|
|
||||||
while (*pc) {
|
|
||||||
switch(*pc) {
|
|
||||||
case '\r':break;
|
|
||||||
case '\n':putchar('\n');
|
|
||||||
col=0;
|
|
||||||
break;
|
|
||||||
default :putchar(*pc);
|
|
||||||
col++;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
pc++;
|
|
||||||
if(col>78) { /* What daring... 78?*/
|
|
||||||
if (*pc) {
|
|
||||||
putchar('\n');
|
|
||||||
col=0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if (!col && *pc) {
|
|
||||||
printf(" ");
|
|
||||||
col=12;line++;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
puts("");
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* show the help. The first command implemented.
|
|
||||||
* Can you see the header of routine? Known?
|
|
||||||
* The same with all the commands....
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
int shell_help(int argc,char * argv[]) {
|
|
||||||
int col,line,arg;
|
|
||||||
shell_topic_t *topic;
|
|
||||||
shell_cmd_t * shell_cmd=shell_first_cmd;
|
|
||||||
if (argc<2) {
|
|
||||||
printf("help: ('r' repeat last cmd - 'e' edit last cmd)\n"
|
|
||||||
" TOPIC? The topics are\n");
|
|
||||||
topic=shell_first_topic;
|
|
||||||
col=0;
|
|
||||||
while (topic) {
|
|
||||||
if (!col){
|
|
||||||
col=printf(" %s",topic->topic);
|
|
||||||
} else {
|
|
||||||
if ((col+strlen(topic->topic)+2)>78){
|
|
||||||
printf("\n");
|
|
||||||
col=printf(" %s",topic->topic);
|
|
||||||
} else {
|
|
||||||
col+=printf(", %s",topic->topic);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
topic=topic->next;
|
|
||||||
};
|
|
||||||
printf("\n");
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
line=0;
|
|
||||||
for (arg=1;arg<argc;arg++) {
|
|
||||||
if (line>16) {
|
|
||||||
printf("Press any key to continue...");getchar();
|
|
||||||
printf("\n");
|
|
||||||
line=0;
|
|
||||||
};
|
|
||||||
topic=shell_lookup_topic(argv[arg]);
|
|
||||||
if (!topic){
|
|
||||||
if ((shell_cmd=shell_lookup_cmd(argv[arg]))==NULL) {
|
|
||||||
printf("help: topic or cmd '%s' not found. Try <help> alone for a list\n",argv[arg]);
|
|
||||||
line++;
|
|
||||||
} else {
|
|
||||||
line+=shell_help_cmd(shell_cmd);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
printf("help: list for the topic '%s'\n",argv[arg]);
|
|
||||||
line++;
|
|
||||||
while (shell_cmd) {
|
|
||||||
if (!strcmp(topic->topic,shell_cmd->topic))
|
|
||||||
line+=shell_help_cmd(shell_cmd);
|
|
||||||
if (line>16) {
|
|
||||||
printf("Press any key to continue...");getchar();
|
|
||||||
printf("\n");
|
|
||||||
line=0;
|
|
||||||
};
|
|
||||||
shell_cmd=shell_cmd->next;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
puts("");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* TODO: Add improvements. History, edit vi or emacs, ...
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
int shell_scanline(char * line,int size,FILE * in,FILE * out) {
|
|
||||||
int c,col;
|
|
||||||
col=0;
|
|
||||||
if (*line) {
|
|
||||||
col=strlen(line);
|
|
||||||
if (out) fprintf(out,"%s",line);
|
|
||||||
};
|
|
||||||
tcdrain(fileno(in ));
|
|
||||||
if (out) tcdrain(fileno(out));
|
|
||||||
for (;;) {
|
|
||||||
line[col]=0;
|
|
||||||
c=fgetc(in);
|
|
||||||
switch (c) {
|
|
||||||
case 0x04:/*Control-d*/
|
|
||||||
if (col) break;
|
|
||||||
case EOF :return 0;
|
|
||||||
case '\n':break;
|
|
||||||
case '\f':if (out) fputc('\f',out);
|
|
||||||
case 0x03:/*Control-C*/
|
|
||||||
line[0]=0;
|
|
||||||
case '\r':if (out) fputc('\n',out);
|
|
||||||
return 1;
|
|
||||||
case 127:
|
|
||||||
case '\b':if (col) {
|
|
||||||
if (out) {
|
|
||||||
fputc('\b',out);
|
|
||||||
fputc(' ',out);
|
|
||||||
fputc('\b',out);
|
|
||||||
};
|
|
||||||
col--;
|
|
||||||
} else {
|
|
||||||
if (out) fputc('\a',out);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
default :if (!iscntrl(c)) {
|
|
||||||
if (col<size-1) {
|
|
||||||
line[col++]=c;
|
|
||||||
if (out) fputc(c,out);
|
|
||||||
} else {
|
|
||||||
if (out) fputc('\a',out);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
if (out)
|
|
||||||
if (c=='\a') fputc('\a',out);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- *
|
|
||||||
* - The shell TASK
|
|
||||||
* Poor but enough..
|
|
||||||
* TODO: Redirection. Tty Signals. ENVVARs. Shell language.
|
|
||||||
* ----------------------------------------------- */
|
|
||||||
shell_env_t global_shell_env ,
|
|
||||||
* current_shell_env=&global_shell_env;
|
|
||||||
|
|
||||||
extern char **environ;
|
|
||||||
|
|
||||||
void cat_file(FILE * out,char * name) {
|
|
||||||
FILE * fd;
|
|
||||||
int c;
|
|
||||||
if (out) {
|
|
||||||
fd=fopen(name,"r");
|
|
||||||
if (fd) {
|
|
||||||
while ((c=fgetc(fd))!=EOF) fputc(c,out);
|
|
||||||
fclose(fd);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_file(char * name,char * content) {
|
|
||||||
FILE * fd;
|
|
||||||
fd=fopen(name,"w");
|
|
||||||
if (fd) {
|
|
||||||
fwrite(content,1,strlen(content),fd);
|
|
||||||
fclose(fd);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_issue(void) {
|
|
||||||
static char issue_inited=FALSE;
|
|
||||||
struct stat buf;
|
|
||||||
if (issue_inited) return;
|
|
||||||
issue_inited=TRUE;
|
|
||||||
getpwnam("root"); /* dummy call to init /etc dir */
|
|
||||||
if (stat("/etc/issue",&buf))
|
|
||||||
write_file("/etc/issue",
|
|
||||||
"Welcome to @V\\n"
|
|
||||||
"Login into @S(@L)\\n");
|
|
||||||
if (stat("/etc/issue.net",&buf))
|
|
||||||
write_file("/etc/issue.net",
|
|
||||||
"Welcome to %v\n"
|
|
||||||
"running on %m\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int shell_login(FILE * in,FILE * out) {
|
|
||||||
FILE * fd;
|
|
||||||
int c;
|
|
||||||
time_t t;
|
|
||||||
int times;
|
|
||||||
char name[128];
|
|
||||||
char pass[128];
|
|
||||||
struct passwd * passwd;
|
|
||||||
init_issue();
|
|
||||||
setuid(0);
|
|
||||||
setgid(0);
|
|
||||||
rtems_current_user_env->euid=
|
|
||||||
rtems_current_user_env->egid=0;
|
|
||||||
if (out) {
|
|
||||||
if((current_shell_env->devname[5]!='p')||
|
|
||||||
(current_shell_env->devname[6]!='t')||
|
|
||||||
(current_shell_env->devname[7]!='y')) {
|
|
||||||
fd=fopen("/etc/issue","r");
|
|
||||||
if (fd) {
|
|
||||||
while ((c=fgetc(fd))!=EOF) {
|
|
||||||
if (c=='@') {
|
|
||||||
switch(c=fgetc(fd)) {
|
|
||||||
case 'L':fprintf(out,"%s",current_shell_env->devname);
|
|
||||||
break;
|
|
||||||
case 'B':fprintf(out,"0");
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
case 'D':time(&t);
|
|
||||||
fprintf(out,"%s",ctime(&t));
|
|
||||||
break;
|
|
||||||
case 'S':fprintf(out,"RTEMS");
|
|
||||||
break;
|
|
||||||
case 'V':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
|
|
||||||
break;
|
|
||||||
case '@':fprintf(out,"@");
|
|
||||||
break;
|
|
||||||
default :fprintf(out,"@%c",c);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
} else
|
|
||||||
if (c=='\\') {
|
|
||||||
switch(c=fgetc(fd)) {
|
|
||||||
case '\\':fprintf(out,"\\");
|
|
||||||
break;
|
|
||||||
case 'b':fprintf(out,"\b"); break;
|
|
||||||
case 'f':fprintf(out,"\f"); break;
|
|
||||||
case 'n':fprintf(out,"\n"); break;
|
|
||||||
case 'r':fprintf(out,"\r"); break;
|
|
||||||
case 's':fprintf(out," "); break;
|
|
||||||
case 't':fprintf(out,"\t"); break;
|
|
||||||
case '@':fprintf(out,"@"); break;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
fputc(c,out);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
fclose(fd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fd=fopen("/etc/issue.net","r");
|
|
||||||
if (fd) {
|
|
||||||
while ((c=fgetc(fd))!=EOF) {
|
|
||||||
if (c=='%') {
|
|
||||||
switch(c=fgetc(fd)) {
|
|
||||||
case 't':fprintf(out,"%s",current_shell_env->devname);
|
|
||||||
break;
|
|
||||||
case 'h':fprintf(out,"0");
|
|
||||||
break;
|
|
||||||
case 'D':fprintf(out," ");
|
|
||||||
break;
|
|
||||||
case 'd':time(&t);
|
|
||||||
fprintf(out,"%s",ctime(&t));
|
|
||||||
break;
|
|
||||||
case 's':fprintf(out,"RTEMS");
|
|
||||||
break;
|
|
||||||
case 'm':fprintf(out,"(" CPU_NAME "/" CPU_MODEL_NAME ")");
|
|
||||||
break;
|
|
||||||
case 'r':fprintf(out,_RTEMS_version);
|
|
||||||
break;
|
|
||||||
case 'v':fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice);
|
|
||||||
break;
|
|
||||||
case '%':fprintf(out,"%%");
|
|
||||||
break;
|
|
||||||
default :fprintf(out,"%%%c",c);
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
fputc(c,out);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
fclose(fd);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
times=0;
|
|
||||||
strcpy(name,"");
|
|
||||||
strcpy(pass,"");
|
|
||||||
for (;;) {
|
|
||||||
times++;
|
|
||||||
if (times>3) break;
|
|
||||||
if (out) fprintf(out,"\nlogin: ");
|
|
||||||
if (!shell_scanline(name,sizeof(name),in,out )) break;
|
|
||||||
if (out) fprintf(out,"Password: ");
|
|
||||||
if (!shell_scanline(pass,sizeof(pass),in,NULL)) break;
|
|
||||||
if (out) fprintf(out,"\n");
|
|
||||||
if ((passwd=getpwnam(name))) {
|
|
||||||
if (strcmp(passwd->pw_passwd,"!")) { /* valid user */
|
|
||||||
setuid(passwd->pw_uid);
|
|
||||||
setgid(passwd->pw_gid);
|
|
||||||
rtems_current_user_env->euid=
|
|
||||||
rtems_current_user_env->egid=0;
|
|
||||||
chown(current_shell_env->devname,passwd->pw_uid,0);
|
|
||||||
rtems_current_user_env->euid=passwd->pw_uid;
|
|
||||||
rtems_current_user_env->egid=passwd->pw_gid;
|
|
||||||
if (!strcmp(passwd->pw_passwd,"*")) {
|
|
||||||
/* /etc/shadow */
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
/* crypt() */
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if (out) fprintf(out,"Login incorrect\n");
|
|
||||||
strcpy(name,"");
|
|
||||||
strcpy(pass,"");
|
|
||||||
};
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rtems_task shell_shell(rtems_task_argument task_argument) {
|
|
||||||
|
|
||||||
shell_env_t * shell_env =(shell_env_t*) task_argument;
|
|
||||||
shell_cmd_t * shell_cmd;
|
|
||||||
|
|
||||||
rtems_status_code sc;
|
|
||||||
|
|
||||||
struct termios term;
|
|
||||||
char * devname;
|
|
||||||
|
|
||||||
char curdir[256];
|
|
||||||
char cmd[256];
|
|
||||||
char last_cmd[256]; /* to repeat 'r' */
|
|
||||||
int argc;
|
|
||||||
char * argv[128];
|
|
||||||
|
|
||||||
sc=rtems_task_variable_add(RTEMS_SELF,(void*)¤t_shell_env,free);
|
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
|
||||||
rtems_error(sc,"rtems_task_variable_add(current_shell_env):");
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
};
|
|
||||||
|
|
||||||
current_shell_env=shell_env;
|
|
||||||
|
|
||||||
sc=rtems_libio_set_private_env();
|
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
|
||||||
rtems_error(sc,"rtems_libio_set_private_env():");
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
devname=shell_env->devname;
|
|
||||||
setuid(0);
|
|
||||||
setgid(0);
|
|
||||||
rtems_current_user_env->euid=
|
|
||||||
rtems_current_user_env->egid=0;
|
|
||||||
|
|
||||||
stdin =fopen(devname,"r+");
|
|
||||||
|
|
||||||
if (!stdin) {
|
|
||||||
fprintf(stderr,"shell:unable to open stdin.%s:%s\n",devname,strerror(errno));
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
};
|
|
||||||
setvbuf(stdin,NULL,_IONBF,0); /* Not buffered*/
|
|
||||||
/* make a raw terminal,Linux MANuals */
|
|
||||||
if (tcgetattr (fileno(stdin), &term)>=0) {
|
|
||||||
term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
|
|
||||||
term.c_oflag &= ~OPOST;
|
|
||||||
term.c_oflag |= (OPOST|ONLCR); /* But with cr+nl on output */
|
|
||||||
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
|
|
||||||
term.c_cflag = CLOCAL | CREAD |(shell_env->tcflag);
|
|
||||||
term.c_cc[VMIN] = 1;
|
|
||||||
term.c_cc[VTIME] = 0;
|
|
||||||
if (tcsetattr (fileno(stdin), TCSADRAIN, &term) < 0) {
|
|
||||||
fprintf(stderr,"shell:cannot set terminal attributes(%s)\n",devname);
|
|
||||||
};
|
|
||||||
stdout=fopen(devname,"r+");
|
|
||||||
if (!stdout) {
|
|
||||||
fprintf(stderr,"shell:unable to open stdout.%s:%s\n",devname,strerror(errno));
|
|
||||||
};
|
|
||||||
setvbuf(stdout,NULL,_IONBF,0); /* Not buffered*/
|
|
||||||
stderr=fopen(devname,"r+");
|
|
||||||
if (!stderr) {
|
|
||||||
printf("shell:unable to open stderr.%s:%s\n",devname,strerror(errno));
|
|
||||||
};
|
|
||||||
/* when the future user environment runs ok
|
|
||||||
* a freopen() reopens the terminals. Now this don't work
|
|
||||||
* (sorry but you can't use because FILENO_STDIN!=0. Better fileno(stdin))
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
shell_add_cmd(NULL,NULL,NULL,NULL); /* init the chain list*/
|
|
||||||
do {
|
|
||||||
/* Set again root user and root filesystem, side effect of set_priv..*/
|
|
||||||
sc=rtems_libio_set_private_env();
|
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
|
||||||
rtems_error(sc,"rtems_libio_set_private_env():");
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
};
|
|
||||||
if (!shell_login(stdin,stdout)) {
|
|
||||||
cat_file(stdout,"/etc/motd");
|
|
||||||
strcpy(last_cmd,"");
|
|
||||||
strcpy(cmd,"");
|
|
||||||
printf("\n"
|
|
||||||
"RTEMS SHELL (Ver.1.0-FRC):%s. "__DATE__". 'help' to list commands.\n",devname);
|
|
||||||
chdir("/"); /* XXX: chdir to getpwent homedir */
|
|
||||||
shell_env->exit_shell=FALSE;
|
|
||||||
for (;;) {
|
|
||||||
/* Prompt section */
|
|
||||||
/* XXX: show_prompt user adjustable */
|
|
||||||
getcwd(curdir,sizeof(curdir));
|
|
||||||
printf("%s [%s] %c ",shell_env->taskname,curdir,geteuid()?'$':'#');
|
|
||||||
/* getcmd section */
|
|
||||||
if (!shell_scanline(cmd,sizeof(cmd),stdin,stdout)) break; /*EOF*/
|
|
||||||
/* evaluate cmd section */
|
|
||||||
if (!strcmp(cmd,"e")) { /* edit last command */
|
|
||||||
strcpy(cmd,last_cmd);
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
if (!strcmp(cmd,"r")) { /* repeat last command */
|
|
||||||
strcpy(cmd,last_cmd);
|
|
||||||
} else
|
|
||||||
if (strcmp(cmd,"")) { /* only for get a new prompt */
|
|
||||||
strcpy(last_cmd,cmd);
|
|
||||||
};
|
|
||||||
/* exec cmd section */
|
|
||||||
/* TODO:
|
|
||||||
* To avoid user crash catch the signals.
|
|
||||||
* Open a new stdio files with posibility of redirection *
|
|
||||||
* Run in a new shell task background. (unix &)
|
|
||||||
* Resuming. A little bash.
|
|
||||||
*/
|
|
||||||
if (shell_make_args(cmd,&argc,argv)) {
|
|
||||||
if ((shell_cmd=shell_lookup_cmd(argv[0]))!=NULL) {
|
|
||||||
shell_env->errorlevel=shell_cmd->command(argc,argv);
|
|
||||||
} else {
|
|
||||||
printf("shell:%s command not found\n",argv[0]);
|
|
||||||
shell_env->errorlevel=-1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
/* end exec cmd section */
|
|
||||||
if (shell_env->exit_shell) break;
|
|
||||||
cmd[0]=0;
|
|
||||||
};
|
|
||||||
printf("\nGoodbye from RTEMS SHELL :-(\n");
|
|
||||||
};
|
|
||||||
} while (shell_env->forever);
|
|
||||||
fclose(stdin );
|
|
||||||
fclose(stdout);
|
|
||||||
fclose(stderr);
|
|
||||||
rtems_task_delete(RTEMS_SELF);
|
|
||||||
}
|
|
||||||
/* ----------------------------------------------- */
|
|
||||||
rtems_status_code shell_init (char * task_name,
|
|
||||||
rtems_unsigned32 task_stacksize,
|
|
||||||
rtems_task_priority task_priority,
|
|
||||||
char * devname,
|
|
||||||
tcflag_t tcflag,
|
|
||||||
int forever) {
|
|
||||||
rtems_id task_id;
|
|
||||||
rtems_status_code sc;
|
|
||||||
shell_env_t * shell_env;
|
|
||||||
sc=rtems_task_create(new_rtems_name(task_name),
|
|
||||||
task_priority,
|
|
||||||
task_stacksize?task_stacksize:RTEMS_MINIMUM_STACK_SIZE,
|
|
||||||
RTEMS_DEFAULT_MODES,
|
|
||||||
RTEMS_DEFAULT_ATTRIBUTES,
|
|
||||||
&task_id);
|
|
||||||
if (sc!=RTEMS_SUCCESSFUL) {
|
|
||||||
rtems_error(sc,"creating task %s in shell_init()",task_name);
|
|
||||||
return sc;
|
|
||||||
};
|
|
||||||
shell_env=malloc(sizeof(shell_env_t));
|
|
||||||
if (!shell_env) {
|
|
||||||
rtems_task_delete(task_id);
|
|
||||||
sc=RTEMS_NO_MEMORY;
|
|
||||||
rtems_error(sc,"allocating shell_env %s in shell_init()",task_name);
|
|
||||||
return sc;
|
|
||||||
};
|
|
||||||
if (global_shell_env.magic!=new_rtems_name("SENV")) {
|
|
||||||
global_shell_env.magic =new_rtems_name("SENV");
|
|
||||||
global_shell_env.devname ="/dev/console";
|
|
||||||
global_shell_env.taskname ="GLOBAL";
|
|
||||||
global_shell_env.tcflag =0;
|
|
||||||
global_shell_env.exit_shell=0;
|
|
||||||
global_shell_env.forever =TRUE;
|
|
||||||
};
|
|
||||||
shell_env->magic =global_shell_env.magic;
|
|
||||||
shell_env->devname =devname;
|
|
||||||
shell_env->taskname =task_name;
|
|
||||||
shell_env->tcflag =tcflag;
|
|
||||||
shell_env->exit_shell=FALSE;
|
|
||||||
shell_env->forever =forever;
|
|
||||||
return rtems_task_start(task_id,shell_shell,(rtems_task_argument) shell_env);
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Instantatiate a new terminal shell.
|
|
||||||
*
|
|
||||||
* Author:
|
|
||||||
*
|
|
||||||
* WORK: fernando.ruiz@ctv.es
|
|
||||||
* HOME: correo@fernando-ruiz.com
|
|
||||||
*
|
|
||||||
* Thanks at:
|
|
||||||
* Chris John
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __SHELL_H__
|
|
||||||
#define __SHELL_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <termios.h>
|
|
||||||
|
|
||||||
typedef int (*shell_command_t)(int argc,char * argv[]);
|
|
||||||
|
|
||||||
struct shell_cmd_tt ;
|
|
||||||
typedef struct shell_cmd_tt shell_cmd_t;
|
|
||||||
|
|
||||||
struct shell_cmd_tt {
|
|
||||||
char * name;
|
|
||||||
char * usage;
|
|
||||||
char * topic;
|
|
||||||
shell_command_t command;
|
|
||||||
shell_cmd_t * alias;
|
|
||||||
shell_cmd_t * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
rtems_unsigned32 new_rtems_name(char * rtems_name);
|
|
||||||
shell_cmd_t * shell_lookup_cmd(char * cmd);
|
|
||||||
shell_cmd_t * shell_add_cmd(char * cmd,
|
|
||||||
char * topic,
|
|
||||||
char * usage,
|
|
||||||
shell_command_t command);
|
|
||||||
shell_cmd_t * shell_alias_cmd(char * cmd, char * alias);
|
|
||||||
|
|
||||||
int shell_make_args(char * cmd,
|
|
||||||
int * pargc,
|
|
||||||
char * argv[]);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
rtems_name magic; /* 'S','E','N','V': Shell Environment */
|
|
||||||
char * devname;
|
|
||||||
char * taskname;
|
|
||||||
tcflag_t tcflag;
|
|
||||||
/* user extensions */
|
|
||||||
int exit_shell; /* logout */
|
|
||||||
int forever ; /* repeat login */
|
|
||||||
int errorlevel;
|
|
||||||
int mdump_adr;
|
|
||||||
} shell_env_t;
|
|
||||||
|
|
||||||
int shell_scanline(char * line,int size,FILE * in,FILE * out) ;
|
|
||||||
void cat_file(FILE * out,char *name);
|
|
||||||
void write_file(char *name,char * content);
|
|
||||||
|
|
||||||
rtems_status_code shell_init(char * task_name ,
|
|
||||||
rtems_unsigned32 task_stacksize,/*0 default*/
|
|
||||||
rtems_task_priority task_priority ,
|
|
||||||
char * devname ,
|
|
||||||
tcflag_t tcflag ,
|
|
||||||
int forever );
|
|
||||||
|
|
||||||
extern shell_env_t global_shell_env,
|
|
||||||
* current_shell_env;
|
|
||||||
/*--------*/
|
|
||||||
/* cmds.c */
|
|
||||||
/*--------*/
|
|
||||||
int str2int(char * s);
|
|
||||||
void register_cmds(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libstackchk-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = check.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
noinst_HEADERS = internal.h
|
|
||||||
include_rtems_HEADERS = stackchk.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README check.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
This directory contains a stack bounds checker. It provides two
|
|
||||||
primary features:
|
|
||||||
|
|
||||||
+ check for stack overflow at each context switch
|
|
||||||
+ provides an educated guess at each task's stack usage
|
|
||||||
|
|
||||||
Enabling
|
|
||||||
========
|
|
||||||
|
|
||||||
Add the stack checker extension to the initial user extension set.
|
|
||||||
If using confdefs.h to build your configuration table, this is
|
|
||||||
as simple as adding -DSTACK_CHECK_ON to the gcc command line which
|
|
||||||
compiles the file defining the configuration table. In the RTEMS
|
|
||||||
test suites and samples, this is always init.c
|
|
||||||
|
|
||||||
Background
|
|
||||||
==========
|
|
||||||
|
|
||||||
The stack overflow check at context switch works by looking for
|
|
||||||
a 16 byte pattern at the logical end of the stack to be corrupted.
|
|
||||||
The "guesser" assumes that the entire stack was prefilled with a known
|
|
||||||
pattern and assumes that the pattern is still in place if the memory
|
|
||||||
has not been used as a stack.
|
|
||||||
|
|
||||||
Both of these can be fooled by pushing large holes onto the stack
|
|
||||||
and not writing to them... or (much more unlikely) writing the
|
|
||||||
magic patterns into memory.
|
|
||||||
|
|
||||||
This code has not been extensively tested. It is provided as a tool
|
|
||||||
for RTEMS users to catch the most common mistake in multitasking
|
|
||||||
systems ... too little stack space. Suggestions and comments are appreciated.
|
|
||||||
|
|
||||||
NOTES:
|
|
||||||
|
|
||||||
1. Stack usage information is questionable on CPUs which push
|
|
||||||
large holes on stack.
|
|
||||||
|
|
||||||
2. The stack checker has a tendency to generate a fault when
|
|
||||||
trying to print the helpful diagnostic message. If it comes
|
|
||||||
out, congratulations. If not, then the variable Stack_check_Blown_task
|
|
||||||
contains a pointer to the TCB of the offending task. This
|
|
||||||
is usually enough to go on.
|
|
||||||
|
|
||||||
FUTURE:
|
|
||||||
|
|
||||||
1. Determine how/if gcc will generate stack probe calls and support that.
|
|
||||||
|
|
||||||
2. Get accurate stack usage numbers on i960.. it pushes very large
|
|
||||||
holes on the stack.
|
|
||||||
@@ -1,550 +0,0 @@
|
|||||||
/*
|
|
||||||
* Stack Overflow Check User Extension Set
|
|
||||||
*
|
|
||||||
* NOTE: This extension set automatically determines at
|
|
||||||
* initialization time whether the stack for this
|
|
||||||
* CPU grows up or down and installs the correct
|
|
||||||
* extension routines for that direction.
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <rtems.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HACK
|
|
||||||
* the stack dump information should be printed by a "fatal" extension.
|
|
||||||
* Fatal extensions only get called via rtems_fatal_error_occurred()
|
|
||||||
* and not when rtems_shutdown_executive() is called.
|
|
||||||
* I hope/think this is changing so that fatal extensions are renamed
|
|
||||||
* to "shutdown" extensions.
|
|
||||||
* When that happens, this #define should be deleted and all the code
|
|
||||||
* it marks.
|
|
||||||
*/
|
|
||||||
#define DONT_USE_FATAL_EXTENSION
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include <rtems/stackchk.h>
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This variable contains the name of the task which "blew" the stack.
|
|
||||||
* It is NULL if the system is all right.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Thread_Control *Stack_check_Blown_task;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The extension table for the stack checker.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rtems_extensions_table Stack_check_Extension_table = {
|
|
||||||
Stack_check_Create_extension, /* rtems_task_create */
|
|
||||||
0, /* rtems_task_start */
|
|
||||||
0, /* rtems_task_restart */
|
|
||||||
0, /* rtems_task_delete */
|
|
||||||
Stack_check_Switch_extension, /* task_switch */
|
|
||||||
Stack_check_Begin_extension, /* task_begin */
|
|
||||||
0, /* task_exitted */
|
|
||||||
#ifdef DONT_USE_FATAL_EXTENSION
|
|
||||||
0, /* fatal */
|
|
||||||
#else
|
|
||||||
Stack_check_Fatal_extension, /* fatal */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The "magic pattern" used to mark the end of the stack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Stack_check_Control Stack_check_Pattern;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Where the pattern goes in the stack area is dependent upon
|
|
||||||
* whether the stack grow to the high or low area of the memory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if ( CPU_STACK_GROWS_UP == TRUE )
|
|
||||||
|
|
||||||
#define Stack_check_Get_pattern_area( _the_stack ) \
|
|
||||||
((Stack_check_Control *) ((char *)(_the_stack)->area + \
|
|
||||||
(_the_stack)->size - sizeof( Stack_check_Control ) ))
|
|
||||||
|
|
||||||
#define Stack_check_Calculate_used( _low, _size, _high_water ) \
|
|
||||||
((char *)(_high_water) - (char *)(_low))
|
|
||||||
|
|
||||||
#define Stack_check_usable_stack_start(_the_stack) \
|
|
||||||
((_the_stack)->area)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define Stack_check_Get_pattern_area( _the_stack ) \
|
|
||||||
((Stack_check_Control *) ((char *)(_the_stack)->area + HEAP_OVERHEAD))
|
|
||||||
|
|
||||||
#define Stack_check_Calculate_used( _low, _size, _high_water) \
|
|
||||||
( ((char *)(_low) + (_size)) - (char *)(_high_water) )
|
|
||||||
|
|
||||||
#define Stack_check_usable_stack_start(_the_stack) \
|
|
||||||
((char *)(_the_stack)->area + sizeof(Stack_check_Control))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Stack_check_usable_stack_size(_the_stack) \
|
|
||||||
((_the_stack)->size - sizeof(Stack_check_Control))
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do we have an interrupt stack?
|
|
||||||
* XXX it would sure be nice if the interrupt stack were also
|
|
||||||
* stored in a "stack" structure!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
Stack_Control stack_check_interrupt_stack;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prototypes necessary for forward references
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Dump_usage( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fill an entire stack area with BYTE_PATTERN.
|
|
||||||
* This will be used by a Fatal extension to check for
|
|
||||||
* amount of actual stack used
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
stack_check_dope_stack(Stack_Control *stack)
|
|
||||||
{
|
|
||||||
memset(stack->area, BYTE_PATTERN, stack->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Initialize
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned32 stack_check_initialized = 0;
|
|
||||||
|
|
||||||
void Stack_check_Initialize( void )
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
rtems_status_code status;
|
|
||||||
Objects_Id id_ignored;
|
|
||||||
#endif
|
|
||||||
unsigned32 *p;
|
|
||||||
#if 0
|
|
||||||
unsigned32 i;
|
|
||||||
unsigned32 api_index;
|
|
||||||
Thread_Control *the_thread;
|
|
||||||
Objects_Information *information;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (stack_check_initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Dope the pattern and fill areas
|
|
||||||
*/
|
|
||||||
|
|
||||||
for ( p = Stack_check_Pattern.pattern;
|
|
||||||
p < &Stack_check_Pattern.pattern[PATTERN_SIZE_WORDS];
|
|
||||||
p += 4
|
|
||||||
)
|
|
||||||
{
|
|
||||||
p[0] = 0xFEEDF00D; /* FEED FOOD to BAD DOG */
|
|
||||||
p[1] = 0x0BAD0D06;
|
|
||||||
p[2] = 0xDEADF00D; /* DEAD FOOD GOOD DOG */
|
|
||||||
p[3] = 0x600D0D06;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
status = rtems_extension_create(
|
|
||||||
rtems_build_name( 'S', 'T', 'C', 'K' ),
|
|
||||||
&Stack_check_Extension_table,
|
|
||||||
&id_ignored
|
|
||||||
);
|
|
||||||
assert ( status == RTEMS_SUCCESSFUL );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Stack_check_Blown_task = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If installed by a task, that task will not get setup properly
|
|
||||||
* since it missed out on the create hook. This will cause a
|
|
||||||
* failure on first switch out of that task.
|
|
||||||
* So pretend here that we actually ran create and begin extensions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* XXX
|
|
||||||
*
|
|
||||||
* Technically this has not been done for any task created before this
|
|
||||||
* happened. So just run through them and fix the situation.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (_Thread_Executing)
|
|
||||||
{
|
|
||||||
Stack_check_Create_extension(_Thread_Executing, _Thread_Executing);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
for ( api_index = 1;
|
|
||||||
api_index <= OBJECTS_APIS_LAST ;
|
|
||||||
api_index++ ) {
|
|
||||||
if ( !_Objects_Information_table[ api_index ] )
|
|
||||||
continue;
|
|
||||||
information = _Objects_Information_table[ api_index ][ 1 ];
|
|
||||||
if ( information ) {
|
|
||||||
for ( i=1 ; i <= information->maximum ; i++ ) {
|
|
||||||
the_thread = (Thread_Control *)information->local_table[ i ];
|
|
||||||
Stack_check_Create_extension( the_thread, the_thread );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If appropriate, setup the interrupt stack for high water testing
|
|
||||||
* also.
|
|
||||||
*/
|
|
||||||
#if (CPU_ALLOCATE_INTERRUPT_STACK == TRUE)
|
|
||||||
if (_CPU_Interrupt_stack_low && _CPU_Interrupt_stack_high)
|
|
||||||
{
|
|
||||||
stack_check_interrupt_stack.area = _CPU_Interrupt_stack_low;
|
|
||||||
stack_check_interrupt_stack.size = (char *) _CPU_Interrupt_stack_high -
|
|
||||||
(char *) _CPU_Interrupt_stack_low;
|
|
||||||
|
|
||||||
stack_check_dope_stack(&stack_check_interrupt_stack);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DONT_USE_FATAL_EXTENSION
|
|
||||||
#ifdef RTEMS_DEBUG
|
|
||||||
/*
|
|
||||||
* this would normally be called by a fatal extension
|
|
||||||
* handler, but we don't run fatal extensions unless
|
|
||||||
* we fatal error.
|
|
||||||
*/
|
|
||||||
atexit(Stack_check_Dump_usage);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
stack_check_initialized = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Create_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
boolean Stack_check_Create_extension(
|
|
||||||
Thread_Control *running,
|
|
||||||
Thread_Control *the_thread
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (!stack_check_initialized)
|
|
||||||
Stack_check_Initialize();
|
|
||||||
|
|
||||||
if (the_thread /* XXX && (the_thread != _Thread_Executing) */ )
|
|
||||||
stack_check_dope_stack(&the_thread->Start.Initial_stack);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Begin_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Begin_extension(
|
|
||||||
Thread_Control *the_thread
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Stack_check_Control *the_pattern;
|
|
||||||
|
|
||||||
if (!stack_check_initialized)
|
|
||||||
Stack_check_Initialize();
|
|
||||||
|
|
||||||
if ( the_thread->Object.id == 0 ) /* skip system tasks */
|
|
||||||
return;
|
|
||||||
|
|
||||||
the_pattern = Stack_check_Get_pattern_area(&the_thread->Start.Initial_stack);
|
|
||||||
|
|
||||||
*the_pattern = Stack_check_Pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_report_blown_task
|
|
||||||
* Report a blown stack. Needs to be a separate routine
|
|
||||||
* so that interrupt handlers can use this too.
|
|
||||||
*
|
|
||||||
* Caller must have set the Stack_check_Blown_task.
|
|
||||||
*
|
|
||||||
* NOTE: The system is in a questionable state... we may not get
|
|
||||||
* the following message out.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_report_blown_task(void)
|
|
||||||
{
|
|
||||||
Stack_Control *stack;
|
|
||||||
Thread_Control *running;
|
|
||||||
|
|
||||||
running = Stack_check_Blown_task;
|
|
||||||
stack = &running->Start.Initial_stack;
|
|
||||||
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"BLOWN STACK!!! Offending task(%p): id=0x%08x; name=0x%08x",
|
|
||||||
running,
|
|
||||||
running->Object.id,
|
|
||||||
(unsigned32)running->Object.name
|
|
||||||
);
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
if (rtems_configuration_get_user_multiprocessing_table())
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"; node=%d\n",
|
|
||||||
rtems_configuration_get_user_multiprocessing_table()->node
|
|
||||||
);
|
|
||||||
else
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
" stack covers range 0x%08x - 0x%08x (%d bytes)\n",
|
|
||||||
(unsigned32) stack->area,
|
|
||||||
(unsigned32) stack->area + stack->size - 1,
|
|
||||||
(unsigned32) stack->size);
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
" Damaged pattern begins at 0x%08lx and is %ld bytes long\n",
|
|
||||||
(unsigned long) Stack_check_Get_pattern_area(stack),
|
|
||||||
(long) PATTERN_SIZE_BYTES);
|
|
||||||
fflush(stderr);
|
|
||||||
|
|
||||||
rtems_fatal_error_occurred( (unsigned32) "STACK BLOWN" );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Switch_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Switch_extension(
|
|
||||||
Thread_Control *running,
|
|
||||||
Thread_Control *heir
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ( running->Object.id == 0 ) /* skip system tasks */
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (0 != memcmp( (void *) Stack_check_Get_pattern_area( &running->Start.Initial_stack)->pattern,
|
|
||||||
(void *) Stack_check_Pattern.pattern,
|
|
||||||
PATTERN_SIZE_BYTES))
|
|
||||||
{
|
|
||||||
Stack_check_Blown_task = running;
|
|
||||||
Stack_check_report_blown_task();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void *Stack_check_find_high_water_mark(
|
|
||||||
const void *s,
|
|
||||||
size_t n
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const unsigned32 *base, *ebase;
|
|
||||||
unsigned32 length;
|
|
||||||
|
|
||||||
base = s;
|
|
||||||
length = n/4;
|
|
||||||
|
|
||||||
#if ( CPU_STACK_GROWS_UP == TRUE )
|
|
||||||
/*
|
|
||||||
* start at higher memory and find first word that does not
|
|
||||||
* match pattern
|
|
||||||
*/
|
|
||||||
|
|
||||||
base += length - 1;
|
|
||||||
for (ebase = s; base > ebase; base--)
|
|
||||||
if (*base != U32_PATTERN)
|
|
||||||
return (void *) base;
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* start at lower memory and find first word that does not
|
|
||||||
* match pattern
|
|
||||||
*/
|
|
||||||
|
|
||||||
base += PATTERN_SIZE_WORDS;
|
|
||||||
for (ebase = base + length; base < ebase; base++)
|
|
||||||
if (*base != U32_PATTERN)
|
|
||||||
return (void *) base;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (void *)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Dump_threads_usage
|
|
||||||
* Try to print out how much stack was actually used by the task.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Dump_threads_usage(
|
|
||||||
Thread_Control *the_thread
|
|
||||||
)
|
|
||||||
{
|
|
||||||
unsigned32 size, used;
|
|
||||||
void *low;
|
|
||||||
void *high_water_mark;
|
|
||||||
Stack_Control *stack;
|
|
||||||
unsigned32 u32_name;
|
|
||||||
char name_str[5];
|
|
||||||
char *name;
|
|
||||||
Objects_Information *info;
|
|
||||||
|
|
||||||
if ( !the_thread )
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX HACK to get to interrupt stack
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (the_thread == (Thread_Control *) -1)
|
|
||||||
{
|
|
||||||
if (stack_check_interrupt_stack.area)
|
|
||||||
{
|
|
||||||
stack = &stack_check_interrupt_stack;
|
|
||||||
the_thread = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
stack = &the_thread->Start.Initial_stack;
|
|
||||||
|
|
||||||
low = Stack_check_usable_stack_start(stack);
|
|
||||||
size = Stack_check_usable_stack_size(stack);
|
|
||||||
|
|
||||||
high_water_mark = Stack_check_find_high_water_mark(low, size);
|
|
||||||
|
|
||||||
if ( high_water_mark )
|
|
||||||
used = Stack_check_Calculate_used( low, size, high_water_mark );
|
|
||||||
else
|
|
||||||
used = 0;
|
|
||||||
|
|
||||||
info = _Objects_Get_information(the_thread->Object.id);
|
|
||||||
name = name_str;
|
|
||||||
if ( the_thread ) {
|
|
||||||
if ( info->is_string ) {
|
|
||||||
name = (char *) the_thread->Object.name;
|
|
||||||
} else {
|
|
||||||
u32_name = (unsigned32 *)the_thread->Object.name;
|
|
||||||
name[ 0 ] = (u32_name >> 24) & 0xff;
|
|
||||||
name[ 1 ] = (u32_name >> 16) & 0xff;
|
|
||||||
name[ 2 ] = (u32_name >> 8) & 0xff;
|
|
||||||
name[ 3 ] = (u32_name >> 0) & 0xff;
|
|
||||||
name[ 4 ] = '\0';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
u32_name = rtems_build_name('I', 'N', 'T', 'R');
|
|
||||||
name[ 0 ] = (u32_name >> 24) & 0xff;
|
|
||||||
name[ 1 ] = (u32_name >> 16) & 0xff;
|
|
||||||
name[ 2 ] = (u32_name >> 8) & 0xff;
|
|
||||||
name[ 3 ] = (u32_name >> 0) & 0xff;
|
|
||||||
name[ 4 ] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
printf( "0x%08x %4s 0x%08x 0x%08x %8d %8d\n",
|
|
||||||
the_thread ? the_thread->Object.id : ~0,
|
|
||||||
name,
|
|
||||||
(unsigned32) stack->area,
|
|
||||||
(unsigned32) stack->area + (unsigned32) stack->size - 1,
|
|
||||||
size,
|
|
||||||
used
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Fatal_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Fatal_extension(
|
|
||||||
Internal_errors_Source source,
|
|
||||||
boolean is_internal,
|
|
||||||
unsigned32 status
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#ifndef DONT_USE_FATAL_EXTENSION
|
|
||||||
if (status == 0)
|
|
||||||
Stack_check_Dump_usage();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* Stack_check_Dump_usage
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Dump_usage( void )
|
|
||||||
{
|
|
||||||
unsigned32 i;
|
|
||||||
unsigned32 api_index;
|
|
||||||
Thread_Control *the_thread;
|
|
||||||
unsigned32 hit_running = 0;
|
|
||||||
Objects_Information *information;
|
|
||||||
|
|
||||||
if (stack_check_initialized == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
printf("Stack usage by thread\n");
|
|
||||||
printf(
|
|
||||||
" ID NAME LOW HIGH AVAILABLE USED\n"
|
|
||||||
);
|
|
||||||
|
|
||||||
for ( api_index = 1 ;
|
|
||||||
api_index <= OBJECTS_APIS_LAST ;
|
|
||||||
api_index++ ) {
|
|
||||||
if ( !_Objects_Information_table[ api_index ] )
|
|
||||||
continue;
|
|
||||||
information = _Objects_Information_table[ api_index ][ 1 ];
|
|
||||||
if ( information ) {
|
|
||||||
for ( i=1 ; i <= information->maximum ; i++ ) {
|
|
||||||
the_thread = (Thread_Control *)information->local_table[ i ];
|
|
||||||
Stack_check_Dump_threads_usage( the_thread );
|
|
||||||
if ( the_thread == _Thread_Executing )
|
|
||||||
hit_running = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !hit_running )
|
|
||||||
Stack_check_Dump_threads_usage( _Thread_Executing );
|
|
||||||
|
|
||||||
/* dump interrupt stack info if any */
|
|
||||||
Stack_check_Dump_threads_usage((Thread_Control *) -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/* internal.h
|
|
||||||
*
|
|
||||||
* This include file contains internal information
|
|
||||||
* for the RTEMS stack checker.
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __INTERNAL_STACK_CHECK_h
|
|
||||||
#define __INTERNAL_STACK_CHECK_h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This structure is used to fill in and compare the "end of stack"
|
|
||||||
* marker pattern.
|
|
||||||
* pattern area must be a multiple of 4 words.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CPU_STACK_CHECK_SIZE
|
|
||||||
#define PATTERN_SIZE_WORDS (((CPU_STACK_CHECK_SIZE / 4) + 3) & ~0x3)
|
|
||||||
#else
|
|
||||||
#define PATTERN_SIZE_WORDS (4)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PATTERN_SIZE_BYTES (PATTERN_SIZE_WORDS * sizeof(unsigned32))
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned32 pattern[ PATTERN_SIZE_WORDS ];
|
|
||||||
} Stack_check_Control;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The pattern used to fill the entire stack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define BYTE_PATTERN 0xA5
|
|
||||||
#define U32_PATTERN 0xA5A5A5A5
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Create_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
boolean Stack_check_Create_extension(
|
|
||||||
Thread_Control *running,
|
|
||||||
Thread_Control *the_thread
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Begin_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Begin_extension(
|
|
||||||
Thread_Control *the_thread
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Switch_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Switch_extension(
|
|
||||||
Thread_Control *running,
|
|
||||||
Thread_Control *heir
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Fatal_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Fatal_extension(
|
|
||||||
Internal_errors_Source source,
|
|
||||||
boolean is_internal,
|
|
||||||
unsigned32 status
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Dump_usage
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Dump_usage( void );
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* end of include file */
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/* stackchk.h
|
|
||||||
*
|
|
||||||
* This include file contains information necessary to utilize
|
|
||||||
* and install the stack checker mechanism.
|
|
||||||
*
|
|
||||||
* COPYRIGHT (c) 1989-1999.
|
|
||||||
* On-Line Applications Research Corporation (OAR).
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __STACK_CHECK_h
|
|
||||||
#define __STACK_CHECK_h
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Initialize
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Initialize( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Dump_usage
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Dump_usage( void );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Create_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
boolean Stack_check_Create_extension(
|
|
||||||
Thread_Control *running,
|
|
||||||
Thread_Control *the_thread
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Begin_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Begin_extension(
|
|
||||||
Thread_Control *the_thread
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Stack_check_Switch_extension
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Stack_check_Switch_extension(
|
|
||||||
Thread_Control *running,
|
|
||||||
Thread_Control *heir
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Extension set definition
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define STACK_CHECKER_EXTENSION \
|
|
||||||
{ \
|
|
||||||
Stack_check_Create_extension, /* rtems_task_create */ \
|
|
||||||
0, /* rtems_task_start */ \
|
|
||||||
0, /* rtems_task_restart */ \
|
|
||||||
0, /* rtems_task_delete */ \
|
|
||||||
Stack_check_Switch_extension, /* task_switch */ \
|
|
||||||
Stack_check_Begin_extension, /* task_begin */ \
|
|
||||||
0, /* task_exitted */ \
|
|
||||||
0 /* Stack_check_Fatal_extension */, /* fatal */ \
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* end of include file */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
|
|
||||||
include_rtemsdir = $(includedir)/rtems
|
|
||||||
|
|
||||||
LIBNAME = libuntar-tmp
|
|
||||||
LIB = $(ARCH)/$(LIBNAME).a
|
|
||||||
|
|
||||||
C_FILES = untar.c
|
|
||||||
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
|
|
||||||
|
|
||||||
include_rtems_HEADERS = untar.h
|
|
||||||
|
|
||||||
OBJS = $(C_O_FILES)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
$(PROJECT_INCLUDE)/rtems:
|
|
||||||
@$(mkinstalldirs) $@
|
|
||||||
$(PROJECT_INCLUDE)/rtems/%.h: %.h
|
|
||||||
$(INSTALL_DATA) $< $@
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(OBJS)
|
|
||||||
$(make-library)
|
|
||||||
|
|
||||||
PREINSTALL_FILES = $(PROJECT_INCLUDE)/rtems \
|
|
||||||
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB)
|
|
||||||
|
|
||||||
.PRECIOUS: $(LIB)
|
|
||||||
|
|
||||||
EXTRA_DIST = README untar.c
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#
|
|
||||||
#
|
|
||||||
# untar information
|
|
||||||
#
|
|
||||||
# Author: Jake Janovetz 7.6.1999
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
|
|
||||||
untar.c contains two procedures for extracting files from a UNIX
|
|
||||||
tar file:
|
|
||||||
|
|
||||||
int Untar_FromMemory(unsigned char *tar_buf, unsigned long size);
|
|
||||||
int Untar_FromFile(char *tar_name);
|
|
||||||
|
|
||||||
Untar_FromMemory(...) takes its input from a chunk of allocated memory.
|
|
||||||
This is particularly useful when the tar is stored in Flash memory or
|
|
||||||
comes from the FTP daemon by way of a hook.
|
|
||||||
|
|
||||||
Untar_FromFile(...) is identical except the source is from an existing
|
|
||||||
file. The fully qualified filename is passed through char *tar_name.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BUGS: Please email janovetz@uiuc.edu
|
|
||||||
-----
|
|
||||||
@@ -1,382 +0,0 @@
|
|||||||
/* FIXME:
|
|
||||||
* 1. Symbolic links are not created.
|
|
||||||
* 2. Untar_FromMemory has printfs.
|
|
||||||
* 3. Untar_FromMemory uses FILE *fp.
|
|
||||||
* 4. How to determine end of archive?
|
|
||||||
*
|
|
||||||
* Written by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "untar.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* TAR file format:
|
|
||||||
*
|
|
||||||
* Offset Length Contents
|
|
||||||
* 0 100 bytes File name ('\0' terminated, 99 maxmum length)
|
|
||||||
* 100 8 bytes File mode (in octal ascii)
|
|
||||||
* 108 8 bytes User ID (in octal ascii)
|
|
||||||
* 116 8 bytes Group ID (in octal ascii)
|
|
||||||
* 124 12 bytes File size (s) (in octal ascii)
|
|
||||||
* 136 12 bytes Modify time (in octal ascii)
|
|
||||||
* 148 8 bytes Header checksum (in octal ascii)
|
|
||||||
* 156 1 bytes Link flag
|
|
||||||
* 157 100 bytes Linkname ('\0' terminated, 99 maxmum length)
|
|
||||||
* 257 8 bytes Magic ("ustar \0")
|
|
||||||
* 265 32 bytes User name ('\0' terminated, 31 maxmum length)
|
|
||||||
* 297 32 bytes Group name ('\0' terminated, 31 maxmum length)
|
|
||||||
* 329 8 bytes Major device ID (in octal ascii)
|
|
||||||
* 337 8 bytes Minor device ID (in octal ascii)
|
|
||||||
* 345 167 bytes Padding
|
|
||||||
* 512 (s+p)bytes File contents (s+p) := (((s) + 511) & ~511),
|
|
||||||
* round up to 512 bytes
|
|
||||||
*
|
|
||||||
* Checksum:
|
|
||||||
* int i, sum;
|
|
||||||
* char* header = tar_header_pointer;
|
|
||||||
* sum = 0;
|
|
||||||
* for(i = 0; i < 512; i++)
|
|
||||||
* sum += 0xFF & header[i];
|
|
||||||
*************************************************************************/
|
|
||||||
|
|
||||||
#define LF_OLDNORMAL '\0' /* Normal disk file, Unix compatible */
|
|
||||||
#define LF_NORMAL '0' /* Normal disk file */
|
|
||||||
#define LF_LINK '1' /* Link to previously dumped file */
|
|
||||||
#define LF_SYMLINK '2' /* Symbolic link */
|
|
||||||
#define LF_CHR '3' /* Character special file */
|
|
||||||
#define LF_BLK '4' /* Block special file */
|
|
||||||
#define LF_DIR '5' /* Directory */
|
|
||||||
#define LF_FIFO '6' /* FIFO special file */
|
|
||||||
#define LF_CONFIG '7' /* Contiguous file */
|
|
||||||
|
|
||||||
#define MAX_NAME_FIELD_SIZE 99
|
|
||||||
|
|
||||||
#define MIN(a,b) ((a)>(b)?(b):(a))
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* This converts octal ASCII number representations into an
|
|
||||||
* unsigned long. Only support 32-bit numbers for now.
|
|
||||||
*************************************************************************/
|
|
||||||
static unsigned long
|
|
||||||
octal2ulong(char *octascii, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
unsigned long num;
|
|
||||||
unsigned long mult;
|
|
||||||
|
|
||||||
num = 0;
|
|
||||||
mult = 1;
|
|
||||||
for (i=len-1; i>=0; i--)
|
|
||||||
{
|
|
||||||
if ((octascii[i] < '0') || (octascii[i] > '9'))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
num += mult*((unsigned long)(octascii[i] - '0'));
|
|
||||||
mult *= 8;
|
|
||||||
}
|
|
||||||
return(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* Function: Untar_FromMemory *
|
|
||||||
**************************************************************************
|
|
||||||
* Description: *
|
|
||||||
* *
|
|
||||||
* This is a simple subroutine used to rip links, directories, and *
|
|
||||||
* files out of a block of memory. *
|
|
||||||
* *
|
|
||||||
* *
|
|
||||||
* Inputs: *
|
|
||||||
* *
|
|
||||||
* unsigned char *tar_buf - Pointer to TAR buffer. *
|
|
||||||
* unsigned long size - Length of TAR buffer. *
|
|
||||||
* *
|
|
||||||
* *
|
|
||||||
* Output: *
|
|
||||||
* *
|
|
||||||
* int - UNTAR_SUCCESSFUL (0) on successful completion. *
|
|
||||||
* UNTAR_INVALID_CHECKSUM for an invalid header checksum. *
|
|
||||||
* UNTAR_INVALID_HEADER for an invalid header. *
|
|
||||||
* *
|
|
||||||
**************************************************************************
|
|
||||||
* Change History: *
|
|
||||||
* 12/30/1998 - Creation (JWJ) *
|
|
||||||
*************************************************************************/
|
|
||||||
int
|
|
||||||
Untar_FromMemory(unsigned char *tar_buf, unsigned long size)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
char *bufr;
|
|
||||||
size_t n;
|
|
||||||
char fname[100];
|
|
||||||
char linkname[100];
|
|
||||||
int sum;
|
|
||||||
int hdr_chksum;
|
|
||||||
int retval;
|
|
||||||
unsigned long ptr;
|
|
||||||
unsigned long i;
|
|
||||||
unsigned long nblocks;
|
|
||||||
unsigned long file_size;
|
|
||||||
unsigned char linkflag;
|
|
||||||
|
|
||||||
|
|
||||||
ptr = 0;
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (ptr + 512 > size)
|
|
||||||
{
|
|
||||||
retval = UNTAR_SUCCESSFUL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the header */
|
|
||||||
bufr = &tar_buf[ptr];
|
|
||||||
ptr += 512;
|
|
||||||
if (strncmp(&bufr[257], "ustar ", 7))
|
|
||||||
{
|
|
||||||
retval = UNTAR_SUCCESSFUL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(fname, bufr, MAX_NAME_FIELD_SIZE);
|
|
||||||
fname[MAX_NAME_FIELD_SIZE] = '\0';
|
|
||||||
|
|
||||||
linkflag = bufr[156];
|
|
||||||
file_size = octal2ulong(&bufr[124], 12);
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Compute the TAR checksum and check with the value in
|
|
||||||
* the archive. The checksum is computed over the entire
|
|
||||||
* header, but the checksum field is substituted with blanks.
|
|
||||||
******************************************************************/
|
|
||||||
hdr_chksum = (int)octal2ulong(&bufr[148], 8);
|
|
||||||
sum = 0;
|
|
||||||
for (i=0; i<512; i++)
|
|
||||||
{
|
|
||||||
if ((i >= 148) && (i < 156))
|
|
||||||
{
|
|
||||||
sum += 0xff & ' ';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sum += 0xff & bufr[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sum != hdr_chksum)
|
|
||||||
{
|
|
||||||
retval = UNTAR_INVALID_CHECKSUM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* We've decoded the header, now figure out what it contains and
|
|
||||||
* do something with it.
|
|
||||||
*****************************************************************/
|
|
||||||
if (linkflag == LF_SYMLINK)
|
|
||||||
{
|
|
||||||
strncpy(linkname, &bufr[157], MAX_NAME_FIELD_SIZE);
|
|
||||||
linkname[MAX_NAME_FIELD_SIZE] = '\0';
|
|
||||||
/* symlink(fname, linkname); */
|
|
||||||
}
|
|
||||||
else if (linkflag == LF_NORMAL)
|
|
||||||
{
|
|
||||||
nblocks = (((file_size) + 511) & ~511) / 512;
|
|
||||||
if ((fp = fopen(fname, "w")) == NULL)
|
|
||||||
{
|
|
||||||
printf("Untar failed to create file %s\n", fname);
|
|
||||||
ptr += 512 * nblocks;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned long sizeToGo = file_size;
|
|
||||||
unsigned long len;
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* Read out the data. There are nblocks of data where nblocks
|
|
||||||
* is the file_size rounded to the nearest 512-byte boundary.
|
|
||||||
**************************************************************/
|
|
||||||
for (i=0; i<nblocks; i++)
|
|
||||||
{
|
|
||||||
len = ((sizeToGo < 512L)?(sizeToGo):(512L));
|
|
||||||
n = fwrite(&tar_buf[ptr], 1, len, fp);
|
|
||||||
if (n != len)
|
|
||||||
{
|
|
||||||
printf("Error during write\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ptr += 512;
|
|
||||||
sizeToGo -= n;
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (linkflag == LF_DIR)
|
|
||||||
{
|
|
||||||
mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* Function: Untar_FromFile *
|
|
||||||
**************************************************************************
|
|
||||||
* Description: *
|
|
||||||
* *
|
|
||||||
* This is a simple subroutine used to rip links, directories, and *
|
|
||||||
* files out of a TAR file. *
|
|
||||||
* *
|
|
||||||
* *
|
|
||||||
* Inputs: *
|
|
||||||
* *
|
|
||||||
* char *tar_name - TAR filename. *
|
|
||||||
* *
|
|
||||||
* *
|
|
||||||
* Output: *
|
|
||||||
* *
|
|
||||||
* int - UNTAR_SUCCESSFUL (0) on successful completion. *
|
|
||||||
* UNTAR_INVALID_CHECKSUM for an invalid header checksum. *
|
|
||||||
* UNTAR_INVALID_HEADER for an invalid header. *
|
|
||||||
* *
|
|
||||||
**************************************************************************
|
|
||||||
* Change History: *
|
|
||||||
* 12/30/1998 - Creation (JWJ) *
|
|
||||||
*************************************************************************/
|
|
||||||
int
|
|
||||||
Untar_FromFile(char *tar_name)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
char *bufr;
|
|
||||||
size_t n;
|
|
||||||
char fname[100];
|
|
||||||
char linkname[100];
|
|
||||||
int sum;
|
|
||||||
int hdr_chksum;
|
|
||||||
int retval;
|
|
||||||
unsigned long i;
|
|
||||||
unsigned long nblocks;
|
|
||||||
unsigned long size;
|
|
||||||
unsigned char linkflag;
|
|
||||||
|
|
||||||
|
|
||||||
retval = UNTAR_SUCCESSFUL;
|
|
||||||
bufr = (char *)malloc(512);
|
|
||||||
if (bufr == NULL)
|
|
||||||
{
|
|
||||||
return(UNTAR_FAIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = open(tar_name, O_RDONLY);
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/* Read the header */
|
|
||||||
/* If the header read fails, we just consider it the end
|
|
||||||
of the tarfile. */
|
|
||||||
if ((n = read(fd, bufr, 512)) != 512)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(&bufr[257], "ustar ", 7))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(fname, bufr, MAX_NAME_FIELD_SIZE);
|
|
||||||
fname[MAX_NAME_FIELD_SIZE] = '\0';
|
|
||||||
|
|
||||||
linkflag = bufr[156];
|
|
||||||
size = octal2ulong(&bufr[124], 12);
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Compute the TAR checksum and check with the value in
|
|
||||||
* the archive. The checksum is computed over the entire
|
|
||||||
* header, but the checksum field is substituted with blanks.
|
|
||||||
******************************************************************/
|
|
||||||
hdr_chksum = (int)octal2ulong(&bufr[148], 8);
|
|
||||||
sum = 0;
|
|
||||||
for (i=0; i<512; i++)
|
|
||||||
{
|
|
||||||
if ((i >= 148) && (i < 156))
|
|
||||||
{
|
|
||||||
sum += 0xff & ' ';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sum += 0xff & bufr[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sum != hdr_chksum)
|
|
||||||
{
|
|
||||||
retval = UNTAR_INVALID_CHECKSUM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* We've decoded the header, now figure out what it contains and
|
|
||||||
* do something with it.
|
|
||||||
*****************************************************************/
|
|
||||||
if (linkflag == LF_SYMLINK)
|
|
||||||
{
|
|
||||||
strncpy(linkname, &bufr[157], MAX_NAME_FIELD_SIZE);
|
|
||||||
linkname[MAX_NAME_FIELD_SIZE] = '\0';
|
|
||||||
}
|
|
||||||
else if (linkflag == LF_NORMAL)
|
|
||||||
{
|
|
||||||
int out_fd;
|
|
||||||
|
|
||||||
/******************************************************************
|
|
||||||
* Read out the data. There are nblocks of data where nblocks
|
|
||||||
* is the size rounded to the nearest 512-byte boundary.
|
|
||||||
*****************************************************************/
|
|
||||||
nblocks = (((size) + 511) & ~511) / 512;
|
|
||||||
|
|
||||||
if ((out_fd = creat(fname, 0644)) == -1)
|
|
||||||
{
|
|
||||||
for (i=0; i<nblocks; i++)
|
|
||||||
{
|
|
||||||
n = read(fd, bufr, 512);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i=0; i<nblocks; i++)
|
|
||||||
{
|
|
||||||
n = read(fd, bufr, 512);
|
|
||||||
n = MIN(n, size - i*512);
|
|
||||||
write(out_fd, bufr, n);
|
|
||||||
}
|
|
||||||
close(out_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (linkflag == LF_DIR)
|
|
||||||
{
|
|
||||||
mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(bufr);
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
return(retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Written by: Jake Janovetz <janovetz@tempest.ece.uiuc.edu>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __UNTAR_H__
|
|
||||||
#define __UNTAR_H__
|
|
||||||
|
|
||||||
|
|
||||||
#define UNTAR_SUCCESSFUL 0
|
|
||||||
#define UNTAR_FAIL 1
|
|
||||||
#define UNTAR_INVALID_CHECKSUM 2
|
|
||||||
#define UNTAR_INVALID_HEADER 3
|
|
||||||
|
|
||||||
|
|
||||||
int Untar_FromMemory(unsigned char *tar_buf, unsigned long size);
|
|
||||||
int Untar_FromFile(char *tar_name);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __UNTAR_H__ */
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Makefile
|
|
||||||
Makefile.in
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
##
|
|
||||||
## $Id$
|
|
||||||
##
|
|
||||||
|
|
||||||
LIB = $(ARCH)/libmisc.a
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/compile.am
|
|
||||||
include $(top_srcdir)/../../../automake/lib.am
|
|
||||||
|
|
||||||
## XXX temporarily remove this from the list because it causes a
|
|
||||||
## XXX number of BSPs to not link "main(){}" used by autoconf
|
|
||||||
## ../serdbg/$(ARCH)/libserdbg-tmp.a
|
|
||||||
|
|
||||||
if RTEMS_LIBSHELL
|
|
||||||
RTEMS_LIBSHELL = ../shell/$(ARCH)/libshell-tmp.a
|
|
||||||
endif
|
|
||||||
|
|
||||||
TMP_LIBS = ../monitor/$(ARCH)/libmonitor-tmp.a \
|
|
||||||
../untar/$(ARCH)/libuntar-tmp.a ../stackchk/$(ARCH)/libstackchk-tmp.a \
|
|
||||||
../cpuuse/$(ARCH)/libcpuuse-tmp.a ../rtmonuse/$(ARCH)/librtmonuse-tmp.a \
|
|
||||||
$(RTEMS_LIBSHELL) ../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
|
|
||||||
|
|
||||||
#
|
|
||||||
# (OPTIONAL) Add local stuff here using +=
|
|
||||||
#
|
|
||||||
|
|
||||||
$(LIB): $(TMP_LIBS)
|
|
||||||
$(RM) $@
|
|
||||||
$(RM) -r $(ARCH)
|
|
||||||
mkdir $(ARCH)
|
|
||||||
cd $(ARCH); for lib in $^; do $(AR) -xv ../$$lib; done
|
|
||||||
$(AR) ruv $@ $(ARCH)/*
|
|
||||||
$(RANLIB) $@
|
|
||||||
|
|
||||||
all-local: $(ARCH) $(LIB)
|
|
||||||
|
|
||||||
include $(top_srcdir)/../../../automake/local.am
|
|
||||||
Reference in New Issue
Block a user