cat /tmp/j | while read f

do
  rpm -qi $f 2>&1 | grep -v "is not ins"
done
This commit is contained in:
Joel Sherrill
1999-10-26 02:49:21 +00:00
parent 3330ecb836
commit 3f06778ed8
42 changed files with 0 additions and 5982 deletions

View File

@@ -1,13 +0,0 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_AMFLAGS = -I $(RTEMS_TOPdir)/aclocal
SUBDIRS = dumpbuf stackchk monitor cpuuse rtmonuse untar wrapup
EXTRA_DIST = README
include $(top_srcdir)/../../../../automake/subdirs.am
include $(top_srcdir)/../../../../automake/local.am

View File

@@ -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

View File

@@ -1,44 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
dnl
dnl $Id$
AC_PREREQ(2.13)
AC_INIT(dumpbuf)
RTEMS_TOP(../../../..)
AC_CONFIG_AUX_DIR(../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE(rtems-c-src-lib-libmisc,$RTEMS_VERSION,no)
AM_MAINTAINER_MODE
RTEMS_ENABLE_MULTIPROCESSING
RTEMS_ENABLE_NETWORKING
RTEMS_ENABLE_LIBCDIR
RTEMS_ENABLE_BARE
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_CPU
RTEMS_CANONICAL_HOST
RTEMS_PROJECT_ROOT
dnl check target cc
RTEMS_PROG_CC_FOR_TARGET
RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_MULTIPROCESSING(RTEMS_BSP)
# Try to explicitly list a Makefile here
AC_OUTPUT(
Makefile
cpuuse/Makefile
dumpbuf/Makefile
monitor/Makefile
rtmonuse/Makefile
stackchk/Makefile
untar/Makefile
wrapup/Makefile
)

View File

@@ -1,72 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = cpuuse
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
LIB = ${ARCH}/libcpuuse-tmp.a
# C source names, if any, go here -- minus the .c
C_PIECES = cpuuse
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
H_FILES =
INSTALLED_H_FILES = $(srcdir)/cpuuse.h
SRCS = $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rtems
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS += -I.
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${LIB}: ${SRCS} preinstall ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) preinstall $(LIB)
preinstall:
@$(INSTALL_CHANGE) -m 644 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/rtems
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -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.

View File

