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

4.104.115
Last change on this file since da9518a2 was da9518a2, checked in by Joel Sherrill <joel.sherrill@…>, on 04/05/10 at 17:12:05

2010-04-05 Thomas Znidar <t.znidar@…>

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