forked from Imagelibrary/rtems
Numerous miscellaneous features incorporated from Tony Bennett
(tbennett@divnc.com) including the following major additions: + variable length messages + named devices + debug monitor + association tables/variables
This commit is contained in:
@@ -23,31 +23,24 @@ extern "C" {
|
||||
/* variables */
|
||||
|
||||
extern volatile rtems_unsigned32 Clock_driver_ticks;
|
||||
extern rtems_device_major_number rtems_clock_major;
|
||||
extern rtems_device_minor_number rtems_clock_minor;
|
||||
|
||||
/* functions */
|
||||
|
||||
rtems_task Exit_task();
|
||||
void exit_task_init();
|
||||
|
||||
void Install_clock( rtems_isr_entry );
|
||||
void ReInstall_clock( rtems_isr_entry );
|
||||
void Clock_exit();
|
||||
|
||||
rtems_isr Clock_isr(
|
||||
rtems_vector_number
|
||||
);
|
||||
|
||||
/* driver entries */
|
||||
/* default clock driver entry */
|
||||
|
||||
#define CLOCK_DRIVER_TABLE_ENTRY \
|
||||
{ Clock_initialize, NULL, NULL, NULL, NULL, NULL }
|
||||
|
||||
{ Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
|
||||
|
||||
rtems_device_driver Clock_initialize(
|
||||
rtems_device_major_number,
|
||||
rtems_device_minor_number,
|
||||
void *,
|
||||
rtems_id,
|
||||
rtems_unsigned32 *
|
||||
void *
|
||||
);
|
||||
|
||||
rtems_device_driver Clock_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
44
c/src/exec/libcsupport/include/rtems/assoc.h
Normal file
44
c/src/exec/libcsupport/include/rtems/assoc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @(#)assoc.h 1.2 - 95/06/28
|
||||
*
|
||||
*
|
||||
* Rtems associativity routines. Mainly used to convert a value from
|
||||
* one space to another (eg: our errno's to host errno's and v.v)
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_ASSOC_H
|
||||
#define _INCLUDE_ASSOC_H
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned32 local_value;
|
||||
unsigned32 remote_value;
|
||||
} rtems_assoc_t;
|
||||
|
||||
/*
|
||||
* Flag/marker for optional default value in each table
|
||||
*/
|
||||
|
||||
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
|
||||
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
|
||||
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
|
||||
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
|
||||
|
||||
|
||||
#endif /* ! _INCLUDE_ASSOC_H */
|
||||
26
c/src/exec/libcsupport/include/rtems/error.h
Normal file
26
c/src/exec/libcsupport/include/rtems/error.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @(#)error.h 1.1 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Defines and externs for rtems error reporting
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* rtems_error() and rtems_panic() support
|
||||
*/
|
||||
|
||||
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
||||
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
|
||||
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
|
||||
|
||||
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
|
||||
RTEMS_ERROR_PANIC) /* all */
|
||||
|
||||
char *rtems_status_text(rtems_status_code);
|
||||
int rtems_error(int error_code, char *printf_format, ...);
|
||||
void rtems_panic(char *printf_format, ...);
|
||||
|
||||
extern int rtems_panic_in_progress;
|
||||
|
||||
101
c/src/exec/libcsupport/include/rtems/libio.h
Normal file
101
c/src/exec/libcsupport/include/rtems/libio.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* @(#)libio.h 1.1 - 95/06/02
|
||||
*
|
||||
*
|
||||
* General purpose communication channel for RTEMS to allow UNIX/POSIX
|
||||
* system call behavior on top of RTEMS IO devices.
|
||||
*
|
||||
* TODO
|
||||
* stat(2)
|
||||
* unlink(2)
|
||||
* rename(2)
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_LIBIO_H
|
||||
#define _RTEMS_LIBIO_H
|
||||
|
||||
typedef unsigned32 rtems_libio_offset_t;
|
||||
|
||||
/*
|
||||
* An open file data structure, indexed by 'fd'
|
||||
* TODO:
|
||||
* should really have a separate per/file data structure that this
|
||||
* points to (eg: size, offset, driver, pathname should be in that)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_driver_name_t *driver;
|
||||
rtems_libio_offset_t size; /* size of file */
|
||||
rtems_libio_offset_t offset; /* current offset into the file */
|
||||
unsigned32 flags;
|
||||
char *pathname; /* opened pathname */
|
||||
Objects_Id sem;
|
||||
unsigned32 data0; /* private to "driver" */
|
||||
unsigned32 data1; /* ... */
|
||||
} rtems_libio_t;
|
||||
|
||||
|
||||
/*
|
||||
* param block for read/write
|
||||
* Note: it must include 'offset' instead of using iop's offset since
|
||||
* we can have multiple outstanding i/o's on a device.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
rtems_libio_offset_t offset;
|
||||
unsigned8 *buffer;
|
||||
unsigned32 count;
|
||||
unsigned32 flags;
|
||||
unsigned32 bytes_moved;
|
||||
} rtems_libio_rw_args_t;
|
||||
|
||||
/*
|
||||
* param block for open/close
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
unsigned32 flags;
|
||||
unsigned32 mode;
|
||||
} rtems_libio_open_close_args_t;
|
||||
|
||||
/*
|
||||
* param block for ioctl
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
unsigned32 command;
|
||||
void *buffer;
|
||||
unsigned32 ioctl_return;
|
||||
} rtems_libio_ioctl_args_t;
|
||||
|
||||
|
||||
/*
|
||||
* Values for 'flag'
|
||||
*/
|
||||
|
||||
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
|
||||
#define LIBIO_FLAGS_READ 0x0002 /* reading */
|
||||
#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
|
||||
#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */
|
||||
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
|
||||
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
|
||||
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
|
||||
|
||||
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
|
||||
|
||||
void rtems_libio_config(rtems_configuration_table *config, unsigned32 max_fds);
|
||||
void rtems_libio_init(void);
|
||||
|
||||
int __open(const char *pathname, unsigned32 flag, unsigned32 mode);
|
||||
int __close(int fd);
|
||||
int __read(int fd, void *buffer, unsigned32 count);
|
||||
int __write(int fd, const void *buffer, unsigned32 count);
|
||||
int __ioctl(int fd, unsigned32 command, void *buffer);
|
||||
int __lseek(int fd, rtems_libio_offset_t offset, int whence);
|
||||
|
||||
#endif /* _RTEMS_LIBIO_H */
|
||||
258
c/src/exec/libcsupport/src/assoc.c
Normal file
258
c/src/exec/libcsupport/src/assoc.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* @(#)assoc.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* assoc.c
|
||||
* rtems assoc routines
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <string.h> /* strcat, strcmp */
|
||||
|
||||
#define STREQ(a,b) (strcmp((a), (b)) == 0)
|
||||
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (strcmp(ap->name, name) == 0)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->local_value == local_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->remote_value == remote_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get values
|
||||
*/
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* what to return if a value is not found
|
||||
* this is not reentrant, but it really shouldn't be invoked anyway
|
||||
*/
|
||||
|
||||
char *
|
||||
rtems_assoc_name_bad(
|
||||
unsigned32 bad_value
|
||||
)
|
||||
{
|
||||
static char bad_buffer[32];
|
||||
|
||||
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
|
||||
return bad_buffer;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(local_value);
|
||||
}
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(remote_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitfield functions assume just 1 bit set in each of remote and local
|
||||
* entries; they do not check for this.
|
||||
*/
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 remote_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & local_value)
|
||||
remote_value |= rtems_assoc_remote_by_local(ap, b);
|
||||
|
||||
return remote_value;
|
||||
}
|
||||
|
||||
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 local_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & remote_value)
|
||||
local_value |= rtems_assoc_local_by_remote(ap, b);
|
||||
|
||||
return local_value;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_local(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
212
c/src/exec/libcsupport/src/error.c
Normal file
212
c/src/exec/libcsupport/src/error.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* @(#)error.c 1.2 - 95/08/02
|
||||
*
|
||||
*
|
||||
* report errors and panics to RTEMS' stderr.
|
||||
* Currently just used by RTEMS monitor.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* These routines provide general purpose error reporting.
|
||||
* rtems_error reports an error to stderr and allows use of
|
||||
* printf style formatting. A newline is appended to all messages.
|
||||
*
|
||||
* error_flag can be specified as any of the following:
|
||||
*
|
||||
* RTEMS_ERROR_ERRNO -- include errno text in output
|
||||
* RTEMS_ERROR_PANIC -- halts local system after output
|
||||
* RTEMS_ERROR_ABORT -- abort after output
|
||||
*
|
||||
* It can also include a rtems_status value which can be OR'd
|
||||
* with the above flags. *
|
||||
*
|
||||
* EXAMPLE
|
||||
* #include <rtems.h>
|
||||
* #include <rtems/error.h>
|
||||
* rtems_error(0, "stray interrupt %d", intr);
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
|
||||
* {
|
||||
* rtems_error(status | RTEMS_ERROR_ABORT,
|
||||
* "could not create task");
|
||||
* }
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((fd = open(pathname, O_RDNLY)) < 0)
|
||||
* {
|
||||
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
|
||||
* goto failed;
|
||||
* }
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* _exit() */
|
||||
|
||||
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
|
||||
#ifdef hpux9
|
||||
char *strerror(int);
|
||||
#endif
|
||||
|
||||
extern char *rtems_progname;
|
||||
int rtems_panic_in_progress;
|
||||
|
||||
rtems_assoc_t rtems_status_assoc[] = {
|
||||
{ "successful completion", RTEMS_SUCCESSFUL, },
|
||||
{ "returned from a thread", RTEMS_TASK_EXITTED, },
|
||||
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
|
||||
{ "invalid object name", RTEMS_INVALID_NAME, },
|
||||
{ "invalid object id", RTEMS_INVALID_ID, },
|
||||
{ "too many", RTEMS_TOO_MANY, },
|
||||
{ "timed out waiting", RTEMS_TIMEOUT, },
|
||||
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
|
||||
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
|
||||
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
|
||||
{ "number was invalid", RTEMS_INVALID_NUMBER, },
|
||||
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
|
||||
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
|
||||
{ "request not satisfied", RTEMS_UNSATISFIED, },
|
||||
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
|
||||
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
|
||||
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
|
||||
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
|
||||
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
|
||||
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
|
||||
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
|
||||
{ "invalid node id", RTEMS_INVALID_NODE, },
|
||||
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
|
||||
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
|
||||
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
|
||||
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
|
||||
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
|
||||
{ "could not get enough memory", RTEMS_NO_MEMORY, },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
rtems_status_text(
|
||||
rtems_status_code status
|
||||
)
|
||||
{
|
||||
return rtems_assoc_name_by_local(rtems_status_assoc, status);
|
||||
}
|
||||
|
||||
|
||||
static int rtems_verror(
|
||||
unsigned32 error_flag,
|
||||
char *printf_format,
|
||||
va_list arglist
|
||||
)
|
||||
{
|
||||
int local_errno = 0;
|
||||
int chars_written = 0;
|
||||
rtems_status_code status;
|
||||
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_panic_in_progress++;
|
||||
|
||||
/* disable task switches */
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/* don't aggravate things */
|
||||
if (rtems_panic_in_progress > 2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) fflush(stdout); /* in case stdout/stderr same */
|
||||
|
||||
status = error_flag & ~RTEMS_ERROR_MASK;
|
||||
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
|
||||
local_errno = errno;
|
||||
|
||||
if (_Configuration_Is_multiprocessing())
|
||||
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
|
||||
|
||||
if (rtems_progname && *rtems_progname)
|
||||
chars_written += fprintf(stderr, "%s: ", rtems_progname);
|
||||
chars_written += vfprintf(stderr, printf_format, arglist);
|
||||
|
||||
if (status)
|
||||
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
|
||||
|
||||
if (local_errno)
|
||||
if ((local_errno > 0) && *strerror(local_errno))
|
||||
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
|
||||
else
|
||||
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
|
||||
|
||||
chars_written += fprintf(stderr, "\n");
|
||||
|
||||
(void) fflush(stderr);
|
||||
|
||||
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
|
||||
{
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_error(0, "fatal error, exiting");
|
||||
_exit(local_errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_error(0, "fatal error, aborting");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Report an error.
|
||||
* error_flag is as above; printf_format is a normal
|
||||
* printf(3) format string, with its concommitant arguments.
|
||||
*
|
||||
* Returns the number of characters written.
|
||||
*/
|
||||
|
||||
int rtems_error(
|
||||
int error_flag,
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
int chars_written;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
chars_written = rtems_verror(error_flag, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
|
||||
*/
|
||||
|
||||
void rtems_panic(
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
433
c/src/exec/libcsupport/src/libio.c
Normal file
433
c/src/exec/libcsupport/src/libio.c
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* @(#)libio.c 1.1 - 95/06/02
|
||||
*
|
||||
*
|
||||
* Provide UNIX/POSIX-like io system calls for RTEMS using the
|
||||
* RTEMS IO manager
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
|
||||
|
||||
#include <fcntl.h> /* O_RDONLY, et.al. */
|
||||
#if defined(solaris2)
|
||||
#define O_NDELAY O_NONBLOCK
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h> /* strcmp */
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h> /* calloc() */
|
||||
|
||||
#include "libio.h" /* libio.h not pulled in by rtems */
|
||||
|
||||
/*
|
||||
* Semaphore to protect the io table
|
||||
*/
|
||||
|
||||
Objects_Id rtems_libio_semaphore;
|
||||
|
||||
#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
|
||||
#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
|
||||
|
||||
unsigned32 rtems_libio_number_iops;
|
||||
rtems_libio_t *rtems_libio_iops;
|
||||
rtems_libio_t *rtems_libio_last_iop;
|
||||
|
||||
#define rtems_libio_iop(fd) ((((unsigned32)(fd)) < rtems_libio_number_iops) ? \
|
||||
&rtems_libio_iops[fd] : 0)
|
||||
|
||||
#define rtems_libio_check_fd(fd) \
|
||||
do { \
|
||||
if ((fd) >= rtems_libio_number_iops) \
|
||||
{ \
|
||||
errno = EBADF; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rtems_libio_check_buffer(buffer) \
|
||||
do { \
|
||||
if ((buffer) == 0) \
|
||||
{ \
|
||||
errno = EINVAL; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rtems_libio_check_count(count) \
|
||||
do { \
|
||||
if ((count) == 0) \
|
||||
{ \
|
||||
return 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rtems_libio_check_permissions(iop, flag) \
|
||||
do { \
|
||||
if (((iop)->flags & (flag)) == 0) \
|
||||
{ \
|
||||
errno = EINVAL; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
void
|
||||
rtems_libio_config(
|
||||
rtems_configuration_table *config,
|
||||
unsigned32 max_fds
|
||||
)
|
||||
{
|
||||
rtems_libio_number_iops = max_fds;
|
||||
|
||||
/*
|
||||
* tweak config to reflect # of semaphores we will need
|
||||
*/
|
||||
|
||||
config->maximum_semaphores += 1; /* one for iop table */
|
||||
config->maximum_semaphores += max_fds;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by bsp startup code to init the libio area.
|
||||
*/
|
||||
|
||||
void
|
||||
rtems_libio_init(void)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
|
||||
if (rtems_libio_number_iops > 0)
|
||||
{
|
||||
rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
|
||||
sizeof(rtems_libio_t));
|
||||
if (rtems_libio_iops == NULL)
|
||||
rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
|
||||
|
||||
rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
|
||||
}
|
||||
|
||||
rc = rtems_semaphore_create(RTEMS_LIBIO_SEM,
|
||||
1,
|
||||
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
&rtems_libio_semaphore);
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert RTEMS status to a UNIX errno
|
||||
*/
|
||||
|
||||
rtems_assoc_t errno_assoc[] = {
|
||||
{ "OK", RTEMS_SUCCESSFUL, 0 },
|
||||
{ "TIMEOUT", RTEMS_TIMEOUT, ETIME },
|
||||
{ "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static unsigned32
|
||||
rtems_libio_errno(rtems_status_code code)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = rtems_assoc_remote_by_local(errno_assoc, (unsigned32) code)))
|
||||
{
|
||||
errno = rc;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
|
||||
*/
|
||||
|
||||
rtems_assoc_t access_modes_assoc[] = {
|
||||
{ "READ", LIBIO_FLAGS_READ, O_RDONLY },
|
||||
{ "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
|
||||
{ "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
rtems_assoc_t status_flags_assoc[] = {
|
||||
{ "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
|
||||
{ "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
|
||||
{ "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static unsigned32
|
||||
rtems_libio_fcntl_flags(unsigned32 fcntl_flags)
|
||||
{
|
||||
unsigned32 flags = 0;
|
||||
unsigned32 access_modes;
|
||||
|
||||
/*
|
||||
* Access mode is a small integer
|
||||
*/
|
||||
|
||||
access_modes = fcntl_flags & O_ACCMODE;
|
||||
fcntl_flags &= ~O_ACCMODE;
|
||||
flags = rtems_assoc_local_by_remote(access_modes_assoc, access_modes);
|
||||
|
||||
/*
|
||||
* Everything else is single bits
|
||||
*/
|
||||
|
||||
flags |= rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
static rtems_libio_t *
|
||||
rtems_libio_allocate(void)
|
||||
{
|
||||
rtems_libio_t *iop;
|
||||
rtems_status_code rc;
|
||||
|
||||
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
|
||||
if ((iop->flags & LIBIO_FLAGS_OPEN) == 0)
|
||||
{
|
||||
/*
|
||||
* Got one; create a semaphore for it
|
||||
*/
|
||||
|
||||
rc = rtems_semaphore_create(RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
|
||||
1, RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
&iop->sem);
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
goto failed;
|
||||
|
||||
iop->flags = LIBIO_FLAGS_OPEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
failed:
|
||||
iop = 0;
|
||||
|
||||
done:
|
||||
rtems_semaphore_release(rtems_libio_semaphore);
|
||||
return iop;
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_libio_free(rtems_libio_t *iop)
|
||||
{
|
||||
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
if (iop->sem)
|
||||
rtems_semaphore_delete(iop->sem);
|
||||
(void) memset(iop, 0, sizeof(*iop));
|
||||
|
||||
rtems_semaphore_release(rtems_libio_semaphore);
|
||||
}
|
||||
|
||||
int
|
||||
__open(
|
||||
const char *pathname,
|
||||
unsigned32 flag,
|
||||
unsigned32 mode)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_libio_t *iop = 0;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_open_close_args_t args;
|
||||
|
||||
if ((rc = rtems_io_lookup_name(pathname, &np)) != RTEMS_SUCCESSFUL)
|
||||
goto done;
|
||||
|
||||
iop = rtems_libio_allocate();
|
||||
if (iop == 0)
|
||||
{
|
||||
rc = RTEMS_TOO_MANY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
iop->driver = np;
|
||||
iop->pathname = (char *) pathname;
|
||||
iop->flags |= rtems_libio_fcntl_flags(flag);
|
||||
|
||||
args.iop = iop;
|
||||
args.flags = iop->flags;
|
||||
args.mode = mode;
|
||||
|
||||
rc = rtems_io_open(np->major, np->minor, (void *) &args);
|
||||
|
||||
done:
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
if (iop)
|
||||
rtems_libio_free(iop);
|
||||
return rtems_libio_errno(rc);
|
||||
}
|
||||
|
||||
return iop - rtems_libio_iops;
|
||||
}
|
||||
|
||||
int
|
||||
__close(
|
||||
int fd
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_open_close_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.flags = 0;
|
||||
args.mode = 0;
|
||||
|
||||
rc = rtems_io_close(np->major, np->minor, (void *) &args);
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__read(
|
||||
int fd,
|
||||
void * buffer,
|
||||
unsigned32 count
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_rw_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
rtems_libio_check_buffer(buffer);
|
||||
rtems_libio_check_count(count);
|
||||
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.offset = iop->offset;
|
||||
args.buffer = buffer;
|
||||
args.count = count;
|
||||
args.flags = iop->flags;
|
||||
args.bytes_moved = 0;
|
||||
|
||||
rc = rtems_io_read(np->major, np->minor, (void *) &args);
|
||||
|
||||
iop->offset += args.bytes_moved;
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
|
||||
return args.bytes_moved;
|
||||
}
|
||||
|
||||
int
|
||||
__write(
|
||||
int fd,
|
||||
const void *buffer,
|
||||
unsigned32 count
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_rw_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
rtems_libio_check_buffer(buffer);
|
||||
rtems_libio_check_count(count);
|
||||
rtems_libio_check_permissions(iop, LIBIO_FLAGS_WRITE);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.offset = iop->offset;
|
||||
args.buffer = (void *) buffer;
|
||||
args.count = count;
|
||||
args.flags = iop->flags;
|
||||
args.bytes_moved = 0;
|
||||
|
||||
rc = rtems_io_write(np->major, np->minor, (void *) &args);
|
||||
|
||||
iop->offset += args.bytes_moved;
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
|
||||
return args.bytes_moved;
|
||||
}
|
||||
|
||||
int
|
||||
__ioctl(
|
||||
int fd,
|
||||
unsigned32 command,
|
||||
void * buffer)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_ioctl_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.command = command;
|
||||
args.buffer = buffer;
|
||||
|
||||
rc = rtems_io_control(np->major, np->minor, (void *) &args);
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
|
||||
return args.ioctl_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* internal only??
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
__lseek(
|
||||
int fd,
|
||||
rtems_libio_offset_t offset,
|
||||
int whence
|
||||
)
|
||||
{
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
iop->offset = offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
iop->offset += offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
iop->offset = iop->size - offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -41,14 +41,22 @@ extern "C" {
|
||||
/*
|
||||
* The following defines the data types needed to manipulate
|
||||
* the contents of message buffers.
|
||||
* Since msgs are variable length we just make a ptr to 1.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned32 field1;
|
||||
unsigned32 field2;
|
||||
unsigned32 field3;
|
||||
unsigned32 field4;
|
||||
} Message_queue_Buffer;
|
||||
unsigned32 size;
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* NOTE: [0] is gcc specific,
|
||||
* but specifically disallowed by ANSI STD C++
|
||||
* g++ warns about it, so we #ifdef it out to
|
||||
* get rid of warnings when compiled by g++.
|
||||
*/
|
||||
unsigned32 buffer[0];
|
||||
#endif
|
||||
|
||||
} Message_queue_Buffer;
|
||||
|
||||
/*
|
||||
* The following records define the organization of a message
|
||||
@@ -68,10 +76,13 @@ typedef struct {
|
||||
typedef struct {
|
||||
Objects_Control Object;
|
||||
Thread_queue_Control Wait_queue;
|
||||
rtems_attribute attribute_set;
|
||||
rtems_attribute attribute_set;
|
||||
unsigned32 maximum_pending_messages;
|
||||
unsigned32 number_of_pending_messages;
|
||||
unsigned32 maximum_message_size;
|
||||
Chain_Control Pending_messages;
|
||||
Message_queue_Buffer *message_buffers;
|
||||
Chain_Control Inactive_messages;
|
||||
} Message_queue_Control;
|
||||
|
||||
/*
|
||||
@@ -81,13 +92,6 @@ typedef struct {
|
||||
|
||||
EXTERN Objects_Information _Message_queue_Information;
|
||||
|
||||
/*
|
||||
* The following defines the data structures used to
|
||||
* manage the pool of inactive message buffers.
|
||||
*/
|
||||
|
||||
EXTERN Chain_Control _Message_queue_Inactive_messages;
|
||||
|
||||
/*
|
||||
* The following enumerated type details the modes in which a message
|
||||
* may be submitted to a message queue. The message may be posted
|
||||
@@ -108,8 +112,7 @@ typedef enum {
|
||||
*/
|
||||
|
||||
void _Message_queue_Manager_initialization(
|
||||
unsigned32 maximum_message_queues,
|
||||
unsigned32 maximum_messages
|
||||
unsigned32 maximum_message_queues
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -126,10 +129,11 @@ void _Message_queue_Manager_initialization(
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_message_queue_create(
|
||||
Objects_Name name,
|
||||
unsigned32 count,
|
||||
Objects_Name name,
|
||||
unsigned32 count,
|
||||
unsigned32 max_message_size,
|
||||
rtems_attribute attribute_set,
|
||||
Objects_Id *id
|
||||
Objects_Id *id
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -183,7 +187,8 @@ rtems_status_code rtems_message_queue_delete(
|
||||
|
||||
rtems_status_code rtems_message_queue_send(
|
||||
Objects_Id id,
|
||||
void *buffer
|
||||
void *buffer,
|
||||
unsigned32 size
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -204,7 +209,8 @@ rtems_status_code rtems_message_queue_send(
|
||||
|
||||
rtems_status_code rtems_message_queue_urgent(
|
||||
Objects_Id id,
|
||||
void *buffer
|
||||
void *buffer,
|
||||
unsigned32 size
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -226,6 +232,7 @@ rtems_status_code rtems_message_queue_urgent(
|
||||
rtems_status_code rtems_message_queue_broadcast(
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
unsigned32 *count
|
||||
);
|
||||
|
||||
@@ -246,8 +253,9 @@ rtems_status_code rtems_message_queue_broadcast(
|
||||
rtems_status_code rtems_message_queue_receive(
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 *size_p,
|
||||
unsigned32 option_set,
|
||||
rtems_interval timeout
|
||||
rtems_interval timeout
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -276,8 +284,9 @@ rtems_status_code rtems_message_queue_flush(
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
Message_queue_Buffer *source,
|
||||
Message_queue_Buffer *destination
|
||||
void *source,
|
||||
void *destination,
|
||||
unsigned32 size
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -295,7 +304,8 @@ STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
boolean _Message_queue_Seize(
|
||||
Message_queue_Control *the_message_queue,
|
||||
unsigned32 option_set,
|
||||
Message_queue_Buffer *buffer
|
||||
void *buffer,
|
||||
unsigned32 *size_p
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -322,7 +332,8 @@ unsigned32 _Message_queue_Flush_support(
|
||||
|
||||
rtems_status_code _Message_queue_Submit(
|
||||
Objects_Id id,
|
||||
Message_queue_Buffer *buffer,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Message_queue_Submit_types submit_type
|
||||
);
|
||||
|
||||
@@ -336,7 +347,9 @@ rtems_status_code _Message_queue_Submit(
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Buffer_control *
|
||||
_Message_queue_Allocate_message_buffer ( void );
|
||||
_Message_queue_Allocate_message_buffer (
|
||||
Message_queue_Control *the_message_queue
|
||||
);
|
||||
|
||||
/*
|
||||
* _Message_queue_Free_message_buffer
|
||||
@@ -348,6 +361,7 @@ STATIC INLINE Message_queue_Buffer_control *
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Free_message_buffer (
|
||||
Message_queue_Control *the_message_queue,
|
||||
Message_queue_Buffer_control *the_message
|
||||
);
|
||||
|
||||
@@ -415,14 +429,17 @@ STATIC INLINE boolean _Message_queue_Is_null (
|
||||
* the inactive chain of free message queue control blocks.
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void );
|
||||
Message_queue_Control *_Message_queue_Allocate (
|
||||
unsigned32 count,
|
||||
unsigned32 max_message_size
|
||||
);
|
||||
|
||||
/*
|
||||
* _Message_queue_Free
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine allocates a message queue control block from
|
||||
* This routine deallocates a message queue control block into
|
||||
* the inactive chain of free message queue control blocks.
|
||||
*/
|
||||
|
||||
|
||||
@@ -55,15 +55,14 @@ typedef enum {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_packet_prefix Prefix;
|
||||
rtems_packet_prefix Prefix;
|
||||
Message_queue_MP_Remote_operations operation;
|
||||
Objects_Name name;
|
||||
rtems_option option_set;
|
||||
rtems_option option_set;
|
||||
Objects_Id proxy_id;
|
||||
unsigned32 count;
|
||||
unsigned32 size;
|
||||
unsigned32 pad0;
|
||||
unsigned32 pad1;
|
||||
unsigned32 pad2;
|
||||
Message_queue_Buffer Buffer;
|
||||
} Message_queue_MP_Packet;
|
||||
|
||||
@@ -95,9 +94,10 @@ void _Message_queue_MP_Send_process_packet (
|
||||
rtems_status_code _Message_queue_MP_Send_request_packet (
|
||||
Message_queue_MP_Remote_operations operation,
|
||||
Objects_Id message_queue_id,
|
||||
Message_queue_Buffer *buffer,
|
||||
rtems_option option_set,
|
||||
rtems_interval timeout
|
||||
void *buffer,
|
||||
unsigned32 *size_p,
|
||||
rtems_option option_set,
|
||||
rtems_interval timeout
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -41,14 +41,22 @@ extern "C" {
|
||||
/*
|
||||
* The following defines the data types needed to manipulate
|
||||
* the contents of message buffers.
|
||||
* Since msgs are variable length we just make a ptr to 1.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned32 field1;
|
||||
unsigned32 field2;
|
||||
unsigned32 field3;
|
||||
unsigned32 field4;
|
||||
} Message_queue_Buffer;
|
||||
unsigned32 size;
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* NOTE: [0] is gcc specific,
|
||||
* but specifically disallowed by ANSI STD C++
|
||||
* g++ warns about it, so we #ifdef it out to
|
||||
* get rid of warnings when compiled by g++.
|
||||
*/
|
||||
unsigned32 buffer[0];
|
||||
#endif
|
||||
|
||||
} Message_queue_Buffer;
|
||||
|
||||
/*
|
||||
* The following records define the organization of a message
|
||||
@@ -68,10 +76,13 @@ typedef struct {
|
||||
typedef struct {
|
||||
Objects_Control Object;
|
||||
Thread_queue_Control Wait_queue;
|
||||
rtems_attribute attribute_set;
|
||||
rtems_attribute attribute_set;
|
||||
unsigned32 maximum_pending_messages;
|
||||
unsigned32 number_of_pending_messages;
|
||||
unsigned32 maximum_message_size;
|
||||
Chain_Control Pending_messages;
|
||||
Message_queue_Buffer *message_buffers;
|
||||
Chain_Control Inactive_messages;
|
||||
} Message_queue_Control;
|
||||
|
||||
/*
|
||||
@@ -81,13 +92,6 @@ typedef struct {
|
||||
|
||||
EXTERN Objects_Information _Message_queue_Information;
|
||||
|
||||
/*
|
||||
* The following defines the data structures used to
|
||||
* manage the pool of inactive message buffers.
|
||||
*/
|
||||
|
||||
EXTERN Chain_Control _Message_queue_Inactive_messages;
|
||||
|
||||
/*
|
||||
* The following enumerated type details the modes in which a message
|
||||
* may be submitted to a message queue. The message may be posted
|
||||
@@ -108,8 +112,7 @@ typedef enum {
|
||||
*/
|
||||
|
||||
void _Message_queue_Manager_initialization(
|
||||
unsigned32 maximum_message_queues,
|
||||
unsigned32 maximum_messages
|
||||
unsigned32 maximum_message_queues
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -126,10 +129,11 @@ void _Message_queue_Manager_initialization(
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_message_queue_create(
|
||||
Objects_Name name,
|
||||
unsigned32 count,
|
||||
Objects_Name name,
|
||||
unsigned32 count,
|
||||
unsigned32 max_message_size,
|
||||
rtems_attribute attribute_set,
|
||||
Objects_Id *id
|
||||
Objects_Id *id
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -183,7 +187,8 @@ rtems_status_code rtems_message_queue_delete(
|
||||
|
||||
rtems_status_code rtems_message_queue_send(
|
||||
Objects_Id id,
|
||||
void *buffer
|
||||
void *buffer,
|
||||
unsigned32 size
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -204,7 +209,8 @@ rtems_status_code rtems_message_queue_send(
|
||||
|
||||
rtems_status_code rtems_message_queue_urgent(
|
||||
Objects_Id id,
|
||||
void *buffer
|
||||
void *buffer,
|
||||
unsigned32 size
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -226,6 +232,7 @@ rtems_status_code rtems_message_queue_urgent(
|
||||
rtems_status_code rtems_message_queue_broadcast(
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
unsigned32 *count
|
||||
);
|
||||
|
||||
@@ -246,8 +253,9 @@ rtems_status_code rtems_message_queue_broadcast(
|
||||
rtems_status_code rtems_message_queue_receive(
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 *size_p,
|
||||
unsigned32 option_set,
|
||||
rtems_interval timeout
|
||||
rtems_interval timeout
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -276,8 +284,9 @@ rtems_status_code rtems_message_queue_flush(
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
Message_queue_Buffer *source,
|
||||
Message_queue_Buffer *destination
|
||||
void *source,
|
||||
void *destination,
|
||||
unsigned32 size
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -295,7 +304,8 @@ STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
boolean _Message_queue_Seize(
|
||||
Message_queue_Control *the_message_queue,
|
||||
unsigned32 option_set,
|
||||
Message_queue_Buffer *buffer
|
||||
void *buffer,
|
||||
unsigned32 *size_p
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -322,7 +332,8 @@ unsigned32 _Message_queue_Flush_support(
|
||||
|
||||
rtems_status_code _Message_queue_Submit(
|
||||
Objects_Id id,
|
||||
Message_queue_Buffer *buffer,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Message_queue_Submit_types submit_type
|
||||
);
|
||||
|
||||
@@ -336,7 +347,9 @@ rtems_status_code _Message_queue_Submit(
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Buffer_control *
|
||||
_Message_queue_Allocate_message_buffer ( void );
|
||||
_Message_queue_Allocate_message_buffer (
|
||||
Message_queue_Control *the_message_queue
|
||||
);
|
||||
|
||||
/*
|
||||
* _Message_queue_Free_message_buffer
|
||||
@@ -348,6 +361,7 @@ STATIC INLINE Message_queue_Buffer_control *
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Free_message_buffer (
|
||||
Message_queue_Control *the_message_queue,
|
||||
Message_queue_Buffer_control *the_message
|
||||
);
|
||||
|
||||
@@ -415,14 +429,17 @@ STATIC INLINE boolean _Message_queue_Is_null (
|
||||
* the inactive chain of free message queue control blocks.
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void );
|
||||
Message_queue_Control *_Message_queue_Allocate (
|
||||
unsigned32 count,
|
||||
unsigned32 max_message_size
|
||||
);
|
||||
|
||||
/*
|
||||
* _Message_queue_Free
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine allocates a message queue control block from
|
||||
* This routine deallocates a message queue control block into
|
||||
* the inactive chain of free message queue control blocks.
|
||||
*/
|
||||
|
||||
|
||||
@@ -55,15 +55,14 @@ typedef enum {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_packet_prefix Prefix;
|
||||
rtems_packet_prefix Prefix;
|
||||
Message_queue_MP_Remote_operations operation;
|
||||
Objects_Name name;
|
||||
rtems_option option_set;
|
||||
rtems_option option_set;
|
||||
Objects_Id proxy_id;
|
||||
unsigned32 count;
|
||||
unsigned32 size;
|
||||
unsigned32 pad0;
|
||||
unsigned32 pad1;
|
||||
unsigned32 pad2;
|
||||
Message_queue_Buffer Buffer;
|
||||
} Message_queue_MP_Packet;
|
||||
|
||||
@@ -95,9 +94,10 @@ void _Message_queue_MP_Send_process_packet (
|
||||
rtems_status_code _Message_queue_MP_Send_request_packet (
|
||||
Message_queue_MP_Remote_operations operation,
|
||||
Objects_Id message_queue_id,
|
||||
Message_queue_Buffer *buffer,
|
||||
rtems_option option_set,
|
||||
rtems_interval timeout
|
||||
void *buffer,
|
||||
unsigned32 *size_p,
|
||||
rtems_option option_set,
|
||||
rtems_interval timeout
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -82,19 +82,6 @@ STATIC INLINE boolean _Attributes_Is_priority(
|
||||
return ( attribute_set & RTEMS_PRIORITY );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_limit
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE boolean _Attributes_Is_limit(
|
||||
rtems_attribute attribute_set
|
||||
)
|
||||
{
|
||||
return ( attribute_set & RTEMS_LIMIT );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_binary_semaphore
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef __MESSAGE_QUEUE_inl
|
||||
#define __MESSAGE_QUEUE_inl
|
||||
|
||||
#include <rtems/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Message_queue_Copy_buffer
|
||||
@@ -24,11 +26,12 @@
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
Message_queue_Buffer *source,
|
||||
Message_queue_Buffer *destination
|
||||
void *source,
|
||||
void *destination,
|
||||
unsigned32 size
|
||||
)
|
||||
{
|
||||
*destination = *source;
|
||||
memcpy(destination, source, size);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -38,10 +41,12 @@ STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Buffer_control *
|
||||
_Message_queue_Allocate_message_buffer ( void )
|
||||
_Message_queue_Allocate_message_buffer (
|
||||
Message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
return (Message_queue_Buffer_control *)
|
||||
_Chain_Get( &_Message_queue_Inactive_messages );
|
||||
_Chain_Get( &the_message_queue->Inactive_messages );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -51,10 +56,11 @@ STATIC INLINE Message_queue_Buffer_control *
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Free_message_buffer (
|
||||
Message_queue_Buffer_control *the_message
|
||||
Message_queue_Control *the_message_queue,
|
||||
Message_queue_Buffer_control *the_message
|
||||
)
|
||||
{
|
||||
_Chain_Append( &_Message_queue_Inactive_messages, &the_message->Node );
|
||||
_Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -116,17 +122,6 @@ STATIC INLINE boolean _Message_queue_Is_null (
|
||||
return ( the_message_queue == NULL );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Message_queue_Allocate
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void )
|
||||
{
|
||||
return (Message_queue_Control *)
|
||||
_Objects_Allocate( &_Message_queue_Information );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -138,6 +133,12 @@ STATIC INLINE void _Message_queue_Free (
|
||||
Message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
if (the_message_queue->message_buffers)
|
||||
{
|
||||
_Workspace_Free((void *) the_message_queue->message_buffers);
|
||||
the_message_queue->message_buffers = 0;
|
||||
}
|
||||
|
||||
_Objects_Free( &_Message_queue_Information, &the_message_queue->Object );
|
||||
}
|
||||
|
||||
|
||||
@@ -82,19 +82,6 @@ STATIC INLINE boolean _Attributes_Is_priority(
|
||||
return ( attribute_set & RTEMS_PRIORITY );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_limit
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE boolean _Attributes_Is_limit(
|
||||
rtems_attribute attribute_set
|
||||
)
|
||||
{
|
||||
return ( attribute_set & RTEMS_LIMIT );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_binary_semaphore
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef __MESSAGE_QUEUE_inl
|
||||
#define __MESSAGE_QUEUE_inl
|
||||
|
||||
#include <rtems/wkspace.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Message_queue_Copy_buffer
|
||||
@@ -24,11 +26,12 @@
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
Message_queue_Buffer *source,
|
||||
Message_queue_Buffer *destination
|
||||
void *source,
|
||||
void *destination,
|
||||
unsigned32 size
|
||||
)
|
||||
{
|
||||
*destination = *source;
|
||||
memcpy(destination, source, size);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -38,10 +41,12 @@ STATIC INLINE void _Message_queue_Copy_buffer (
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Buffer_control *
|
||||
_Message_queue_Allocate_message_buffer ( void )
|
||||
_Message_queue_Allocate_message_buffer (
|
||||
Message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
return (Message_queue_Buffer_control *)
|
||||
_Chain_Get( &_Message_queue_Inactive_messages );
|
||||
_Chain_Get( &the_message_queue->Inactive_messages );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -51,10 +56,11 @@ STATIC INLINE Message_queue_Buffer_control *
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Message_queue_Free_message_buffer (
|
||||
Message_queue_Buffer_control *the_message
|
||||
Message_queue_Control *the_message_queue,
|
||||
Message_queue_Buffer_control *the_message
|
||||
)
|
||||
{
|
||||
_Chain_Append( &_Message_queue_Inactive_messages, &the_message->Node );
|
||||
_Chain_Append( &the_message_queue->Inactive_messages, &the_message->Node );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -116,17 +122,6 @@ STATIC INLINE boolean _Message_queue_Is_null (
|
||||
return ( the_message_queue == NULL );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Message_queue_Allocate
|
||||
*
|
||||
*/
|
||||
|
||||
STATIC INLINE Message_queue_Control *_Message_queue_Allocate ( void )
|
||||
{
|
||||
return (Message_queue_Control *)
|
||||
_Objects_Allocate( &_Message_queue_Information );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -138,6 +133,12 @@ STATIC INLINE void _Message_queue_Free (
|
||||
Message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
if (the_message_queue->message_buffers)
|
||||
{
|
||||
_Workspace_Free((void *) the_message_queue->message_buffers);
|
||||
the_message_queue->message_buffers = 0;
|
||||
}
|
||||
|
||||
_Objects_Free( &_Message_queue_Information, &the_message_queue->Object );
|
||||
}
|
||||
|
||||
|
||||
@@ -60,15 +60,6 @@
|
||||
#define _Attributes_Is_priority( _attribute_set ) \
|
||||
( (_attribute_set) & RTEMS_PRIORITY )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_limit
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Attributes_Is_limit( _attribute_set ) \
|
||||
( (_attribute_set) & RTEMS_LIMIT )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_binary_semaphore
|
||||
|
||||
@@ -60,15 +60,6 @@
|
||||
#define _Attributes_Is_priority( _attribute_set ) \
|
||||
( (_attribute_set) & RTEMS_PRIORITY )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_limit
|
||||
*
|
||||
*/
|
||||
|
||||
#define _Attributes_Is_limit( _attribute_set ) \
|
||||
( (_attribute_set) & RTEMS_LIMIT )
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Attributes_Is_binary_semaphore
|
||||
|
||||
@@ -26,8 +26,7 @@
|
||||
#include <rtems/wkspace.h>
|
||||
|
||||
void _Message_queue_Manager_initialization(
|
||||
unsigned32 maximum_message_queues,
|
||||
unsigned32 maximum_messages
|
||||
unsigned32 maximum_message_queues
|
||||
)
|
||||
{
|
||||
}
|
||||
@@ -35,7 +34,8 @@ void _Message_queue_Manager_initialization(
|
||||
rtems_status_code rtems_message_queue_create(
|
||||
Objects_Name name,
|
||||
unsigned32 count,
|
||||
rtems_attribute attribute_set,
|
||||
unsigned32 max_message_size,
|
||||
rtems_attribute attribute_set,
|
||||
Objects_Id *id
|
||||
)
|
||||
{
|
||||
@@ -60,7 +60,8 @@ rtems_status_code rtems_message_queue_delete(
|
||||
|
||||
rtems_status_code rtems_message_queue_send(
|
||||
Objects_Id id,
|
||||
void *buffer
|
||||
void *buffer,
|
||||
unsigned32 size
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -68,7 +69,8 @@ rtems_status_code rtems_message_queue_send(
|
||||
|
||||
rtems_status_code rtems_message_queue_urgent(
|
||||
Objects_Id id,
|
||||
void *buffer
|
||||
void *buffer,
|
||||
unsigned32 size
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -77,6 +79,7 @@ rtems_status_code rtems_message_queue_urgent(
|
||||
rtems_status_code rtems_message_queue_broadcast(
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
unsigned32 *count
|
||||
)
|
||||
{
|
||||
@@ -86,8 +89,9 @@ rtems_status_code rtems_message_queue_broadcast(
|
||||
rtems_status_code rtems_message_queue_receive(
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 *size_p,
|
||||
unsigned32 option_set,
|
||||
rtems_interval timeout
|
||||
rtems_interval timeout
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -110,8 +114,9 @@ unsigned32 _Message_queue_Flush_support(
|
||||
|
||||
boolean _Message_queue_Seize(
|
||||
Message_queue_Control *the_message_queue,
|
||||
rtems_option option_set,
|
||||
Message_queue_Buffer *buffer
|
||||
rtems_option option_set,
|
||||
void *buffer,
|
||||
unsigned32 *size_p
|
||||
)
|
||||
{
|
||||
_Thread_Executing->Wait.return_code = RTEMS_UNSATISFIED;
|
||||
@@ -120,7 +125,8 @@ boolean _Message_queue_Seize(
|
||||
|
||||
rtems_status_code _Message_queue_Submit(
|
||||
Objects_Id id,
|
||||
Message_queue_Buffer *buffer,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Message_queue_Submit_types submit_type
|
||||
)
|
||||
{
|
||||
|
||||
@@ -32,14 +32,14 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Objects_Name name; /* task name */
|
||||
unsigned32 stack_size; /* task stack size */
|
||||
Objects_Name name; /* task name */
|
||||
unsigned32 stack_size; /* task stack size */
|
||||
rtems_task_priority initial_priority; /* task priority */
|
||||
rtems_attribute attribute_set; /* task attributes */
|
||||
rtems_task_entry entry_point; /* task entry point */
|
||||
rtems_mode mode_set; /* task initial mode */
|
||||
unsigned32 argument; /* task argument */
|
||||
} rtems_initialization_tasks_table;
|
||||
rtems_attribute attribute_set; /* task attributes */
|
||||
rtems_task_entry entry_point; /* task entry point */
|
||||
rtems_mode mode_set; /* task initial mode */
|
||||
unsigned32 argument; /* task argument */
|
||||
} rtems_initialization_tasks_table;
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -56,14 +56,12 @@ typedef struct {
|
||||
typedef unsigned32 rtems_device_major_number;
|
||||
typedef unsigned32 rtems_device_minor_number;
|
||||
|
||||
typedef void rtems_device_driver;
|
||||
typedef rtems_status_code rtems_device_driver;
|
||||
|
||||
typedef rtems_device_driver ( *rtems_device_driver_entry )(
|
||||
rtems_device_major_number,
|
||||
rtems_device_minor_number,
|
||||
void *,
|
||||
Objects_Id,
|
||||
unsigned32 *
|
||||
void *
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
@@ -173,12 +171,13 @@ typedef rtems_mpci_entry ( *rtems_mpci_receive_entry )(
|
||||
|
||||
typedef struct {
|
||||
unsigned32 default_timeout; /* in ticks */
|
||||
unsigned32 maximum_packet_size;
|
||||
rtems_mpci_initialization_entry initialization;
|
||||
rtems_mpci_get_packet_entry get_packet;
|
||||
rtems_mpci_return_packet_entry return_packet;
|
||||
rtems_mpci_send_entry send_packet;
|
||||
rtems_mpci_receive_entry receive_packet;
|
||||
} rtems_mpci_table;
|
||||
} rtems_mpci_table;
|
||||
|
||||
/*
|
||||
* The following records define the Multiprocessor Configuration
|
||||
@@ -192,8 +191,7 @@ struct Configuration_Table_MP {
|
||||
unsigned32 maximum_nodes; /* maximum # nodes in system */
|
||||
unsigned32 maximum_global_objects; /* maximum # global objects */
|
||||
unsigned32 maximum_proxies; /* maximum # proxies */
|
||||
rtems_mpci_table *User_mpci_table;
|
||||
/* pointer to MPCI table */
|
||||
rtems_mpci_table *User_mpci_table; /* pointer to MPCI table */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -209,25 +207,24 @@ struct Configuration_Table_MP {
|
||||
*/
|
||||
|
||||
struct Configuration_Table {
|
||||
void *work_space_start;
|
||||
unsigned32 work_space_size;
|
||||
unsigned32 maximum_tasks;
|
||||
unsigned32 maximum_timers;
|
||||
unsigned32 maximum_semaphores;
|
||||
unsigned32 maximum_message_queues;
|
||||
unsigned32 maximum_messages;
|
||||
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;
|
||||
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_initialization_tasks_table *User_initialization_tasks_table;
|
||||
unsigned32 number_of_device_drivers;
|
||||
unsigned32 number_of_device_drivers;
|
||||
rtems_driver_address_table *Device_driver_table;
|
||||
rtems_extensions_table *User_extension_table;
|
||||
rtems_extensions_table *User_extension_table;
|
||||
rtems_multiprocessing_table *User_multiprocessing_table;
|
||||
};
|
||||
|
||||
@@ -244,7 +241,7 @@ extern const rtems_multiprocessing_table
|
||||
* configuration information.
|
||||
*/
|
||||
|
||||
EXTERN rtems_configuration_table *_Configuration_Table;
|
||||
EXTERN rtems_configuration_table *_Configuration_Table;
|
||||
EXTERN rtems_multiprocessing_table *_Configuration_MP_table;
|
||||
EXTERN rtems_mpci_table *_Configuration_MPCI_table;
|
||||
|
||||
@@ -258,7 +255,7 @@ EXTERN rtems_mpci_table *_Configuration_MPCI_table;
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Configuration_Handler_initialization(
|
||||
rtems_configuration_table *configuration_table,
|
||||
rtems_configuration_table *configuration_table,
|
||||
rtems_multiprocessing_table *multiprocessing_table,
|
||||
rtems_mpci_table *users_mpci_table
|
||||
);
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __RTEMS_DIRECTIVES_h
|
||||
#define RTEMS___DIRECTIVES_h
|
||||
#define __RTEMS_DIRECTIVES_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -85,20 +87,24 @@ extern "C" {
|
||||
#define RTEMS_DUAL_PORTED_MEMORY_EXTERNAL_TO_INTERNAL 63
|
||||
#define RTEMS_DUAL_PORTED_MEMORY_INTERNAL_TO_EXTERNAL 64
|
||||
#define RTEMS_IO_INITIALIZE 65
|
||||
#define RTEMS_IO_OPEN 66
|
||||
#define RTEMS_IO_CLOSE 67
|
||||
#define RTEMS_IO_READ 68
|
||||
#define RTEMS_IO_WRITE 69
|
||||
#define RTEMS_IO_CONTROL 70
|
||||
#define RTEMS_FATAL_ERROR_OCCURRED 71
|
||||
#define RTEMS_RATE_MONOTONIC_CREATE 72
|
||||
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 73
|
||||
#define RTEMS_RATE_MONOTONIC_DELETE 74
|
||||
#define RTEMS_RATE_MONOTONIC_CANCEL 75
|
||||
#define RTEMS_RATE_MONOTONIC_PERIOD 76
|
||||
#define RTEMS_MULTIPROCESSING_ANNOUNCE 77
|
||||
#define RTEMS_DEBUG_ENABLE 78
|
||||
#define RTEMS_DEBUG_DISABLE 79
|
||||
#define RTEMS_IO_REGISTER_NAME 66
|
||||
#define RTEMS_IO_LOOKUP_NAME 67
|
||||
#define RTEMS_IO_OPEN 68
|
||||
#define RTEMS_IO_CLOSE 69
|
||||
#define RTEMS_IO_READ 70
|
||||
#define RTEMS_IO_WRITE 71
|
||||
#define RTEMS_IO_CONTROL 72
|
||||
#define RTEMS_FATAL_ERROR_OCCURRED 73
|
||||
#define RTEMS_RATE_MONOTONIC_CREATE 74
|
||||
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 75
|
||||
#define RTEMS_RATE_MONOTONIC_DELETE 76
|
||||
#define RTEMS_RATE_MONOTONIC_CANCEL 77
|
||||
#define RTEMS_RATE_MONOTONIC_PERIOD 78
|
||||
#define RTEMS_MULTIPROCESSING_ANNOUNCE 79
|
||||
#define RTEMS_DEBUG_ENABLE 80
|
||||
#define RTEMS_DEBUG_DISABLE 81
|
||||
|
||||
#define RTEMS_NUMBER_OF_ENTRY_POINTS 82
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -34,29 +34,32 @@ extern "C" {
|
||||
|
||||
#include <rtems/config.h>
|
||||
|
||||
/*
|
||||
* The following type defines the set of IO operations which are
|
||||
* recognized by _IO_Handler and can be supported by a RTEMS
|
||||
* device driver.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
IO_INITIALIZE_OPERATION = 0,
|
||||
IO_OPEN_OPERATION = 1,
|
||||
IO_CLOSE_OPERATION = 2,
|
||||
IO_READ_OPERATION = 3,
|
||||
IO_WRITE_OPERATION = 4,
|
||||
IO_CONTROL_OPERATION = 5
|
||||
} IO_operations;
|
||||
|
||||
/*
|
||||
* The following declare the data required to manage the Device Driver
|
||||
* Address Table.
|
||||
*/
|
||||
|
||||
EXTERN unsigned32 _IO_Number_of_drivers;
|
||||
EXTERN unsigned32 _IO_Number_of_drivers;
|
||||
EXTERN rtems_driver_address_table *_IO_Driver_address_table;
|
||||
|
||||
/*
|
||||
* Table for the io device names
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *device_name;
|
||||
unsigned32 device_name_length;
|
||||
rtems_device_major_number major;
|
||||
rtems_device_minor_number minor;
|
||||
} rtems_driver_name_t;
|
||||
|
||||
/*XXX this really should be allocated some better way... */
|
||||
/*XXX it should probably be a chain and use a 'maximum' drivers field
|
||||
* in config table */
|
||||
#define RTEMS_MAX_DRIVER_NAMES 20
|
||||
EXTERN rtems_driver_name_t rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES];
|
||||
|
||||
|
||||
/*
|
||||
* _IO_Manager_initialization
|
||||
*
|
||||
@@ -70,6 +73,36 @@ STATIC INLINE void _IO_Manager_initialization(
|
||||
unsigned32 number_of_drivers
|
||||
);
|
||||
|
||||
/*
|
||||
* rtems_io_register_name
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Associate a name with a driver.
|
||||
*
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_register_name(
|
||||
char *device_name,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* rtems_io_lookup_name
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Find what driver "owns" this name
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_lookup_name(
|
||||
const char *pathname,
|
||||
rtems_driver_name_t **rnp
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* rtems_io_initialize
|
||||
*
|
||||
@@ -82,8 +115,7 @@ STATIC INLINE void _IO_Manager_initialization(
|
||||
rtems_status_code rtems_io_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -98,8 +130,7 @@ rtems_status_code rtems_io_initialize(
|
||||
rtems_status_code rtems_io_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -114,8 +145,7 @@ rtems_status_code rtems_io_open(
|
||||
rtems_status_code rtems_io_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -130,8 +160,7 @@ rtems_status_code rtems_io_close(
|
||||
rtems_status_code rtems_io_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -146,8 +175,7 @@ rtems_status_code rtems_io_read(
|
||||
rtems_status_code rtems_io_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -162,8 +190,7 @@ rtems_status_code rtems_io_write(
|
||||
rtems_status_code rtems_io_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -177,23 +204,6 @@ rtems_status_code rtems_io_control(
|
||||
|
||||
void _IO_Initialize_all_drivers( void );
|
||||
|
||||
/*
|
||||
* _IO_Handler_routine
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine provides the common foundation for all of the IO
|
||||
* Manager's directives.
|
||||
*/
|
||||
|
||||
rtems_status_code _IO_Handler_routine(
|
||||
IO_operations operation,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
);
|
||||
|
||||
#include <rtems/io.inl>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -49,7 +49,7 @@ const char _RTEMS_version[] =
|
||||
* This table is used by the single entry point code.
|
||||
*/
|
||||
|
||||
const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
|
||||
const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ] = {
|
||||
(void *) rtems_initialize_executive, /* 0 */
|
||||
(void *) rtems_initialize_executive_early, /* 1 */
|
||||
(void *) rtems_initialize_executive_late, /* 2 */
|
||||
@@ -116,20 +116,22 @@ const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
|
||||
(void *) rtems_port_external_to_internal, /* 63 */
|
||||
(void *) rtems_port_internal_to_external, /* 64 */
|
||||
(void *) rtems_io_initialize, /* 65 */
|
||||
(void *) rtems_io_open, /* 66 */
|
||||
(void *) rtems_io_close, /* 67 */
|
||||
(void *) rtems_io_read, /* 68 */
|
||||
(void *) rtems_io_write, /* 69 */
|
||||
(void *) rtems_io_control, /* 70 */
|
||||
(void *) rtems_fatal_error_occurred, /* 71 */
|
||||
(void *) rtems_rate_monotonic_create, /* 72 */
|
||||
(void *) rtems_rate_monotonic_ident, /* 73 */
|
||||
(void *) rtems_rate_monotonic_delete, /* 74 */
|
||||
(void *) rtems_rate_monotonic_cancel, /* 75 */
|
||||
(void *) rtems_rate_monotonic_period, /* 76 */
|
||||
(void *) rtems_multiprocessing_announce, /* 77 */
|
||||
(void *) rtems_debug_enable, /* 78 */
|
||||
(void *) rtems_debug_disable /* 79 */
|
||||
(void *) rtems_io_register_name, /* 66 */
|
||||
(void *) rtems_io_lookup_name, /* 67 */
|
||||
(void *) rtems_io_open, /* 68 */
|
||||
(void *) rtems_io_close, /* 69 */
|
||||
(void *) rtems_io_read, /* 70 */
|
||||
(void *) rtems_io_write, /* 71 */
|
||||
(void *) rtems_io_control, /* 72 */
|
||||
(void *) rtems_fatal_error_occurred, /* 73 */
|
||||
(void *) rtems_rate_monotonic_create, /* 74 */
|
||||
(void *) rtems_rate_monotonic_ident, /* 75 */
|
||||
(void *) rtems_rate_monotonic_delete, /* 76 */
|
||||
(void *) rtems_rate_monotonic_cancel, /* 77 */
|
||||
(void *) rtems_rate_monotonic_period, /* 78 */
|
||||
(void *) rtems_multiprocessing_announce, /* 79 */
|
||||
(void *) rtems_debug_enable, /* 80 */
|
||||
(void *) rtems_debug_disable /* 81 */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -32,14 +32,14 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Objects_Name name; /* task name */
|
||||
unsigned32 stack_size; /* task stack size */
|
||||
Objects_Name name; /* task name */
|
||||
unsigned32 stack_size; /* task stack size */
|
||||
rtems_task_priority initial_priority; /* task priority */
|
||||
rtems_attribute attribute_set; /* task attributes */
|
||||
rtems_task_entry entry_point; /* task entry point */
|
||||
rtems_mode mode_set; /* task initial mode */
|
||||
unsigned32 argument; /* task argument */
|
||||
} rtems_initialization_tasks_table;
|
||||
rtems_attribute attribute_set; /* task attributes */
|
||||
rtems_task_entry entry_point; /* task entry point */
|
||||
rtems_mode mode_set; /* task initial mode */
|
||||
unsigned32 argument; /* task argument */
|
||||
} rtems_initialization_tasks_table;
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -56,14 +56,12 @@ typedef struct {
|
||||
typedef unsigned32 rtems_device_major_number;
|
||||
typedef unsigned32 rtems_device_minor_number;
|
||||
|
||||
typedef void rtems_device_driver;
|
||||
typedef rtems_status_code rtems_device_driver;
|
||||
|
||||
typedef rtems_device_driver ( *rtems_device_driver_entry )(
|
||||
rtems_device_major_number,
|
||||
rtems_device_minor_number,
|
||||
void *,
|
||||
Objects_Id,
|
||||
unsigned32 *
|
||||
void *
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
@@ -173,12 +171,13 @@ typedef rtems_mpci_entry ( *rtems_mpci_receive_entry )(
|
||||
|
||||
typedef struct {
|
||||
unsigned32 default_timeout; /* in ticks */
|
||||
unsigned32 maximum_packet_size;
|
||||
rtems_mpci_initialization_entry initialization;
|
||||
rtems_mpci_get_packet_entry get_packet;
|
||||
rtems_mpci_return_packet_entry return_packet;
|
||||
rtems_mpci_send_entry send_packet;
|
||||
rtems_mpci_receive_entry receive_packet;
|
||||
} rtems_mpci_table;
|
||||
} rtems_mpci_table;
|
||||
|
||||
/*
|
||||
* The following records define the Multiprocessor Configuration
|
||||
@@ -192,8 +191,7 @@ struct Configuration_Table_MP {
|
||||
unsigned32 maximum_nodes; /* maximum # nodes in system */
|
||||
unsigned32 maximum_global_objects; /* maximum # global objects */
|
||||
unsigned32 maximum_proxies; /* maximum # proxies */
|
||||
rtems_mpci_table *User_mpci_table;
|
||||
/* pointer to MPCI table */
|
||||
rtems_mpci_table *User_mpci_table; /* pointer to MPCI table */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -209,25 +207,24 @@ struct Configuration_Table_MP {
|
||||
*/
|
||||
|
||||
struct Configuration_Table {
|
||||
void *work_space_start;
|
||||
unsigned32 work_space_size;
|
||||
unsigned32 maximum_tasks;
|
||||
unsigned32 maximum_timers;
|
||||
unsigned32 maximum_semaphores;
|
||||
unsigned32 maximum_message_queues;
|
||||
unsigned32 maximum_messages;
|
||||
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;
|
||||
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_initialization_tasks_table *User_initialization_tasks_table;
|
||||
unsigned32 number_of_device_drivers;
|
||||
unsigned32 number_of_device_drivers;
|
||||
rtems_driver_address_table *Device_driver_table;
|
||||
rtems_extensions_table *User_extension_table;
|
||||
rtems_extensions_table *User_extension_table;
|
||||
rtems_multiprocessing_table *User_multiprocessing_table;
|
||||
};
|
||||
|
||||
@@ -244,7 +241,7 @@ extern const rtems_multiprocessing_table
|
||||
* configuration information.
|
||||
*/
|
||||
|
||||
EXTERN rtems_configuration_table *_Configuration_Table;
|
||||
EXTERN rtems_configuration_table *_Configuration_Table;
|
||||
EXTERN rtems_multiprocessing_table *_Configuration_MP_table;
|
||||
EXTERN rtems_mpci_table *_Configuration_MPCI_table;
|
||||
|
||||
@@ -258,7 +255,7 @@ EXTERN rtems_mpci_table *_Configuration_MPCI_table;
|
||||
*/
|
||||
|
||||
STATIC INLINE void _Configuration_Handler_initialization(
|
||||
rtems_configuration_table *configuration_table,
|
||||
rtems_configuration_table *configuration_table,
|
||||
rtems_multiprocessing_table *multiprocessing_table,
|
||||
rtems_mpci_table *users_mpci_table
|
||||
);
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
* This material may be reproduced by or for the U.S. Government pursuant
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __RTEMS_DIRECTIVES_h
|
||||
#define RTEMS___DIRECTIVES_h
|
||||
#define __RTEMS_DIRECTIVES_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -85,20 +87,24 @@ extern "C" {
|
||||
#define RTEMS_DUAL_PORTED_MEMORY_EXTERNAL_TO_INTERNAL 63
|
||||
#define RTEMS_DUAL_PORTED_MEMORY_INTERNAL_TO_EXTERNAL 64
|
||||
#define RTEMS_IO_INITIALIZE 65
|
||||
#define RTEMS_IO_OPEN 66
|
||||
#define RTEMS_IO_CLOSE 67
|
||||
#define RTEMS_IO_READ 68
|
||||
#define RTEMS_IO_WRITE 69
|
||||
#define RTEMS_IO_CONTROL 70
|
||||
#define RTEMS_FATAL_ERROR_OCCURRED 71
|
||||
#define RTEMS_RATE_MONOTONIC_CREATE 72
|
||||
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 73
|
||||
#define RTEMS_RATE_MONOTONIC_DELETE 74
|
||||
#define RTEMS_RATE_MONOTONIC_CANCEL 75
|
||||
#define RTEMS_RATE_MONOTONIC_PERIOD 76
|
||||
#define RTEMS_MULTIPROCESSING_ANNOUNCE 77
|
||||
#define RTEMS_DEBUG_ENABLE 78
|
||||
#define RTEMS_DEBUG_DISABLE 79
|
||||
#define RTEMS_IO_REGISTER_NAME 66
|
||||
#define RTEMS_IO_LOOKUP_NAME 67
|
||||
#define RTEMS_IO_OPEN 68
|
||||
#define RTEMS_IO_CLOSE 69
|
||||
#define RTEMS_IO_READ 70
|
||||
#define RTEMS_IO_WRITE 71
|
||||
#define RTEMS_IO_CONTROL 72
|
||||
#define RTEMS_FATAL_ERROR_OCCURRED 73
|
||||
#define RTEMS_RATE_MONOTONIC_CREATE 74
|
||||
#define RTEMS_RATE_MONOTONIC_NAME_TO_ID 75
|
||||
#define RTEMS_RATE_MONOTONIC_DELETE 76
|
||||
#define RTEMS_RATE_MONOTONIC_CANCEL 77
|
||||
#define RTEMS_RATE_MONOTONIC_PERIOD 78
|
||||
#define RTEMS_MULTIPROCESSING_ANNOUNCE 79
|
||||
#define RTEMS_DEBUG_ENABLE 80
|
||||
#define RTEMS_DEBUG_DISABLE 81
|
||||
|
||||
#define RTEMS_NUMBER_OF_ENTRY_POINTS 82
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -34,29 +34,32 @@ extern "C" {
|
||||
|
||||
#include <rtems/config.h>
|
||||
|
||||
/*
|
||||
* The following type defines the set of IO operations which are
|
||||
* recognized by _IO_Handler and can be supported by a RTEMS
|
||||
* device driver.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
IO_INITIALIZE_OPERATION = 0,
|
||||
IO_OPEN_OPERATION = 1,
|
||||
IO_CLOSE_OPERATION = 2,
|
||||
IO_READ_OPERATION = 3,
|
||||
IO_WRITE_OPERATION = 4,
|
||||
IO_CONTROL_OPERATION = 5
|
||||
} IO_operations;
|
||||
|
||||
/*
|
||||
* The following declare the data required to manage the Device Driver
|
||||
* Address Table.
|
||||
*/
|
||||
|
||||
EXTERN unsigned32 _IO_Number_of_drivers;
|
||||
EXTERN unsigned32 _IO_Number_of_drivers;
|
||||
EXTERN rtems_driver_address_table *_IO_Driver_address_table;
|
||||
|
||||
/*
|
||||
* Table for the io device names
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *device_name;
|
||||
unsigned32 device_name_length;
|
||||
rtems_device_major_number major;
|
||||
rtems_device_minor_number minor;
|
||||
} rtems_driver_name_t;
|
||||
|
||||
/*XXX this really should be allocated some better way... */
|
||||
/*XXX it should probably be a chain and use a 'maximum' drivers field
|
||||
* in config table */
|
||||
#define RTEMS_MAX_DRIVER_NAMES 20
|
||||
EXTERN rtems_driver_name_t rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES];
|
||||
|
||||
|
||||
/*
|
||||
* _IO_Manager_initialization
|
||||
*
|
||||
@@ -70,6 +73,36 @@ STATIC INLINE void _IO_Manager_initialization(
|
||||
unsigned32 number_of_drivers
|
||||
);
|
||||
|
||||
/*
|
||||
* rtems_io_register_name
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Associate a name with a driver.
|
||||
*
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_register_name(
|
||||
char *device_name,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* rtems_io_lookup_name
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Find what driver "owns" this name
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_lookup_name(
|
||||
const char *pathname,
|
||||
rtems_driver_name_t **rnp
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* rtems_io_initialize
|
||||
*
|
||||
@@ -82,8 +115,7 @@ STATIC INLINE void _IO_Manager_initialization(
|
||||
rtems_status_code rtems_io_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -98,8 +130,7 @@ rtems_status_code rtems_io_initialize(
|
||||
rtems_status_code rtems_io_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -114,8 +145,7 @@ rtems_status_code rtems_io_open(
|
||||
rtems_status_code rtems_io_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -130,8 +160,7 @@ rtems_status_code rtems_io_close(
|
||||
rtems_status_code rtems_io_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -146,8 +175,7 @@ rtems_status_code rtems_io_read(
|
||||
rtems_status_code rtems_io_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -162,8 +190,7 @@ rtems_status_code rtems_io_write(
|
||||
rtems_status_code rtems_io_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -177,23 +204,6 @@ rtems_status_code rtems_io_control(
|
||||
|
||||
void _IO_Initialize_all_drivers( void );
|
||||
|
||||
/*
|
||||
* _IO_Handler_routine
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine provides the common foundation for all of the IO
|
||||
* Manager's directives.
|
||||
*/
|
||||
|
||||
rtems_status_code _IO_Handler_routine(
|
||||
IO_operations operation,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
);
|
||||
|
||||
#include <rtems/io.inl>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -49,7 +49,7 @@ const char _RTEMS_version[] =
|
||||
* This table is used by the single entry point code.
|
||||
*/
|
||||
|
||||
const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
|
||||
const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ] = {
|
||||
(void *) rtems_initialize_executive, /* 0 */
|
||||
(void *) rtems_initialize_executive_early, /* 1 */
|
||||
(void *) rtems_initialize_executive_late, /* 2 */
|
||||
@@ -116,20 +116,22 @@ const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ] = {
|
||||
(void *) rtems_port_external_to_internal, /* 63 */
|
||||
(void *) rtems_port_internal_to_external, /* 64 */
|
||||
(void *) rtems_io_initialize, /* 65 */
|
||||
(void *) rtems_io_open, /* 66 */
|
||||
(void *) rtems_io_close, /* 67 */
|
||||
(void *) rtems_io_read, /* 68 */
|
||||
(void *) rtems_io_write, /* 69 */
|
||||
(void *) rtems_io_control, /* 70 */
|
||||
(void *) rtems_fatal_error_occurred, /* 71 */
|
||||
(void *) rtems_rate_monotonic_create, /* 72 */
|
||||
(void *) rtems_rate_monotonic_ident, /* 73 */
|
||||
(void *) rtems_rate_monotonic_delete, /* 74 */
|
||||
(void *) rtems_rate_monotonic_cancel, /* 75 */
|
||||
(void *) rtems_rate_monotonic_period, /* 76 */
|
||||
(void *) rtems_multiprocessing_announce, /* 77 */
|
||||
(void *) rtems_debug_enable, /* 78 */
|
||||
(void *) rtems_debug_disable /* 79 */
|
||||
(void *) rtems_io_register_name, /* 66 */
|
||||
(void *) rtems_io_lookup_name, /* 67 */
|
||||
(void *) rtems_io_open, /* 68 */
|
||||
(void *) rtems_io_close, /* 69 */
|
||||
(void *) rtems_io_read, /* 70 */
|
||||
(void *) rtems_io_write, /* 71 */
|
||||
(void *) rtems_io_control, /* 72 */
|
||||
(void *) rtems_fatal_error_occurred, /* 73 */
|
||||
(void *) rtems_rate_monotonic_create, /* 74 */
|
||||
(void *) rtems_rate_monotonic_ident, /* 75 */
|
||||
(void *) rtems_rate_monotonic_delete, /* 76 */
|
||||
(void *) rtems_rate_monotonic_cancel, /* 77 */
|
||||
(void *) rtems_rate_monotonic_period, /* 78 */
|
||||
(void *) rtems_multiprocessing_announce, /* 79 */
|
||||
(void *) rtems_debug_enable, /* 80 */
|
||||
(void *) rtems_debug_disable /* 81 */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -23,11 +23,27 @@ void _IO_Initialize_all_drivers( void )
|
||||
{
|
||||
}
|
||||
|
||||
rtems_status_code rtems_io_register_name(
|
||||
char *device_name,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor
|
||||
)
|
||||
{
|
||||
return RTEMS_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
rtems_status_code rtems_io_lookup_name(
|
||||
const char *pathname,
|
||||
rtems_driver_name_t **rnp
|
||||
)
|
||||
{
|
||||
return RTEMS_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
rtems_status_code rtems_io_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -36,8 +52,7 @@ rtems_status_code rtems_io_initialize(
|
||||
rtems_status_code rtems_io_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -46,8 +61,7 @@ rtems_status_code rtems_io_open(
|
||||
rtems_status_code rtems_io_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -56,8 +70,7 @@ rtems_status_code rtems_io_close(
|
||||
rtems_status_code rtems_io_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -66,8 +79,7 @@ rtems_status_code rtems_io_read(
|
||||
rtems_status_code rtems_io_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
@@ -76,19 +88,7 @@ rtems_status_code rtems_io_write(
|
||||
rtems_status_code rtems_io_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
}
|
||||
|
||||
rtems_status_code _IO_Handler_routine(
|
||||
IO_operations operation,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return( RTEMS_NOT_CONFIGURED );
|
||||
|
||||
@@ -177,8 +177,7 @@ rtems_interrupt_level rtems_initialize_executive_early(
|
||||
_Event_Manager_initialization();
|
||||
|
||||
_Message_queue_Manager_initialization(
|
||||
configuration_table->maximum_message_queues,
|
||||
configuration_table->maximum_messages
|
||||
configuration_table->maximum_message_queues
|
||||
);
|
||||
|
||||
_Semaphore_Manager_initialization(
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
#include <rtems/io.h>
|
||||
#include <rtems/isr.h>
|
||||
#include <rtems/thread.h>
|
||||
#include <rtems/intr.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
@@ -33,12 +36,82 @@
|
||||
void _IO_Initialize_all_drivers( void )
|
||||
{
|
||||
rtems_device_major_number major;
|
||||
unsigned32 ignored;
|
||||
|
||||
for ( major=0 ; major < _IO_Number_of_drivers ; major ++ )
|
||||
(void) rtems_io_initialize( major, 0, _Configuration_Table, &ignored );
|
||||
(void) rtems_io_initialize( major, 0, _Configuration_Table);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* rtems_io_register_name
|
||||
*
|
||||
* Associate a name with a driver
|
||||
*
|
||||
* Input Paramters:
|
||||
*
|
||||
* Output Parameters:
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_register_name(
|
||||
char *device_name,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor
|
||||
)
|
||||
{
|
||||
rtems_driver_name_t *np;
|
||||
unsigned32 level;
|
||||
|
||||
/* find an empty slot */
|
||||
for (np = rtems_driver_name_table; np < &rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES]; np++)
|
||||
{
|
||||
rtems_interrupt_disable(level);
|
||||
if (np->device_name == 0)
|
||||
{
|
||||
np->device_name = device_name;
|
||||
np->device_name_length = strlen(device_name);
|
||||
np->major = major;
|
||||
np->minor = minor;
|
||||
rtems_interrupt_enable(level);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
rtems_interrupt_enable(level);
|
||||
}
|
||||
|
||||
return RTEMS_TOO_MANY;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* rtems_io_lookup_name
|
||||
*
|
||||
* Find what driver "owns" this name
|
||||
*
|
||||
* Input Paramters:
|
||||
*
|
||||
* Output Parameters:
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_lookup_name(
|
||||
const char *pathname,
|
||||
rtems_driver_name_t **rnp
|
||||
)
|
||||
{
|
||||
rtems_driver_name_t *np;
|
||||
|
||||
for (np = rtems_driver_name_table; np < &rtems_driver_name_table[RTEMS_MAX_DRIVER_NAMES]; np++)
|
||||
if (np->device_name)
|
||||
if (strncmp(np->device_name, pathname, np->device_name_length) == 0)
|
||||
{
|
||||
*rnp = np;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
*rnp = 0;
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* rtems_io_initialize
|
||||
@@ -49,27 +122,24 @@ void _IO_Initialize_all_drivers( void )
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return _IO_Handler_routine(
|
||||
IO_INITIALIZE_OPERATION,
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
return_value
|
||||
);
|
||||
rtems_device_driver_entry callout;
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
callout = _IO_Driver_address_table[major].initialization;
|
||||
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -82,27 +152,24 @@ rtems_status_code rtems_io_initialize(
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return _IO_Handler_routine(
|
||||
IO_OPEN_OPERATION,
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
return_value
|
||||
);
|
||||
rtems_device_driver_entry callout;
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
callout = _IO_Driver_address_table[major].open;
|
||||
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -115,27 +182,24 @@ rtems_status_code rtems_io_open(
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return _IO_Handler_routine(
|
||||
IO_CLOSE_OPERATION,
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
return_value
|
||||
);
|
||||
rtems_device_driver_entry callout;
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
callout = _IO_Driver_address_table[major].close;
|
||||
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -148,27 +212,24 @@ rtems_status_code rtems_io_close(
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return _IO_Handler_routine(
|
||||
IO_READ_OPERATION,
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
return_value
|
||||
);
|
||||
rtems_device_driver_entry callout;
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
callout = _IO_Driver_address_table[major].read;
|
||||
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -181,27 +242,24 @@ rtems_status_code rtems_io_read(
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return _IO_Handler_routine(
|
||||
IO_WRITE_OPERATION,
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
return_value
|
||||
);
|
||||
rtems_device_driver_entry callout;
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
callout = _IO_Driver_address_table[major].write;
|
||||
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
@@ -214,103 +272,23 @@ rtems_status_code rtems_io_write(
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code rtems_io_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
void *argument
|
||||
)
|
||||
{
|
||||
return _IO_Handler_routine(
|
||||
IO_CONTROL_OPERATION,
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
return_value
|
||||
);
|
||||
rtems_device_driver_entry callout;
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return RTEMS_INVALID_NUMBER;
|
||||
|
||||
callout = _IO_Driver_address_table[major].control;
|
||||
return callout ? callout(major, minor, argument) : RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _IO_Handler_routine
|
||||
*
|
||||
* This routine implements all IO manager directives.
|
||||
*
|
||||
* Input Paramters:
|
||||
* operation - I/O operation to be performed
|
||||
* major - device driver number
|
||||
* minor - device number
|
||||
* argument - pointer to argument(s)
|
||||
* return_value - pointer to driver's return value
|
||||
*
|
||||
* Output Parameters:
|
||||
* returns - return code
|
||||
* *return_value - driver's return code
|
||||
*/
|
||||
|
||||
rtems_status_code _IO_Handler_routine(
|
||||
IO_operations operation,
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *argument,
|
||||
unsigned32 *return_value
|
||||
)
|
||||
{
|
||||
rtems_device_driver_entry io_callout;
|
||||
|
||||
/*
|
||||
* NOTE: There is no range checking as in Ada because:
|
||||
* + arrays in Ada are not always zero based.
|
||||
* + with zero based arrays, a comparison of an unsigned
|
||||
* number being less than zero would be necessary to
|
||||
* check it as a range. This would cause a warning for
|
||||
* checking an unsigned number for being negative.
|
||||
*/
|
||||
|
||||
if ( major >= _IO_Number_of_drivers )
|
||||
return ( RTEMS_INVALID_NUMBER );
|
||||
|
||||
switch ( operation ) {
|
||||
case IO_INITIALIZE_OPERATION:
|
||||
io_callout = _IO_Driver_address_table[ major ].initialization;
|
||||
break;
|
||||
case IO_OPEN_OPERATION:
|
||||
io_callout = _IO_Driver_address_table[ major ].open;
|
||||
break;
|
||||
case IO_CLOSE_OPERATION:
|
||||
io_callout = _IO_Driver_address_table[ major ].close;
|
||||
break;
|
||||
case IO_READ_OPERATION:
|
||||
io_callout = _IO_Driver_address_table[ major ].read;
|
||||
break;
|
||||
case IO_WRITE_OPERATION:
|
||||
io_callout = _IO_Driver_address_table[ major ].write;
|
||||
break;
|
||||
case IO_CONTROL_OPERATION:
|
||||
io_callout = _IO_Driver_address_table[ major ].control;
|
||||
break;
|
||||
default: /* unreached -- only to remove warnings */
|
||||
io_callout = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( io_callout != NULL )
|
||||
(*io_callout)(
|
||||
major,
|
||||
minor,
|
||||
argument,
|
||||
_Thread_Executing->Object.id,
|
||||
return_value
|
||||
);
|
||||
else
|
||||
*return_value = 0;
|
||||
|
||||
return( RTEMS_SUCCESSFUL );
|
||||
}
|
||||
|
||||
@@ -99,6 +99,18 @@ EXTERN unsigned32 _Objects_Local_node;
|
||||
#define RTEMS_SEARCH_LOCAL_NODE 0x7FFFFFFF
|
||||
#define RTEMS_WHO_AM_I 0
|
||||
|
||||
/*
|
||||
* Parameters and return id's for _Objects_Get_next
|
||||
*/
|
||||
|
||||
#define RTEMS_OBJECT_ID_INITIAL_INDEX (0)
|
||||
#define RTEMS_OBJECT_ID_FINAL_INDEX (0xffff)
|
||||
|
||||
#define RTEMS_OBJECT_ID_INITIAL(node) (_Objects_Build_id( \
|
||||
node, \
|
||||
RTEMS_OBJECT_ID_INITIAL_INDEX))
|
||||
#define RTEMS_OBJECT_ID_FINAL ((Objects_Id) ~0)
|
||||
|
||||
/*
|
||||
* _Objects_Handler_initialization
|
||||
*
|
||||
@@ -178,6 +190,22 @@ Objects_Control *_Objects_Get (
|
||||
Objects_Locations *location
|
||||
);
|
||||
|
||||
/*
|
||||
* _Objects_Get_next
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Like _Objects_Get, but is used to find "next" open object.
|
||||
*
|
||||
*/
|
||||
|
||||
Objects_Control *_Objects_Get_next(
|
||||
Objects_Information *information,
|
||||
Objects_Id id,
|
||||
unsigned32 *location_p,
|
||||
Objects_Id *next_id_p
|
||||
);
|
||||
|
||||
/*
|
||||
* _Objects_Is_name_valid
|
||||
*
|
||||
|
||||
@@ -78,6 +78,7 @@ typedef void * proc_ptr;
|
||||
|
||||
#include <rtems/cpu.h> /* processor specific information */
|
||||
#include <rtems/status.h> /* RTEMS status codes */
|
||||
#include <rtems/directives.h>
|
||||
|
||||
/*
|
||||
* Define NULL
|
||||
@@ -103,6 +104,9 @@ typedef void * proc_ptr;
|
||||
|
||||
#define stringify( _x ) # _x
|
||||
|
||||
#define RTEMS_offsetof(type, field) \
|
||||
((unsigned32) &(((type *) 0)->field))
|
||||
|
||||
/*
|
||||
* The following is the extern for the RTEMS version string.
|
||||
* The contents of this string are CPU specific.
|
||||
@@ -115,8 +119,7 @@ extern const char _Copyright_Notice[]; /* RTEMS copyright string */
|
||||
* The jump table of entry points into RTEMS directives.
|
||||
*/
|
||||
|
||||
#define NUMBER_OF_ENTRY_POINTS 79
|
||||
extern const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ];
|
||||
extern const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ];
|
||||
|
||||
/*
|
||||
* The following defines the CPU dependent information table.
|
||||
|
||||
@@ -115,6 +115,7 @@ typedef struct {
|
||||
union {
|
||||
unsigned32 segment_size; /* size of segment requested */
|
||||
rtems_event_set event_condition;
|
||||
unsigned32 *message_size_p; /* ptr for return size of message */
|
||||
} Extra;
|
||||
void *return_argument; /* address of user return param */
|
||||
rtems_status_code return_code; /* status for thread awakened */
|
||||
|
||||
@@ -99,6 +99,18 @@ EXTERN unsigned32 _Objects_Local_node;
|
||||
#define RTEMS_SEARCH_LOCAL_NODE 0x7FFFFFFF
|
||||
#define RTEMS_WHO_AM_I 0
|
||||
|
||||
/*
|
||||
* Parameters and return id's for _Objects_Get_next
|
||||
*/
|
||||
|
||||
#define RTEMS_OBJECT_ID_INITIAL_INDEX (0)
|
||||
#define RTEMS_OBJECT_ID_FINAL_INDEX (0xffff)
|
||||
|
||||
#define RTEMS_OBJECT_ID_INITIAL(node) (_Objects_Build_id( \
|
||||
node, \
|
||||
RTEMS_OBJECT_ID_INITIAL_INDEX))
|
||||
#define RTEMS_OBJECT_ID_FINAL ((Objects_Id) ~0)
|
||||
|
||||
/*
|
||||
* _Objects_Handler_initialization
|
||||
*
|
||||
@@ -178,6 +190,22 @@ Objects_Control *_Objects_Get (
|
||||
Objects_Locations *location
|
||||
);
|
||||
|
||||
/*
|
||||
* _Objects_Get_next
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Like _Objects_Get, but is used to find "next" open object.
|
||||
*
|
||||
*/
|
||||
|
||||
Objects_Control *_Objects_Get_next(
|
||||
Objects_Information *information,
|
||||
Objects_Id id,
|
||||
unsigned32 *location_p,
|
||||
Objects_Id *next_id_p
|
||||
);
|
||||
|
||||
/*
|
||||
* _Objects_Is_name_valid
|
||||
*
|
||||
|
||||
@@ -115,6 +115,7 @@ typedef struct {
|
||||
union {
|
||||
unsigned32 segment_size; /* size of segment requested */
|
||||
rtems_event_set event_condition;
|
||||
unsigned32 *message_size_p; /* ptr for return size of message */
|
||||
} Extra;
|
||||
void *return_argument; /* address of user return param */
|
||||
rtems_status_code return_code; /* status for thread awakened */
|
||||
|
||||
@@ -78,6 +78,7 @@ typedef void * proc_ptr;
|
||||
|
||||
#include <rtems/cpu.h> /* processor specific information */
|
||||
#include <rtems/status.h> /* RTEMS status codes */
|
||||
#include <rtems/directives.h>
|
||||
|
||||
/*
|
||||
* Define NULL
|
||||
@@ -103,6 +104,9 @@ typedef void * proc_ptr;
|
||||
|
||||
#define stringify( _x ) # _x
|
||||
|
||||
#define RTEMS_offsetof(type, field) \
|
||||
((unsigned32) &(((type *) 0)->field))
|
||||
|
||||
/*
|
||||
* The following is the extern for the RTEMS version string.
|
||||
* The contents of this string are CPU specific.
|
||||
@@ -115,8 +119,7 @@ extern const char _Copyright_Notice[]; /* RTEMS copyright string */
|
||||
* The jump table of entry points into RTEMS directives.
|
||||
*/
|
||||
|
||||
#define NUMBER_OF_ENTRY_POINTS 79
|
||||
extern const void * _Entry_points[ NUMBER_OF_ENTRY_POINTS + 1 ];
|
||||
extern const void * _Entry_points[ RTEMS_NUMBER_OF_ENTRY_POINTS ];
|
||||
|
||||
/*
|
||||
* The following defines the CPU dependent information table.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems/system.h>
|
||||
#include <rtems/chain.h>
|
||||
#include <rtems/config.h>
|
||||
@@ -226,3 +227,69 @@ Objects_Control *_Objects_Get(
|
||||
_Objects_MP_Is_remote( information, id, location, &the_object );
|
||||
return the_object;
|
||||
}
|
||||
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Objects_Get_next
|
||||
*
|
||||
* Like _Objects_Get, but considers the 'id' as a "hint" and
|
||||
* finds next valid one after that point.
|
||||
* Mostly used for monitor and debug traversal of an object.
|
||||
*
|
||||
* Input parameters:
|
||||
* information - pointer to entry in table for this class
|
||||
* id - object id to search for
|
||||
* location - address of where to store the location
|
||||
* next_id - address to store next id to try
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - address of object if local
|
||||
* location - one of the following:
|
||||
* OBJECTS_ERROR - invalid object ID
|
||||
* OBJECTS_REMOTE - remote object
|
||||
* OBJECTS_LOCAL - local object
|
||||
* next_id - will contain a reasonable "next" id to continue traversal
|
||||
*
|
||||
* NOTE:
|
||||
* assumes can add '1' to an id to get to next index.
|
||||
*/
|
||||
|
||||
Objects_Control *
|
||||
_Objects_Get_next(
|
||||
Objects_Information *information,
|
||||
Objects_Id id,
|
||||
unsigned32 *location_p,
|
||||
Objects_Id *next_id_p
|
||||
)
|
||||
{
|
||||
Objects_Control *object;
|
||||
Objects_Id next_id;
|
||||
|
||||
if (rtems_get_index(id) == RTEMS_OBJECT_ID_INITIAL_INDEX)
|
||||
next_id = information->minimum_id;
|
||||
else
|
||||
next_id = id;
|
||||
|
||||
do {
|
||||
/* walked off end of list? */
|
||||
if (next_id > information->maximum_id)
|
||||
{
|
||||
*location_p = OBJECTS_ERROR;
|
||||
goto final;
|
||||
}
|
||||
|
||||
/* try to grab one */
|
||||
object = _Objects_Get(information, next_id, location_p);
|
||||
|
||||
next_id++;
|
||||
|
||||
} while (*location_p != OBJECTS_LOCAL);
|
||||
|
||||
*next_id_p = next_id;
|
||||
return object;
|
||||
|
||||
final:
|
||||
*next_id_p = RTEMS_OBJECT_ID_FINAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,31 +23,24 @@ extern "C" {
|
||||
/* variables */
|
||||
|
||||
extern volatile rtems_unsigned32 Clock_driver_ticks;
|
||||
extern rtems_device_major_number rtems_clock_major;
|
||||
extern rtems_device_minor_number rtems_clock_minor;
|
||||
|
||||
/* functions */
|
||||
|
||||
rtems_task Exit_task();
|
||||
void exit_task_init();
|
||||
|
||||
void Install_clock( rtems_isr_entry );
|
||||
void ReInstall_clock( rtems_isr_entry );
|
||||
void Clock_exit();
|
||||
|
||||
rtems_isr Clock_isr(
|
||||
rtems_vector_number
|
||||
);
|
||||
|
||||
/* driver entries */
|
||||
/* default clock driver entry */
|
||||
|
||||
#define CLOCK_DRIVER_TABLE_ENTRY \
|
||||
{ Clock_initialize, NULL, NULL, NULL, NULL, NULL }
|
||||
|
||||
{ Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
|
||||
|
||||
rtems_device_driver Clock_initialize(
|
||||
rtems_device_major_number,
|
||||
rtems_device_minor_number,
|
||||
void *,
|
||||
rtems_id,
|
||||
rtems_unsigned32 *
|
||||
void *
|
||||
);
|
||||
|
||||
rtems_device_driver Clock_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
44
c/src/lib/include/rtems/assoc.h
Normal file
44
c/src/lib/include/rtems/assoc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @(#)assoc.h 1.2 - 95/06/28
|
||||
*
|
||||
*
|
||||
* Rtems associativity routines. Mainly used to convert a value from
|
||||
* one space to another (eg: our errno's to host errno's and v.v)
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_ASSOC_H
|
||||
#define _INCLUDE_ASSOC_H
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned32 local_value;
|
||||
unsigned32 remote_value;
|
||||
} rtems_assoc_t;
|
||||
|
||||
/*
|
||||
* Flag/marker for optional default value in each table
|
||||
*/
|
||||
|
||||
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
|
||||
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
|
||||
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
|
||||
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
|
||||
|
||||
|
||||
#endif /* ! _INCLUDE_ASSOC_H */
|
||||
26
c/src/lib/include/rtems/error.h
Normal file
26
c/src/lib/include/rtems/error.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @(#)error.h 1.1 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Defines and externs for rtems error reporting
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* rtems_error() and rtems_panic() support
|
||||
*/
|
||||
|
||||
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
||||
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
|
||||
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
|
||||
|
||||
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
|
||||
RTEMS_ERROR_PANIC) /* all */
|
||||
|
||||
char *rtems_status_text(rtems_status_code);
|
||||
int rtems_error(int error_code, char *printf_format, ...);
|
||||
void rtems_panic(char *printf_format, ...);
|
||||
|
||||
extern int rtems_panic_in_progress;
|
||||
|
||||
101
c/src/lib/include/rtems/libio.h
Normal file
101
c/src/lib/include/rtems/libio.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* @(#)libio.h 1.1 - 95/06/02
|
||||
*
|
||||
*
|
||||
* General purpose communication channel for RTEMS to allow UNIX/POSIX
|
||||
* system call behavior on top of RTEMS IO devices.
|
||||
*
|
||||
* TODO
|
||||
* stat(2)
|
||||
* unlink(2)
|
||||
* rename(2)
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_LIBIO_H
|
||||
#define _RTEMS_LIBIO_H
|
||||
|
||||
typedef unsigned32 rtems_libio_offset_t;
|
||||
|
||||
/*
|
||||
* An open file data structure, indexed by 'fd'
|
||||
* TODO:
|
||||
* should really have a separate per/file data structure that this
|
||||
* points to (eg: size, offset, driver, pathname should be in that)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_driver_name_t *driver;
|
||||
rtems_libio_offset_t size; /* size of file */
|
||||
rtems_libio_offset_t offset; /* current offset into the file */
|
||||
unsigned32 flags;
|
||||
char *pathname; /* opened pathname */
|
||||
Objects_Id sem;
|
||||
unsigned32 data0; /* private to "driver" */
|
||||
unsigned32 data1; /* ... */
|
||||
} rtems_libio_t;
|
||||
|
||||
|
||||
/*
|
||||
* param block for read/write
|
||||
* Note: it must include 'offset' instead of using iop's offset since
|
||||
* we can have multiple outstanding i/o's on a device.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
rtems_libio_offset_t offset;
|
||||
unsigned8 *buffer;
|
||||
unsigned32 count;
|
||||
unsigned32 flags;
|
||||
unsigned32 bytes_moved;
|
||||
} rtems_libio_rw_args_t;
|
||||
|
||||
/*
|
||||
* param block for open/close
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
unsigned32 flags;
|
||||
unsigned32 mode;
|
||||
} rtems_libio_open_close_args_t;
|
||||
|
||||
/*
|
||||
* param block for ioctl
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
unsigned32 command;
|
||||
void *buffer;
|
||||
unsigned32 ioctl_return;
|
||||
} rtems_libio_ioctl_args_t;
|
||||
|
||||
|
||||
/*
|
||||
* Values for 'flag'
|
||||
*/
|
||||
|
||||
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
|
||||
#define LIBIO_FLAGS_READ 0x0002 /* reading */
|
||||
#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
|
||||
#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */
|
||||
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
|
||||
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
|
||||
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
|
||||
|
||||
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
|
||||
|
||||
void rtems_libio_config(rtems_configuration_table *config, unsigned32 max_fds);
|
||||
void rtems_libio_init(void);
|
||||
|
||||
int __open(const char *pathname, unsigned32 flag, unsigned32 mode);
|
||||
int __close(int fd);
|
||||
int __read(int fd, void *buffer, unsigned32 count);
|
||||
int __write(int fd, const void *buffer, unsigned32 count);
|
||||
int __ioctl(int fd, unsigned32 command, void *buffer);
|
||||
int __lseek(int fd, rtems_libio_offset_t offset, int whence);
|
||||
|
||||
#endif /* _RTEMS_LIBIO_H */
|
||||
@@ -21,7 +21,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <rtems.h>
|
||||
#include <iosupp.h>
|
||||
#include <clockdrv.h>
|
||||
#include <rtems/ttydrv.h>
|
||||
#include <libcsupport.h>
|
||||
|
||||
/*
|
||||
* Define the time limits for RTEMS Test Suite test durations.
|
||||
@@ -64,6 +66,18 @@ extern void Clock_delay(rtems_unsigned32 microseconds);
|
||||
#define delay( microseconds ) \
|
||||
Clock_delay(microseconds);
|
||||
|
||||
/*
|
||||
* Todo: this should be put somewhere else
|
||||
*/
|
||||
|
||||
#undef CLOCK_DRIVER_TABLE_ENTRY
|
||||
#define CLOCK_DRIVER_TABLE_ENTRY { Clock_initialize, NULL, NULL, NULL, NULL, Clock_control }
|
||||
rtems_device_driver Clock_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
);
|
||||
|
||||
/*
|
||||
* We printf() to a buffer if multiprocessing, *or* if this is set.
|
||||
* ref: src/lib/libbsp/hppa/simhppa/iosupp/consupp.c
|
||||
@@ -71,8 +85,23 @@ extern void Clock_delay(rtems_unsigned32 microseconds);
|
||||
|
||||
extern int use_print_buffer;
|
||||
|
||||
/*
|
||||
* When not doing printf to a buffer, we do printf thru RTEMS libio
|
||||
* and our tty driver. Set it up so that console is right.
|
||||
*/
|
||||
|
||||
#define CONSOLE_DRIVER_TABLE_ENTRY \
|
||||
{ tty_initialize, tty_open, tty_close, tty_read, tty_write, tty_control }
|
||||
|
||||
/*
|
||||
* How many libio files we want
|
||||
*/
|
||||
#define BSP_LIBIO_MAX_FDS 20
|
||||
|
||||
#define HPPA_INTERRUPT_EXTERNAL_MPCI HPPA_INTERRUPT_EXTERNAL_10
|
||||
|
||||
rtems_isr_entry set_vector(rtems_isr_entry, rtems_vector_number, int);
|
||||
|
||||
void bsp_start( void );
|
||||
void bsp_cleanup( void );
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* @(#)bspstart.c 1.14 - 95/05/16
|
||||
*
|
||||
* @(#)bspstart.c 1.16 - 95/06/28
|
||||
*/
|
||||
|
||||
/* bsp_start()
|
||||
@@ -24,13 +23,17 @@
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* bspstart.c,v 1.2 1995/05/09 20:17:33 joel Exp
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <libcsupport.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
#include <stackchk.h>
|
||||
@@ -127,8 +130,17 @@ bsp_libc_init(void)
|
||||
|
||||
RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0);
|
||||
|
||||
/*
|
||||
* Init the RTEMS libio facility to provide UNIX-like system
|
||||
* calls for use by newlib (ie: provide __open, __close, etc)
|
||||
* Uses malloc() to get area for the iops, so must be after malloc init
|
||||
*/
|
||||
|
||||
rtems_libio_init();
|
||||
|
||||
/*
|
||||
* Set up for the libc handling.
|
||||
* XXX; this should allow for case of some other non-clock interrupts
|
||||
*/
|
||||
|
||||
if (BSP_Configuration.ticks_per_timeslice > 0)
|
||||
@@ -219,6 +231,32 @@ bsp_pretasking_hook(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* After drivers are setup, register some "filenames"
|
||||
* and open stdin, stdout, stderr files
|
||||
*
|
||||
* Newlib will automatically associate the files with these
|
||||
* (it hardcodes the numbers)
|
||||
*/
|
||||
|
||||
void
|
||||
bsp_postdriver_hook(void)
|
||||
{
|
||||
int stdin_fd, stdout_fd, stderr_fd;
|
||||
|
||||
if ((stdin_fd = __open("/dev/tty00", O_RDONLY, 0)) == -1)
|
||||
rtems_fatal_error_occurred('STD0');
|
||||
|
||||
if ((stdout_fd = __open("/dev/tty00", O_WRONLY, 0)) == -1)
|
||||
rtems_fatal_error_occurred('STD1');
|
||||
|
||||
if ((stderr_fd = __open("/dev/tty00", O_WRONLY, 0)) == -1)
|
||||
rtems_fatal_error_occurred('STD2');
|
||||
|
||||
if ((stdin_fd != 0) || (stdout_fd != 1) || (stderr_fd != 2))
|
||||
rtems_fatal_error_occurred('STIO');
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: bsp_start
|
||||
* Created: 94/12/6
|
||||
@@ -289,7 +327,7 @@ bsp_start(void)
|
||||
|
||||
Cpu_table.predriver_hook = NULL;
|
||||
|
||||
Cpu_table.postdriver_hook = NULL;
|
||||
Cpu_table.postdriver_hook = bsp_postdriver_hook; /* register drivers */
|
||||
|
||||
Cpu_table.idle_task = NULL; /* do not override system IDLE task */
|
||||
|
||||
@@ -342,21 +380,27 @@ bsp_start(void)
|
||||
#endif
|
||||
|
||||
#ifdef STACK_CHECKER_ON
|
||||
/*
|
||||
* Add 1 extension for stack checker
|
||||
*/
|
||||
/*
|
||||
* Add 1 extension for stack checker
|
||||
*/
|
||||
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
#endif
|
||||
|
||||
#if SIMHPPA_FAST_IDLE
|
||||
/*
|
||||
* Add 1 extension for fast idle
|
||||
*/
|
||||
/*
|
||||
* Add 1 extension for fast idle
|
||||
*/
|
||||
|
||||
BSP_Configuration.maximum_extensions++;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tell libio how many fd's we want and allow it to tweak config
|
||||
*/
|
||||
|
||||
rtems_libio_config(&BSP_Configuration, BSP_LIBIO_MAX_FDS);
|
||||
|
||||
/*
|
||||
* Add 1 extension for MPCI_fatal
|
||||
*/
|
||||
|
||||
@@ -16,20 +16,24 @@
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* poll.c,v 1.2 1995/05/09 20:22:57 joel Exp
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/sysstate.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include "shm.h"
|
||||
#include "clockdrv.h"
|
||||
|
||||
void Shm_Poll()
|
||||
{
|
||||
rtems_unsigned32 tmpfront;
|
||||
rtems_libio_ioctl_args_t args;
|
||||
|
||||
Clock_isr( 0 ); /* invoke standard clock ISR */
|
||||
|
||||
/* invoke clock isr */
|
||||
args.iop = 0;
|
||||
args.command = rtems_build_name('I', 'S', 'R', ' ');
|
||||
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
|
||||
|
||||
/*
|
||||
* Check for msgs only if we are "up"
|
||||
@@ -39,14 +43,11 @@ void Shm_Poll()
|
||||
|
||||
if (_System_state_Is_up(_System_state_Get()))
|
||||
{
|
||||
/* enable_tracing(); */
|
||||
/* ticks += 1; */
|
||||
Shm_Lock( Shm_Local_receive_queue );
|
||||
tmpfront = Shm_Local_receive_queue->front;
|
||||
Shm_Unlock( Shm_Local_receive_queue );
|
||||
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list ) {
|
||||
rtems_multiprocessing_announce();
|
||||
Shm_Interrupt_count++;
|
||||
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list )
|
||||
{
|
||||
rtems_multiprocessing_announce();
|
||||
Shm_Interrupt_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,16 @@
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include "shm.h"
|
||||
#include "clockdrv.h"
|
||||
|
||||
rtems_isr Shm_setclockvec()
|
||||
{
|
||||
ReInstall_clock( Shm_Poll );
|
||||
rtems_libio_ioctl_args_t args;
|
||||
args.iop = 0;
|
||||
args.command = rtems_build_name('N', 'E', 'W', ' ');
|
||||
args.buffer = (void *) Shm_Poll;
|
||||
|
||||
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __SHM_h
|
||||
#define __SHM_h
|
||||
|
||||
#include <clockdrv.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -518,6 +520,7 @@ extern rtems_mpci_table MPCI_table;
|
||||
|
||||
rtems_mpci_table MPCI_table = {
|
||||
100000, /* default timeout value in ticks */
|
||||
MAX_PACKET_SIZE, /* maximum packet size */
|
||||
Shm_Initialization, /* initialization procedure */
|
||||
Shm_Get_packet, /* get packet procedure */
|
||||
Shm_Return_packet, /* return packet procedure */
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __SHM_h
|
||||
#define __SHM_h
|
||||
|
||||
#include <clockdrv.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -518,6 +520,7 @@ extern rtems_mpci_table MPCI_table;
|
||||
|
||||
rtems_mpci_table MPCI_table = {
|
||||
100000, /* default timeout value in ticks */
|
||||
MAX_PACKET_SIZE, /* maximum packet size */
|
||||
Shm_Initialization, /* initialization procedure */
|
||||
Shm_Get_packet, /* get packet procedure */
|
||||
Shm_Return_packet, /* return packet procedure */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Clock
|
||||
*
|
||||
* This routine initializes the interval timer on the
|
||||
* PA-RISC CPU. The tick frequency is specified by the bsp.
|
||||
* This routine generates clock ticks using standard POSIX services.
|
||||
* The tick frequency is specified by the bsp.
|
||||
*
|
||||
* COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
|
||||
* On-Line Applications Research Corporation (OAR).
|
||||
@@ -15,62 +15,44 @@
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <bsp.h>
|
||||
|
||||
/*
|
||||
* In order to get the types and prototypes used in this file under
|
||||
* Solaris 2.3, it is necessary to pull the following magic.
|
||||
*/
|
||||
|
||||
#if defined(solaris)
|
||||
#warning "Ignore the undefining __STDC__ warning"
|
||||
#undef __STDC__
|
||||
#define __STDC__ 0
|
||||
#undef _POSIX_C_SOURCE
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
extern rtems_configuration_table Configuration;
|
||||
extern sigset_t UNIX_SIGNAL_MASK;
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
|
||||
void Install_clock();
|
||||
void Clock_isr();
|
||||
void Clock_exit();
|
||||
|
||||
/*
|
||||
* CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32
|
||||
* allocated and set by bsp_start()
|
||||
*/
|
||||
|
||||
#ifndef CPU_HPPA_CLICKS_PER_TICK
|
||||
extern rtems_unsigned32 CPU_HPPA_CLICKS_PER_TICK;
|
||||
#endif
|
||||
void Clock_exit(void);
|
||||
|
||||
volatile rtems_unsigned32 Clock_driver_ticks;
|
||||
|
||||
struct itimerval new;
|
||||
/*
|
||||
* These are set by clock driver during its init
|
||||
*/
|
||||
|
||||
rtems_device_driver
|
||||
Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp,
|
||||
rtems_id tid,
|
||||
rtems_unsigned32 *rval
|
||||
)
|
||||
{
|
||||
Install_clock(Clock_isr);
|
||||
}
|
||||
|
||||
void
|
||||
ReInstall_clock(rtems_isr_entry new_clock_isr)
|
||||
{
|
||||
rtems_unsigned32 isrlevel = 0;
|
||||
|
||||
rtems_interrupt_disable(isrlevel);
|
||||
(void)set_vector(new_clock_isr, SIGALRM, 1);
|
||||
rtems_interrupt_enable(isrlevel);
|
||||
}
|
||||
rtems_device_major_number rtems_clock_major = ~0;
|
||||
rtems_device_minor_number rtems_clock_minor;
|
||||
|
||||
void
|
||||
Install_clock(rtems_isr_entry clock_isr)
|
||||
{
|
||||
struct itimerval new;
|
||||
|
||||
Clock_driver_ticks = 0;
|
||||
|
||||
new.it_value.tv_sec = 0;
|
||||
@@ -85,11 +67,20 @@ Install_clock(rtems_isr_entry clock_isr)
|
||||
atexit(Clock_exit);
|
||||
}
|
||||
|
||||
void
|
||||
ReInstall_clock(rtems_isr_entry new_clock_isr)
|
||||
{
|
||||
rtems_unsigned32 isrlevel = 0;
|
||||
|
||||
rtems_interrupt_disable(isrlevel);
|
||||
(void)set_vector(new_clock_isr, SIGALRM, 1);
|
||||
rtems_interrupt_enable(isrlevel);
|
||||
}
|
||||
|
||||
void
|
||||
Clock_isr(int vector)
|
||||
{
|
||||
Clock_driver_ticks++;
|
||||
|
||||
rtems_clock_tick();
|
||||
}
|
||||
|
||||
@@ -101,6 +92,7 @@ Clock_isr(int vector)
|
||||
void
|
||||
Clock_exit(void)
|
||||
{
|
||||
struct itimerval new;
|
||||
struct sigaction act;
|
||||
|
||||
/*
|
||||
@@ -121,3 +113,50 @@ Clock_exit(void)
|
||||
|
||||
(void)set_vector(0, SIGALRM, 1);
|
||||
}
|
||||
|
||||
rtems_device_driver
|
||||
Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
Install_clock((rtems_isr_entry) Clock_isr);
|
||||
|
||||
/*
|
||||
* make major/minor avail to others such as shared memory driver
|
||||
*/
|
||||
rtems_clock_major = major;
|
||||
rtems_clock_minor = minor;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver Clock_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *args = pargp;
|
||||
|
||||
if (args == 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* This is hokey, but until we get a defined interface
|
||||
* to do this, it will just be this simple...
|
||||
*/
|
||||
|
||||
if (args->command == rtems_build_name('I', 'S', 'R', ' '))
|
||||
{
|
||||
Clock_isr(SIGALRM);
|
||||
}
|
||||
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
|
||||
{
|
||||
ReInstall_clock(args->buffer);
|
||||
}
|
||||
|
||||
done:
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,9 @@
|
||||
rtems_device_driver
|
||||
console_initialize(rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void * arg,
|
||||
rtems_id self,
|
||||
rtems_unsigned32 * status)
|
||||
void * arg
|
||||
)
|
||||
{
|
||||
*status = RTEMS_SUCCESSFUL;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,20 @@ extern rtems_configuration_table BSP_Configuration;
|
||||
*/
|
||||
|
||||
/* #define INTERRUPT_EXTERNAL_MPCI SIGUSR1 */
|
||||
|
||||
/*
|
||||
* Console driver init
|
||||
*/
|
||||
|
||||
rtems_device_driver console_initialize(
|
||||
rtems_device_major_number, rtems_device_minor_number minor, void *);
|
||||
|
||||
#define CONSOLE_DRIVER_TABLE_ENTRY \
|
||||
{ console_initialize, NULL, NULL, NULL, NULL, NULL }
|
||||
|
||||
/*
|
||||
* NOTE: Use the standard Clock driver entry
|
||||
*/
|
||||
|
||||
/* functions */
|
||||
|
||||
|
||||
258
c/src/lib/libc/assoc.c
Normal file
258
c/src/lib/libc/assoc.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* @(#)assoc.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* assoc.c
|
||||
* rtems assoc routines
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <string.h> /* strcat, strcmp */
|
||||
|
||||
#define STREQ(a,b) (strcmp((a), (b)) == 0)
|
||||
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (strcmp(ap->name, name) == 0)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->local_value == local_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->remote_value == remote_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get values
|
||||
*/
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* what to return if a value is not found
|
||||
* this is not reentrant, but it really shouldn't be invoked anyway
|
||||
*/
|
||||
|
||||
char *
|
||||
rtems_assoc_name_bad(
|
||||
unsigned32 bad_value
|
||||
)
|
||||
{
|
||||
static char bad_buffer[32];
|
||||
|
||||
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
|
||||
return bad_buffer;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(local_value);
|
||||
}
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(remote_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitfield functions assume just 1 bit set in each of remote and local
|
||||
* entries; they do not check for this.
|
||||
*/
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 remote_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & local_value)
|
||||
remote_value |= rtems_assoc_remote_by_local(ap, b);
|
||||
|
||||
return remote_value;
|
||||
}
|
||||
|
||||
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 local_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & remote_value)
|
||||
local_value |= rtems_assoc_local_by_remote(ap, b);
|
||||
|
||||
return local_value;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_local(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
44
c/src/lib/libc/assoc.h
Normal file
44
c/src/lib/libc/assoc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @(#)assoc.h 1.2 - 95/06/28
|
||||
*
|
||||
*
|
||||
* Rtems associativity routines. Mainly used to convert a value from
|
||||
* one space to another (eg: our errno's to host errno's and v.v)
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_ASSOC_H
|
||||
#define _INCLUDE_ASSOC_H
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned32 local_value;
|
||||
unsigned32 remote_value;
|
||||
} rtems_assoc_t;
|
||||
|
||||
/*
|
||||
* Flag/marker for optional default value in each table
|
||||
*/
|
||||
|
||||
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
|
||||
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
|
||||
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
|
||||
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
|
||||
|
||||
|
||||
#endif /* ! _INCLUDE_ASSOC_H */
|
||||
212
c/src/lib/libc/error.c
Normal file
212
c/src/lib/libc/error.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* @(#)error.c 1.2 - 95/08/02
|
||||
*
|
||||
*
|
||||
* report errors and panics to RTEMS' stderr.
|
||||
* Currently just used by RTEMS monitor.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* These routines provide general purpose error reporting.
|
||||
* rtems_error reports an error to stderr and allows use of
|
||||
* printf style formatting. A newline is appended to all messages.
|
||||
*
|
||||
* error_flag can be specified as any of the following:
|
||||
*
|
||||
* RTEMS_ERROR_ERRNO -- include errno text in output
|
||||
* RTEMS_ERROR_PANIC -- halts local system after output
|
||||
* RTEMS_ERROR_ABORT -- abort after output
|
||||
*
|
||||
* It can also include a rtems_status value which can be OR'd
|
||||
* with the above flags. *
|
||||
*
|
||||
* EXAMPLE
|
||||
* #include <rtems.h>
|
||||
* #include <rtems/error.h>
|
||||
* rtems_error(0, "stray interrupt %d", intr);
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
|
||||
* {
|
||||
* rtems_error(status | RTEMS_ERROR_ABORT,
|
||||
* "could not create task");
|
||||
* }
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((fd = open(pathname, O_RDNLY)) < 0)
|
||||
* {
|
||||
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
|
||||
* goto failed;
|
||||
* }
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* _exit() */
|
||||
|
||||
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
|
||||
#ifdef hpux9
|
||||
char *strerror(int);
|
||||
#endif
|
||||
|
||||
extern char *rtems_progname;
|
||||
int rtems_panic_in_progress;
|
||||
|
||||
rtems_assoc_t rtems_status_assoc[] = {
|
||||
{ "successful completion", RTEMS_SUCCESSFUL, },
|
||||
{ "returned from a thread", RTEMS_TASK_EXITTED, },
|
||||
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
|
||||
{ "invalid object name", RTEMS_INVALID_NAME, },
|
||||
{ "invalid object id", RTEMS_INVALID_ID, },
|
||||
{ "too many", RTEMS_TOO_MANY, },
|
||||
{ "timed out waiting", RTEMS_TIMEOUT, },
|
||||
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
|
||||
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
|
||||
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
|
||||
{ "number was invalid", RTEMS_INVALID_NUMBER, },
|
||||
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
|
||||
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
|
||||
{ "request not satisfied", RTEMS_UNSATISFIED, },
|
||||
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
|
||||
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
|
||||
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
|
||||
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
|
||||
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
|
||||
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
|
||||
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
|
||||
{ "invalid node id", RTEMS_INVALID_NODE, },
|
||||
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
|
||||
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
|
||||
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
|
||||
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
|
||||
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
|
||||
{ "could not get enough memory", RTEMS_NO_MEMORY, },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
rtems_status_text(
|
||||
rtems_status_code status
|
||||
)
|
||||
{
|
||||
return rtems_assoc_name_by_local(rtems_status_assoc, status);
|
||||
}
|
||||
|
||||
|
||||
static int rtems_verror(
|
||||
unsigned32 error_flag,
|
||||
char *printf_format,
|
||||
va_list arglist
|
||||
)
|
||||
{
|
||||
int local_errno = 0;
|
||||
int chars_written = 0;
|
||||
rtems_status_code status;
|
||||
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_panic_in_progress++;
|
||||
|
||||
/* disable task switches */
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/* don't aggravate things */
|
||||
if (rtems_panic_in_progress > 2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) fflush(stdout); /* in case stdout/stderr same */
|
||||
|
||||
status = error_flag & ~RTEMS_ERROR_MASK;
|
||||
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
|
||||
local_errno = errno;
|
||||
|
||||
if (_Configuration_Is_multiprocessing())
|
||||
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
|
||||
|
||||
if (rtems_progname && *rtems_progname)
|
||||
chars_written += fprintf(stderr, "%s: ", rtems_progname);
|
||||
chars_written += vfprintf(stderr, printf_format, arglist);
|
||||
|
||||
if (status)
|
||||
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
|
||||
|
||||
if (local_errno)
|
||||
if ((local_errno > 0) && *strerror(local_errno))
|
||||
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
|
||||
else
|
||||
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
|
||||
|
||||
chars_written += fprintf(stderr, "\n");
|
||||
|
||||
(void) fflush(stderr);
|
||||
|
||||
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
|
||||
{
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_error(0, "fatal error, exiting");
|
||||
_exit(local_errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_error(0, "fatal error, aborting");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Report an error.
|
||||
* error_flag is as above; printf_format is a normal
|
||||
* printf(3) format string, with its concommitant arguments.
|
||||
*
|
||||
* Returns the number of characters written.
|
||||
*/
|
||||
|
||||
int rtems_error(
|
||||
int error_flag,
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
int chars_written;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
chars_written = rtems_verror(error_flag, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
|
||||
*/
|
||||
|
||||
void rtems_panic(
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
26
c/src/lib/libc/error.h
Normal file
26
c/src/lib/libc/error.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @(#)error.h 1.1 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Defines and externs for rtems error reporting
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* rtems_error() and rtems_panic() support
|
||||
*/
|
||||
|
||||
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
||||
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
|
||||
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
|
||||
|
||||
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
|
||||
RTEMS_ERROR_PANIC) /* all */
|
||||
|
||||
char *rtems_status_text(rtems_status_code);
|
||||
int rtems_error(int error_code, char *printf_format, ...);
|
||||
void rtems_panic(char *printf_format, ...);
|
||||
|
||||
extern int rtems_panic_in_progress;
|
||||
|
||||
433
c/src/lib/libc/libio.c
Normal file
433
c/src/lib/libc/libio.c
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* @(#)libio.c 1.1 - 95/06/02
|
||||
*
|
||||
*
|
||||
* Provide UNIX/POSIX-like io system calls for RTEMS using the
|
||||
* RTEMS IO manager
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/assoc.h> /* assoc.h not included by rtems.h */
|
||||
|
||||
#include <fcntl.h> /* O_RDONLY, et.al. */
|
||||
#if defined(solaris2)
|
||||
#define O_NDELAY O_NONBLOCK
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h> /* strcmp */
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h> /* calloc() */
|
||||
|
||||
#include "libio.h" /* libio.h not pulled in by rtems */
|
||||
|
||||
/*
|
||||
* Semaphore to protect the io table
|
||||
*/
|
||||
|
||||
Objects_Id rtems_libio_semaphore;
|
||||
|
||||
#define RTEMS_LIBIO_SEM rtems_build_name('L', 'B', 'I', 'O')
|
||||
#define RTEMS_LIBIO_IOP_SEM(n) rtems_build_name('L', 'B', 'I', n)
|
||||
|
||||
unsigned32 rtems_libio_number_iops;
|
||||
rtems_libio_t *rtems_libio_iops;
|
||||
rtems_libio_t *rtems_libio_last_iop;
|
||||
|
||||
#define rtems_libio_iop(fd) ((((unsigned32)(fd)) < rtems_libio_number_iops) ? \
|
||||
&rtems_libio_iops[fd] : 0)
|
||||
|
||||
#define rtems_libio_check_fd(fd) \
|
||||
do { \
|
||||
if ((fd) >= rtems_libio_number_iops) \
|
||||
{ \
|
||||
errno = EBADF; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rtems_libio_check_buffer(buffer) \
|
||||
do { \
|
||||
if ((buffer) == 0) \
|
||||
{ \
|
||||
errno = EINVAL; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rtems_libio_check_count(count) \
|
||||
do { \
|
||||
if ((count) == 0) \
|
||||
{ \
|
||||
return 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rtems_libio_check_permissions(iop, flag) \
|
||||
do { \
|
||||
if (((iop)->flags & (flag)) == 0) \
|
||||
{ \
|
||||
errno = EINVAL; \
|
||||
return -1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
void
|
||||
rtems_libio_config(
|
||||
rtems_configuration_table *config,
|
||||
unsigned32 max_fds
|
||||
)
|
||||
{
|
||||
rtems_libio_number_iops = max_fds;
|
||||
|
||||
/*
|
||||
* tweak config to reflect # of semaphores we will need
|
||||
*/
|
||||
|
||||
config->maximum_semaphores += 1; /* one for iop table */
|
||||
config->maximum_semaphores += max_fds;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by bsp startup code to init the libio area.
|
||||
*/
|
||||
|
||||
void
|
||||
rtems_libio_init(void)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
|
||||
if (rtems_libio_number_iops > 0)
|
||||
{
|
||||
rtems_libio_iops = (rtems_libio_t *) calloc(rtems_libio_number_iops,
|
||||
sizeof(rtems_libio_t));
|
||||
if (rtems_libio_iops == NULL)
|
||||
rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
|
||||
|
||||
rtems_libio_last_iop = rtems_libio_iops + (rtems_libio_number_iops - 1);
|
||||
}
|
||||
|
||||
rc = rtems_semaphore_create(RTEMS_LIBIO_SEM,
|
||||
1,
|
||||
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
&rtems_libio_semaphore);
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
rtems_fatal_error_occurred(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert RTEMS status to a UNIX errno
|
||||
*/
|
||||
|
||||
rtems_assoc_t errno_assoc[] = {
|
||||
{ "OK", RTEMS_SUCCESSFUL, 0 },
|
||||
{ "TIMEOUT", RTEMS_TIMEOUT, ETIME },
|
||||
{ "NO MEMORY", RTEMS_NO_MEMORY, ENOMEM },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static unsigned32
|
||||
rtems_libio_errno(rtems_status_code code)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((rc = rtems_assoc_remote_by_local(errno_assoc, (unsigned32) code)))
|
||||
{
|
||||
errno = rc;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert UNIX fnctl(2) flags to ones that RTEMS drivers understand
|
||||
*/
|
||||
|
||||
rtems_assoc_t access_modes_assoc[] = {
|
||||
{ "READ", LIBIO_FLAGS_READ, O_RDONLY },
|
||||
{ "WRITE", LIBIO_FLAGS_WRITE, O_WRONLY },
|
||||
{ "READ/WRITE", LIBIO_FLAGS_READ_WRITE, O_RDWR },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
rtems_assoc_t status_flags_assoc[] = {
|
||||
{ "NO DELAY", LIBIO_FLAGS_NO_DELAY, O_NDELAY },
|
||||
{ "APPEND", LIBIO_FLAGS_APPEND, O_APPEND },
|
||||
{ "CREATE", LIBIO_FLAGS_CREATE, O_CREAT },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
static unsigned32
|
||||
rtems_libio_fcntl_flags(unsigned32 fcntl_flags)
|
||||
{
|
||||
unsigned32 flags = 0;
|
||||
unsigned32 access_modes;
|
||||
|
||||
/*
|
||||
* Access mode is a small integer
|
||||
*/
|
||||
|
||||
access_modes = fcntl_flags & O_ACCMODE;
|
||||
fcntl_flags &= ~O_ACCMODE;
|
||||
flags = rtems_assoc_local_by_remote(access_modes_assoc, access_modes);
|
||||
|
||||
/*
|
||||
* Everything else is single bits
|
||||
*/
|
||||
|
||||
flags |= rtems_assoc_local_by_remote_bitfield(status_flags_assoc, fcntl_flags);
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
static rtems_libio_t *
|
||||
rtems_libio_allocate(void)
|
||||
{
|
||||
rtems_libio_t *iop;
|
||||
rtems_status_code rc;
|
||||
|
||||
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
for (iop = rtems_libio_iops; iop <= rtems_libio_last_iop; iop++)
|
||||
if ((iop->flags & LIBIO_FLAGS_OPEN) == 0)
|
||||
{
|
||||
/*
|
||||
* Got one; create a semaphore for it
|
||||
*/
|
||||
|
||||
rc = rtems_semaphore_create(RTEMS_LIBIO_IOP_SEM(iop - rtems_libio_iops),
|
||||
1, RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
|
||||
&iop->sem);
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
goto failed;
|
||||
|
||||
iop->flags = LIBIO_FLAGS_OPEN;
|
||||
goto done;
|
||||
}
|
||||
|
||||
failed:
|
||||
iop = 0;
|
||||
|
||||
done:
|
||||
rtems_semaphore_release(rtems_libio_semaphore);
|
||||
return iop;
|
||||
}
|
||||
|
||||
static void
|
||||
rtems_libio_free(rtems_libio_t *iop)
|
||||
{
|
||||
rtems_semaphore_obtain(rtems_libio_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
|
||||
if (iop->sem)
|
||||
rtems_semaphore_delete(iop->sem);
|
||||
(void) memset(iop, 0, sizeof(*iop));
|
||||
|
||||
rtems_semaphore_release(rtems_libio_semaphore);
|
||||
}
|
||||
|
||||
int
|
||||
__open(
|
||||
const char *pathname,
|
||||
unsigned32 flag,
|
||||
unsigned32 mode)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_libio_t *iop = 0;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_open_close_args_t args;
|
||||
|
||||
if ((rc = rtems_io_lookup_name(pathname, &np)) != RTEMS_SUCCESSFUL)
|
||||
goto done;
|
||||
|
||||
iop = rtems_libio_allocate();
|
||||
if (iop == 0)
|
||||
{
|
||||
rc = RTEMS_TOO_MANY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
iop->driver = np;
|
||||
iop->pathname = (char *) pathname;
|
||||
iop->flags |= rtems_libio_fcntl_flags(flag);
|
||||
|
||||
args.iop = iop;
|
||||
args.flags = iop->flags;
|
||||
args.mode = mode;
|
||||
|
||||
rc = rtems_io_open(np->major, np->minor, (void *) &args);
|
||||
|
||||
done:
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
if (iop)
|
||||
rtems_libio_free(iop);
|
||||
return rtems_libio_errno(rc);
|
||||
}
|
||||
|
||||
return iop - rtems_libio_iops;
|
||||
}
|
||||
|
||||
int
|
||||
__close(
|
||||
int fd
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_open_close_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.flags = 0;
|
||||
args.mode = 0;
|
||||
|
||||
rc = rtems_io_close(np->major, np->minor, (void *) &args);
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__read(
|
||||
int fd,
|
||||
void * buffer,
|
||||
unsigned32 count
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_rw_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
rtems_libio_check_buffer(buffer);
|
||||
rtems_libio_check_count(count);
|
||||
rtems_libio_check_permissions(iop, LIBIO_FLAGS_READ);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.offset = iop->offset;
|
||||
args.buffer = buffer;
|
||||
args.count = count;
|
||||
args.flags = iop->flags;
|
||||
args.bytes_moved = 0;
|
||||
|
||||
rc = rtems_io_read(np->major, np->minor, (void *) &args);
|
||||
|
||||
iop->offset += args.bytes_moved;
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
|
||||
return args.bytes_moved;
|
||||
}
|
||||
|
||||
int
|
||||
__write(
|
||||
int fd,
|
||||
const void *buffer,
|
||||
unsigned32 count
|
||||
)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_rw_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
rtems_libio_check_buffer(buffer);
|
||||
rtems_libio_check_count(count);
|
||||
rtems_libio_check_permissions(iop, LIBIO_FLAGS_WRITE);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.offset = iop->offset;
|
||||
args.buffer = (void *) buffer;
|
||||
args.count = count;
|
||||
args.flags = iop->flags;
|
||||
args.bytes_moved = 0;
|
||||
|
||||
rc = rtems_io_write(np->major, np->minor, (void *) &args);
|
||||
|
||||
iop->offset += args.bytes_moved;
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
|
||||
return args.bytes_moved;
|
||||
}
|
||||
|
||||
int
|
||||
__ioctl(
|
||||
int fd,
|
||||
unsigned32 command,
|
||||
void * buffer)
|
||||
{
|
||||
rtems_status_code rc;
|
||||
rtems_driver_name_t *np;
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
rtems_libio_ioctl_args_t args;
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
|
||||
np = iop->driver;
|
||||
|
||||
args.iop = iop;
|
||||
args.command = command;
|
||||
args.buffer = buffer;
|
||||
|
||||
rc = rtems_io_control(np->major, np->minor, (void *) &args);
|
||||
|
||||
if (rc != RTEMS_SUCCESSFUL)
|
||||
return rtems_libio_errno(rc);
|
||||
|
||||
return args.ioctl_return;
|
||||
}
|
||||
|
||||
/*
|
||||
* internal only??
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
__lseek(
|
||||
int fd,
|
||||
rtems_libio_offset_t offset,
|
||||
int whence
|
||||
)
|
||||
{
|
||||
rtems_libio_t *iop = rtems_libio_iop(fd);
|
||||
|
||||
rtems_libio_check_fd(fd);
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
iop->offset = offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
iop->offset += offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
iop->offset = iop->size - offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
101
c/src/lib/libc/libio.h
Normal file
101
c/src/lib/libc/libio.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* @(#)libio.h 1.1 - 95/06/02
|
||||
*
|
||||
*
|
||||
* General purpose communication channel for RTEMS to allow UNIX/POSIX
|
||||
* system call behavior on top of RTEMS IO devices.
|
||||
*
|
||||
* TODO
|
||||
* stat(2)
|
||||
* unlink(2)
|
||||
* rename(2)
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _RTEMS_LIBIO_H
|
||||
#define _RTEMS_LIBIO_H
|
||||
|
||||
typedef unsigned32 rtems_libio_offset_t;
|
||||
|
||||
/*
|
||||
* An open file data structure, indexed by 'fd'
|
||||
* TODO:
|
||||
* should really have a separate per/file data structure that this
|
||||
* points to (eg: size, offset, driver, pathname should be in that)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_driver_name_t *driver;
|
||||
rtems_libio_offset_t size; /* size of file */
|
||||
rtems_libio_offset_t offset; /* current offset into the file */
|
||||
unsigned32 flags;
|
||||
char *pathname; /* opened pathname */
|
||||
Objects_Id sem;
|
||||
unsigned32 data0; /* private to "driver" */
|
||||
unsigned32 data1; /* ... */
|
||||
} rtems_libio_t;
|
||||
|
||||
|
||||
/*
|
||||
* param block for read/write
|
||||
* Note: it must include 'offset' instead of using iop's offset since
|
||||
* we can have multiple outstanding i/o's on a device.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
rtems_libio_offset_t offset;
|
||||
unsigned8 *buffer;
|
||||
unsigned32 count;
|
||||
unsigned32 flags;
|
||||
unsigned32 bytes_moved;
|
||||
} rtems_libio_rw_args_t;
|
||||
|
||||
/*
|
||||
* param block for open/close
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
unsigned32 flags;
|
||||
unsigned32 mode;
|
||||
} rtems_libio_open_close_args_t;
|
||||
|
||||
/*
|
||||
* param block for ioctl
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
rtems_libio_t *iop;
|
||||
unsigned32 command;
|
||||
void *buffer;
|
||||
unsigned32 ioctl_return;
|
||||
} rtems_libio_ioctl_args_t;
|
||||
|
||||
|
||||
/*
|
||||
* Values for 'flag'
|
||||
*/
|
||||
|
||||
#define LIBIO_FLAGS_NO_DELAY 0x0001 /* return immediately if no data */
|
||||
#define LIBIO_FLAGS_READ 0x0002 /* reading */
|
||||
#define LIBIO_FLAGS_WRITE 0x0004 /* writing */
|
||||
#define LIBIO_FLAGS_LINE_BUFFERED 0x0008 /* line buffered io (^h, ^u, etc) */
|
||||
#define LIBIO_FLAGS_OPEN 0x0100 /* device is open */
|
||||
#define LIBIO_FLAGS_APPEND 0x0200 /* all writes append */
|
||||
#define LIBIO_FLAGS_CREATE 0x0400 /* create file */
|
||||
|
||||
#define LIBIO_FLAGS_READ_WRITE (LIBIO_FLAGS_READ | LIBIO_FLAGS_WRITE)
|
||||
|
||||
void rtems_libio_config(rtems_configuration_table *config, unsigned32 max_fds);
|
||||
void rtems_libio_init(void);
|
||||
|
||||
int __open(const char *pathname, unsigned32 flag, unsigned32 mode);
|
||||
int __close(int fd);
|
||||
int __read(int fd, void *buffer, unsigned32 count);
|
||||
int __write(int fd, const void *buffer, unsigned32 count);
|
||||
int __ioctl(int fd, unsigned32 command, void *buffer);
|
||||
int __lseek(int fd, rtems_libio_offset_t offset, int whence);
|
||||
|
||||
#endif /* _RTEMS_LIBIO_H */
|
||||
@@ -35,27 +35,6 @@ __isatty(int _fd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
__close(int _fd)
|
||||
{
|
||||
/* return value usually ignored anyhow */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__open(const char *filename)
|
||||
{
|
||||
/* always fail */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
__lseek(int _fd, off_t offset, int whence)
|
||||
{
|
||||
/* nothing is ever seekable */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int stat( const char *path, struct stat *buf )
|
||||
{
|
||||
/* always fail */
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <bsp.h>
|
||||
#include <clockdrv.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <stdlib.h> /* for atexit() */
|
||||
|
||||
@@ -23,6 +24,13 @@ extern rtems_cpu_table Cpu_table; /* owned by BSP */
|
||||
|
||||
typedef unsigned long long hppa_click_count_t;
|
||||
|
||||
/*
|
||||
* These are set by clock driver during its init
|
||||
*/
|
||||
|
||||
rtems_device_major_number rtems_clock_major = ~0;
|
||||
rtems_device_minor_number rtems_clock_minor;
|
||||
|
||||
/*
|
||||
* CPU_HPPA_CLICKS_PER_TICK is either a #define or an rtems_unsigned32
|
||||
* allocated and set by bsp_start()
|
||||
@@ -41,16 +49,7 @@ rtems_unsigned64 Clock_clicks; /* running total of cycles */
|
||||
|
||||
rtems_unsigned32 Clock_clicks_interrupt;
|
||||
|
||||
rtems_device_driver Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp,
|
||||
rtems_id tid,
|
||||
rtems_unsigned32 *rval
|
||||
)
|
||||
{
|
||||
Install_clock(Clock_isr);
|
||||
}
|
||||
void Clock_exit(void);
|
||||
|
||||
void
|
||||
ReInstall_clock(rtems_isr_entry new_clock_isr)
|
||||
@@ -218,3 +217,48 @@ Clock_delay(rtems_unsigned32 microseconds)
|
||||
}
|
||||
}
|
||||
|
||||
rtems_device_driver Clock_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
Install_clock(Clock_isr);
|
||||
|
||||
/*
|
||||
* make major/minor avail to others such as shared memory driver
|
||||
*/
|
||||
rtems_clock_major = major;
|
||||
rtems_clock_minor = minor;
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver Clock_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *args = pargp;
|
||||
|
||||
if (args == 0)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* This is hokey, but until we get a defined interface
|
||||
* to do this, it will just be this simple...
|
||||
*/
|
||||
|
||||
if (args->command == rtems_build_name('I', 'S', 'R', ' '))
|
||||
{
|
||||
Clock_isr(HPPA_INTERRUPT_EXTERNAL_INTERVAL_TIMER);
|
||||
}
|
||||
else if (args->command == rtems_build_name('N', 'E', 'W', ' '))
|
||||
{
|
||||
ReInstall_clock(args->buffer);
|
||||
}
|
||||
|
||||
done:
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
258
c/src/lib/libmisc/assoc/assoc.c
Normal file
258
c/src/lib/libmisc/assoc/assoc.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* @(#)assoc.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* assoc.c
|
||||
* rtems assoc routines
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <string.h> /* strcat, strcmp */
|
||||
|
||||
#define STREQ(a,b) (strcmp((a), (b)) == 0)
|
||||
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (strcmp(ap->name, name) == 0)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->local_value == local_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->remote_value == remote_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get values
|
||||
*/
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* what to return if a value is not found
|
||||
* this is not reentrant, but it really shouldn't be invoked anyway
|
||||
*/
|
||||
|
||||
char *
|
||||
rtems_assoc_name_bad(
|
||||
unsigned32 bad_value
|
||||
)
|
||||
{
|
||||
static char bad_buffer[32];
|
||||
|
||||
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
|
||||
return bad_buffer;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(local_value);
|
||||
}
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(remote_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitfield functions assume just 1 bit set in each of remote and local
|
||||
* entries; they do not check for this.
|
||||
*/
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 remote_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & local_value)
|
||||
remote_value |= rtems_assoc_remote_by_local(ap, b);
|
||||
|
||||
return remote_value;
|
||||
}
|
||||
|
||||
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 local_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & remote_value)
|
||||
local_value |= rtems_assoc_local_by_remote(ap, b);
|
||||
|
||||
return local_value;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_local(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
44
c/src/lib/libmisc/assoc/assoc.h
Normal file
44
c/src/lib/libmisc/assoc/assoc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @(#)assoc.h 1.2 - 95/06/28
|
||||
*
|
||||
*
|
||||
* Rtems associativity routines. Mainly used to convert a value from
|
||||
* one space to another (eg: our errno's to host errno's and v.v)
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_ASSOC_H
|
||||
#define _INCLUDE_ASSOC_H
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned32 local_value;
|
||||
unsigned32 remote_value;
|
||||
} rtems_assoc_t;
|
||||
|
||||
/*
|
||||
* Flag/marker for optional default value in each table
|
||||
*/
|
||||
|
||||
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
|
||||
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
|
||||
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
|
||||
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
|
||||
|
||||
|
||||
#endif /* ! _INCLUDE_ASSOC_H */
|
||||
212
c/src/lib/libmisc/error/error.c
Normal file
212
c/src/lib/libmisc/error/error.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* @(#)error.c 1.2 - 95/08/02
|
||||
*
|
||||
*
|
||||
* report errors and panics to RTEMS' stderr.
|
||||
* Currently just used by RTEMS monitor.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* These routines provide general purpose error reporting.
|
||||
* rtems_error reports an error to stderr and allows use of
|
||||
* printf style formatting. A newline is appended to all messages.
|
||||
*
|
||||
* error_flag can be specified as any of the following:
|
||||
*
|
||||
* RTEMS_ERROR_ERRNO -- include errno text in output
|
||||
* RTEMS_ERROR_PANIC -- halts local system after output
|
||||
* RTEMS_ERROR_ABORT -- abort after output
|
||||
*
|
||||
* It can also include a rtems_status value which can be OR'd
|
||||
* with the above flags. *
|
||||
*
|
||||
* EXAMPLE
|
||||
* #include <rtems.h>
|
||||
* #include <rtems/error.h>
|
||||
* rtems_error(0, "stray interrupt %d", intr);
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
|
||||
* {
|
||||
* rtems_error(status | RTEMS_ERROR_ABORT,
|
||||
* "could not create task");
|
||||
* }
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((fd = open(pathname, O_RDNLY)) < 0)
|
||||
* {
|
||||
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
|
||||
* goto failed;
|
||||
* }
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* _exit() */
|
||||
|
||||
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
|
||||
#ifdef hpux9
|
||||
char *strerror(int);
|
||||
#endif
|
||||
|
||||
extern char *rtems_progname;
|
||||
int rtems_panic_in_progress;
|
||||
|
||||
rtems_assoc_t rtems_status_assoc[] = {
|
||||
{ "successful completion", RTEMS_SUCCESSFUL, },
|
||||
{ "returned from a thread", RTEMS_TASK_EXITTED, },
|
||||
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
|
||||
{ "invalid object name", RTEMS_INVALID_NAME, },
|
||||
{ "invalid object id", RTEMS_INVALID_ID, },
|
||||
{ "too many", RTEMS_TOO_MANY, },
|
||||
{ "timed out waiting", RTEMS_TIMEOUT, },
|
||||
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
|
||||
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
|
||||
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
|
||||
{ "number was invalid", RTEMS_INVALID_NUMBER, },
|
||||
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
|
||||
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
|
||||
{ "request not satisfied", RTEMS_UNSATISFIED, },
|
||||
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
|
||||
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
|
||||
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
|
||||
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
|
||||
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
|
||||
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
|
||||
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
|
||||
{ "invalid node id", RTEMS_INVALID_NODE, },
|
||||
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
|
||||
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
|
||||
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
|
||||
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
|
||||
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
|
||||
{ "could not get enough memory", RTEMS_NO_MEMORY, },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
rtems_status_text(
|
||||
rtems_status_code status
|
||||
)
|
||||
{
|
||||
return rtems_assoc_name_by_local(rtems_status_assoc, status);
|
||||
}
|
||||
|
||||
|
||||
static int rtems_verror(
|
||||
unsigned32 error_flag,
|
||||
char *printf_format,
|
||||
va_list arglist
|
||||
)
|
||||
{
|
||||
int local_errno = 0;
|
||||
int chars_written = 0;
|
||||
rtems_status_code status;
|
||||
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_panic_in_progress++;
|
||||
|
||||
/* disable task switches */
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/* don't aggravate things */
|
||||
if (rtems_panic_in_progress > 2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) fflush(stdout); /* in case stdout/stderr same */
|
||||
|
||||
status = error_flag & ~RTEMS_ERROR_MASK;
|
||||
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
|
||||
local_errno = errno;
|
||||
|
||||
if (_Configuration_Is_multiprocessing())
|
||||
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
|
||||
|
||||
if (rtems_progname && *rtems_progname)
|
||||
chars_written += fprintf(stderr, "%s: ", rtems_progname);
|
||||
chars_written += vfprintf(stderr, printf_format, arglist);
|
||||
|
||||
if (status)
|
||||
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
|
||||
|
||||
if (local_errno)
|
||||
if ((local_errno > 0) && *strerror(local_errno))
|
||||
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
|
||||
else
|
||||
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
|
||||
|
||||
chars_written += fprintf(stderr, "\n");
|
||||
|
||||
(void) fflush(stderr);
|
||||
|
||||
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
|
||||
{
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_error(0, "fatal error, exiting");
|
||||
_exit(local_errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_error(0, "fatal error, aborting");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Report an error.
|
||||
* error_flag is as above; printf_format is a normal
|
||||
* printf(3) format string, with its concommitant arguments.
|
||||
*
|
||||
* Returns the number of characters written.
|
||||
*/
|
||||
|
||||
int rtems_error(
|
||||
int error_flag,
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
int chars_written;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
chars_written = rtems_verror(error_flag, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
|
||||
*/
|
||||
|
||||
void rtems_panic(
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
26
c/src/lib/libmisc/error/error.h
Normal file
26
c/src/lib/libmisc/error/error.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @(#)error.h 1.1 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Defines and externs for rtems error reporting
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* rtems_error() and rtems_panic() support
|
||||
*/
|
||||
|
||||
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
||||
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
|
||||
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
|
||||
|
||||
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
|
||||
RTEMS_ERROR_PANIC) /* all */
|
||||
|
||||
char *rtems_status_text(rtems_status_code);
|
||||
int rtems_error(int error_code, char *printf_format, ...);
|
||||
void rtems_panic(char *printf_format, ...);
|
||||
|
||||
extern int rtems_panic_in_progress;
|
||||
|
||||
@@ -2,6 +2,96 @@
|
||||
# $Id$
|
||||
#
|
||||
|
||||
This is a snapshot of a work in process. It is the beginnings of a
|
||||
debug monitor task and trap handler which is tasking aware.
|
||||
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)
|
||||
|
||||
|
||||
190
c/src/lib/libmisc/monitor/mon-command.c
Normal file
190
c/src/lib/libmisc/monitor/mon-command.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* @(#)command.c 1.5 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Command parsing routines for RTEMS monitor
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* make_argv(cp): token-count
|
||||
* Break up the command line in 'cp' into global argv[] and argc (return
|
||||
* value).
|
||||
*/
|
||||
|
||||
int
|
||||
rtems_monitor_make_argv(
|
||||
char *cp,
|
||||
int *argc_p,
|
||||
char **argv)
|
||||
{
|
||||
int argc = 0;
|
||||
|
||||
while ((cp = strtok(cp, " \t\n\r")))
|
||||
{
|
||||
argv[argc++] = cp;
|
||||
cp = (char *) NULL;
|
||||
}
|
||||
argv[argc] = (char *) NULL; /* end of argv */
|
||||
|
||||
return *argc_p = argc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read and break up a monitor command
|
||||
*
|
||||
* We have to loop on the gets call, since it will return NULL under UNIX
|
||||
* RTEMS when we get a signal (eg: SIGALRM).
|
||||
*/
|
||||
|
||||
int
|
||||
rtems_monitor_command_read(char *command,
|
||||
int *argc,
|
||||
char **argv)
|
||||
{
|
||||
extern rtems_configuration_table BSP_Configuration;
|
||||
static char monitor_prompt[32];
|
||||
|
||||
/*
|
||||
* put node number in the prompt if we are multiprocessing
|
||||
*/
|
||||
|
||||
if (BSP_Configuration.User_multiprocessing_table == 0)
|
||||
sprintf(monitor_prompt, "%s", MONITOR_PROMPT);
|
||||
else if (rtems_monitor_default_node != rtems_monitor_node)
|
||||
sprintf(monitor_prompt, "%d-%s-%d", rtems_monitor_node, MONITOR_PROMPT, rtems_monitor_default_node);
|
||||
else
|
||||
sprintf(monitor_prompt, "%d-%s", rtems_monitor_node, MONITOR_PROMPT);
|
||||
|
||||
#ifdef RTEMS_UNIX
|
||||
/* RTEMS on unix gets so many interrupt system calls this is hosed */
|
||||
printf("%s> ", monitor_prompt);
|
||||
fflush(stdout);
|
||||
while (gets(command) == (char *) 0)
|
||||
;
|
||||
#else
|
||||
do
|
||||
{
|
||||
printf("%s> ", monitor_prompt);
|
||||
fflush(stdout);
|
||||
} while (gets(command) == (char *) 0);
|
||||
#endif
|
||||
|
||||
return rtems_monitor_make_argv(command, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up a command in a command table
|
||||
*
|
||||
*/
|
||||
|
||||
rtems_monitor_command_entry_t *
|
||||
rtems_monitor_command_lookup(
|
||||
rtems_monitor_command_entry_t *table,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
rtems_monitor_command_entry_t *p;
|
||||
rtems_monitor_command_entry_t *abbreviated_match = 0;
|
||||
int abbreviated_matches = 0;
|
||||
char *command;
|
||||
int command_length;
|
||||
|
||||
command = argv[0];
|
||||
|
||||
if ((table == 0) || (command == 0))
|
||||
goto failed;
|
||||
|
||||
command_length = strlen(command);
|
||||
|
||||
for (p = table; p->command; p++)
|
||||
if (STREQ(command, p->command)) /* exact match */
|
||||
goto done;
|
||||
else if (STRNEQ(command, p->command, command_length))
|
||||
{
|
||||
abbreviated_matches++;
|
||||
abbreviated_match = p;
|
||||
}
|
||||
|
||||
/* no perfect match; is there a non-ambigous abbreviated match? */
|
||||
if ( ! abbreviated_match)
|
||||
{
|
||||
printf("Unrecognized command '%s'; try 'help'\n", command);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (abbreviated_matches > 1)
|
||||
{
|
||||
printf("Command '%s' is ambiguous; try 'help'\n", command);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
p = abbreviated_match;
|
||||
|
||||
done:
|
||||
if (p->command_function == 0)
|
||||
goto failed;
|
||||
return p;
|
||||
|
||||
failed:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rtems_monitor_command_usage(rtems_monitor_command_entry_t *table,
|
||||
char *command_string)
|
||||
{
|
||||
rtems_monitor_command_entry_t *help = 0;
|
||||
char *help_command_argv[2];
|
||||
|
||||
/* if first entry in table is a usage, then print it out */
|
||||
if (command_string == 0)
|
||||
{
|
||||
if (STREQ(table->command, "--usage--") && table->usage)
|
||||
help = table;
|
||||
}
|
||||
else
|
||||
{
|
||||
help_command_argv[0] = command_string;
|
||||
help_command_argv[1] = 0;
|
||||
help = rtems_monitor_command_lookup(table, 1, help_command_argv);
|
||||
}
|
||||
|
||||
if (help)
|
||||
printf("%s\n", help->usage);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rtems_monitor_help_cmd(
|
||||
int argc,
|
||||
char **argv,
|
||||
unsigned32 command_arg,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
int arg;
|
||||
rtems_monitor_command_entry_t *command;
|
||||
|
||||
command = (rtems_monitor_command_entry_t *) command_arg;
|
||||
|
||||
if (argc == 1)
|
||||
rtems_monitor_command_usage(command, 0);
|
||||
else
|
||||
{
|
||||
for (arg=1; argv[arg]; arg++)
|
||||
rtems_monitor_command_usage(command, argv[arg]);
|
||||
}
|
||||
}
|
||||
132
c/src/lib/libmisc/monitor/mon-config.c
Normal file
132
c/src/lib/libmisc/monitor/mon-config.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* @(#)config.c 1.5 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS Config display support
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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;
|
||||
|
||||
canonical_config->work_space_start = c->work_space_start;
|
||||
canonical_config->work_space_size = c->work_space_size;
|
||||
canonical_config->maximum_tasks = c->maximum_tasks;
|
||||
canonical_config->maximum_timers = c->maximum_timers;
|
||||
canonical_config->maximum_semaphores = c->maximum_semaphores;
|
||||
canonical_config->maximum_message_queues = c->maximum_message_queues;
|
||||
canonical_config->maximum_partitions = c->maximum_partitions;
|
||||
canonical_config->maximum_regions = c->maximum_regions;
|
||||
canonical_config->maximum_ports = c->maximum_ports;
|
||||
canonical_config->maximum_periods = c->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 = c->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);
|
||||
}
|
||||
113
c/src/lib/libmisc/monitor/mon-dname.c
Normal file
113
c/src/lib/libmisc/monitor/mon-dname.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* @(#)dname.c 1.3 - 95/07/31
|
||||
*
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "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
|
||||
)
|
||||
{
|
||||
int n = rtems_get_index(*next_id);
|
||||
rtems_driver_name_t *table = object_information;
|
||||
rtems_driver_name_t *np = 0;
|
||||
|
||||
for (np = table + n ; n<RTEMS_MAX_DRIVER_NAMES; 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;
|
||||
}
|
||||
138
c/src/lib/libmisc/monitor/mon-driver.c
Normal file
138
c/src/lib/libmisc/monitor/mon-driver.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* @(#)driver.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "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,
|
||||
d->initialization);
|
||||
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
|
||||
d->open);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
|
||||
d->close);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
|
||||
d->read);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
|
||||
d->write);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
|
||||
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;
|
||||
int 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;
|
||||
}
|
||||
101
c/src/lib/libmisc/monitor/mon-extension.c
Normal file
101
c/src/lib/libmisc/monitor/mon-extension.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* @(#)extension.c 1.3 - 95/07/31
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor extension support
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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->create,
|
||||
e->rtems_task_create);
|
||||
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->start,
|
||||
e->rtems_task_start);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->restart,
|
||||
e->rtems_task_restart);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->delete,
|
||||
e->rtems_task_delete);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->tswitch,
|
||||
e->task_switch);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->begin,
|
||||
e->task_begin);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->exitted,
|
||||
e->task_exitted);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->fatal,
|
||||
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->create, verbose);
|
||||
length += printf("; start: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->start, verbose);
|
||||
length += printf("; restart: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->restart, verbose);
|
||||
length += printf("\n");
|
||||
length = 0;
|
||||
|
||||
length += rtems_monitor_pad(18, length);
|
||||
length += printf("delete: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->delete, verbose);
|
||||
length += printf("; switch: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->tswitch, verbose);
|
||||
length += printf("; begin: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->begin, verbose);
|
||||
length += printf("\n");
|
||||
length = 0;
|
||||
|
||||
length += rtems_monitor_pad(18, length);
|
||||
length += printf("exitted: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->exitted, verbose);
|
||||
length += printf("; fatal: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->fatal, verbose);
|
||||
length += printf("\n");
|
||||
length = 0;
|
||||
printf("\n");
|
||||
}
|
||||
117
c/src/lib/libmisc/monitor/mon-itask.c
Normal file
117
c/src/lib/libmisc/monitor/mon-itask.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* @(#)itask.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor init task support
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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,
|
||||
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;
|
||||
int n = rtems_get_index(*next_id);
|
||||
|
||||
if (n >= c->number_of_initialization_tasks)
|
||||
goto failed;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
itask = c->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");
|
||||
}
|
||||
52
c/src/lib/libmisc/monitor/mon-manager.c
Normal file
52
c/src/lib/libmisc/monitor/mon-manager.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @(#)manager.c 1.2 - 95/07/31
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor "manager" support.
|
||||
* Used to traverse object (chain) lists and print them out.
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <monitor.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;
|
||||
unsigned32 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;
|
||||
copy->name = table->name_table[rtems_get_index(copy->id)];
|
||||
}
|
||||
|
||||
done:
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -1,125 +1,239 @@
|
||||
/*
|
||||
* @(#)monitor.c 1.6 - 95/04/24
|
||||
* @(#)monitor.c 1.18 - 95/08/02
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* mon-task.c
|
||||
*
|
||||
* Description:
|
||||
* RTEMS monitor task
|
||||
*
|
||||
*
|
||||
* RTEMS monitor main body
|
||||
*
|
||||
* TODO:
|
||||
* add pause command (monitor sleeps for 'n' ticks, then wakes up)
|
||||
*
|
||||
* 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??
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
/* #include <bsp.h> */
|
||||
|
||||
#include "symbols.h"
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define STREQ(a,b) (strcmp(a,b) == 0)
|
||||
#include "monitor.h"
|
||||
|
||||
/* set by trap handler */
|
||||
extern rtems_tcb *debugger_interrupted_task;
|
||||
extern rtems_context *debugger_interrupted_task_context;
|
||||
extern rtems_unsigned32 debugger_trap;
|
||||
|
||||
/* our task id needs to be public so any debugger can resume us */
|
||||
rtems_unsigned32 rtems_monitor_task_id;
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef MONITOR_PROMPT
|
||||
#define MONITOR_PROMPT "rtems> "
|
||||
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"
|
||||
" 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_OBJECT_CONFIG,
|
||||
},
|
||||
{ "itask",
|
||||
"itask\n"
|
||||
" List init tasks for the system\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_OBJECT_INIT_TASK,
|
||||
},
|
||||
{ "mpci",
|
||||
"mpci\n"
|
||||
" Show the MPCI system configuration, if configured.\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_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_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_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_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_OBJECT_INVALID,
|
||||
},
|
||||
{ "driver",
|
||||
"driver [ major [ major ... ] ]\n"
|
||||
" Display the RTEMS device driver table.\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_OBJECT_DRIVER,
|
||||
},
|
||||
{ "dname",
|
||||
"dname\n"
|
||||
" Displays information about named drivers.\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_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,
|
||||
CPU_INVOKE_DEBUGGER,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
|
||||
|
||||
/*
|
||||
* Function: rtems_monitor_init
|
||||
*
|
||||
* Description:
|
||||
* Create the RTEMS monitor task
|
||||
*
|
||||
* Parameters:
|
||||
* 'monitor_suspend' arg is passed as initial arg to monitor task
|
||||
* If TRUE, monitor will suspend itself as it starts up. Otherwise
|
||||
* it will begin its command loop.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*
|
||||
* Side Effects:
|
||||
*
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*
|
||||
* Deficiencies/ToDo:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
void
|
||||
rtems_monitor_init(rtems_boolean monitor_suspend)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
status = rtems_task_create(rtems_build_name('R', 'M', 'O', 'N'),
|
||||
1, 0/*stack*/, RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
printf("could not create monitor task\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
rtems_monitor_symbols_loadup();
|
||||
|
||||
status = rtems_task_start(rtems_monitor_task_id, rtems_monitor_task, monitor_suspend);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
printf("could not start monitor!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
}
|
||||
|
||||
rtems_status_code
|
||||
rtems_monitor_suspend(rtems_interval timeout)
|
||||
@@ -127,7 +241,10 @@ 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);
|
||||
status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
|
||||
RTEMS_DEFAULT_OPTIONS,
|
||||
timeout,
|
||||
&event_set);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -140,93 +257,76 @@ rtems_monitor_wakeup(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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_read_command(char *command,
|
||||
int *argc,
|
||||
char **argv)
|
||||
void
|
||||
rtems_monitor_pause_cmd(
|
||||
int argc,
|
||||
char **argv,
|
||||
unsigned32 command_arg,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
printf("%s", MONITOR_PROMPT); fflush(stdout);
|
||||
while (gets(command) == (char *) 0)
|
||||
;
|
||||
return rtems_monitor_make_argv(command, argc, argv);
|
||||
if (argc == 1)
|
||||
rtems_monitor_suspend(1);
|
||||
else
|
||||
rtems_monitor_suspend(strtoul(argv[1], 0, 0));
|
||||
}
|
||||
|
||||
void
|
||||
rtems_monitor_task(rtems_task_argument monitor_suspend)
|
||||
rtems_monitor_fatal_cmd(
|
||||
int argc,
|
||||
char **argv,
|
||||
unsigned32 command_arg,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
rtems_tcb *debugee = 0;
|
||||
char command[513];
|
||||
rtems_context *rp;
|
||||
rtems_context_fp *fp;
|
||||
char *cp;
|
||||
int argc;
|
||||
char *argv[64];
|
||||
|
||||
if ((rtems_boolean) monitor_suspend)
|
||||
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
extern rtems_tcb * _Thread_Executing;
|
||||
debugee = _Thread_Executing;
|
||||
rp = &debugee->Registers;
|
||||
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
|
||||
|
||||
if (0 == rtems_monitor_read_command(command, &argc, argv))
|
||||
continue;
|
||||
|
||||
if (STREQ(argv[0], "quit"))
|
||||
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
|
||||
else if (STREQ(argv[0], "pause"))
|
||||
rtems_monitor_suspend(1);
|
||||
|
||||
#ifdef CPU_INVOKE_DEBUGGER
|
||||
else if (STREQ(argv[0], "debug"))
|
||||
{
|
||||
CPU_INVOKE_DEBUGGER;
|
||||
}
|
||||
#endif
|
||||
else if (STREQ(argv[0], "symbol"))
|
||||
{
|
||||
char *symbol;
|
||||
char *value;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
printf("usage: symbol symname symvalue\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
symbol = argv[1];
|
||||
value = argv[2];
|
||||
if (symbol && value)
|
||||
{
|
||||
rtems_symbol_t *sp;
|
||||
sp = rtems_symbol_create(rtems_monitor_symbols,
|
||||
symbol,
|
||||
(rtems_unsigned32) strtoul(value, 0, 16));
|
||||
if (sp)
|
||||
printf("symbol defined is at %p\n", sp);
|
||||
else
|
||||
printf("could not define symbol\n");
|
||||
}
|
||||
else
|
||||
printf("parsing error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unrecognized command: '%s'\n", argv[0]);
|
||||
}
|
||||
}
|
||||
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) && (new_node <= _Configuration_MP_table->maximum_nodes))
|
||||
rtems_monitor_default_node = new_node;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: rtems_monitor_symbols_loadup
|
||||
*
|
||||
@@ -266,11 +366,19 @@ 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 = fdopen(8, "r");
|
||||
#ifdef simhppa
|
||||
fp = fdopen(8, "r"); /* don't ask; don't tell */
|
||||
#else
|
||||
fp = fopen("symbols", "r");
|
||||
#endif
|
||||
|
||||
if (fp == 0)
|
||||
return;
|
||||
|
||||
@@ -292,16 +400,115 @@ rtems_monitor_symbols_loadup(void)
|
||||
(rtems_unsigned32) strtoul(value, 0, 16));
|
||||
if (sp == 0)
|
||||
{
|
||||
printf("could not define symbol\n");
|
||||
printf("could not define symbol '%s'\n", symbol);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("parsing error\n");
|
||||
printf("parsing error on '%s'\n", buffer);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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,
|
||||
0 /* default stack */,
|
||||
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:
|
||||
}
|
||||
|
||||
161
c/src/lib/libmisc/monitor/mon-mpci.c
Normal file
161
c/src/lib/libmisc/monitor/mon-mpci.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* @(#)mpci.c 1.6 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS MPCI Config display support
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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,
|
||||
mt->initialization);
|
||||
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->get_packet,
|
||||
mt->get_packet);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->return_packet,
|
||||
mt->return_packet);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->send_packet,
|
||||
mt->send_packet);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->receive_packet,
|
||||
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;
|
||||
}
|
||||
376
c/src/lib/libmisc/monitor/mon-object.c
Normal file
376
c/src/lib/libmisc/monitor/mon-object.c
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* @(#)object.c 1.7 - 95/08/02
|
||||
*
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* strtoul() */
|
||||
|
||||
#include <monitor.h>
|
||||
|
||||
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
/*
|
||||
* add:
|
||||
* next
|
||||
*/
|
||||
|
||||
rtems_monitor_object_info_t rtems_monitor_object_info[] =
|
||||
{
|
||||
{ RTEMS_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_OBJECT_MPCI,
|
||||
(void *) 0,
|
||||
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,
|
||||
},
|
||||
{ RTEMS_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_OBJECT_TASK,
|
||||
(void *) &_Thread_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_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_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_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_OBJECT_DNAME,
|
||||
(void *) &rtems_driver_name_table[0],
|
||||
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_object_type_t type
|
||||
)
|
||||
{
|
||||
unsigned32 node;
|
||||
|
||||
node = rtems_get_node(id);
|
||||
if (node == 0)
|
||||
{
|
||||
#if 0
|
||||
/* XXX Uncomment this when types are added to id's */
|
||||
if (rtems_get_type(id) != RTEMS_OBJECT_INVALID)
|
||||
type = rtems_get_type(id);
|
||||
|
||||
id = _Objects_Build_id(type, default_node, rtems_get_index(id));
|
||||
#else
|
||||
id = _Objects_Build_id(default_node, rtems_get_index(id));
|
||||
#endif
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
rtems_monitor_object_info_t *
|
||||
rtems_monitor_object_lookup(
|
||||
rtems_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_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_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(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_object_type_t type = (rtems_object_type_t) command_arg;
|
||||
|
||||
/* what is the default type? */
|
||||
type = (rtems_object_type_t) command_arg;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
if (type == RTEMS_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_object_type_t last_type = RTEMS_OBJECT_INVALID;
|
||||
rtems_id id;
|
||||
|
||||
for (arg=1; argv[arg]; arg++)
|
||||
{
|
||||
id = (rtems_id) strtoul(argv[arg], 0, 0);
|
||||
id = rtems_monitor_id_fixup(id, default_node, type);
|
||||
#if 0
|
||||
type = rtems_get_type(id);
|
||||
#endif
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
not_found: printf("Invalid or unsupported type %d\n", type);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (info->dump_header)
|
||||
info->dump_header(verbose);
|
||||
}
|
||||
|
||||
rtems_monitor_object_dump_1(info, id, verbose);
|
||||
|
||||
default_node = rtems_get_node(id);
|
||||
|
||||
last_type = type;
|
||||
}
|
||||
}
|
||||
done:
|
||||
}
|
||||
257
c/src/lib/libmisc/monitor/mon-prmisc.c
Normal file
257
c/src/lib/libmisc/monitor/mon-prmisc.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* @(#)prmisc.c 1.9 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Print misc stuff for the monitor dump routines
|
||||
* Each routine returns the number of characters it output.
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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;
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
unsigned32 length = 0;
|
||||
union {
|
||||
unsigned32 ui;
|
||||
char c[4];
|
||||
} u;
|
||||
|
||||
u.ui = (rtems_unsigned32) name;
|
||||
|
||||
for (i=0; i<sizeof(u.c); i++)
|
||||
length += rtems_monitor_dump_char(u.c[i]);
|
||||
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;
|
||||
}
|
||||
66
c/src/lib/libmisc/monitor/mon-queue.c
Normal file
66
c/src/lib/libmisc/monitor/mon-queue.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* @(#)queue.c 1.5 - 95/07/31
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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->maximum_message_size;
|
||||
canonical_queue->maximum_pending_messages = rtems_queue->maximum_pending_messages;
|
||||
canonical_queue->number_of_pending_messages = rtems_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");
|
||||
}
|
||||
305
c/src/lib/libmisc/monitor/mon-server.c
Normal file
305
c/src/lib/libmisc/monitor/mon-server.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* @(#)server.c 1.3 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS monitor server (handles requests for info from RTEMS monitors
|
||||
* running on other nodes)
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "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_object_type_t object_type;
|
||||
rtems_id id;
|
||||
rtems_id next_id;
|
||||
|
||||
object_type = (rtems_object_type_t) request.argument0;
|
||||
id = (rtems_id) request.argument1;
|
||||
next_id = rtems_monitor_object_canonical_get(object_type,
|
||||
id,
|
||||
&response.payload,
|
||||
&size);
|
||||
|
||||
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
|
||||
response.result0 = next_id;
|
||||
response.result1 = size;
|
||||
|
||||
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
|
||||
payload))
|
||||
|
||||
status = rtems_message_queue_send(request.return_id,
|
||||
&response,
|
||||
size + SERVER_OVERHEAD);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
rtems_error(status, "response send failed");
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
rtems_error(0, "invalid command to monitor server: %d", request.command);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
rtems_task_delete(RTEMS_SELF);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Kill off any old server
|
||||
* Not sure if this is useful, but it doesn't help
|
||||
*/
|
||||
|
||||
void
|
||||
rtems_monitor_server_kill(void)
|
||||
{
|
||||
if (rtems_monitor_server_task_id)
|
||||
rtems_task_delete(rtems_monitor_server_task_id);
|
||||
rtems_monitor_task_id = 0;
|
||||
|
||||
if (rtems_monitor_server_request_queue_id)
|
||||
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
|
||||
rtems_monitor_server_response_queue_id = 0;
|
||||
|
||||
if (rtems_monitor_server_response_queue_id)
|
||||
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
|
||||
rtems_monitor_server_request_queue_ids = 0;
|
||||
|
||||
if (rtems_monitor_server_request_queue_ids)
|
||||
free(rtems_monitor_server_request_queue_ids);
|
||||
rtems_monitor_server_request_queue_ids = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rtems_monitor_server_init(
|
||||
unsigned32 monitor_flags
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
if (_Configuration_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:
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* @(#)symbols.c 1.3 - 95/04/24
|
||||
* @(#)symbols.c 1.10 - 95/08/02
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/* #define qsort _quicksort */
|
||||
@@ -21,34 +22,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "monitor.h"
|
||||
#include "symbols.h"
|
||||
|
||||
extern rtems_symbol_table_t *rtems_monitor_symbols;
|
||||
|
||||
#ifdef RTEMS_DEBUG
|
||||
#define CHK_ADR_PTR(p) \
|
||||
do { \
|
||||
if (((p) < rtems_monitor_symbols->addresses) || \
|
||||
((p) >= (rtems_monitor_symbols->addresses + rtems_monitor_symbols->next))) \
|
||||
{ \
|
||||
printf("bad address pointer %p\n", (p)); \
|
||||
rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHK_NAME_PTR(p) \
|
||||
do { \
|
||||
if (((p) < rtems_monitor_symbols->symbols) || \
|
||||
((p) >= (rtems_monitor_symbols->symbols + rtems_monitor_symbols->next))) \
|
||||
{ \
|
||||
printf("bad symbol pointer %p\n", (p)); \
|
||||
rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define CHK_ADR_PTR(p)
|
||||
#define CHK_NAME_PTR(p)
|
||||
#endif
|
||||
|
||||
rtems_symbol_table_t *
|
||||
rtems_symbol_table_create()
|
||||
@@ -178,9 +154,6 @@ rtems_symbol_compare(const void *e1,
|
||||
s1 = (rtems_symbol_t *) e1;
|
||||
s2 = (rtems_symbol_t *) e2;
|
||||
|
||||
CHK_ADR_PTR(s1);
|
||||
CHK_ADR_PTR(s2);
|
||||
|
||||
if (s1->value < s2->value)
|
||||
return -1;
|
||||
if (s1->value > s2->value)
|
||||
@@ -200,9 +173,6 @@ rtems_symbol_string_compare(const void *e1,
|
||||
s1 = (rtems_symbol_t *) e1;
|
||||
s2 = (rtems_symbol_t *) e2;
|
||||
|
||||
CHK_NAME_PTR(s1);
|
||||
CHK_NAME_PTR(s2);
|
||||
|
||||
return strcasecmp(s1->name, s2->name);
|
||||
}
|
||||
|
||||
@@ -252,6 +222,9 @@ rtems_symbol_value_lookup(
|
||||
rtems_unsigned32 best_distance = ~0;
|
||||
rtems_unsigned32 elements;
|
||||
|
||||
if (table == 0)
|
||||
table = rtems_monitor_symbols;
|
||||
|
||||
if ((table == 0) || (table->size == 0))
|
||||
return 0;
|
||||
|
||||
@@ -300,13 +273,14 @@ rtems_symbol_name_lookup(
|
||||
rtems_symbol_t *sp = 0;
|
||||
rtems_symbol_t key;
|
||||
|
||||
if (table == 0)
|
||||
table = rtems_monitor_symbols;
|
||||
|
||||
if ((table == 0) || (name == 0))
|
||||
goto done;
|
||||
|
||||
if (table->sorted == 0)
|
||||
{
|
||||
rtems_symbol_sort(table);
|
||||
}
|
||||
|
||||
/*
|
||||
* dummy up one for bsearch()
|
||||
@@ -325,3 +299,192 @@ done:
|
||||
return sp;
|
||||
}
|
||||
|
||||
void *
|
||||
rtems_monitor_symbol_next(
|
||||
void *object_info,
|
||||
rtems_monitor_symbol_t *canonical,
|
||||
rtems_id *next_id
|
||||
)
|
||||
{
|
||||
rtems_symbol_table_t *table;
|
||||
int 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->symbols + 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",
|
||||
sizeof(canonical_symbol->name),
|
||||
canonical_symbol->name);
|
||||
else
|
||||
length += printf("<%.*s+0x%x>",
|
||||
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
|
||||
)
|
||||
{
|
||||
int 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->symbols; 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
85
c/src/lib/libmisc/monitor/mon-task.c
Normal file
85
c/src/lib/libmisc/monitor/mon-task.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* @(#)task.c 1.9 - 95/08/01
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor task support
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
rtems_monitor_task_canonical(
|
||||
rtems_monitor_task_t *canonical_task,
|
||||
void *thread_void
|
||||
)
|
||||
{
|
||||
Thread_Control *rtems_thread = (Thread_Control *) thread_void;
|
||||
|
||||
canonical_task->entry = rtems_thread->Start.entry_point;
|
||||
canonical_task->argument = rtems_thread->Start.initial_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 = rtems_thread->pending_events;
|
||||
canonical_task->modes = rtems_thread->current_modes;
|
||||
canonical_task->attributes = rtems_thread->attribute_set;
|
||||
(void) memcpy(canonical_task->notepad, rtems_thread->Notepads, sizeof(canonical_task->notepad));
|
||||
(void) memcpy(&canonical_task->wait_args, &rtems_thread->Wait.Extra, sizeof(canonical_task->wait_args));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rtems_monitor_task_dump_header(
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
printf("\
|
||||
ID NAME PRIO STAT MODES EVENTS WAITID WAITARG NOTES\n");
|
||||
/*23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
|
||||
0 1 2 3 4 5 6 7 */
|
||||
|
||||
rtems_monitor_separator();
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
void
|
||||
rtems_monitor_task_dump(
|
||||
rtems_monitor_task_t *monitor_task,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
length += rtems_monitor_dump_id(monitor_task->id);
|
||||
length += rtems_monitor_pad(11, length);
|
||||
length += rtems_monitor_dump_name(monitor_task->name);
|
||||
length += rtems_monitor_pad(18, length);
|
||||
length += rtems_monitor_dump_priority(monitor_task->priority);
|
||||
length += rtems_monitor_pad(24, length);
|
||||
length += rtems_monitor_dump_state(monitor_task->state);
|
||||
length += rtems_monitor_pad(31, length);
|
||||
length += rtems_monitor_dump_modes(monitor_task->modes);
|
||||
length += rtems_monitor_pad(39, length);
|
||||
length += rtems_monitor_dump_events(monitor_task->events);
|
||||
if (monitor_task->wait_id)
|
||||
{
|
||||
length += rtems_monitor_pad(47, length);
|
||||
length += rtems_monitor_dump_id(monitor_task->wait_id);
|
||||
length += rtems_monitor_pad(57, length);
|
||||
length += rtems_monitor_dump_hex(monitor_task->wait_args);
|
||||
}
|
||||
|
||||
length += rtems_monitor_pad(65, length);
|
||||
length += rtems_monitor_dump_notepad(monitor_task->notepad);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* @(#)monitor.h 1.2 - 95/04/24
|
||||
* @(#)monitor.h 1.14 - 95/08/02
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -9,28 +10,430 @@
|
||||
* Description:
|
||||
* The RTEMS monitor task include file.
|
||||
*
|
||||
*
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MONITOR_H
|
||||
#define __MONITOR_H
|
||||
|
||||
#include "symbols.h"
|
||||
#include <rtems/error.h> /* rtems_error() */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void rtems_monitor_init(rtems_boolean monitor_suspend);
|
||||
void rtems_monitor_wakeup(void);
|
||||
void rtems_monitor_task(rtems_task_argument monitor_suspend);
|
||||
void rtems_monitor_symbols_loadup(void);
|
||||
/*
|
||||
* XXX this should be in rtems proper when type becomes part of id
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RTEMS_OBJECT_INVALID = 0,
|
||||
RTEMS_OBJECT_TASK = 1,
|
||||
RTEMS_OBJECT_EXTENSION = 2,
|
||||
RTEMS_OBJECT_QUEUE = 3,
|
||||
RTEMS_OBJECT_SEMAPHORE = 4,
|
||||
RTEMS_OBJECT_DRIVER = 5,
|
||||
RTEMS_OBJECT_DNAME = 6,
|
||||
RTEMS_OBJECT_CONFIG = 7,
|
||||
RTEMS_OBJECT_INIT_TASK = 8,
|
||||
RTEMS_OBJECT_MPCI = 9,
|
||||
RTEMS_OBJECT_PARTITION = 10,
|
||||
RTEMS_OBJECT_REGION = 11,
|
||||
RTEMS_OBJECT_PORT = 12,
|
||||
RTEMS_OBJECT_SYMBOL = 13,
|
||||
} rtems_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 create;
|
||||
rtems_monitor_symbol_t start;
|
||||
rtems_monitor_symbol_t restart;
|
||||
rtems_monitor_symbol_t delete;
|
||||
rtems_monitor_symbol_t tswitch;
|
||||
rtems_monitor_symbol_t begin;
|
||||
rtems_monitor_symbol_t exitted;
|
||||
rtems_monitor_symbol_t 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
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
rtems_monitor_mpci_t mpci;
|
||||
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_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(rtems_boolean);
|
||||
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_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_object_type_t);
|
||||
rtems_id rtems_monitor_object_canonical_get(rtems_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 */
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
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_unsigned32 rtems_monitor_task_id;
|
||||
|
||||
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
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* File: symbols.h
|
||||
* @(#)symbols.h 1.3 - 95/06/09
|
||||
*
|
||||
*
|
||||
* RTEMS monitor symbol table functions
|
||||
*
|
||||
* Description:
|
||||
* Entry points for symbol table routines.
|
||||
@@ -8,6 +11,7 @@
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SYMBOLS_H
|
||||
@@ -61,15 +65,6 @@ typedef struct {
|
||||
|
||||
} rtems_symbol_table_t;
|
||||
|
||||
void rtems_symbol_table_destroy(rtems_symbol_table_t *table);
|
||||
rtems_symbol_table_t *rtems_symbol_table_create();
|
||||
rtems_symbol_t *rtems_symbol_create(rtems_symbol_table_t *,
|
||||
char *, rtems_unsigned32);
|
||||
rtems_symbol_t *rtems_symbol_value_lookup(rtems_symbol_table_t *,
|
||||
rtems_unsigned32);
|
||||
rtems_symbol_t *rtems_symbol_name_lookup(rtems_symbol_table_t *,
|
||||
char *);
|
||||
|
||||
#define rtems_symbol_name(sp) ((sp)->name)
|
||||
#define rtems_symbol_value(sp) ((sp)->value)
|
||||
|
||||
|
||||
@@ -16,20 +16,24 @@
|
||||
* to the copyright license under the clause at DFARS 252.227-7013. This
|
||||
* notice must appear in all copies of this file and its derivatives.
|
||||
*
|
||||
* poll.c,v 1.2 1995/05/09 20:22:57 joel Exp
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/sysstate.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include "shm.h"
|
||||
#include "clockdrv.h"
|
||||
|
||||
void Shm_Poll()
|
||||
{
|
||||
rtems_unsigned32 tmpfront;
|
||||
rtems_libio_ioctl_args_t args;
|
||||
|
||||
Clock_isr( 0 ); /* invoke standard clock ISR */
|
||||
|
||||
/* invoke clock isr */
|
||||
args.iop = 0;
|
||||
args.command = rtems_build_name('I', 'S', 'R', ' ');
|
||||
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
|
||||
|
||||
/*
|
||||
* Check for msgs only if we are "up"
|
||||
@@ -39,14 +43,11 @@ void Shm_Poll()
|
||||
|
||||
if (_System_state_Is_up(_System_state_Get()))
|
||||
{
|
||||
/* enable_tracing(); */
|
||||
/* ticks += 1; */
|
||||
Shm_Lock( Shm_Local_receive_queue );
|
||||
tmpfront = Shm_Local_receive_queue->front;
|
||||
Shm_Unlock( Shm_Local_receive_queue );
|
||||
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list ) {
|
||||
rtems_multiprocessing_announce();
|
||||
Shm_Interrupt_count++;
|
||||
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list )
|
||||
{
|
||||
rtems_multiprocessing_announce();
|
||||
Shm_Interrupt_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,16 @@
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include "shm.h"
|
||||
#include "clockdrv.h"
|
||||
|
||||
rtems_isr Shm_setclockvec()
|
||||
{
|
||||
ReInstall_clock( Shm_Poll );
|
||||
rtems_libio_ioctl_args_t args;
|
||||
args.iop = 0;
|
||||
args.command = rtems_build_name('N', 'E', 'W', ' ');
|
||||
args.buffer = (void *) Shm_Poll;
|
||||
|
||||
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __SHM_h
|
||||
#define __SHM_h
|
||||
|
||||
#include <clockdrv.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -518,6 +520,7 @@ extern rtems_mpci_table MPCI_table;
|
||||
|
||||
rtems_mpci_table MPCI_table = {
|
||||
100000, /* default timeout value in ticks */
|
||||
MAX_PACKET_SIZE, /* maximum packet size */
|
||||
Shm_Initialization, /* initialization procedure */
|
||||
Shm_Get_packet, /* get packet procedure */
|
||||
Shm_Return_packet, /* return packet procedure */
|
||||
|
||||
258
c/src/libmisc/assoc/assoc.c
Normal file
258
c/src/libmisc/assoc/assoc.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* @(#)assoc.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* assoc.c
|
||||
* rtems assoc routines
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h> /* sprintf */
|
||||
#include <string.h> /* strcat, strcmp */
|
||||
|
||||
#define STREQ(a,b) (strcmp((a), (b)) == 0)
|
||||
#define rtems_assoc_is_default(ap) ((ap)->name && STREQ(ap->name, RTEMS_ASSOC_DEFAULT_NAME))
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (strcmp(ap->name, name) == 0)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->local_value == local_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
rtems_assoc_t *
|
||||
rtems_assoc_ptr_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *default_ap = 0;
|
||||
|
||||
if (rtems_assoc_is_default(ap))
|
||||
default_ap = ap++;
|
||||
|
||||
for ( ; ap->name; ap++)
|
||||
if (ap->remote_value == remote_value)
|
||||
return ap;
|
||||
|
||||
return default_ap;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get values
|
||||
*/
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_remote_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->remote_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned32
|
||||
rtems_assoc_local_by_name(
|
||||
rtems_assoc_t *ap,
|
||||
char *name
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_name(ap, name);
|
||||
if (nap)
|
||||
return nap->local_value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* what to return if a value is not found
|
||||
* this is not reentrant, but it really shouldn't be invoked anyway
|
||||
*/
|
||||
|
||||
char *
|
||||
rtems_assoc_name_bad(
|
||||
unsigned32 bad_value
|
||||
)
|
||||
{
|
||||
static char bad_buffer[32];
|
||||
|
||||
sprintf(bad_buffer, "< %d [0x%x] >", bad_value, bad_value);
|
||||
return bad_buffer;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_local(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_local(ap, local_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(local_value);
|
||||
}
|
||||
|
||||
char *
|
||||
rtems_assoc_name_by_remote(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
rtems_assoc_t *nap;
|
||||
nap = rtems_assoc_ptr_by_remote(ap, remote_value);
|
||||
if (nap)
|
||||
return nap->name;
|
||||
|
||||
return rtems_assoc_name_bad(remote_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitfield functions assume just 1 bit set in each of remote and local
|
||||
* entries; they do not check for this.
|
||||
*/
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 local_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 remote_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & local_value)
|
||||
remote_value |= rtems_assoc_remote_by_local(ap, b);
|
||||
|
||||
return remote_value;
|
||||
}
|
||||
|
||||
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 remote_value
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
unsigned32 local_value = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & remote_value)
|
||||
local_value |= rtems_assoc_local_by_remote(ap, b);
|
||||
|
||||
return local_value;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_remote_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_remote(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *rtems_assoc_name_by_local_bitfield(
|
||||
rtems_assoc_t *ap,
|
||||
unsigned32 value,
|
||||
char *buffer
|
||||
)
|
||||
{
|
||||
unsigned32 b;
|
||||
|
||||
*buffer = 0;
|
||||
|
||||
for (b = 1; b; b <<= 1)
|
||||
if (b & value)
|
||||
{
|
||||
if (*buffer)
|
||||
strcat(buffer, " ");
|
||||
strcat(buffer, rtems_assoc_name_by_local(ap, b));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
44
c/src/libmisc/assoc/assoc.h
Normal file
44
c/src/libmisc/assoc/assoc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* @(#)assoc.h 1.2 - 95/06/28
|
||||
*
|
||||
*
|
||||
* Rtems associativity routines. Mainly used to convert a value from
|
||||
* one space to another (eg: our errno's to host errno's and v.v)
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_ASSOC_H
|
||||
#define _INCLUDE_ASSOC_H
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
unsigned32 local_value;
|
||||
unsigned32 remote_value;
|
||||
} rtems_assoc_t;
|
||||
|
||||
/*
|
||||
* Flag/marker for optional default value in each table
|
||||
*/
|
||||
|
||||
#define RTEMS_ASSOC_DEFAULT_NAME "(default)"
|
||||
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_name(rtems_assoc_t *, char *);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_value(rtems_assoc_t *, unsigned32);
|
||||
rtems_assoc_t *rtems_assoc_ptr_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_local_by_remote(rtems_assoc_t *, unsigned32);
|
||||
unsigned32 rtems_assoc_remote_by_name(rtems_assoc_t *, char *);
|
||||
unsigned32 rtems_assoc_local_by_name(rtems_assoc_t *, char *);
|
||||
char *rtems_assoc_name_by_local(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_remote(rtems_assoc_t *, unsigned32);
|
||||
|
||||
unsigned32 rtems_assoc_remote_by_local_bitfield(rtems_assoc_t *, unsigned32);
|
||||
char *rtems_assoc_name_by_local_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
char *rtems_assoc_name_by_remote_bitfield(rtems_assoc_t *, unsigned32, char *);
|
||||
unsigned32 rtems_assoc_local_by_remote_bitfield(rtems_assoc_t *ap, unsigned32);
|
||||
|
||||
|
||||
#endif /* ! _INCLUDE_ASSOC_H */
|
||||
212
c/src/libmisc/error/error.c
Normal file
212
c/src/libmisc/error/error.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* @(#)error.c 1.2 - 95/08/02
|
||||
*
|
||||
*
|
||||
* report errors and panics to RTEMS' stderr.
|
||||
* Currently just used by RTEMS monitor.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* These routines provide general purpose error reporting.
|
||||
* rtems_error reports an error to stderr and allows use of
|
||||
* printf style formatting. A newline is appended to all messages.
|
||||
*
|
||||
* error_flag can be specified as any of the following:
|
||||
*
|
||||
* RTEMS_ERROR_ERRNO -- include errno text in output
|
||||
* RTEMS_ERROR_PANIC -- halts local system after output
|
||||
* RTEMS_ERROR_ABORT -- abort after output
|
||||
*
|
||||
* It can also include a rtems_status value which can be OR'd
|
||||
* with the above flags. *
|
||||
*
|
||||
* EXAMPLE
|
||||
* #include <rtems.h>
|
||||
* #include <rtems/error.h>
|
||||
* rtems_error(0, "stray interrupt %d", intr);
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((status = rtems_task_create(...)) != RTEMS_SUCCCESSFUL)
|
||||
* {
|
||||
* rtems_error(status | RTEMS_ERROR_ABORT,
|
||||
* "could not create task");
|
||||
* }
|
||||
*
|
||||
* EXAMPLE
|
||||
* if ((fd = open(pathname, O_RDNLY)) < 0)
|
||||
* {
|
||||
* rtems_error(FLOSS_ERROR_ERRNO, "open of '%s' failed", pathname);
|
||||
* goto failed;
|
||||
* }
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "assoc.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* _exit() */
|
||||
|
||||
/* bug in hpux <errno.h>: no prototypes unless you are C++ */
|
||||
#ifdef hpux9
|
||||
char *strerror(int);
|
||||
#endif
|
||||
|
||||
extern char *rtems_progname;
|
||||
int rtems_panic_in_progress;
|
||||
|
||||
rtems_assoc_t rtems_status_assoc[] = {
|
||||
{ "successful completion", RTEMS_SUCCESSFUL, },
|
||||
{ "returned from a thread", RTEMS_TASK_EXITTED, },
|
||||
{ "multiprocessing not configured", RTEMS_MP_NOT_CONFIGURED, },
|
||||
{ "invalid object name", RTEMS_INVALID_NAME, },
|
||||
{ "invalid object id", RTEMS_INVALID_ID, },
|
||||
{ "too many", RTEMS_TOO_MANY, },
|
||||
{ "timed out waiting", RTEMS_TIMEOUT, },
|
||||
{ "object deleted while waiting", RTEMS_OBJECT_WAS_DELETED, },
|
||||
{ "specified size was invalid", RTEMS_INVALID_SIZE, },
|
||||
{ "address specified is invalid", RTEMS_INVALID_ADDRESS, },
|
||||
{ "number was invalid", RTEMS_INVALID_NUMBER, },
|
||||
{ "item has not been initialized", RTEMS_NOT_DEFINED, },
|
||||
{ "resources still outstanding", RTEMS_RESOURCE_IN_USE, },
|
||||
{ "request not satisfied", RTEMS_UNSATISFIED, },
|
||||
{ "thread is in wrong state", RTEMS_INCORRECT_STATE, },
|
||||
{ "thread already in state", RTEMS_ALREADY_SUSPENDED, },
|
||||
{ "illegal on calling thread", RTEMS_ILLEGAL_ON_SELF, },
|
||||
{ "illegal for remote object", RTEMS_ILLEGAL_ON_REMOTE_OBJECT, },
|
||||
{ "called from wrong environment", RTEMS_CALLED_FROM_ISR, },
|
||||
{ "invalid thread priority", RTEMS_INVALID_PRIORITY, },
|
||||
{ "invalid date/time", RTEMS_INVALID_CLOCK, },
|
||||
{ "invalid node id", RTEMS_INVALID_NODE, },
|
||||
{ "directive not configured", RTEMS_NOT_CONFIGURED, },
|
||||
{ "not owner of resource", RTEMS_NOT_OWNER_OF_RESOURCE , },
|
||||
{ "directive not implemented", RTEMS_NOT_IMPLEMENTED, },
|
||||
{ "RTEMS inconsistency detected", RTEMS_INTERNAL_ERROR, },
|
||||
{ "internal multiprocessing only", RTEMS_PROXY_BLOCKING, },
|
||||
{ "could not get enough memory", RTEMS_NO_MEMORY, },
|
||||
{ 0, 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
char *
|
||||
rtems_status_text(
|
||||
rtems_status_code status
|
||||
)
|
||||
{
|
||||
return rtems_assoc_name_by_local(rtems_status_assoc, status);
|
||||
}
|
||||
|
||||
|
||||
static int rtems_verror(
|
||||
unsigned32 error_flag,
|
||||
char *printf_format,
|
||||
va_list arglist
|
||||
)
|
||||
{
|
||||
int local_errno = 0;
|
||||
int chars_written = 0;
|
||||
rtems_status_code status;
|
||||
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_panic_in_progress++;
|
||||
|
||||
/* disable task switches */
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
/* don't aggravate things */
|
||||
if (rtems_panic_in_progress > 2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) fflush(stdout); /* in case stdout/stderr same */
|
||||
|
||||
status = error_flag & ~RTEMS_ERROR_MASK;
|
||||
if (error_flag & RTEMS_ERROR_ERRNO) /* include errno? */
|
||||
local_errno = errno;
|
||||
|
||||
if (_Configuration_Is_multiprocessing())
|
||||
fprintf(stderr, "[%d] ", _Configuration_MP_table->node);
|
||||
|
||||
if (rtems_progname && *rtems_progname)
|
||||
chars_written += fprintf(stderr, "%s: ", rtems_progname);
|
||||
chars_written += vfprintf(stderr, printf_format, arglist);
|
||||
|
||||
if (status)
|
||||
chars_written += fprintf(stderr, " (status: %s)", rtems_status_text(status));
|
||||
|
||||
if (local_errno)
|
||||
if ((local_errno > 0) && *strerror(local_errno))
|
||||
chars_written += fprintf(stderr, " (errno: %s)", strerror(local_errno));
|
||||
else
|
||||
chars_written += fprintf(stderr, " (unknown errno=%d)", local_errno);
|
||||
|
||||
chars_written += fprintf(stderr, "\n");
|
||||
|
||||
(void) fflush(stderr);
|
||||
|
||||
if (error_flag & (RTEMS_ERROR_PANIC | RTEMS_ERROR_ABORT))
|
||||
{
|
||||
if (error_flag & RTEMS_ERROR_PANIC)
|
||||
{
|
||||
rtems_error(0, "fatal error, exiting");
|
||||
_exit(local_errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
rtems_error(0, "fatal error, aborting");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Report an error.
|
||||
* error_flag is as above; printf_format is a normal
|
||||
* printf(3) format string, with its concommitant arguments.
|
||||
*
|
||||
* Returns the number of characters written.
|
||||
*/
|
||||
|
||||
int rtems_error(
|
||||
int error_flag,
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
int chars_written;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
chars_written = rtems_verror(error_flag, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
|
||||
return chars_written;
|
||||
}
|
||||
|
||||
/*
|
||||
* rtems_panic is shorthand for rtems_error(RTEMS_ERROR_PANIC, ...)
|
||||
*/
|
||||
|
||||
void rtems_panic(
|
||||
char *printf_format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arglist;
|
||||
|
||||
va_start(arglist, printf_format);
|
||||
(void) rtems_verror(RTEMS_ERROR_PANIC, printf_format, arglist);
|
||||
va_end(arglist);
|
||||
}
|
||||
26
c/src/libmisc/error/error.h
Normal file
26
c/src/libmisc/error/error.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @(#)error.h 1.1 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Defines and externs for rtems error reporting
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* rtems_error() and rtems_panic() support
|
||||
*/
|
||||
|
||||
#define RTEMS_ERROR_ERRNO (1<<((sizeof(int) * 8) - 2)) /* hi bit; use 'errno' */
|
||||
#define RTEMS_ERROR_PANIC (RTEMS_ERROR_ERRNO / 2) /* err fatal; no return */
|
||||
#define RTEMS_ERROR_ABORT (RTEMS_ERROR_ERRNO / 4) /* err is fatal; panic */
|
||||
|
||||
#define RTEMS_ERROR_MASK (RTEMS_ERROR_ERRNO | RTEMS_ERROR_ABORT | \
|
||||
RTEMS_ERROR_PANIC) /* all */
|
||||
|
||||
char *rtems_status_text(rtems_status_code);
|
||||
int rtems_error(int error_code, char *printf_format, ...);
|
||||
void rtems_panic(char *printf_format, ...);
|
||||
|
||||
extern int rtems_panic_in_progress;
|
||||
|
||||
@@ -2,6 +2,96 @@
|
||||
# $Id$
|
||||
#
|
||||
|
||||
This is a snapshot of a work in process. It is the beginnings of a
|
||||
debug monitor task and trap handler which is tasking aware.
|
||||
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)
|
||||
|
||||
|
||||
190
c/src/libmisc/monitor/mon-command.c
Normal file
190
c/src/libmisc/monitor/mon-command.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* @(#)command.c 1.5 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Command parsing routines for RTEMS monitor
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* make_argv(cp): token-count
|
||||
* Break up the command line in 'cp' into global argv[] and argc (return
|
||||
* value).
|
||||
*/
|
||||
|
||||
int
|
||||
rtems_monitor_make_argv(
|
||||
char *cp,
|
||||
int *argc_p,
|
||||
char **argv)
|
||||
{
|
||||
int argc = 0;
|
||||
|
||||
while ((cp = strtok(cp, " \t\n\r")))
|
||||
{
|
||||
argv[argc++] = cp;
|
||||
cp = (char *) NULL;
|
||||
}
|
||||
argv[argc] = (char *) NULL; /* end of argv */
|
||||
|
||||
return *argc_p = argc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read and break up a monitor command
|
||||
*
|
||||
* We have to loop on the gets call, since it will return NULL under UNIX
|
||||
* RTEMS when we get a signal (eg: SIGALRM).
|
||||
*/
|
||||
|
||||
int
|
||||
rtems_monitor_command_read(char *command,
|
||||
int *argc,
|
||||
char **argv)
|
||||
{
|
||||
extern rtems_configuration_table BSP_Configuration;
|
||||
static char monitor_prompt[32];
|
||||
|
||||
/*
|
||||
* put node number in the prompt if we are multiprocessing
|
||||
*/
|
||||
|
||||
if (BSP_Configuration.User_multiprocessing_table == 0)
|
||||
sprintf(monitor_prompt, "%s", MONITOR_PROMPT);
|
||||
else if (rtems_monitor_default_node != rtems_monitor_node)
|
||||
sprintf(monitor_prompt, "%d-%s-%d", rtems_monitor_node, MONITOR_PROMPT, rtems_monitor_default_node);
|
||||
else
|
||||
sprintf(monitor_prompt, "%d-%s", rtems_monitor_node, MONITOR_PROMPT);
|
||||
|
||||
#ifdef RTEMS_UNIX
|
||||
/* RTEMS on unix gets so many interrupt system calls this is hosed */
|
||||
printf("%s> ", monitor_prompt);
|
||||
fflush(stdout);
|
||||
while (gets(command) == (char *) 0)
|
||||
;
|
||||
#else
|
||||
do
|
||||
{
|
||||
printf("%s> ", monitor_prompt);
|
||||
fflush(stdout);
|
||||
} while (gets(command) == (char *) 0);
|
||||
#endif
|
||||
|
||||
return rtems_monitor_make_argv(command, argc, argv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up a command in a command table
|
||||
*
|
||||
*/
|
||||
|
||||
rtems_monitor_command_entry_t *
|
||||
rtems_monitor_command_lookup(
|
||||
rtems_monitor_command_entry_t *table,
|
||||
int argc,
|
||||
char **argv
|
||||
)
|
||||
{
|
||||
rtems_monitor_command_entry_t *p;
|
||||
rtems_monitor_command_entry_t *abbreviated_match = 0;
|
||||
int abbreviated_matches = 0;
|
||||
char *command;
|
||||
int command_length;
|
||||
|
||||
command = argv[0];
|
||||
|
||||
if ((table == 0) || (command == 0))
|
||||
goto failed;
|
||||
|
||||
command_length = strlen(command);
|
||||
|
||||
for (p = table; p->command; p++)
|
||||
if (STREQ(command, p->command)) /* exact match */
|
||||
goto done;
|
||||
else if (STRNEQ(command, p->command, command_length))
|
||||
{
|
||||
abbreviated_matches++;
|
||||
abbreviated_match = p;
|
||||
}
|
||||
|
||||
/* no perfect match; is there a non-ambigous abbreviated match? */
|
||||
if ( ! abbreviated_match)
|
||||
{
|
||||
printf("Unrecognized command '%s'; try 'help'\n", command);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (abbreviated_matches > 1)
|
||||
{
|
||||
printf("Command '%s' is ambiguous; try 'help'\n", command);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
p = abbreviated_match;
|
||||
|
||||
done:
|
||||
if (p->command_function == 0)
|
||||
goto failed;
|
||||
return p;
|
||||
|
||||
failed:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rtems_monitor_command_usage(rtems_monitor_command_entry_t *table,
|
||||
char *command_string)
|
||||
{
|
||||
rtems_monitor_command_entry_t *help = 0;
|
||||
char *help_command_argv[2];
|
||||
|
||||
/* if first entry in table is a usage, then print it out */
|
||||
if (command_string == 0)
|
||||
{
|
||||
if (STREQ(table->command, "--usage--") && table->usage)
|
||||
help = table;
|
||||
}
|
||||
else
|
||||
{
|
||||
help_command_argv[0] = command_string;
|
||||
help_command_argv[1] = 0;
|
||||
help = rtems_monitor_command_lookup(table, 1, help_command_argv);
|
||||
}
|
||||
|
||||
if (help)
|
||||
printf("%s\n", help->usage);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rtems_monitor_help_cmd(
|
||||
int argc,
|
||||
char **argv,
|
||||
unsigned32 command_arg,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
int arg;
|
||||
rtems_monitor_command_entry_t *command;
|
||||
|
||||
command = (rtems_monitor_command_entry_t *) command_arg;
|
||||
|
||||
if (argc == 1)
|
||||
rtems_monitor_command_usage(command, 0);
|
||||
else
|
||||
{
|
||||
for (arg=1; argv[arg]; arg++)
|
||||
rtems_monitor_command_usage(command, argv[arg]);
|
||||
}
|
||||
}
|
||||
132
c/src/libmisc/monitor/mon-config.c
Normal file
132
c/src/libmisc/monitor/mon-config.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* @(#)config.c 1.5 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS Config display support
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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;
|
||||
|
||||
canonical_config->work_space_start = c->work_space_start;
|
||||
canonical_config->work_space_size = c->work_space_size;
|
||||
canonical_config->maximum_tasks = c->maximum_tasks;
|
||||
canonical_config->maximum_timers = c->maximum_timers;
|
||||
canonical_config->maximum_semaphores = c->maximum_semaphores;
|
||||
canonical_config->maximum_message_queues = c->maximum_message_queues;
|
||||
canonical_config->maximum_partitions = c->maximum_partitions;
|
||||
canonical_config->maximum_regions = c->maximum_regions;
|
||||
canonical_config->maximum_ports = c->maximum_ports;
|
||||
canonical_config->maximum_periods = c->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 = c->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);
|
||||
}
|
||||
113
c/src/libmisc/monitor/mon-dname.c
Normal file
113
c/src/libmisc/monitor/mon-dname.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* @(#)dname.c 1.3 - 95/07/31
|
||||
*
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "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
|
||||
)
|
||||
{
|
||||
int n = rtems_get_index(*next_id);
|
||||
rtems_driver_name_t *table = object_information;
|
||||
rtems_driver_name_t *np = 0;
|
||||
|
||||
for (np = table + n ; n<RTEMS_MAX_DRIVER_NAMES; 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;
|
||||
}
|
||||
138
c/src/libmisc/monitor/mon-driver.c
Normal file
138
c/src/libmisc/monitor/mon-driver.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* @(#)driver.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include "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,
|
||||
d->initialization);
|
||||
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->open,
|
||||
d->open);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->close,
|
||||
d->close);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->read,
|
||||
d->read);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->write,
|
||||
d->write);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_driver->control,
|
||||
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;
|
||||
int 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;
|
||||
}
|
||||
101
c/src/libmisc/monitor/mon-extension.c
Normal file
101
c/src/libmisc/monitor/mon-extension.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* @(#)extension.c 1.3 - 95/07/31
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor extension support
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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->create,
|
||||
e->rtems_task_create);
|
||||
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->start,
|
||||
e->rtems_task_start);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->restart,
|
||||
e->rtems_task_restart);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->delete,
|
||||
e->rtems_task_delete);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->tswitch,
|
||||
e->task_switch);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->begin,
|
||||
e->task_begin);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->exitted,
|
||||
e->task_exitted);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_extension->fatal,
|
||||
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->create, verbose);
|
||||
length += printf("; start: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->start, verbose);
|
||||
length += printf("; restart: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->restart, verbose);
|
||||
length += printf("\n");
|
||||
length = 0;
|
||||
|
||||
length += rtems_monitor_pad(18, length);
|
||||
length += printf("delete: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->delete, verbose);
|
||||
length += printf("; switch: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->tswitch, verbose);
|
||||
length += printf("; begin: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->begin, verbose);
|
||||
length += printf("\n");
|
||||
length = 0;
|
||||
|
||||
length += rtems_monitor_pad(18, length);
|
||||
length += printf("exitted: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->exitted, verbose);
|
||||
length += printf("; fatal: ");
|
||||
length += rtems_monitor_symbol_dump(&monitor_extension->fatal, verbose);
|
||||
length += printf("\n");
|
||||
length = 0;
|
||||
printf("\n");
|
||||
}
|
||||
117
c/src/libmisc/monitor/mon-itask.c
Normal file
117
c/src/libmisc/monitor/mon-itask.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* @(#)itask.c 1.4 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor init task support
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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,
|
||||
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;
|
||||
int n = rtems_get_index(*next_id);
|
||||
|
||||
if (n >= c->number_of_initialization_tasks)
|
||||
goto failed;
|
||||
|
||||
_Thread_Disable_dispatch();
|
||||
|
||||
itask = c->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");
|
||||
}
|
||||
52
c/src/libmisc/monitor/mon-manager.c
Normal file
52
c/src/libmisc/monitor/mon-manager.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @(#)manager.c 1.2 - 95/07/31
|
||||
*
|
||||
*
|
||||
* RTEMS Monitor "manager" support.
|
||||
* Used to traverse object (chain) lists and print them out.
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <monitor.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;
|
||||
unsigned32 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;
|
||||
copy->name = table->name_table[rtems_get_index(copy->id)];
|
||||
}
|
||||
|
||||
done:
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -1,125 +1,239 @@
|
||||
/*
|
||||
* @(#)monitor.c 1.6 - 95/04/24
|
||||
* @(#)monitor.c 1.18 - 95/08/02
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* mon-task.c
|
||||
*
|
||||
* Description:
|
||||
* RTEMS monitor task
|
||||
*
|
||||
*
|
||||
* RTEMS monitor main body
|
||||
*
|
||||
* TODO:
|
||||
* add pause command (monitor sleeps for 'n' ticks, then wakes up)
|
||||
*
|
||||
* 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??
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
/* #include <bsp.h> */
|
||||
|
||||
#include "symbols.h"
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define STREQ(a,b) (strcmp(a,b) == 0)
|
||||
#include "monitor.h"
|
||||
|
||||
/* set by trap handler */
|
||||
extern rtems_tcb *debugger_interrupted_task;
|
||||
extern rtems_context *debugger_interrupted_task_context;
|
||||
extern rtems_unsigned32 debugger_trap;
|
||||
|
||||
/* our task id needs to be public so any debugger can resume us */
|
||||
rtems_unsigned32 rtems_monitor_task_id;
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef MONITOR_PROMPT
|
||||
#define MONITOR_PROMPT "rtems> "
|
||||
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"
|
||||
" 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_OBJECT_CONFIG,
|
||||
},
|
||||
{ "itask",
|
||||
"itask\n"
|
||||
" List init tasks for the system\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_OBJECT_INIT_TASK,
|
||||
},
|
||||
{ "mpci",
|
||||
"mpci\n"
|
||||
" Show the MPCI system configuration, if configured.\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_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_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_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_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_OBJECT_INVALID,
|
||||
},
|
||||
{ "driver",
|
||||
"driver [ major [ major ... ] ]\n"
|
||||
" Display the RTEMS device driver table.\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_OBJECT_DRIVER,
|
||||
},
|
||||
{ "dname",
|
||||
"dname\n"
|
||||
" Displays information about named drivers.\n",
|
||||
0,
|
||||
rtems_monitor_object_cmd,
|
||||
RTEMS_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,
|
||||
CPU_INVOKE_DEBUGGER,
|
||||
0,
|
||||
},
|
||||
#endif
|
||||
{ 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
#define MONITOR_WAKEUP_EVENT RTEMS_EVENT_0
|
||||
|
||||
/*
|
||||
* Function: rtems_monitor_init
|
||||
*
|
||||
* Description:
|
||||
* Create the RTEMS monitor task
|
||||
*
|
||||
* Parameters:
|
||||
* 'monitor_suspend' arg is passed as initial arg to monitor task
|
||||
* If TRUE, monitor will suspend itself as it starts up. Otherwise
|
||||
* it will begin its command loop.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*
|
||||
* Side Effects:
|
||||
*
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*
|
||||
* Deficiencies/ToDo:
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
void
|
||||
rtems_monitor_init(rtems_boolean monitor_suspend)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
status = rtems_task_create(rtems_build_name('R', 'M', 'O', 'N'),
|
||||
1, 0/*stack*/, RTEMS_NO_PREEMPT | RTEMS_INTERRUPT_LEVEL(0), RTEMS_DEFAULT_ATTRIBUTES, &rtems_monitor_task_id);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
printf("could not create monitor task\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
rtems_monitor_symbols_loadup();
|
||||
|
||||
status = rtems_task_start(rtems_monitor_task_id, rtems_monitor_task, monitor_suspend);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
printf("could not start monitor!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
}
|
||||
|
||||
rtems_status_code
|
||||
rtems_monitor_suspend(rtems_interval timeout)
|
||||
@@ -127,7 +241,10 @@ 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);
|
||||
status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
|
||||
RTEMS_DEFAULT_OPTIONS,
|
||||
timeout,
|
||||
&event_set);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -140,93 +257,76 @@ rtems_monitor_wakeup(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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_read_command(char *command,
|
||||
int *argc,
|
||||
char **argv)
|
||||
void
|
||||
rtems_monitor_pause_cmd(
|
||||
int argc,
|
||||
char **argv,
|
||||
unsigned32 command_arg,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
printf("%s", MONITOR_PROMPT); fflush(stdout);
|
||||
while (gets(command) == (char *) 0)
|
||||
;
|
||||
return rtems_monitor_make_argv(command, argc, argv);
|
||||
if (argc == 1)
|
||||
rtems_monitor_suspend(1);
|
||||
else
|
||||
rtems_monitor_suspend(strtoul(argv[1], 0, 0));
|
||||
}
|
||||
|
||||
void
|
||||
rtems_monitor_task(rtems_task_argument monitor_suspend)
|
||||
rtems_monitor_fatal_cmd(
|
||||
int argc,
|
||||
char **argv,
|
||||
unsigned32 command_arg,
|
||||
boolean verbose
|
||||
)
|
||||
{
|
||||
rtems_tcb *debugee = 0;
|
||||
char command[513];
|
||||
rtems_context *rp;
|
||||
rtems_context_fp *fp;
|
||||
char *cp;
|
||||
int argc;
|
||||
char *argv[64];
|
||||
|
||||
if ((rtems_boolean) monitor_suspend)
|
||||
(void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
extern rtems_tcb * _Thread_Executing;
|
||||
debugee = _Thread_Executing;
|
||||
rp = &debugee->Registers;
|
||||
fp = (rtems_context_fp *) debugee->fp_context; /* possibly 0 */
|
||||
|
||||
if (0 == rtems_monitor_read_command(command, &argc, argv))
|
||||
continue;
|
||||
|
||||
if (STREQ(argv[0], "quit"))
|
||||
rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
|
||||
else if (STREQ(argv[0], "pause"))
|
||||
rtems_monitor_suspend(1);
|
||||
|
||||
#ifdef CPU_INVOKE_DEBUGGER
|
||||
else if (STREQ(argv[0], "debug"))
|
||||
{
|
||||
CPU_INVOKE_DEBUGGER;
|
||||
}
|
||||
#endif
|
||||
else if (STREQ(argv[0], "symbol"))
|
||||
{
|
||||
char *symbol;
|
||||
char *value;
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
printf("usage: symbol symname symvalue\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
symbol = argv[1];
|
||||
value = argv[2];
|
||||
if (symbol && value)
|
||||
{
|
||||
rtems_symbol_t *sp;
|
||||
sp = rtems_symbol_create(rtems_monitor_symbols,
|
||||
symbol,
|
||||
(rtems_unsigned32) strtoul(value, 0, 16));
|
||||
if (sp)
|
||||
printf("symbol defined is at %p\n", sp);
|
||||
else
|
||||
printf("could not define symbol\n");
|
||||
}
|
||||
else
|
||||
printf("parsing error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unrecognized command: '%s'\n", argv[0]);
|
||||
}
|
||||
}
|
||||
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) && (new_node <= _Configuration_MP_table->maximum_nodes))
|
||||
rtems_monitor_default_node = new_node;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: rtems_monitor_symbols_loadup
|
||||
*
|
||||
@@ -266,11 +366,19 @@ 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 = fdopen(8, "r");
|
||||
#ifdef simhppa
|
||||
fp = fdopen(8, "r"); /* don't ask; don't tell */
|
||||
#else
|
||||
fp = fopen("symbols", "r");
|
||||
#endif
|
||||
|
||||
if (fp == 0)
|
||||
return;
|
||||
|
||||
@@ -292,16 +400,115 @@ rtems_monitor_symbols_loadup(void)
|
||||
(rtems_unsigned32) strtoul(value, 0, 16));
|
||||
if (sp == 0)
|
||||
{
|
||||
printf("could not define symbol\n");
|
||||
printf("could not define symbol '%s'\n", symbol);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("parsing error\n");
|
||||
printf("parsing error on '%s'\n", buffer);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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,
|
||||
0 /* default stack */,
|
||||
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:
|
||||
}
|
||||
|
||||
161
c/src/libmisc/monitor/mon-mpci.c
Normal file
161
c/src/libmisc/monitor/mon-mpci.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* @(#)mpci.c 1.6 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS MPCI Config display support
|
||||
*
|
||||
* TODO
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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,
|
||||
mt->initialization);
|
||||
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->get_packet,
|
||||
mt->get_packet);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->return_packet,
|
||||
mt->return_packet);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->send_packet,
|
||||
mt->send_packet);
|
||||
rtems_monitor_symbol_canonical_by_value(&canonical_mpci->receive_packet,
|
||||
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;
|
||||
}
|
||||
376
c/src/libmisc/monitor/mon-object.c
Normal file
376
c/src/libmisc/monitor/mon-object.c
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* @(#)object.c 1.7 - 95/08/02
|
||||
*
|
||||
*
|
||||
* 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$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "monitor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* strtoul() */
|
||||
|
||||
#include <monitor.h>
|
||||
|
||||
#define NUMELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
/*
|
||||
* add:
|
||||
* next
|
||||
*/
|
||||
|
||||
rtems_monitor_object_info_t rtems_monitor_object_info[] =
|
||||
{
|
||||
{ RTEMS_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_OBJECT_MPCI,
|
||||
(void *) 0,
|
||||
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,
|
||||
},
|
||||
{ RTEMS_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_OBJECT_TASK,
|
||||
(void *) &_Thread_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_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_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_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_OBJECT_DNAME,
|
||||
(void *) &rtems_driver_name_table[0],
|
||||
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_object_type_t type
|
||||
)
|
||||
{
|
||||
unsigned32 node;
|
||||
|
||||
node = rtems_get_node(id);
|
||||
if (node == 0)
|
||||
{
|
||||
#if 0
|
||||
/* XXX Uncomment this when types are added to id's */
|
||||
if (rtems_get_type(id) != RTEMS_OBJECT_INVALID)
|
||||
type = rtems_get_type(id);
|
||||
|
||||
id = _Objects_Build_id(type, default_node, rtems_get_index(id));
|
||||
#else
|
||||
id = _Objects_Build_id(default_node, rtems_get_index(id));
|
||||
#endif
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
rtems_monitor_object_info_t *
|
||||
rtems_monitor_object_lookup(
|
||||
rtems_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_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_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(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_object_type_t type = (rtems_object_type_t) command_arg;
|
||||
|
||||
/* what is the default type? */
|
||||
type = (rtems_object_type_t) command_arg;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
if (type == RTEMS_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_object_type_t last_type = RTEMS_OBJECT_INVALID;
|
||||
rtems_id id;
|
||||
|
||||
for (arg=1; argv[arg]; arg++)
|
||||
{
|
||||
id = (rtems_id) strtoul(argv[arg], 0, 0);
|
||||
id = rtems_monitor_id_fixup(id, default_node, type);
|
||||
#if 0
|
||||
type = rtems_get_type(id);
|
||||
#endif
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
not_found: printf("Invalid or unsupported type %d\n", type);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (info->dump_header)
|
||||
info->dump_header(verbose);
|
||||
}
|
||||
|
||||
rtems_monitor_object_dump_1(info, id, verbose);
|
||||
|
||||
default_node = rtems_get_node(id);
|
||||
|
||||
last_type = type;
|
||||
}
|
||||
}
|
||||
done:
|
||||
}
|
||||
257
c/src/libmisc/monitor/mon-prmisc.c
Normal file
257
c/src/libmisc/monitor/mon-prmisc.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* @(#)prmisc.c 1.9 - 95/08/02
|
||||
*
|
||||
*
|
||||
* Print misc stuff for the monitor dump routines
|
||||
* Each routine returns the number of characters it output.
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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;
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
unsigned32 length = 0;
|
||||
union {
|
||||
unsigned32 ui;
|
||||
char c[4];
|
||||
} u;
|
||||
|
||||
u.ui = (rtems_unsigned32) name;
|
||||
|
||||
for (i=0; i<sizeof(u.c); i++)
|
||||
length += rtems_monitor_dump_char(u.c[i]);
|
||||
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;
|
||||
}
|
||||
66
c/src/libmisc/monitor/mon-queue.c
Normal file
66
c/src/libmisc/monitor/mon-queue.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* @(#)queue.c 1.5 - 95/07/31
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include "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->maximum_message_size;
|
||||
canonical_queue->maximum_pending_messages = rtems_queue->maximum_pending_messages;
|
||||
canonical_queue->number_of_pending_messages = rtems_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");
|
||||
}
|
||||
305
c/src/libmisc/monitor/mon-server.c
Normal file
305
c/src/libmisc/monitor/mon-server.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* @(#)server.c 1.3 - 95/08/02
|
||||
*
|
||||
*
|
||||
* RTEMS monitor server (handles requests for info from RTEMS monitors
|
||||
* running on other nodes)
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "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_object_type_t object_type;
|
||||
rtems_id id;
|
||||
rtems_id next_id;
|
||||
|
||||
object_type = (rtems_object_type_t) request.argument0;
|
||||
id = (rtems_id) request.argument1;
|
||||
next_id = rtems_monitor_object_canonical_get(object_type,
|
||||
id,
|
||||
&response.payload,
|
||||
&size);
|
||||
|
||||
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
|
||||
response.result0 = next_id;
|
||||
response.result1 = size;
|
||||
|
||||
#define SERVER_OVERHEAD (RTEMS_offsetof(rtems_monitor_server_response_t, \
|
||||
payload))
|
||||
|
||||
status = rtems_message_queue_send(request.return_id,
|
||||
&response,
|
||||
size + SERVER_OVERHEAD);
|
||||
if (status != RTEMS_SUCCESSFUL)
|
||||
{
|
||||
rtems_error(status, "response send failed");
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
rtems_error(0, "invalid command to monitor server: %d", request.command);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
failed:
|
||||
rtems_task_delete(RTEMS_SELF);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Kill off any old server
|
||||
* Not sure if this is useful, but it doesn't help
|
||||
*/
|
||||
|
||||
void
|
||||
rtems_monitor_server_kill(void)
|
||||
{
|
||||
if (rtems_monitor_server_task_id)
|
||||
rtems_task_delete(rtems_monitor_server_task_id);
|
||||
rtems_monitor_task_id = 0;
|
||||
|
||||
if (rtems_monitor_server_request_queue_id)
|
||||
rtems_message_queue_delete(rtems_monitor_server_request_queue_id);
|
||||
rtems_monitor_server_response_queue_id = 0;
|
||||
|
||||
if (rtems_monitor_server_response_queue_id)
|
||||
rtems_message_queue_delete(rtems_monitor_server_response_queue_id);
|
||||
rtems_monitor_server_request_queue_ids = 0;
|
||||
|
||||
if (rtems_monitor_server_request_queue_ids)
|
||||
free(rtems_monitor_server_request_queue_ids);
|
||||
rtems_monitor_server_request_queue_ids = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
rtems_monitor_server_init(
|
||||
unsigned32 monitor_flags
|
||||
)
|
||||
{
|
||||
rtems_status_code status;
|
||||
|
||||
if (_Configuration_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:
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user