@@ -1,142 +0,0 @@
/*
* CPU Usage Reporter
*
* COPYRIGHT (c) 1989-1998. 1996.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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>
extern rtems_configuration_table BSP_Configuration;
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <rtems/cpuuse.h>
unsigned32 CPU_usage_Ticks_at_last_reset;
/*PAGE
*
* CPU_usage_Dump
*/
void CPU_usage_Dump( void )
{
unsigned32 i;
unsigned32 class_index;
Thread_Control *the_thread;
Objects_Information *information;
unsigned32 u32_name;
char name[5];
unsigned32 total_units = 0;
for ( class_index = OBJECTS_CLASSES_FIRST ;
class_index <= OBJECTS_CLASSES_LAST ;
class_index++ ) {
information = _Objects_Information_table[ class_index ];
if ( information && information->is_thread ) {
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 ( class_index = OBJECTS_CLASSES_FIRST ;
class_index <= OBJECTS_CLASSES_LAST ;
class_index++ ) {
information = _Objects_Information_table[ class_index ];
if ( information && information->is_thread ) {
for ( i=1 ; i <= information->maximum ; i++ ) {
the_thread = (Thread_Control *)information->local_table[ i ];
if ( !the_thread )
continue;
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 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 class_index;
Thread_Control *the_thread;
Objects_Information *information;
CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot;
for ( class_index = OBJECTS_CLASSES_FIRST ;
class_index <= OBJECTS_CLASSES_LAST ;
class_index++ ) {
information = _Objects_Information_table[ class_index ];
if ( information && information->is_thread ) {
for ( i=1 ; i <= information->maximum ; i++ ) {
the_thread = (Thread_Control *)information->local_table[ i ];
if ( !the_thread )
continue;
the_thread->ticks_executed = 0;
}
}
}
}

View File

@@ -1,41 +0,0 @@
/* cpuuse.h
*
* This include file contains information necessary to utilize
* and install the cpu usage reporting mechanism.
*
* COPYRIGHT (c) 1989-1998. 1996.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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 */

View File

@@ -1,72 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = dumpbuf
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
LIB = ${ARCH}/libdumpbuf-tmp.a
# C source names, if any, go here -- minus the .c
C_PIECES = dumpbuf
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
H_FILES =
INSTALLED_H_FILES = $(srcdir)/dumpbuf.h
SRCS = $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rtems
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS += -I.
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${LIB}: ${SRCS} preinstall ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) preinstall $(LIB)
preinstall:
@$(INSTALL_CHANGE) -m 644 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/rtems
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -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 );
}

View File

@@ -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 */

View File

@@ -1,80 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = monitor
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rtems
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
LIB = ${ARCH}/libmonitor-tmp.a
# C source names, if any, go here -- minus the .c
# We only build multiprocessing related files if HAS_MP was defined
MP_C_PIECES_yes_V = mon-mpci
MP_C_PIECES = $(MP_C_PIECES_$(HAS_MP)_V)
C_PIECES = mon-command mon-symbols mon-prmisc mon-monitor mon-object \
mon-server mon-task mon-queue mon-driver mon-dname mon-itask \
mon-extension mon-manager mon-config $(MP_C_PIECES)
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
H_FILES =
INSTALLED_H_FILES = $(srcdir)/monitor.h $(srcdir)/symbols.h
SRCS = README $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES)
OBJS = $(C_O_FILES)
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS += -I$(srcdir)
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
.PHONY: preinstall
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${LIB}: ${SRCS} ${OBJS}
$(make-library)
all: preinstall ${ARCH} $(SRCS) $(LIB)
preinstall: $(INSTALLED_H_FILES)
@$(INSTALL_CHANGE) -m 644 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/rtems
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -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)

View File

@@ -1,187 +0,0 @@
/*
* Command parsing routines for RTEMS monitor
*
* TODO:
*
* $Id$
*/
#include <rtems.h>
#include <rtems/monitor.h>
#include <stdio.h>
#include <string.h>
/*
* 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)
{
extern rtems_configuration_table BSP_Configuration;
static char monitor_prompt[32];
/*
* put node number in the prompt if we are multiprocessing
*/
if (BSP_Configuration.User_multiprocessing_table == 0)
sprintf(monitor_prompt, "%s", MONITOR_PROMPT);
else if (rtems_monitor_default_node != rtems_monitor_node)
sprintf(monitor_prompt, "%d-%s-%d", rtems_monitor_node, MONITOR_PROMPT, rtems_monitor_default_node);
else
sprintf(monitor_prompt, "%d-%s", rtems_monitor_node, MONITOR_PROMPT);
#ifdef 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
do
{
printf("%s> ", monitor_prompt);
fflush(stdout);
} while (gets(command) == (char *) 0);
#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
)
{
rtems_monitor_command_entry_t *p;
rtems_monitor_command_entry_t *abbreviated_match = 0;
int abbreviated_matches = 0;
char *command;
int command_length;
command = argv[0];
if ((table == 0) || (command == 0))
goto failed;
command_length = strlen(command);
for (p = table; p->command; p++)
if (STREQ(command, p->command)) /* exact match */
goto done;
else if (STRNEQ(command, p->command, command_length))
{
abbreviated_matches++;
abbreviated_match = p;
}
/* no perfect match; is there a non-ambigous abbreviated match? */
if ( ! abbreviated_match)
{
printf("Unrecognized command '%s'; try 'help'\n", command);
goto failed;
}
if (abbreviated_matches > 1)
{
printf("Command '%s' is ambiguous; try 'help'\n", command);
goto failed;
}
p = abbreviated_match;
done:
if (p->command_function == 0)
goto failed;
return p;
failed:
return 0;
}
void
rtems_monitor_command_usage(rtems_monitor_command_entry_t *table,
char *command_string)
{
rtems_monitor_command_entry_t *help = 0;
char *help_command_argv[2];
/* if first entry in table is a usage, then print it out */
if (command_string == 0)
{
if (STREQ(table->command, "--usage--") && table->usage)
help = table;
}
else
{
help_command_argv[0] = command_string;
help_command_argv[1] = 0;
help = rtems_monitor_command_lookup(table, 1, help_command_argv);
}
if (help)
printf("%s\n", help->usage);
}
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]);
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
(void *) d->open);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
(void *) d->close);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
(void *) d->read);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
(void *) d->write);
rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
(void *) d->control);
}
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;
}

