source: rtems/cpukit/libmisc/monitor/mon-monitor.c @ 031deada

4.104.115
Last change on this file since 031deada was 031deada, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/02/09 at 13:04:13

Add attribute((unused)) to unused function args.

  • Property mode set to 100644
File size: 13.5 KB
RevLine 
[ac7d5ef0]1/*
[b06e68ef]2 * RTEMS monitor main body
[aed742c]3 *
[ac7d5ef0]4 *  TODO:
[b06e68ef]5 *      add stuff to RTEMS api
6 *            rtems_get_name(id)
7 *            rtems_get_type(id)
8 *            rtems_build_id(node, type, num)
9 *      Add a command to dump out info about an arbitrary id when
10 *         types are added to id's
11 *         rtems> id idnum
12 *                idnum: node n, object: whatever, id: whatever
13 *      allow id's to be specified as n:t:id, where 'n:t' is optional
14 *      should have a separate monitor FILE stream (ala the debugger)
15 *      remote request/response stuff should be cleaned up
16 *         maybe we can use real rpc??
[8389628]17 *      'info' command to print out:
[c64e4ed4]18 *           interrupt stack location, direction and size
19 *           floating point config stuff
20 *           interrupt config stuff
[b06e68ef]21 *
22 *  $Id$
[ac7d5ef0]23 */
24
[550c3df7]25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
[ac7d5ef0]29#include <rtems.h>
30
31#include <stdio.h>
32#include <string.h>
33#include <stdlib.h>
34
[5beb562]35#include <rtems/monitor.h>
[ac7d5ef0]36
37/* set by trap handler */
38extern rtems_tcb       *debugger_interrupted_task;
39extern rtems_context   *debugger_interrupted_task_context;
[3e08d4e]40extern uint32_t   debugger_trap;
[ac7d5ef0]41
[b06e68ef]42/*
43 * Various id's for the monitor
44 * They need to be public variables for access by other agencies
45 * such as debugger and remote servers'
46 */
[ac7d5ef0]47
[b06e68ef]48rtems_id  rtems_monitor_task_id;
[ac7d5ef0]49
[3e08d4e]50uint32_t   rtems_monitor_node;          /* our node number */
51uint32_t   rtems_monitor_default_node;  /* current default for commands */
[ac7d5ef0]52
53/*
[b06e68ef]54 * The rtems symbol table
[ac7d5ef0]55 */
56
[b06e68ef]57rtems_symbol_table_t *rtems_monitor_symbols;
58
[ac7d5ef0]59/*
[b06e68ef]60 * The top-level commands
[ac7d5ef0]61 */
62
[eb961961]63static const rtems_monitor_command_entry_t rtems_monitor_commands[] = {
[b06e68ef]64    { "config",
[32e2554]65      "Show the system configuration.",
[b06e68ef]66      0,
67      rtems_monitor_object_cmd,
[d4c4078]68      { RTEMS_MONITOR_OBJECT_CONFIG },
[32e2554]69      &rtems_monitor_commands[1],
[b06e68ef]70    },
71    { "itask",
[32e2554]72      "List init tasks for the system",
[b06e68ef]73      0,
74      rtems_monitor_object_cmd,
[d4c4078]75      { RTEMS_MONITOR_OBJECT_INIT_TASK },
[32e2554]76      &rtems_monitor_commands[2],
[aed742c]77    },
[b06e68ef]78   { "mpci",
[32e2554]79      "Show the MPCI system configuration, if configured.",
[b06e68ef]80      0,
81      rtems_monitor_object_cmd,
[d4c4078]82      { RTEMS_MONITOR_OBJECT_MPCI },
[32e2554]83      &rtems_monitor_commands[3],
[b06e68ef]84    },
85    { "pause",
[32e2554]86      "Monitor goes to \"sleep\" for specified ticks (default is 1). "
87      "Monitor will resume at end of period or if explicitly awakened\n"
88      "  pause [ticks]",
[b06e68ef]89      0,
90      rtems_monitor_pause_cmd,
[d4c4078]91      { 0 },
[32e2554]92      &rtems_monitor_commands[4],
[b06e68ef]93    },
94    { "continue",
[32e2554]95      "Put the monitor to sleep waiting for an explicit wakeup from the "
96      "program running.\n",
[b06e68ef]97      0,
98      rtems_monitor_continue_cmd,
[d4c4078]99      { 0 },
[32e2554]100      &rtems_monitor_commands[5],
[b06e68ef]101    },
102    { "go",
[32e2554]103      "Alias for 'continue'",
[b06e68ef]104      0,
105      rtems_monitor_continue_cmd,
[d4c4078]106      { 0 },
[32e2554]107      &rtems_monitor_commands[6],
[b06e68ef]108    },
109    { "node",
[32e2554]110      "Specify default node number for commands that take id's.\n"
111      "  node [ node number ]",
[b06e68ef]112      0,
113      rtems_monitor_node_cmd,
[d4c4078]114      { 0 },
[32e2554]115      &rtems_monitor_commands[7],
[b06e68ef]116    },
117    { "symbol",
[32e2554]118      "Display value associated with specified symbol. "
119      "Defaults to displaying all known symbols.\n"
120      "  symbol [ symbolname [symbolname ... ] ]",
[b06e68ef]121      0,
122      rtems_monitor_symbol_cmd,
[d4c4078]123      { .symbol_table = &rtems_monitor_symbols },
[32e2554]124      &rtems_monitor_commands[8],
[b06e68ef]125    },
126    { "extension",
[32e2554]127      "Display information about specified extensions. "
128      "Default is to display information about all extensions on this node.\n"
129      "  extension [id [id ...] ]",
[b06e68ef]130      0,
131      rtems_monitor_object_cmd,
[d4c4078]132      { RTEMS_MONITOR_OBJECT_EXTENSION },
[32e2554]133      &rtems_monitor_commands[9],
[b06e68ef]134    },
135    { "task",
[32e2554]136      "Display information about the specified tasks. "
137      "Default is to display information about all tasks on this node.\n"
138      "  task [id [id ...] ]",
[b06e68ef]139      0,
140      rtems_monitor_object_cmd,
[d4c4078]141      { RTEMS_MONITOR_OBJECT_TASK },
[32e2554]142      &rtems_monitor_commands[10],
[b06e68ef]143    },
144    { "queue",
[32e2554]145      "Display information about the specified message queues. "
146      "Default is to display information about all queues on this node.\n"
147      "  queue [id [id ... ] ]",
[b06e68ef]148      0,
149      rtems_monitor_object_cmd,
[d4c4078]150      { RTEMS_MONITOR_OBJECT_QUEUE },
[32e2554]151      &rtems_monitor_commands[11],
[b06e68ef]152    },
[501ab691]153    { "sema",
154      "sema [id [id ... ] ]\n"
155      "  display information about the specified semaphores\n"
156      "  Default is to display information about all semaphores on this node\n"
157      ,
158      0,
159      rtems_monitor_object_cmd,
[e420436]160      { RTEMS_MONITOR_OBJECT_SEMAPHORE },
[908d6ed]161      &rtems_monitor_commands[12],
[501ab691]162    },
163    { "region",
164      "region [id [id ... ] ]\n"
165      "  display information about the specified regions\n"
166      "  Default is to display information about all regions on this node\n"
167      ,
168      0,
169      rtems_monitor_object_cmd,
[e420436]170      { RTEMS_MONITOR_OBJECT_REGION },
[908d6ed]171      &rtems_monitor_commands[13],
[501ab691]172    },
173    { "part",
174      "part [id [id ... ] ]\n"
175      "  display information about the specified partitions\n"
176      "  Default is to display information about all partitions on this node\n"
177      ,
178      0,
179      rtems_monitor_object_cmd,
[e420436]180      { RTEMS_MONITOR_OBJECT_PARTITION },
[908d6ed]181      &rtems_monitor_commands[14],
[501ab691]182    },
[b06e68ef]183    { "object",
[32e2554]184      "Display information about specified RTEMS objects. "
185      "Object id's must include 'type' information. "
186      "(which may normally be defaulted)\n"
187      "  object [id [id ...] ]",
[b06e68ef]188      0,
189      rtems_monitor_object_cmd,
[d4c4078]190      { RTEMS_MONITOR_OBJECT_INVALID },
[908d6ed]191      &rtems_monitor_commands[15],
[b06e68ef]192    },
193    { "driver",
[32e2554]194      "Display the RTEMS device driver table.\n"
195      "  driver [ major [ major ... ] ]",
[b06e68ef]196      0,
197      rtems_monitor_object_cmd,
[d4c4078]198      { RTEMS_MONITOR_OBJECT_DRIVER },
[908d6ed]199      &rtems_monitor_commands[16],
[b06e68ef]200    },
201    { "dname",
[32e2554]202      "Displays information about named drivers.\n",
[b06e68ef]203      0,
204      rtems_monitor_object_cmd,
[d4c4078]205      { RTEMS_MONITOR_OBJECT_DNAME },
[908d6ed]206      &rtems_monitor_commands[17],
[b06e68ef]207    },
208    { "exit",
[32e2554]209      "Invoke 'rtems_fatal_error_occurred' with 'status' "
210      "(default is RTEMS_SUCCESSFUL)\n"
211      "  exit [status]",
[b06e68ef]212      0,
213      rtems_monitor_fatal_cmd,
[d4c4078]214      { .status_code = RTEMS_SUCCESSFUL },
[908d6ed]215      &rtems_monitor_commands[18],
[b06e68ef]216    },
217    { "fatal",
[32e2554]218      "'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n"
219      "  fatal [status]",
[b06e68ef]220      0,
221      rtems_monitor_fatal_cmd,
[d4c4078]222      { .status_code = RTEMS_TASK_EXITTED },            /* exit value */
[908d6ed]223      &rtems_monitor_commands[19],
[b06e68ef]224    },
225    { "quit",
[32e2554]226      "Alias for 'exit'\n",
[b06e68ef]227      0,
228      rtems_monitor_fatal_cmd,
[d4c4078]229      { .status_code = RTEMS_SUCCESSFUL },              /* exit value */
[908d6ed]230      &rtems_monitor_commands[20],
[b06e68ef]231    },
[00a2d366]232#ifdef RTEMS_POSIX_API
233    { "pthread",
234      "Display information about the specified pthreads. "
235      "Default is to display information about all pthreads on this node.\n"
236      "  pthread [id [id ...] ]",
237      0,
238      rtems_monitor_object_cmd,
239      { RTEMS_MONITOR_OBJECT_PTHREAD },
[e41eaa88]240      &rtems_monitor_commands[21],
[00a2d366]241    },
[e41eaa88]242  #define RTEMS_MONITOR_DEBUGGER_NEXT 22
243#else
244  #define RTEMS_MONITOR_DEBUGGER_NEXT 21
[00a2d366]245#endif
[b06e68ef]246#ifdef CPU_INVOKE_DEBUGGER
247    { "debugger",
[32e2554]248      "Enter the debugger, if possible. "
249      "A continue from the debugger will return to the monitor.\n",
[b06e68ef]250      0,
[c64e4ed4]251      rtems_monitor_debugger_cmd,
[d4c4078]252      { 0 },
[e41eaa88]253      &rtems_monitor_commands[RTEMS_MONITOR_DEBUGGER_NEXT],
[b06e68ef]254    },
[aed742c]255#endif
[e41eaa88]256    { "help",
257      "Provide information about commands. "
258      "Default is show basic command summary.\n"
259      "help [ command [ command ] ]",
260      0,
261      rtems_monitor_help_cmd,
262      { .monitor_command_entry = rtems_monitor_commands },
263      NULL
264    }
[b06e68ef]265};
[ac7d5ef0]266
[e41eaa88]267/*
268 * All registered commands.
269 */
270
271static const rtems_monitor_command_entry_t *rtems_monitor_registered_commands =
272  &rtems_monitor_commands [0];
273
[ac7d5ef0]274
275rtems_status_code
276rtems_monitor_suspend(rtems_interval timeout)
277{
278    rtems_event_set event_set;
279    rtems_status_code status;
[aed742c]280
[b06e68ef]281    status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
282                                 RTEMS_DEFAULT_OPTIONS,
283                                 timeout,
284                                 &event_set);
[ac7d5ef0]285    return status;
286}
287
288void
289rtems_monitor_wakeup(void)
290{
291    rtems_status_code status;
[aed742c]292
[ac7d5ef0]293    status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
294}
295
[e41eaa88]296void rtems_monitor_debugger_cmd(
[031deada]297  int                                argc __attribute__((unused)),
298  char                             **argv __attribute__((unused)),
299  const rtems_monitor_command_arg_t *command_arg __attribute__((unused)),
300  bool                               verbose __attribute__((unused))
[8389628]301)
302{
303#ifdef CPU_INVOKE_DEBUGGER
304    CPU_INVOKE_DEBUGGER;
305#endif
306}
[ac7d5ef0]307
[e41eaa88]308void rtems_monitor_pause_cmd(
309  int                                argc,
310  char                             **argv,
[031deada]311  const rtems_monitor_command_arg_t *command_arg __attribute__((unused)),
312  bool                               verbose __attribute__((unused))
[b06e68ef]313)
314{
315    if (argc == 1)
316        rtems_monitor_suspend(1);
317    else
318        rtems_monitor_suspend(strtoul(argv[1], 0, 0));
319}
[ac7d5ef0]320
[e41eaa88]321void rtems_monitor_fatal_cmd(
322  int                                argc,
323  char                             **argv,
324  const rtems_monitor_command_arg_t *command_arg,
[031deada]325  bool                               verbose __attribute__((unused))
[b06e68ef]326)
[ac7d5ef0]327{
[b06e68ef]328    if (argc == 1)
[d4c4078]329        rtems_fatal_error_occurred(command_arg->status_code);
[b06e68ef]330    else
331        rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
[ac7d5ef0]332}
333
[e41eaa88]334void rtems_monitor_continue_cmd(
[031deada]335  int                                argc __attribute__((unused)),
336  char                             **argv __attribute__((unused)),
337  const rtems_monitor_command_arg_t *command_arg __attribute__((unused)),
338  bool                               verbose __attribute__((unused))
[b06e68ef]339)
[ac7d5ef0]340{
[b06e68ef]341    rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
342}
[ac7d5ef0]343
[e41eaa88]344void rtems_monitor_node_cmd(
345  int                                argc,
346  char                             **argv,
[031deada]347  const rtems_monitor_command_arg_t *command_arg __attribute__((unused)),
348  bool                               verbose __attribute__((unused))
[b06e68ef]349)
350{
[3e08d4e]351    uint32_t   new_node = rtems_monitor_default_node;
[aed742c]352
[b06e68ef]353    switch (argc)
[ac7d5ef0]354    {
[b06e68ef]355        case 1:                 /* no node, just set back to ours */
356            new_node = rtems_monitor_node;
357            break;
[ac7d5ef0]358
[b06e68ef]359        case 2:
360            new_node = strtoul(argv[1], 0, 0);
361            break;
[ac7d5ef0]362
[b06e68ef]363        default:
[714f06c]364            fprintf(stdout,"invalid syntax, try 'help node'\n");
[b06e68ef]365            break;
[ac7d5ef0]366    }
[b06e68ef]367
[361457db]368    #if defined(RTEMS_MULTIPROCESSING)
369      if ((new_node >= 1) &&
[8389628]370        _Configuration_MP_table &&
371        (new_node <= _Configuration_MP_table->maximum_nodes))
372            rtems_monitor_default_node = new_node;
[361457db]373    #endif
[ac7d5ef0]374}
375
[b06e68ef]376
[ac7d5ef0]377/*
378 *  Function:   rtems_monitor_symbols_loadup
379 *
380 *  Description:
381 *      Create and load the monitor's symbol table.
382 *      We are reading the output format of 'gnm' which looks like this:
383 *
384 *              400a7068 ? _Rate_monotonic_Information
385 *              400a708c ? _Thread_Dispatch_disable_level
386 *              400a7090 ? _Configuration_Table
387 *
388 *      We ignore the type field.
389 *
390 *  Side Effects:
391 *      Creates and fills in 'rtems_monitor_symbols' table
392 *
[c64e4ed4]393 *  TODO
394 *      there should be a BSP #define or something like that
395 *         to do this;  Assuming stdio is crazy.
[ac7d5ef0]396 *      Someday this should know BFD
397 *              Maybe we could get objcopy to just copy the symbol areas
398 *              and copy that down.
399 *
400 */
401
402void
403rtems_monitor_symbols_loadup(void)
404{
405    FILE *fp;
406    char buffer[128];
407
[b06e68ef]408    if (rtems_monitor_symbols)
409        rtems_symbol_table_destroy(rtems_monitor_symbols);
[aed742c]410
[2b643609]411    rtems_monitor_symbols = rtems_symbol_table_create();
[ac7d5ef0]412    if (rtems_monitor_symbols == 0)
413        return;
414
[b06e68ef]415    fp = fopen("symbols", "r");
[aed742c]416
[ac7d5ef0]417    if (fp == 0)
418        return;
419
420    while (fgets(buffer, sizeof(buffer) - 1, fp))
421    {
422        char *symbol;
423        char *value;
424        char *ignored_type;
425
426        value = strtok(buffer, " \t\n");
427        ignored_type = strtok(0, " \t\n");
428        symbol = strtok(0, " \t\n");
429
430        if (symbol && ignored_type && value)
431        {
432            rtems_symbol_t *sp;
433            sp = rtems_symbol_create(rtems_monitor_symbols,
434                                     symbol,
[a5b6cdd]435                                     (uint32_t) strtoul(value, 0, 16));
[ac7d5ef0]436            if (sp == 0)
437            {
[714f06c]438                fprintf(stdout,"could not define symbol '%s'\n", symbol);
[ac7d5ef0]439                goto done;
440            }
441        }
442        else
443        {
[714f06c]444            fprintf(stdout,"parsing error on '%s'\n", buffer);
[ac7d5ef0]445            goto done;
446        }
447    }
448
449done:
[be95da0]450    return;
[ac7d5ef0]451}
[b06e68ef]452
[32e2554]453/*
454 * User registered commands.
455 */
456
457int
458rtems_monitor_insert_cmd (
[e41eaa88]459  rtems_monitor_command_entry_t *command
[32e2554]460)
461{
[e41eaa88]462  const rtems_monitor_command_entry_t *e = rtems_monitor_registered_commands;
[aed742c]463
[e41eaa88]464  /* Reject empty commands */
465  if (command->command == NULL) {
[32e2554]466    return 0;
[e41eaa88]467  }
[2d99235e]468
[e41eaa88]469  /* Reject command if already present */
470  while (e->next != NULL) {
471      if (e->command != NULL && strcmp(command->command, e->command) == 0) {
472        return 0;
[32e2554]473      }
[e41eaa88]474      e = e->next;
475  }
[b06e68ef]476
[e41eaa88]477  /* Prepend new command */
478  command->next = rtems_monitor_registered_commands;
479  rtems_monitor_registered_commands = command;
[b06e68ef]480
[e41eaa88]481  return 1;
[b06e68ef]482}
[eb961961]483
484/**
485 * @brief Iterates through all registerd commands.
486 *
487 * For each command the interation routine @a routine is called with the
488 * command entry and the user provided argument @a arg.  It is guaranteed that
489 * the command name and function are not NULL.
490 */
491void rtems_monitor_command_iterate(
492  rtems_monitor_per_command_routine routine,
493  void *arg
494)
495{
496  const rtems_monitor_command_entry_t *e = rtems_monitor_registered_commands;
497
498  while (e != NULL) {
499    if (e->command != NULL && e->command_function != NULL) {
500      if (!routine(e, arg)) {
501        break;
502      }
503    }
504    e = e->next;
505  }
506}
Note: See TracBrowser for help on using the repository browser.