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

4.104.114.84.95
Last change on this file since a29d2e7 was 714f06c, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/17/04 at 08:12:02

2004-04-17 Ralf Corsepius <ralf_corsepius@…>

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