source: rtems/cpukit/libmisc/capture/capture-cli.c @ a29d2e7

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

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: 32.7 KB
Line 
1/*
2  ------------------------------------------------------------------------
3  $Id$
4  ------------------------------------------------------------------------
5
6  Copyright Objective Design Systems Pty Ltd, 2002
7  All rights reserved Objective Design Systems Pty Ltd, 2002
8  Chris Johns (ccj@acm.org)
9
10  COPYRIGHT (c) 1989-1998.
11  On-Line Applications Research Corporation (OAR).
12
13  The license and distribution terms for this file may be
14  found in the file LICENSE in this distribution.
15
16  This software with is provided ``as is'' and with NO WARRANTY.
17
18  ------------------------------------------------------------------------
19
20  RTEMS Performance Monitoring and Measurement Framework.
21
22  This is the Target Interface Command Line Interface. You need
23  start the RTEMS monitor.
24
25*/
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <ctype.h>
32#include <stdlib.h>
33#include <stdio.h>
34#include <string.h>
35
36#include <rtems.h>
37#include <rtems/capture-cli.h>
38#include <rtems/monitor.h>
39
40#define RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS (32)
41
42/*
43 * The user capture timestamper.
44 */
45static rtems_capture_timestamp capture_timestamp;
46
47/*
48 * Common variable to sync the load monitor task.
49 */
50static volatile int cli_load_thread_active;
51
52/*
53 * rtems_capture_cli_open
54 *
55 *  DESCRIPTION:
56 *
57 * This function opens the capture engine. We need the size of the
58 * capture buffer.
59 *
60 */
61
62static const char* open_usage = "usage: copen [-i] size\n";
63
64static void
65rtems_capture_cli_open (
66  int argc,
67  char **argv,
68  rtems_monitor_command_arg_t *command_arg,
69  boolean verbose )
70{
71  uint32_t    size = 0;
72  rtems_boolean     enable = 0;
73  rtems_status_code sc;
74  int               arg;
75
76  if (argc <= 1)
77  {
78    fprintf(stdout,open_usage);
79    return;
80  }
81
82  for (arg = 1; arg < argc; arg++)
83  {
84    if (argv[arg][0] == '-')
85    {
86      if (argv[arg][1] == 'i')
87        enable = 1;
88      else
89        fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
90    }
91    else
92    {
93      size = strtoul (argv[arg], 0, 0);
94
95      if (size < 100)
96      {
97        fprintf(stdout,"error: size must be greater than or equal to 100\n");
98        return;
99      }
100    }
101  }
102
103  sc = rtems_capture_open (size, capture_timestamp);
104
105  if (sc != RTEMS_SUCCESSFUL)
106  {
107    fprintf(stdout,"error: open failed: %s\n", rtems_status_text (sc));
108    return;
109  }
110
111  fprintf(stdout,"capture engine opened.\n");
112
113  if (!enable)
114    return;
115
116  sc = rtems_capture_control (enable);
117
118  if (sc != RTEMS_SUCCESSFUL)
119  {
120    fprintf(stdout,"error: open enable failed: %s\n", rtems_status_text (sc));
121    return;
122  }
123
124  fprintf(stdout,"capture engine enabled.\n");
125}
126
127/*
128 * rtems_capture_cli_close
129 *
130 *  DESCRIPTION:
131 *
132 * This function closes the capture engine.
133 *
134 */
135
136static void
137rtems_capture_cli_close (
138  int argc,
139  char **argv,
140  rtems_monitor_command_arg_t *command_arg,
141  boolean verbose )
142{
143  rtems_status_code sc;
144
145  sc = rtems_capture_close ();
146
147  if (sc != RTEMS_SUCCESSFUL)
148  {
149    fprintf(stdout,"error: close failed: %s\n", rtems_status_text (sc));
150    return;
151  }
152
153  fprintf(stdout,"capture engine closed.\n");
154}
155
156/*
157 * rtems_capture_cli_enable
158 *
159 *  DESCRIPTION:
160 *
161 * This function enables the capture engine.
162 *
163 */
164
165static void
166rtems_capture_cli_enable (
167  int argc,
168  char **argv,
169  rtems_monitor_command_arg_t *command_arg,
170  boolean verbose )
171{
172  rtems_status_code sc;
173
174  sc = rtems_capture_control (1);
175
176  if (sc != RTEMS_SUCCESSFUL)
177  {
178    fprintf(stdout,"error: enable failed: %s\n", rtems_status_text (sc));
179    return;
180  }
181
182  fprintf(stdout,"capture engine enabled.\n");
183}
184
185/*
186 * rtems_capture_cli_disable
187 *
188 *  DESCRIPTION:
189 *
190 * This function disables the capture engine.
191 *
192 */
193
194static void
195rtems_capture_cli_disable (
196  int argc,
197  char **argv,
198  rtems_monitor_command_arg_t *command_arg,
199  boolean verbose )
200{
201  rtems_status_code sc;
202
203  sc = rtems_capture_control (0);
204
205  if (sc != RTEMS_SUCCESSFUL)
206  {
207    fprintf(stdout,"error: disable failed: %s\n", rtems_status_text (sc));
208    return;
209  }
210
211  fprintf(stdout,"capture engine disabled.\n");
212}
213
214/*
215 * rtems_capture_cli_task_list
216 *
217 *  DESCRIPTION:
218 *
219 * This function lists the tasks the capture engine knows about.
220 *
221 */
222
223static void
224rtems_capture_cli_task_list (
225  int argc,
226  char **argv,
227  rtems_monitor_command_arg_t *command_arg,
228  boolean verbose )
229{
230  rtems_task_priority   ceiling = rtems_capture_watch_get_ceiling ();
231  rtems_task_priority   floor = rtems_capture_watch_get_floor ();
232  rtems_capture_task_t* task = rtems_capture_get_task_list ();
233  uint32_t        ticks;
234  uint32_t        tick_offset;
235  unsigned long long    total_time;
236  int                   count = rtems_capture_task_count ();
237
238  if (capture_timestamp)
239    capture_timestamp (&ticks, &tick_offset);
240  else
241  {
242    ticks = _Watchdog_Ticks_since_boot;
243    tick_offset = 0;
244  }
245
246  total_time = (ticks * rtems_capture_task_time (task)) + tick_offset;
247
248  fprintf(stdout,"total %i\n", count);
249
250  while (task)
251  {
252    rtems_task_priority priority;
253    int                 stack_used;
254    int                 time_used;
255
256    stack_used = rtems_capture_task_stack_usage (task) * 100;
257    stack_used /= rtems_capture_task_stack_size (task);
258
259    if (stack_used > 100)
260      stack_used = 100;
261
262    time_used = (rtems_capture_task_time (task) * 100) / total_time;
263
264    if (time_used > 100)
265      time_used = 100;
266
267    priority = rtems_capture_task_real_priority (task);
268
269    fprintf(stdout," ");
270    rtems_monitor_dump_id (rtems_capture_task_id (task));
271    fprintf(stdout," ");
272    rtems_monitor_dump_name (rtems_capture_task_name (task));
273    fprintf(stdout," ");
274    rtems_monitor_dump_priority (rtems_capture_task_start_priority (task));
275    fprintf(stdout," ");
276    rtems_monitor_dump_priority (rtems_capture_task_real_priority (task));
277    fprintf(stdout," ");
278    rtems_monitor_dump_priority (rtems_capture_task_curr_priority (task));
279    fprintf(stdout," ");
280    rtems_monitor_dump_state (rtems_capture_task_state (task));
281    fprintf(stdout," %c%c%c%c%c",
282            rtems_capture_task_valid (task) ? 'a' : 'd',
283            rtems_capture_task_flags (task) & RTEMS_CAPTURE_TRACED ? 't' : '-',
284            rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
285            rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
286            rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
287    if ((floor > ceiling) && (ceiling > priority))
288      fprintf(stdout,"--");
289    else
290      fprintf(stdout,"%c%c",
291              rtems_capture_task_control (task) ?
292              (rtems_capture_task_control_flags (task) & RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
293              rtems_capture_watch_global_on () ? 'g' : '-');
294    fprintf(stdout," %3i%% %3i%% (%i)\n",
295            stack_used, time_used, rtems_capture_task_ticks (task));
296
297    task = rtems_capture_next_task (task);
298  }
299}
300
301/*
302 * rtems_capture_cli_task_load_thread
303 *
304 *  DESCRIPTION:
305 *
306 * This function displays the load of the tasks on an ANSI terminal.
307 *
308 */
309
310static void
311rtems_capture_cli_task_load_thread (rtems_task_argument arg)
312{
313  rtems_task_priority ceiling = rtems_capture_watch_get_ceiling ();
314  rtems_task_priority floor = rtems_capture_watch_get_floor ();
315  int                 last_count = 0;
316
317  fprintf(stdout,"\x1b[2J Press ENTER to exit.\n\n");
318  fprintf(stdout,"     PID NAME RPRI CPRI STATE  %%CPU     %%STK FLGS   EXEC TIME\n");
319
320  for (;;)
321  {
322    rtems_capture_task_t* tasks[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
323    unsigned long long    load[RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS + 1];
324    rtems_capture_task_t* task;
325    unsigned long long    total_time;
326    int                   count = 0;
327    int                   i;
328    int                   j;
329
330    cli_load_thread_active = 1;
331
332    /*
333     * Iterate over the tasks and sort the highest load tasks
334     * into our local arrays. We only handle a limited number of
335     * tasks.
336     */
337
338    memset (tasks, 0, sizeof (tasks));
339    memset (load, 0, sizeof (load));
340
341    task = rtems_capture_get_task_list ();
342
343    while (task)
344    {
345      if (rtems_capture_task_valid (task))
346      {
347        unsigned long long l = rtems_capture_task_delta_time (task);
348
349        count++;
350
351        for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
352        {
353          if (tasks[i])
354          {
355            if ((l == 0) || (l < load[i]))
356              continue;
357
358            for (j = (RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS - 1); j >= i; j--)
359            {
360              tasks[j + 1] = tasks[j];
361              load[j + 1]  = load[j];
362            }
363          }
364
365          tasks[i] = task;
366          load[i]  = l;
367          break;
368        }
369      }
370      task = rtems_capture_next_task (task);
371    }
372
373    fprintf(stdout,"\x1b[4;0H");
374
375    total_time = 0;
376
377    for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
378      total_time += load[i];
379
380    if (count > last_count)
381      j = count;
382    else
383      j = last_count;
384
385    for (i = 0; i < RTEMS_CAPTURE_CLI_MAX_LOAD_TASKS; i++)
386    {
387      rtems_task_priority priority;
388      int                 stack_used;
389      int                 task_load;
390      int                 k;
391
392      if (!tasks[i])
393        break;
394
395      j--;
396
397      stack_used = rtems_capture_task_stack_usage (tasks[i]) * 100;
398      stack_used /= rtems_capture_task_stack_size (tasks[i]);
399
400      if (stack_used > 100)
401        stack_used = 100;
402
403      task_load = (int) ((load[i] * 100000) / total_time);
404
405      priority = rtems_capture_task_real_priority (tasks[i]);
406
407      fprintf(stdout,"\x1b[K");
408      rtems_monitor_dump_id (rtems_capture_task_id (tasks[i]));
409      fprintf(stdout," ");
410      rtems_monitor_dump_name (rtems_capture_task_name (tasks[i]));
411      fprintf(stdout,"  ");
412      rtems_monitor_dump_priority (priority);
413      fprintf(stdout,"  ");
414      rtems_monitor_dump_priority (rtems_capture_task_curr_priority (tasks[i]));
415      fprintf(stdout," ");
416      k = rtems_monitor_dump_state (rtems_capture_task_state (tasks[i]));
417      fprintf(stdout,"%*c %3i.%03i%% ", 6 - k, ' ', task_load / 1000, task_load % 1000);
418      fprintf(stdout,"%3i%% %c%c%c%c%c", stack_used,
419              rtems_capture_task_valid (tasks[i]) ? 'a' : 'd',
420              rtems_capture_task_flags (tasks[i]) & RTEMS_CAPTURE_TRACED ? 't' : '-',
421              rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
422              rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
423              rtems_capture_task_control_flags (tasks[i]) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
424      if ((floor > ceiling) && (ceiling > priority))
425        fprintf(stdout,"--");
426      else
427        fprintf(stdout,"%c%c",
428                rtems_capture_task_control (tasks[i]) ?
429                (rtems_capture_task_control_flags (tasks[i]) &
430                 RTEMS_CAPTURE_WATCH ? 'w' : '+') : '-',
431                rtems_capture_watch_global_on () ? 'g' : '-');
432
433      fprintf(stdout,"   %qi\n", rtems_capture_task_time (tasks[i]));
434    }
435
436    while (j)
437    {
438      fprintf(stdout,"\x1b[K\n");
439      j--;
440    }
441
442    last_count = count;
443
444    cli_load_thread_active = 0;
445
446    rtems_task_wake_after (TOD_MICROSECONDS_TO_TICKS (5000000));
447  }
448}
449
450/*
451 * rtems_capture_cli_task_load
452 *
453 *  DESCRIPTION:
454 *
455 * This function is a monitor command.
456 *
457 */
458
459static void
460rtems_capture_cli_task_load (
461  int argc,
462  char **argv,
463  rtems_monitor_command_arg_t *command_arg,
464  boolean verbose )
465{
466  rtems_status_code   sc;
467  rtems_task_priority priority;
468  rtems_name          name;
469  rtems_id            id;
470
471  sc = rtems_task_set_priority (RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &priority);
472
473  if (sc != RTEMS_SUCCESSFUL)
474  {
475    fprintf(stdout,"error: cannot obtain the current priority: %s\n", rtems_status_text (sc));
476    return;
477  }
478
479  memcpy (&name, "CPlt", 4);
480
481  sc = rtems_task_create (name, priority, 1024,
482                          RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
483                          RTEMS_PREEMPT | RTEMS_TIMESLICE | RTEMS_NO_ASR,
484                          &id);
485
486  if (sc != RTEMS_SUCCESSFUL)
487  {
488    fprintf(stdout,"error: cannot create helper thread: %s\n", rtems_status_text (sc));
489    return;
490  }
491
492  sc = rtems_task_start (id, rtems_capture_cli_task_load_thread, 0);
493
494  if (sc != RTEMS_SUCCESSFUL)
495  {
496    fprintf(stdout,"error: cannot start helper thread: %s\n", rtems_status_text (sc));
497    rtems_task_delete (id);
498    return;
499  }
500
501  for (;;)
502  {
503    int c = getchar ();
504
505    if ((c == '\r') || (c == '\n'))
506    {
507      int loops = 20;
508
509      while (loops && cli_load_thread_active)
510        rtems_task_wake_after (TOD_MICROSECONDS_TO_TICKS (100000));
511
512      rtems_task_delete (id);
513
514      fprintf(stdout,"load monitoring stopped.\n");
515
516      return;
517    }
518  }
519}
520
521/*
522 * rtems_capture_cli_watch_list
523 *
524 *  DESCRIPTION:
525 *
526 * This function lists the controls in the capture engine.
527 *
528 */
529
530static void
531rtems_capture_cli_watch_list (
532  int argc,
533  char **argv,
534  rtems_monitor_command_arg_t *command_arg,
535  boolean verbose )
536{
537  rtems_capture_control_t* control = rtems_capture_get_control_list ();
538  rtems_task_priority      ceiling = rtems_capture_watch_get_ceiling ();
539  rtems_task_priority      floor = rtems_capture_watch_get_floor ();
540
541  fprintf(stdout,"watch priority ceiling is %i\n", ceiling);
542  fprintf(stdout,"watch priority floor is %i\n", floor);
543  fprintf(stdout,"global watch is %s\n",
544          rtems_capture_watch_global_on () ? "enabled" : "disabled");
545  fprintf(stdout,"total %d\n", rtems_capture_control_count ());
546
547  while (control)
548  {
549    int f;
550    int fshowed;
551    int lf;
552
553    fprintf(stdout," ");
554    rtems_monitor_dump_id (rtems_capture_control_id (control));
555    fprintf(stdout," ");
556    rtems_monitor_dump_name (rtems_capture_control_name (control));
557    fprintf(stdout," %c%c%c%c%c",
558            rtems_capture_control_flags (control) & RTEMS_CAPTURE_WATCH ? 'w' : '-',
559            rtems_capture_watch_global_on () ? 'g' : '-',
560            rtems_capture_control_flags (control) & RTEMS_CAPTURE_TO_ANY ? 'F' : '-',
561            rtems_capture_control_flags (control) & RTEMS_CAPTURE_FROM_ANY ? 'T' : '-',
562            rtems_capture_control_flags (control) & RTEMS_CAPTURE_FROM_TO ? 'E' : '-');
563
564    for (f = 0, fshowed = 0, lf = 1; f < RTEMS_CAPTURE_TRIGGER_TASKS; f++)
565    {
566      if (lf && ((fshowed % 16) == 0))
567      {
568        fprintf(stdout,"\n");
569        lf = 0;
570      }
571
572      /*
573       * FIXME: name test.
574       */
575      if (rtems_capture_control_from_name (control, f))
576      {
577        fprintf(stdout,"  %2i:", f);
578        rtems_monitor_dump_name (rtems_capture_control_from_name (control, f));
579        fprintf(stdout,"/");
580        rtems_monitor_dump_id (rtems_capture_control_from_id (control, f));
581        fshowed++;
582        lf = 1;
583      }
584    }
585
586    if (lf)
587      fprintf(stdout,"\n");
588
589    control = rtems_capture_next_control (control);
590  }
591}
592
593/*
594 * rtems_capture_cli_get_name_id
595 *
596 *  DESCRIPTION:
597 *
598 * This function checks arguments for a name or an id.
599 *
600 */
601
602static rtems_boolean
603rtems_capture_cli_get_name_id (char*          arg,
604                               rtems_boolean* valid_name,
605                               rtems_boolean* valid_id,
606                               rtems_name*    name,
607                               rtems_id*      id)
608{
609  uint32_t   objclass;
610  int             l;
611  int             i;
612
613  if (*valid_name && *valid_id)
614  {
615    fprintf(stdout,"error: too many arguments\n");
616    return 0;
617  }
618
619  /*
620   * See if the arg is all hex digits.
621   */
622
623  l = strlen (arg);
624
625  for (i = 0; i < l; i++)
626    if (!isxdigit (arg[i]))
627      break;
628
629  *id = strtoul (arg, 0, 16);
630
631  objclass = _Objects_Get_class (*id);
632
633  if ((i == l))
634    *valid_id = 1;
635  else
636  {
637    memcpy (name, arg, sizeof (rtems_name));
638    *valid_name = 1;
639  }
640
641  return 1;
642}
643
644/*
645 * rtems_capture_cli_watch_add
646 *
647 *  DESCRIPTION:
648 *
649 * This function is a monitor command that add a watch to the capture
650 * engine.
651 *
652 */
653
654static char const * watch_add_usage = "usage: cwadd [task name] [id]\n";
655
656static void
657rtems_capture_cli_watch_add (
658  int argc,
659  char **argv,
660  rtems_monitor_command_arg_t *command_arg,
661  boolean verbose )
662{
663  rtems_status_code sc;
664  int               arg;
665  rtems_name        name = 0;
666  rtems_id          id = 0;
667  rtems_boolean     valid_name = 0;
668  rtems_boolean     valid_id = 0;
669
670  if (argc <= 1)
671  {
672    fprintf(stdout,watch_add_usage);
673    return;
674  }
675
676  for (arg = 1; arg < argc; arg++)
677  {
678    if (argv[arg][0] == '-')
679    {
680      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
681    }
682    else
683    {
684      if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
685        return;
686    }
687  }
688
689  if (!valid_name && !valid_id)
690  {
691    fprintf(stdout,"error: no valid name or task id located\n");
692    return;
693  }
694
695  sc = rtems_capture_watch_add (name, id);
696
697  if (sc != RTEMS_SUCCESSFUL)
698  {
699    fprintf(stdout,"error: watch add failed: %s\n", rtems_status_text (sc));
700    return;
701  }
702
703  fprintf(stdout,"watch added.\n");
704}
705
706/*
707 * rtems_capture_cli_watch_del
708 *
709 *  DESCRIPTION:
710 *
711 * This function is a monitor command that deletes a watch from the capture
712 * engine.
713 *
714 */
715
716static char const * watch_del_usage = "usage: cwdel [task name] [id]\n";
717
718static void
719rtems_capture_cli_watch_del (
720  int argc,
721  char **argv,
722  rtems_monitor_command_arg_t *command_arg,
723  boolean verbose )
724{
725  rtems_status_code sc;
726  int               arg;
727  rtems_name        name = 0;
728  rtems_id          id = 0;
729  rtems_boolean     valid_name = 0;
730  rtems_boolean     valid_id = 0;
731
732  if (argc <= 1)
733  {
734    fprintf(stdout,watch_del_usage);
735    return;
736  }
737
738  for (arg = 1; arg < argc; arg++)
739  {
740    if (argv[arg][0] == '-')
741    {
742      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
743    }
744    else
745    {
746      if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
747        return;
748    }
749  }
750
751  if (!valid_name && !valid_id)
752  {
753    fprintf(stdout,"error: no valid name or task id located\n");
754    return;
755  }
756
757  sc = rtems_capture_watch_del (name, id);
758
759  if (sc != RTEMS_SUCCESSFUL)
760  {
761    fprintf(stdout,"error: watch delete failed: %s\n", rtems_status_text (sc));
762    return;
763  }
764
765  fprintf(stdout,"watch delete.\n");
766}
767
768/*
769 * rtems_capture_cli_watch_control
770 *
771 *  DESCRIPTION:
772 *
773 * This function is a monitor command that controls a watch.
774 *
775 */
776
777static char const * watch_control_usage = "usage: cwctl [task name] [id] on/off\n";
778
779static void
780rtems_capture_cli_watch_control (
781  int argc,
782  char **argv,
783  rtems_monitor_command_arg_t *command_arg,
784  boolean verbose )
785{
786  rtems_status_code sc;
787  int               arg;
788  rtems_name        name = 0;
789  rtems_id          id = 0;
790  rtems_boolean     valid_name = 0;
791  rtems_boolean     valid_id = 0;
792  rtems_boolean     enable = 0;
793
794  if (argc <= 2)
795  {
796    fprintf(stdout,watch_control_usage);
797    return;
798  }
799
800  for (arg = 1; arg < argc; arg++)
801  {
802    if (argv[arg][0] == '-')
803    {
804      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
805    }
806    else
807    {
808      if (strcmp (argv[arg], "on") == 0)
809        enable = 1;
810      else if (strcmp (argv[arg], "off") == 0)
811        enable = 0;
812      else if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id, &name, &id))
813        return;
814    }
815  }
816
817  if (!valid_name && !valid_id)
818  {
819    fprintf(stdout,"error: no valid name or task id located\n");
820    return;
821  }
822
823  sc = rtems_capture_watch_ctrl (name, id, enable);
824
825  if (sc != RTEMS_SUCCESSFUL)
826  {
827    fprintf(stdout,"error: watch control failed: %s\n", rtems_status_text (sc));
828    return;
829  }
830
831  fprintf(stdout,"watch %s.\n", enable ? "enabled" : "disabled");
832}
833
834/*
835 * rtems_capture_cli_watch_global
836 *
837 *  DESCRIPTION:
838 *
839 * This function is a monitor command that sets a global watch.
840 *
841 */
842
843static char const * watch_global_usage = "usage: cwglob on/off\n";
844
845static void
846rtems_capture_cli_watch_global (
847  int argc,
848  char **argv,
849  rtems_monitor_command_arg_t *command_arg,
850  boolean verbose )
851{
852  rtems_status_code sc;
853  int               arg;
854  rtems_boolean     enable = 0;
855
856  if (argc <= 1)
857  {
858    fprintf(stdout,watch_global_usage);
859    return;
860  }
861
862  for (arg = 1; arg < argc; arg++)
863  {
864    if (argv[arg][0] == '-')
865    {
866      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
867    }
868    else
869    {
870      if (strcmp (argv[arg], "on") == 0)
871        enable = 1;
872      else if (strcmp (argv[arg], "off") == 0)
873        enable = 0;
874    }
875  }
876
877  sc = rtems_capture_watch_global (enable);
878
879  if (sc != RTEMS_SUCCESSFUL)
880  {
881    fprintf(stdout,"error: global watch failed: %s\n", rtems_status_text (sc));
882    return;
883  }
884
885  fprintf(stdout,"global watch %s.\n", enable ? "enabled" : "disabled");
886}
887
888/*
889 * rtems_capture_cli_watch_ceiling
890 *
891 *  DESCRIPTION:
892 *
893 * This function is a monitor command that sets watch ceiling.
894 *
895 */
896
897static char const * watch_ceiling_usage = "usage: cwceil priority\n";
898
899static void
900rtems_capture_cli_watch_ceiling (
901  int argc,
902  char **argv,
903  rtems_monitor_command_arg_t *command_arg,
904  boolean verbose )
905{
906  rtems_status_code   sc;
907  int                 arg;
908  rtems_task_priority priority = 0;
909
910  if (argc <= 1)
911  {
912    fprintf(stdout,watch_ceiling_usage);
913    return;
914  }
915
916  for (arg = 1; arg < argc; arg++)
917  {
918    if (argv[arg][0] == '-')
919    {
920      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
921    }
922    else
923    {
924      priority = strtoul (argv[arg], 0, 0);
925    }
926  }
927
928  sc = rtems_capture_watch_ceiling (priority);
929
930  if (sc != RTEMS_SUCCESSFUL)
931  {
932    fprintf(stdout,"error: watch ceiling failed: %s\n", rtems_status_text (sc));
933    return;
934  }
935
936  fprintf(stdout,"watch ceiling is %i.\n", priority);
937}
938
939/*
940 * rtems_capture_cli_watch_floor
941 *
942 *  DESCRIPTION:
943 *
944 * This function is a monitor command that sets watch floor.
945 *
946 */
947
948static char const * watch_floor_usage = "usage: cwfloor priority\n";
949
950static void
951rtems_capture_cli_watch_floor (
952  int argc,
953  char **argv,
954  rtems_monitor_command_arg_t *command_arg,
955  boolean verbose )
956{
957  rtems_status_code   sc;
958  int                 arg;
959  rtems_task_priority priority = 0;
960
961  if (argc <= 1)
962  {
963    fprintf(stdout,watch_floor_usage);
964    return;
965  }
966
967  for (arg = 1; arg < argc; arg++)
968  {
969    if (argv[arg][0] == '-')
970    {
971      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
972    }
973    else
974    {
975      priority = strtoul (argv[arg], 0, 0);
976    }
977  }
978
979  sc = rtems_capture_watch_floor (priority);
980
981  if (sc != RTEMS_SUCCESSFUL)
982  {
983    fprintf(stdout,"error: watch floor failed: %s\n", rtems_status_text (sc));
984    return;
985  }
986
987  fprintf(stdout,"watch floor is %i.\n", priority);
988}
989
990/*
991 * rtems_capture_cli_trigger_set
992 *
993 *  DESCRIPTION:
994 *
995 * This function is a monitor command that sets a trigger.
996 *
997 */
998
999static char const *trigger_set_usage = "usage: ctrig type [from] [fromid] [to] [to id]\n";
1000
1001static void
1002rtems_capture_cli_trigger_set (
1003  int argc,
1004  char **argv,
1005  rtems_monitor_command_arg_t *command_arg,
1006  boolean verbose )
1007{
1008  rtems_status_code       sc;
1009  int                     arg;
1010  rtems_capture_trigger_t trigger = rtems_capture_from_to;
1011  rtems_boolean           trigger_set = 0;
1012  rtems_name              name = 0;
1013  rtems_id                id = 0;
1014  rtems_boolean           valid_name = 0;
1015  rtems_boolean           valid_id = 0;
1016  rtems_name              from_name = 0;
1017  rtems_id                from_id = 0;
1018  rtems_boolean           from_valid_name = 0;
1019  rtems_boolean           from_valid_id = 0;
1020  rtems_name              to_name = 0;
1021  rtems_id                to_id = 0;
1022  rtems_boolean           to_valid_name = 0;
1023  rtems_boolean           to_valid_id = 0;
1024
1025  if (argc <= 2)
1026  {
1027    fprintf(stdout,trigger_set_usage);
1028    return;
1029  }
1030
1031  for (arg = 1; arg < argc; arg++)
1032  {
1033    if (argv[arg][0] == '-')
1034    {
1035      fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
1036    }
1037    else
1038    {
1039      if (!trigger_set)
1040      {
1041        if (strcmp (argv[arg], "from") == 0)
1042          trigger = rtems_capture_to_any;
1043        else if (strcmp (argv[arg], "to") == 0)
1044          trigger = rtems_capture_from_any;
1045        else if (strcmp (argv[arg], "edge") == 0)
1046          trigger = rtems_capture_from_any;
1047        else
1048        {
1049          fprintf(stdout,"error: the first argument is the trigger type (from/to/edge)\n");
1050          return;
1051        }
1052        trigger_set = 1;
1053      }
1054      else
1055      {
1056        if (trigger == rtems_capture_to_any)
1057        {
1058          if (from_valid_name && from_valid_id)
1059            fprintf(stdout,"warning: extra arguments ignored\n");
1060          else if (!rtems_capture_cli_get_name_id (argv[arg], &from_valid_name, &from_valid_id,
1061                                           &from_name, &from_id))
1062            return;
1063        }
1064        else if (trigger == rtems_capture_from_any)
1065        {
1066          if (to_valid_name && to_valid_id)
1067            fprintf(stdout,"warning: extra arguments ignored\n");
1068          else if (!rtems_capture_cli_get_name_id (argv[arg], &to_valid_name, &to_valid_id,
1069                                           &to_name, &to_id))
1070            return;
1071        }
1072        else if (trigger == rtems_capture_from_to)
1073        {
1074          if (from_valid_name && from_valid_id && to_valid_name && to_valid_id)
1075            fprintf(stdout,"warning: extra arguments ignored\n");
1076          else
1077          {
1078            if (!rtems_capture_cli_get_name_id (argv[arg], &valid_name, &valid_id,
1079                                        &name, &id))
1080              return;
1081
1082            if (valid_name)
1083            {
1084              if (!from_valid_name && !from_valid_id)
1085              {
1086                from_valid_name = 1;
1087                from_name       = name;
1088              }
1089              else if (to_valid_name)
1090                fprintf(stdout,"warning: extra arguments ignored\n");
1091              else
1092              {
1093                to_valid_name = 1;
1094                to_name       = name;
1095              }
1096            }
1097            if (valid_id)
1098            {
1099              if (!from_valid_id && !to_valid_name)
1100              {
1101                from_valid_id = 1;
1102                from_id       = id;
1103              }
1104              else if (to_valid_id)
1105                fprintf(stdout,"warning: extra arguments ignored\n");
1106              else
1107              {
1108                to_valid_id = 1;
1109                to_id       = id;
1110              }
1111            }
1112          }
1113        }
1114      }
1115    }
1116  }
1117
1118  if ((trigger == rtems_capture_to_any) && !from_valid_name && !from_valid_id)
1119  {
1120    fprintf(stdout,"error: a from trigger need a to name or id\n");
1121    return;
1122  }
1123
1124  if ((trigger == rtems_capture_from_any) && !to_valid_name && !to_valid_id)
1125  {
1126    fprintf(stdout,"error: a to trigger need a from name or id\n");
1127    return;
1128  }
1129
1130  if ((trigger == rtems_capture_from_to) &&
1131      ((!from_valid_name && !from_valid_id) || (!to_valid_name && !to_valid_id)))
1132  {
1133    fprintf(stdout,"error: an edge trigger need a from and to name or id\n");
1134    return;
1135  }
1136
1137  sc = rtems_capture_set_trigger (from_name, from_id, to_name, to_id, trigger);
1138
1139  if (sc != RTEMS_SUCCESSFUL)
1140  {
1141    fprintf(stdout,"error: setting the trigger failed: %s\n", rtems_status_text (sc));
1142    return;
1143  }
1144
1145  fprintf(stdout,"trigger set.\n");
1146}
1147
1148/*
1149 * rtems_capture_cli_trace_records
1150 *
1151 *  DESCRIPTION:
1152 *
1153 * This function is a monitor command that dumps trace records.
1154 *
1155 */
1156
1157static void
1158rtems_capture_cli_trace_records (
1159  int argc,
1160  char **argv,
1161  rtems_monitor_command_arg_t *command_arg,
1162  boolean verbose )
1163{
1164  rtems_status_code       sc;
1165  rtems_boolean           csv = 0;
1166  static int              dump_total = 32;
1167  int                     total;
1168  int                     count;
1169  uint32_t          read;
1170  rtems_capture_record_t* rec;
1171  int                     arg;
1172
1173  for (arg = 1; arg < argc; arg++)
1174  {
1175    if (argv[arg][0] == '-')
1176    {
1177      if (argv[arg][1] == 'c')
1178        csv = 1;
1179      else if (argv[arg][1] == 'r')
1180      {
1181        int i;
1182        int l;
1183
1184        arg++;
1185        if (arg == argc)
1186        {
1187          fprintf(stdout,"error: option -r requires number\n");
1188          return;
1189        }
1190
1191        l = strlen (argv[arg]);
1192
1193        for (i = 0; i < l; i++)
1194          if (!isdigit (argv[arg][i]))
1195          {
1196            fprintf(stdout,"error: option -r requires number and currently it is not\n");
1197            return;
1198          }
1199
1200        dump_total = strtoul (argv[arg], 0, 0);
1201      }
1202      else
1203        fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
1204    }
1205  }
1206
1207  total = dump_total;
1208
1209  while (total)
1210  {
1211    sc = rtems_capture_read (0, 0, &read, &rec);
1212
1213    if (sc != RTEMS_SUCCESSFUL)
1214    {
1215      fprintf(stdout,"error: trace read failed: %s\n", rtems_status_text (sc));
1216      rtems_capture_flush (0);
1217      return;
1218    }
1219
1220    if (read == 0)
1221      break;
1222
1223    for (count = 0; count < read; count++, rec++)
1224    {
1225      if (csv)
1226        fprintf(stdout,"%08x,%03d,%03d,%04x,%d,%d\n",
1227                (uint32_t  ) rec->task,
1228                (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
1229                (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
1230                (rec->events >> RTEMS_CAPTURE_EVENT_START),
1231                rec->ticks, rec->tick_offset);
1232      else
1233      {
1234        unsigned long long t;
1235        uint32_t     event;
1236        int                e;
1237
1238        event = rec->events >> RTEMS_CAPTURE_EVENT_START;
1239
1240        t  = rec->ticks;
1241        t *= rtems_capture_tick_time ();
1242        t += rec->tick_offset;
1243
1244        for (e = RTEMS_CAPTURE_EVENT_START; e < RTEMS_CAPTURE_EVENT_END; e++)
1245        {
1246          if (event & 1)
1247          {
1248            fprintf(stdout,"%9li.%06li ", (unsigned long) (t / 1000000),
1249                    (unsigned long) (t % 1000000));
1250            rtems_monitor_dump_id (rtems_capture_task_id (rec->task));
1251            fprintf(stdout," ");
1252            rtems_monitor_dump_name (rtems_capture_task_name (rec->task));
1253            fprintf(stdout," %3i %3i %s\n",
1254                    (rec->events >> RTEMS_CAPTURE_REAL_PRIORITY_EVENT) & 0xff,
1255                    (rec->events >> RTEMS_CAPTURE_CURR_PRIORITY_EVENT) & 0xff,
1256                    rtems_capture_event_text (e));
1257          }
1258          event >>= 1;
1259        }
1260      }
1261    }
1262
1263    if (read < total)
1264      total -= read;
1265    else
1266      total = 0;
1267
1268    rtems_capture_release (read);
1269  }
1270}
1271
1272/*
1273 * rtems_capture_cli_flush
1274 *
1275 *  DESCRIPTION:
1276 *
1277 * This function is a monitor command that flushes and primes the capture
1278 * engine.
1279 *
1280 */
1281
1282static void
1283rtems_capture_cli_flush (
1284  int argc,
1285  char **argv,
1286  rtems_monitor_command_arg_t *command_arg,
1287  boolean verbose )
1288{
1289  rtems_status_code sc;
1290  rtems_boolean     prime = 1;
1291  int               arg;
1292
1293  for (arg = 1; arg < argc; arg++)
1294  {
1295    if (argv[arg][0] == '-')
1296    {
1297      if (argv[arg][1] == 'n')
1298        prime = 0;
1299      else
1300        fprintf(stdout,"warning: option -%c ignored\n", argv[arg][1]);
1301    }
1302  }
1303
1304  sc = rtems_capture_flush (prime);
1305
1306  if (sc != RTEMS_SUCCESSFUL)
1307  {
1308    fprintf(stdout,"error: flush failed: %s\n", rtems_status_text (sc));
1309    return;
1310  }
1311
1312  fprintf(stdout,"trace buffer flushed and %s.\n", prime ? "primed" : "not primed");
1313}
1314
1315static rtems_monitor_command_entry_t rtems_capture_cli_cmds[] =
1316{
1317  {
1318    "copen",
1319    "usage: copen [-i] size\n",
1320    0,
1321    rtems_capture_cli_open,
1322    { 0 },
1323    0
1324  },
1325  {
1326    "cclose",
1327    "usage: cclose\n",
1328    0,
1329    rtems_capture_cli_close,
1330    { 0 },
1331    0
1332  },
1333  {
1334    "cenable",
1335    "usage: cenable\n",
1336    0,
1337    rtems_capture_cli_enable,
1338    { 0 },
1339    0
1340  },
1341  {
1342    "cdisable",
1343    "usage: cdisable\n",
1344    0,
1345    rtems_capture_cli_disable,
1346    { 0 },
1347    0
1348  },
1349  {
1350    "ctlist",
1351    "usage: ctlist \n",
1352    0,
1353     rtems_capture_cli_task_list,
1354    { 0 },
1355    0
1356  },
1357  {
1358    "ctload",
1359    "usage: ctload \n",
1360    0,
1361    rtems_capture_cli_task_load,
1362    { 0 },
1363    0
1364  },
1365  {
1366    "cwlist",
1367    "usage: cwlist\n",
1368    0,
1369    rtems_capture_cli_watch_list,
1370    { 0 },
1371    0
1372  },
1373  {
1374    "cwadd",
1375    "usage: cwadd [task name] [id]\n",
1376    0,
1377    rtems_capture_cli_watch_add,
1378    { 0 },
1379    0
1380  },
1381  {
1382    "cwdel",
1383    "usage: cwdel [task name] [id]\n",
1384    0,
1385    rtems_capture_cli_watch_del,
1386    { 0 },
1387    0
1388  },
1389  {
1390    "cwctl",
1391    "usage: cwctl [task name] [id] on/off\n",
1392    0,
1393    rtems_capture_cli_watch_control,
1394    { 0 },
1395    0
1396  },
1397  {
1398    "cwglob",
1399    "usage: cwglob on/off\n",
1400    0,
1401    rtems_capture_cli_watch_global,
1402    { 0 },
1403    0
1404  },
1405  {
1406    "cwceil",
1407    "usage: cwceil priority\n",
1408    0,
1409    rtems_capture_cli_watch_ceiling,
1410    { 0 },
1411    0
1412  },
1413  {
1414    "cwfloor",
1415    "usage: cwfloor priority\n",
1416    0,
1417    rtems_capture_cli_watch_floor,
1418    { 0 },
1419    0
1420  },
1421  {
1422    "ctrace",
1423    "usage: ctrace [-c] [-r records]\n",
1424    0,
1425    rtems_capture_cli_trace_records,
1426    { 0 },
1427    0
1428  },
1429  {
1430    "ctrig",
1431    "usage: ctrig type [from name] [from id] [to name] [to id]\n",
1432    0,
1433    rtems_capture_cli_trigger_set,
1434    { 0 },
1435    0
1436  },
1437  {
1438    "cflush",
1439    "usage: cflush [-n]\n",
1440    0,
1441    rtems_capture_cli_flush,
1442    { 0 },
1443    0
1444  }
1445};
1446
1447/*
1448 * rtems_capture_cli_init
1449 *
1450 *  DESCRIPTION:
1451 *
1452 * This function initialises the command line interface to the capture
1453 * engine.
1454 *
1455 */
1456
1457rtems_status_code
1458rtems_capture_cli_init (rtems_capture_timestamp timestamp)
1459{
1460  int cmd;
1461
1462  capture_timestamp = timestamp;
1463
1464  for (cmd = 0;
1465       cmd < sizeof (rtems_capture_cli_cmds) / sizeof (rtems_monitor_command_entry_t);
1466       cmd++)
1467      rtems_monitor_insert_cmd (&rtems_capture_cli_cmds[cmd]);
1468
1469  return RTEMS_SUCCESSFUL;
1470}
Note: See TracBrowser for help on using the repository browser.