View File

@@ -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");
}

View File

@@ -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");
}

View File

@@ -1,48 +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;
_Objects_Copy_name_raw(object->name, &copy->name, sizeof(copy->name));
}
done:
return object;
}

View File

@@ -1,518 +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 <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;
/*
* The top-level commands
*/
rtems_monitor_command_entry_t rtems_monitor_commands[] = {
{ "--usage--",
"\n"
"RTEMS monitor\n"
"\n"
"Commands (may be abbreviated)\n"
"\n"
" help -- get this message or command specific help\n"
" pause -- pause monitor for a specified number of ticks\n"
" exit -- invoke a fatal RTEMS error\n"
" symbol -- show entries from symbol table\n"
" continue -- put monitor to sleep waiting for explicit wakeup\n"
" config -- show system configuration\n"
" itask -- list init tasks\n"
" mpci -- list mpci config\n"
" task -- show task information\n"
" queue -- show message queue information\n"
" extension -- user extensions\n"
" driver -- show information about named drivers\n"
" dname -- show information about named drivers\n"
" object -- generic object information\n"
" node -- specify default node for commands that take id's\n"
#ifdef CPU_INVOKE_DEBUGGER
" debugger -- invoke system debugger\n"
#endif
,
0,
0,
(unsigned32) rtems_monitor_commands,
},
{ "config",
"config\n"
" Show the system configuration.\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_CONFIG,
},
{ "itask",
"itask\n"
" List init tasks for the system\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_INIT_TASK,
},
{ "mpci",
"mpci\n"
" Show the MPCI system configuration, if configured.\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_MPCI,
},
{ "pause",
"pause [ticks]\n"
" monitor goes to \"sleep\" for specified ticks (default is 1)\n"
" monitor will resume at end of period or if explicitly awakened\n",
0,
rtems_monitor_pause_cmd,
0,
},
{ "continue",
"continue\n"
" put the monitor to sleep waiting for an explicit wakeup from the\n"
" program running.\n",
0,
rtems_monitor_continue_cmd,
0,
},
{ "go",
"go\n"
" Alias for 'continue'\n",
0,
rtems_monitor_continue_cmd,
0,
},
{ "node",
"node [ node number ]\n"
" Specify default node number for commands that take id's\n",
0,
rtems_monitor_node_cmd,
0,
},
{ "symbol",
"symbol [ symbolname [symbolname ... ] ]\n"
" display value associated with specified symbol.\n"
" Defaults to displaying all known symbols.\n",
0,
rtems_monitor_symbol_cmd,
(unsigned32) &rtems_monitor_symbols,
},
{ "extension",
"extension [id [id ...] ]\n"
" display information about specified extensions.\n"
" Default is to display information about all extensions on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_EXTENSION,
},
{ "task",
"task [id [id ...] ]\n"
" display information about the specified tasks.\n"
" Default is to display information about all tasks on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_TASK,
},
{ "queue",
"queue [id [id ... ] ]\n"
" display information about the specified message queues\n"
" Default is to display information about all queues on this node\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_QUEUE,
},
{ "object",
"object [id [id ...] ]\n"
" display information about specified RTEMS objects.\n"
" Object id's must include 'type' information.\n"
" (which may normally be defaulted)\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_INVALID,
},
{ "driver",
"driver [ major [ major ... ] ]\n"
" Display the RTEMS device driver table.\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_DRIVER,
},
{ "dname",
"dname\n"
" Displays information about named drivers.\n",
0,
rtems_monitor_object_cmd,
RTEMS_MONITOR_OBJECT_DNAME,
},
{ "exit",
"exit [status]\n"
" Invoke 'rtems_fatal_error_occurred' with 'status'\n"
" (default is RTEMS_SUCCESSFUL)\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_SUCCESSFUL,
},
{ "fatal",
"fatal [status]\n"
" 'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_TASK_EXITTED, /* exit value */
},
{ "quit",
"quit [status]\n"
" Alias for 'exit'\n",
0,
rtems_monitor_fatal_cmd,
RTEMS_SUCCESSFUL, /* exit value */
},
{ "help",
"help [ command [ command ] ]\n"
" provide information about commands\n"
" Default is show basic command summary.\n",
0,
rtems_monitor_help_cmd,
(unsigned32) rtems_monitor_commands,
},
#ifdef CPU_INVOKE_DEBUGGER
{ "debugger",
"debugger\n"
" Enter the debugger, if possible.\n"
" A continue from the debugger will return to the monitor.\n",
0,
rtems_monitor_debugger_cmd,
0,
},
#endif
{ 0, 0, 0, 0, 0 },
};
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;
}
/*
* 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;
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;
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
continue;
if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
argc,
argv)) == 0)
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");
goto done;
}
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");
goto done;
}
done:
}

View File

@@ -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;
}

View File

@@ -1,382 +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(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(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;
}

View File

@@ -1,259 +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=sizeof(u.c)-1; i ; i--)
length += rtems_monitor_dump_char(u.c[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 },
{ "WRATE", STATES_WAITING_FOR_PERIOD },
{ 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;
}

View File

@@ -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");
}

View File

@@ -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_task_id = 0;
if (rtems_monitor_server_request_queue_id)
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
rtems_monitor_server_response_queue_id = 0;
if (rtems_monitor_server_response_queue_id)
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
rtems_monitor_server_request_queue_ids = 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;
}

View File

@@ -1,483 +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$
*/
/* for strcasecmp in linux and solaris */
#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");
}
}
}

