source: rtems/c/src/lib/libmisc/monitor/mon-monitor.c @ 674c900

4.104.114.84.95
Last change on this file since 674c900 was 5beb562, checked in by Joel Sherrill <joel.sherrill@…>, on 09/21/97 at 16:58:57

Cleaned up as part of adding the Monitor test.

  • Property mode set to 100644
File size: 12.9 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#include <rtems.h>
26
27#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
30#include <unistd.h>
31
32#include <rtems/monitor.h>
33
34/* set by trap handler */
35extern rtems_tcb       *debugger_interrupted_task;
36extern rtems_context   *debugger_interrupted_task_context;
37extern rtems_unsigned32 debugger_trap;
38
39/*
40 * Various id's for the monitor
41 * They need to be public variables for access by other agencies
42 * such as debugger and remote servers'
43 */
44
45rtems_id  rtems_monitor_task_id;
46
47unsigned32 rtems_monitor_node;          /* our node number */
48unsigned32 rtems_monitor_default_node;  /* current default for commands */
49
50/*
51 * The rtems symbol table
52 */
53
54rtems_symbol_table_t *rtems_monitor_symbols;
55
56/*
57 * The top-level commands
58 */
59
60rtems_monitor_command_entry_t rtems_monitor_commands[] = {
61    { "--usage--",
62      "\n"
63      "RTEMS monitor\n"
64      "\n"
65      "Commands (may be abbreviated)\n"
66      "\n"
67      "  help      -- get this message or command specific help\n"
68      "  pause     -- pause monitor for a specified number of ticks\n"
69      "  exit      -- invoke a fatal RTEMS error\n"
70      "  symbol    -- show entries from symbol table\n"
71      "  continue  -- put monitor to sleep waiting for explicit wakeup\n"
72      "  config    -- show system configuration\n"
73      "  itask     -- list init tasks\n"
74      "  mpci      -- list mpci config\n"
75      "  task      -- show task information\n"
76      "  queue     -- show message queue information\n"
77      "  extension -- user extensions\n"
78      "  driver    -- show information about named drivers\n"
79      "  dname     -- show information about named drivers\n"
80      "  object    -- generic object information\n"
81      "  node      -- specify default node for commands that take id's\n"
82#ifdef CPU_INVOKE_DEBUGGER
83      "  debugger  -- invoke system debugger\n"
84#endif
85      ,
86      0,
87      0,
88      (unsigned32) rtems_monitor_commands,
89    },
90    { "config",
91      "config\n"
92      "  Show the system configuration.\n",
93      0,
94      rtems_monitor_object_cmd,
95      RTEMS_MONITOR_OBJECT_CONFIG,
96    },
97    { "itask",
98      "itask\n"
99      "  List init tasks for the system\n",
100      0,
101      rtems_monitor_object_cmd,
102      RTEMS_MONITOR_OBJECT_INIT_TASK,
103    },
104   { "mpci",
105      "mpci\n"
106      "  Show the MPCI system configuration, if configured.\n",
107      0,
108      rtems_monitor_object_cmd,
109      RTEMS_MONITOR_OBJECT_MPCI,
110    },
111    { "pause",
112      "pause [ticks]\n"
113      "  monitor goes to \"sleep\" for specified ticks (default is 1)\n"
114      "  monitor will resume at end of period or if explicitly awakened\n",
115      0,
116      rtems_monitor_pause_cmd,
117      0,
118    },
119    { "continue",
120      "continue\n"
121      "  put the monitor to sleep waiting for an explicit wakeup from the\n"
122      "  program running.\n",
123      0,
124      rtems_monitor_continue_cmd,
125      0,
126    },
127    { "go",
128      "go\n"
129      "  Alias for 'continue'\n",
130      0,
131      rtems_monitor_continue_cmd,
132      0,
133    },
134    { "node",
135      "node [ node number ]\n"
136      "  Specify default node number for commands that take id's\n",
137      0,
138      rtems_monitor_node_cmd,
139      0,
140    },
141    { "symbol",
142      "symbol [ symbolname [symbolname ... ] ]\n"
143      "  display value associated with specified symbol.\n"
144      "  Defaults to displaying all known symbols.\n",
145      0,
146      rtems_monitor_symbol_cmd,
147      (unsigned32) &rtems_monitor_symbols,
148    },
149    { "extension",
150      "extension [id [id ...] ]\n"
151      "  display information about specified extensions.\n"
152      "  Default is to display information about all extensions on this node\n",
153      0,
154      rtems_monitor_object_cmd,
155      RTEMS_MONITOR_OBJECT_EXTENSION,
156    },
157    { "task",
158      "task [id [id ...] ]\n"
159      "  display information about the specified tasks.\n"
160      "  Default is to display information about all tasks on this node\n",
161      0,
162      rtems_monitor_object_cmd,
163      RTEMS_MONITOR_OBJECT_TASK,
164    },
165    { "queue",
166      "queue [id [id ... ] ]\n"
167      "  display information about the specified message queues\n"
168      "  Default is to display information about all queues on this node\n",
169      0,
170      rtems_monitor_object_cmd,
171      RTEMS_MONITOR_OBJECT_QUEUE,
172    },
173    { "object",
174      "object [id [id ...] ]\n"
175      "  display information about specified RTEMS objects.\n"
176      "  Object id's must include 'type' information.\n"
177      "  (which may normally be defaulted)\n",
178      0,
179      rtems_monitor_object_cmd,
180      RTEMS_MONITOR_OBJECT_INVALID,
181    },
182    { "driver",
183      "driver [ major [ major ... ] ]\n"
184      "  Display the RTEMS device driver table.\n",
185      0,
186      rtems_monitor_object_cmd,
187      RTEMS_MONITOR_OBJECT_DRIVER,
188    },
189    { "dname",
190      "dname\n"
191      "  Displays information about named drivers.\n",
192      0,
193      rtems_monitor_object_cmd,
194      RTEMS_MONITOR_OBJECT_DNAME,
195    },
196    { "exit",
197      "exit [status]\n"
198      "  Invoke 'rtems_fatal_error_occurred' with 'status'\n"
199      "  (default is RTEMS_SUCCESSFUL)\n",
200      0,
201      rtems_monitor_fatal_cmd,
202      RTEMS_SUCCESSFUL,
203    },
204    { "fatal",
205      "fatal [status]\n"
206      "  'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n",
207      0,
208      rtems_monitor_fatal_cmd,
209      RTEMS_TASK_EXITTED,                       /* exit value */
210    },
211    { "quit",
212      "quit [status]\n"
213      "  Alias for 'exit'\n",
214      0,
215      rtems_monitor_fatal_cmd,
216      RTEMS_SUCCESSFUL,                         /* exit value */
217    },
218    { "help",
219      "help [ command [ command ] ]\n"
220      "  provide information about commands\n"
221      "  Default is show basic command summary.\n",
222      0,
223      rtems_monitor_help_cmd,
224      (unsigned32) rtems_monitor_commands,
225    },
226#ifdef CPU_INVOKE_DEBUGGER
227    { "debugger",
228      "debugger\n"
229      "  Enter the debugger, if possible.\n"
230      "  A continue from the debugger will return to the monitor.\n",
231      0,
232      rtems_monitor_debugger_cmd,
233      0,
234    },
235#endif           
236    { 0, 0, 0, 0, 0 },
237};
238
239
240rtems_status_code
241rtems_monitor_suspend(rtems_interval timeout)
242{
243    rtems_event_set event_set;
244    rtems_status_code status;
245   
246    status = rtems_event_receive(MONITOR_WAKEUP_EVENT,
247                                 RTEMS_DEFAULT_OPTIONS,
248                                 timeout,
249                                 &event_set);
250    return status;
251}
252
253void
254rtems_monitor_wakeup(void)
255{
256    rtems_status_code status;
257   
258    status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT);
259}
260
261void
262rtems_monitor_debugger_cmd(
263    int        argc,
264    char     **argv,
265    unsigned32 command_arg,
266    boolean    verbose
267)
268{
269#ifdef CPU_INVOKE_DEBUGGER
270    CPU_INVOKE_DEBUGGER;
271#endif
272}
273
274void
275rtems_monitor_pause_cmd(
276    int        argc,
277    char     **argv,
278    unsigned32 command_arg,
279    boolean    verbose
280)
281{
282    if (argc == 1)
283        rtems_monitor_suspend(1);
284    else
285        rtems_monitor_suspend(strtoul(argv[1], 0, 0));
286}
287
288void
289rtems_monitor_fatal_cmd(
290    int     argc,
291    char  **argv,
292    unsigned32 command_arg,
293    boolean verbose
294)
295{
296    if (argc == 1)
297        rtems_fatal_error_occurred(command_arg);
298    else
299        rtems_fatal_error_occurred(strtoul(argv[1], 0, 0));
300}
301
302void
303rtems_monitor_continue_cmd(
304    int     argc,
305    char  **argv,
306    unsigned32 command_arg,
307    boolean verbose
308)
309{
310    rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
311}
312
313void
314rtems_monitor_node_cmd(
315    int     argc,
316    char  **argv,
317    unsigned32 command_arg,
318    boolean verbose
319)
320{
321    unsigned32 new_node = rtems_monitor_default_node;
322   
323    switch (argc)
324    {
325        case 1:                 /* no node, just set back to ours */
326            new_node = rtems_monitor_node;
327            break;
328
329        case 2:
330            new_node = strtoul(argv[1], 0, 0);
331            break;
332
333        default:
334            printf("invalid syntax, try 'help node'\n");
335            break;
336    }
337
338    if ((new_node >= 1) &&
339        _Configuration_MP_table &&
340        (new_node <= _Configuration_MP_table->maximum_nodes))
341            rtems_monitor_default_node = new_node;
342}
343
344
345/*
346 *  Function:   rtems_monitor_symbols_loadup
347 *
348 *  Description:
349 *      Create and load the monitor's symbol table.
350 *      We are reading the output format of 'gnm' which looks like this:
351 *
352 *              400a7068 ? _Rate_monotonic_Information
353 *              400a708c ? _Thread_Dispatch_disable_level
354 *              400a7090 ? _Configuration_Table
355 *
356 *      We ignore the type field.
357 *
358 *  Side Effects:
359 *      Creates and fills in 'rtems_monitor_symbols' table
360 *
361 *  TODO
362 *      there should be a BSP #define or something like that
363 *         to do this;  Assuming stdio is crazy.
364 *      Someday this should know BFD
365 *              Maybe we could get objcopy to just copy the symbol areas
366 *              and copy that down.
367 *
368 */
369
370void
371rtems_monitor_symbols_loadup(void)
372{
373    FILE *fp;
374    char buffer[128];
375
376    if (rtems_monitor_symbols)
377        rtems_symbol_table_destroy(rtems_monitor_symbols);
378   
379    rtems_monitor_symbols = rtems_symbol_table_create(10);
380    if (rtems_monitor_symbols == 0)
381        return;
382
383    fp = fopen("symbols", "r");
384   
385    if (fp == 0)
386        return;
387
388    while (fgets(buffer, sizeof(buffer) - 1, fp))
389    {
390        char *symbol;
391        char *value;
392        char *ignored_type;
393
394        value = strtok(buffer, " \t\n");
395        ignored_type = strtok(0, " \t\n");
396        symbol = strtok(0, " \t\n");
397
398        if (symbol && ignored_type && value)
399        {
400            rtems_symbol_t *sp;
401            sp = rtems_symbol_create(rtems_monitor_symbols,
402                                     symbol,
403                                     (rtems_unsigned32) strtoul(value, 0, 16));
404            if (sp == 0)
405            {
406                printf("could not define symbol '%s'\n", symbol);
407                goto done;
408            }
409        }
410        else
411        {
412            printf("parsing error on '%s'\n", buffer);
413            goto done;
414        }
415    }
416
417done:
418    return;
419}
420
421
422/*
423 * Main monitor command loop
424 */
425
426void
427rtems_monitor_task(
428    rtems_task_argument monitor_flags
429)
430{
431    rtems_tcb *debugee = 0;
432    rtems_context *rp;
433    rtems_context_fp *fp;
434    char command_buffer[513];
435    int argc;
436    char *argv[64];       
437    boolean verbose = FALSE;
438
439    if (monitor_flags & RTEMS_MONITOR_SUSPEND)
440        (void) rtems_monitor_suspend(RTEMS_NO_TIMEOUT);
441
442    for (;;)
443    {
444        extern rtems_tcb * _Thread_Executing;
445        rtems_monitor_command_entry_t *command;
446
447        debugee = _Thread_Executing;
448        rp = &debugee->Registers;
449        fp = (rtems_context_fp *) debugee->fp_context;  /* possibly 0 */
450
451        if (0 == rtems_monitor_command_read(command_buffer, &argc, argv))
452            continue;
453        if ((command = rtems_monitor_command_lookup(rtems_monitor_commands,
454                                                    argc,
455                                                    argv)) == 0)
456            continue;
457
458        command->command_function(argc, argv, command->command_arg, verbose);
459
460        fflush(stdout);
461    }
462}
463
464
465void
466rtems_monitor_kill(void)
467{
468    if (rtems_monitor_task_id)
469        rtems_task_delete(rtems_monitor_task_id);
470    rtems_monitor_task_id = 0;
471   
472    rtems_monitor_server_kill();
473}
474
475void
476rtems_monitor_init(
477    unsigned32 monitor_flags
478)
479{
480    rtems_status_code status;
481   
482    rtems_monitor_kill();
483
484    status = rtems_task_create(RTEMS_MONITOR_NAME,
485                               1,
486                               0 /* default stack */,
487                               RTEMS_INTERRUPT_LEVEL(0),
488                               RTEMS_DEFAULT_ATTRIBUTES,
489                               &rtems_monitor_task_id);
490    if (status != RTEMS_SUCCESSFUL)
491    {
492        rtems_error(status, "could not create monitor task");
493        goto done;
494    }
495
496    rtems_monitor_node = rtems_get_node(rtems_monitor_task_id);
497    rtems_monitor_default_node = rtems_monitor_node;
498
499    rtems_monitor_symbols_loadup();
500
501    if (monitor_flags & RTEMS_MONITOR_GLOBAL)
502        rtems_monitor_server_init(monitor_flags);
503
504    /*
505     * Start the monitor task itself
506     */
507   
508    status = rtems_task_start(rtems_monitor_task_id,
509                              rtems_monitor_task,
510                              monitor_flags);
511    if (status != RTEMS_SUCCESSFUL)
512    {
513        rtems_error(status, "could not start monitor");
514        goto done;
515    }
516
517done:
518}
Note: See TracBrowser for help on using the repository browser.