URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/rtems/c/src/libmisc/monitor
- from Rev 30 to Rev 173
- ↔ Reverse comparison
Rev 30 → Rev 173
/mon-manager.c
0,0 → 1,48
/* |
* RTEMS Monitor "manager" support. |
* Used to traverse object (chain) lists and print them out. |
* |
* $Id: mon-manager.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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, ©->name, sizeof(copy->name)); |
} |
|
done: |
return object; |
} |
|
/mon-itask.c
0,0 → 1,115
/* |
* RTEMS Monitor init task support |
* |
* $Id: mon-itask.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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"); |
} |
/mon-extension.c
0,0 → 1,98
/* |
* RTEMS Monitor extension support |
* |
* $Id: mon-extension.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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"); |
} |
/mon-command.c
0,0 → 1,186
/* |
* Command parsing routines for RTEMS monitor |
* |
* TODO: |
* |
* $Id: mon-command.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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) |
{ |
static char monitor_prompt[32]; |
|
/* |
* put node number in the prompt if we are multiprocessing |
*/ |
|
if (!rtems_configuration_get_user_multiprocessing_table()) |
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]); |
} |
} |
/mon-dname.c
0,0 → 1,112
/* |
* 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: mon-dname.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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; |
} |
/mon-queue.c
0,0 → 1,64
/* |
* $Id: mon-queue.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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"); |
} |
/README
0,0 → 1,97
# |
# $Id: README,v 1.2 2001-09-27 12:01:43 chris Exp $ |
# |
|
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) |
|
/mon-monitor.c
0,0 → 1,518
/* |
* 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: mon-monitor.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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: |
} |
/mon-mpci.c
0,0 → 1,159
/* |
* RTEMS MPCI Config display support |
* |
* TODO |
* |
* $Id: mon-mpci.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
|
#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; |
} |
/mon-symbols.c
0,0 → 1,484
/* |
* File: symbols.c |
* |
* Description: |
* Symbol table manager for the RTEMS monitor. |
* These routines may be used by other system resources also. |
* |
* |
* TODO: |
* |
* $Id: mon-symbols.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
/* for strcasecmp in linux and solaris */ |
#undef __STRICT_ANSI__ |
#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"); |
} |
} |
} |
/mon-driver.c
0,0 → 1,136
/* |
* 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: mon-driver.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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; |
} |
/mon-prmisc.c
0,0 → 1,259
/* |
* Print misc stuff for the monitor dump routines |
* Each routine returns the number of characters it output. |
* |
* TODO: |
* |
* $Id: mon-prmisc.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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; |
} |
/Makefile.am
0,0 → 1,54
## |
## $Id: Makefile.am,v 1.2 2001-09-27 12:01:43 chris Exp $ |
## |
|
AUTOMAKE_OPTIONS = foreign 1.4 |
|
LIBNAME = libmonitor-tmp |
LIB = $(ARCH)/$(LIBNAME).a |
|
# We only build multiprocessing related files if HAS_MP was defined |
MP_C_FILES = mon-mpci.c |
|
C_FILES = mon-command.c mon-symbols.c mon-prmisc.c mon-monitor.c \ |
mon-object.c mon-server.c mon-task.c mon-queue.c mon-driver.c \ |
mon-dname.c mon-itask.c mon-extension.c mon-manager.c mon-config.c |
|
if HAS_MP |
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) $(MP_C_FILES:%.c=$(ARCH)/%.o) |
else |
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o) |
endif |
|
H_FILES = monitor.h symbols.h |
|
OBJS = $(C_O_FILES) |
|
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg |
include $(top_srcdir)/../../../automake/lib.am |
|
$(PROJECT_INCLUDE)/rtems: |
$(mkinstalldirs) $@ |
$(PROJECT_INCLUDE)/rtems/%.h: %.h |
$(INSTALL_DATA) $< $@ |
|
# |
# (OPTIONAL) Add local stuff here using += |
# |
|
$(LIB): $(OBJS) |
$(make-library) |
|
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems \ |
$(H_FILES:%=$(PROJECT_INCLUDE)/rtems/%) |
|
all-local: $(ARCH) $(PREINSTALL_FILES) $(OBJS) $(LIB) |
|
.PRECIOUS: $(LIB) |
|
EXTRA_DIST = README mon-command.c mon-config.c mon-dname.c mon-driver.c \ |
mon-extension.c mon-itask.c mon-manager.c mon-monitor.c mon-mpci.c \ |
mon-object.c mon-prmisc.c mon-queue.c mon-server.c mon-symbols.c \ |
mon-task.c monitor.h symbols.h |
|
include $(top_srcdir)/../../../automake/local.am |
/mon-task.c
0,0 → 1,93
/* |
* RTEMS Monitor task support |
* |
* $Id: mon-task.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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"); |
} |
|
/monitor.h
0,0 → 1,449
/* |
* File: monitor.h |
* |
* Description: |
* The RTEMS monitor task include file. |
* |
* TODO: |
* |
* $Id: monitor.h,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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 */ |
/mon-config.c
0,0 → 1,131
/* |
* RTEMS Config display support |
* |
* TODO |
* |
* $Id: mon-config.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
|
#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); |
} |
/mon-server.c
0,0 → 1,303
/* |
* RTEMS monitor server (handles requests for info from RTEMS monitors |
* running on other nodes) |
* |
* $Id: mon-server.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#include <rtems.h> |
|
#include <stdio.h> |
#include <string.h> |
#include <stdlib.h> |
#include <unistd.h> |
|
#include <rtems/monitor.h> |
|
/* |
* Various id's for the server |
*/ |
|
rtems_id rtems_monitor_server_task_id; |
rtems_id rtems_monitor_server_request_queue_id; /* our server */ |
rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */ |
rtems_id rtems_monitor_server_response_queue_id; /* our server */ |
|
|
/* |
* Send a request to a server task |
*/ |
|
rtems_status_code |
rtems_monitor_server_request( |
unsigned32 server_node, |
rtems_monitor_server_request_t *request, |
rtems_monitor_server_response_t *response |
) |
{ |
rtems_id server_id; |
rtems_status_code status; |
unsigned32 size; |
|
/* |
* What is id of monitor on target node? |
* Look it up if we don't know it yet. |
*/ |
|
server_id = rtems_monitor_server_request_queue_ids[server_node]; |
if (server_id == 0) |
{ |
status = rtems_message_queue_ident(RTEMS_MONITOR_QUEUE_NAME, |
server_node, |
&server_id); |
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "ident of remote server failed"); |
goto done; |
} |
|
rtems_monitor_server_request_queue_ids[server_node] = server_id; |
} |
|
request->return_id = rtems_monitor_server_response_queue_id; |
|
status = rtems_message_queue_send(server_id, request, sizeof(*request)); |
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "monitor server request send failed"); |
goto done; |
} |
|
/* |
* Await response, if requested |
*/ |
|
if (response) |
{ |
status = rtems_message_queue_receive(rtems_monitor_server_response_queue_id, |
response, |
&size, |
RTEMS_WAIT, |
100); |
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "server did not respond"); |
|
/* maybe server task was restarted; look it up again next time */ |
rtems_monitor_server_request_queue_ids[server_node] = 0; |
|
goto done; |
} |
|
if (response->command != RTEMS_MONITOR_SERVER_RESPONSE) |
{ |
status = RTEMS_INCORRECT_STATE; |
goto done; |
} |
} |
|
done: |
return status; |
} |
|
|
|
/* |
* monitor server task |
*/ |
|
void |
rtems_monitor_server_task( |
rtems_task_argument monitor_flags |
) |
{ |
rtems_monitor_server_request_t request; |
rtems_monitor_server_response_t response; |
rtems_status_code status; |
unsigned32 size; |
|
for (;;) |
{ |
status = rtems_message_queue_receive( |
rtems_monitor_server_request_queue_id, |
&request, |
&size, |
RTEMS_WAIT, |
(rtems_interval) 0); |
|
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "monitor server msg queue receive error"); |
goto failed; |
} |
|
if (size != sizeof(request)) |
{ |
rtems_error(0, "monitor server bad size on receive"); |
goto failed; |
} |
|
switch (request.command) |
{ |
case RTEMS_MONITOR_SERVER_CANONICAL: |
{ |
rtems_monitor_object_type_t object_type; |
rtems_id id; |
rtems_id next_id; |
|
object_type = (rtems_monitor_object_type_t) request.argument0; |
id = (rtems_id) request.argument1; |
next_id = rtems_monitor_object_canonical_get(object_type, |
id, |
&response.payload, |
&size); |
|
response.command = RTEMS_MONITOR_SERVER_RESPONSE; |
response.result0 = next_id; |
response.result1 = size; |
|
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \ |
payload)) |
|
status = rtems_message_queue_send(request.return_id, |
&response, |
size + SERVER_OVERHEAD); |
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "response send failed"); |
goto failed; |
} |
break; |
} |
|
default: |
{ |
rtems_error(0, "invalid command to monitor server: %d", request.command); |
goto failed; |
} |
} |
} |
|
failed: |
rtems_task_delete(RTEMS_SELF); |
} |
|
|
/* |
* Kill off any old server |
* Not sure if this is useful, but it doesn't help |
*/ |
|
void |
rtems_monitor_server_kill(void) |
{ |
if (rtems_monitor_server_task_id) |
rtems_task_delete(rtems_monitor_server_task_id); |
rtems_monitor_server_task_id = 0; |
|
if (rtems_monitor_server_request_queue_id) |
rtems_message_queue_delete(rtems_monitor_server_request_queue_id); |
rtems_monitor_server_request_queue_ids = 0; |
|
if (rtems_monitor_server_response_queue_id) |
rtems_message_queue_delete(rtems_monitor_server_response_queue_id); |
rtems_monitor_server_response_queue_id = 0; |
|
if (rtems_monitor_server_request_queue_ids) |
free(rtems_monitor_server_request_queue_ids); |
rtems_monitor_server_request_queue_ids = 0; |
} |
|
|
void |
rtems_monitor_server_init( |
unsigned32 monitor_flags |
) |
{ |
rtems_status_code status; |
|
if (_System_state_Is_multiprocessing && |
(_Configuration_MP_table->maximum_nodes > 1)) |
{ |
unsigned32 maximum_nodes = _Configuration_MP_table->maximum_nodes; |
|
/* |
* create the msg que our server will listen |
* Since we only get msgs from other RTEMS monitors, we just |
* need reserve space for 1 msg from each node. |
*/ |
|
status = rtems_message_queue_create( |
RTEMS_MONITOR_QUEUE_NAME, |
maximum_nodes, |
sizeof(rtems_monitor_server_request_t), |
RTEMS_GLOBAL, |
&rtems_monitor_server_request_queue_id); |
|
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "could not create monitor server message queue"); |
goto done; |
} |
|
/* |
* create the msg que our responses will come on |
* Since monitor just does one thing at a time, we only need 1 item |
* message queue. |
*/ |
|
status = rtems_message_queue_create( |
RTEMS_MONITOR_RESPONSE_QUEUE_NAME, |
1, /* depth */ |
sizeof(rtems_monitor_server_response_t), |
RTEMS_GLOBAL, |
&rtems_monitor_server_response_queue_id); |
|
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "could not create monitor response message queue"); |
goto done; |
} |
|
/* need an id for queue of each other server we might talk to */ |
/* indexed by node, so add 1 to maximum_nodes */ |
rtems_monitor_server_request_queue_ids = |
(rtems_id *) malloc((maximum_nodes + 1) * sizeof(rtems_id)); |
(void) memset(rtems_monitor_server_request_queue_ids, |
0, |
(maximum_nodes + 1) * sizeof(rtems_id)); |
|
rtems_monitor_server_request_queue_ids[rtems_monitor_node] = |
rtems_monitor_server_request_queue_id; |
|
/* |
* create the server task |
*/ |
status = rtems_task_create(RTEMS_MONITOR_SERVER_NAME, |
1, |
0 /* default stack */, |
RTEMS_INTERRUPT_LEVEL(0), |
RTEMS_DEFAULT_ATTRIBUTES, |
&rtems_monitor_server_task_id); |
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "could not create monitor server task"); |
goto done; |
} |
|
/* |
* Start the server task |
*/ |
status = rtems_task_start(rtems_monitor_server_task_id, |
rtems_monitor_server_task, |
monitor_flags); |
if (status != RTEMS_SUCCESSFUL) |
{ |
rtems_error(status, "could not start monitor server"); |
goto done; |
} |
} |
|
done: |
return; |
} |
/mon-object.c
0,0 → 1,382
/* |
* 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: mon-object.c,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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; |
} |
/symbols.h
0,0 → 1,62
/* |
* RTEMS monitor symbol table functions |
* |
* Description: |
* Entry points for symbol table routines. |
* |
* |
* |
* TODO: |
* |
* $Id: symbols.h,v 1.2 2001-09-27 12:01:43 chris Exp $ |
*/ |
|
#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 */ |