source: rtems/c/src/libmisc/monitor/mon-monitor.c @ 3652ad35

4.104.114.84.95
Last change on this file since 3652ad35 was b06e68ef, checked in by Joel Sherrill <joel.sherrill@…>, on 08/17/95 at 19:51:51

Numerous miscellaneous features incorporated from Tony Bennett
(tbennett@…) including the following major additions:

+ variable length messages
+ named devices
+ debug monitor
+ association tables/variables

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