View File

@@ -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");
}

View File

@@ -1,449 +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_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
);
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 */
unsigned32 command_arg;
};
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);
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 */

View File

@@ -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 */

View File

@@ -1,72 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = rtmonuse
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
LIB = ${ARCH}/librtmonuse-tmp.a
# C source names, if any, go here -- minus the .c
C_PIECES = rtmonuse
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
H_FILES =
INSTALLED_H_FILES = $(srcdir)/rtmonuse.h
SRCS = $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rtems
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS += -I.
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${LIB}: ${SRCS} preinstall ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) preinstall $(LIB)
preinstall:
@$(INSTALL_CHANGE) -m 644 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/rtems
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -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
);
}
}

View File

@@ -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

View File

@@ -1,72 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = stackchk
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
LIB = ${ARCH}/libstackchk-tmp.a
# C source names, if any, go here -- minus the .c
C_PIECES = check
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
H_FILES = internal.h
INSTALLED_H_FILES = $(srcdir)/stackchk.h
SRCS = $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rtems
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS +=
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${LIB}: ${SRCS} preinstall ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) $(LIB)
preinstall:
@$(INSTALL_CHANGE) -m 644 $(INSTALLED_H_FILES) $(PROJECT_INCLUDE)/rtems
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -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.

View File

@@ -1,535 +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-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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
extern rtems_configuration_table BSP_Configuration;
#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 class_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 ( class_index = OBJECTS_CLASSES_FIRST ;
class_index <= OBJECTS_CLASSES_LAST ;
class_index++ ) {
information = _Objects_Information_table[ class_index ];
if ( information && information->is_thread ) {
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_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);
}
#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 (BSP_Configuration.User_multiprocessing_table)
fprintf(
stderr,
"; node=%d\n",
BSP_Configuration.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%08x and is %d bytes long\n",
(unsigned32) Stack_check_Get_pattern_area(stack), 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[5];
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;
if ( the_thread )
u32_name = *(unsigned32 *)the_thread->Object.name;
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 class_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 ( class_index = OBJECTS_CLASSES_FIRST ;
class_index <= OBJECTS_CLASSES_LAST ;
class_index++ ) {
information = _Objects_Information_table[ class_index ];
if ( information && information->is_thread ) {
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);
}

View File

@@ -1,96 +0,0 @@
/* internal.h
*
* This include file contains internal information
* for the RTEMS stack checker.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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 * 4)
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 */

View File

@@ -1,83 +0,0 @@
/* stackchk.h
*
* This include file contains information necessary to utilize
* and install the stack checker mechanism.
*
* COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
* Copyright assigned to U.S. Government, 1994.
*
* 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 */

View File

@@ -1,69 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = untar
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
LIB = ${ARCH}/libuntar-tmp.a
# C source names, if any, go here -- minus the .c
C_PIECES = untar
C_FILES = $(C_PIECES:%=%.c)
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
H_FILES = $(srcdir)/untar.h
SRCS = $(C_FILES) $(H_FILES) $(INSTALLED_H_FILES)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
mkinstalldirs = $(SHELL) $(top_srcdir)/@RTEMS_TOPdir@/mkinstalldirs
INSTALLDIRS = $(PROJECT_INCLUDE)/rtems
$(INSTALLDIRS):
@$(mkinstalldirs) $(INSTALLDIRS)
#
# (OPTIONAL) Add local stuff here using +=
#
DEFINES +=
CPPFLAGS += -I.
CFLAGS +=
LD_PATHS +=
LD_LIBS +=
LDFLAGS +=
#
# Add your list of files to delete here. The config files
# already know how to delete some stuff, so you may want
# to just run 'make clean' first to see what gets missed.
# 'make clobber' already includes 'make clean'
#
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
${LIB}: ${SRCS} ${OBJS}
$(make-library)
all: ${ARCH} $(SRCS) $(LIB)
@$(INSTALL_CHANGE) -m 644 $(H_FILES) $(PROJECT_INCLUDE)/rtems
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status

View File

@@ -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
-----

View File

@@ -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);
}

View File

@@ -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__ */

View File

@@ -1,50 +0,0 @@
#
# $Id$
#
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = ..
subdir = wrapup
RTEMS_ROOT = @RTEMS_ROOT@
PROJECT_ROOT = @PROJECT_ROOT@
VPATH = @srcdir@
LIB = $(ARCH)/libmisc.a
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(RTEMS_ROOT)/make/lib.cfg
INSTALL_CHANGE = @INSTALL_CHANGE@
# Using the wildcard on the Purify support makes sure it may not be there
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 \
../dumpbuf/$(ARCH)/libdumpbuf-tmp.a
RELS =
CLEAN_ADDITIONS +=
CLOBBER_ADDITIONS +=
$(LIB): ${LIBS} $(RELS)
$(RM) -r $(ARCH)
mkdir $(ARCH)
cd $(ARCH); for lib in $(LIBS:%=../%); do \
$(AR) -xv $$lib; \
done
$(RM) $@
$(AR) ruv $@ $(ARCH)/*
$(RANLIB) $@
all: ${ARCH} $(SRCS) $(LIB)
@$(INSTALL_VARIANT) -m 644 $(LIB) $(PROJECT_RELEASE)/lib
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status