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

Last change on this file since 9cde23b was 529fc62, checked in by Ralf Corsepius <ralf.corsepius@…>, on 02/18/03 at 15:19:13

2003-02-18 Ralf Corsepius <corsepiu@…>

capture/capture-cli.c: Add proper definition to avoid compiler
warnings. Apply int = getchar().

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