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

4.104.114.84.95
Last change on this file since 5a8a05b was aebc8290, checked in by Ralf Corsepius <ralf.corsepius@…>, on 07/20/02 at 09:18:37

2002-07-20 Ralf Corsepius <corsepiu@…>

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