OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libmisc/] [capture/] [capture-cli.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
2
  ------------------------------------------------------------------------
3
  capture-cli.c,v 1.3 2002/07/20 09:18:37 ralf Exp
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
 */
41
static rtems_capture_timestamp capture_timestamp;
42
 
43
/*
44
 * Common variable to sync the load monitor task.
45
 */
46
static 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
 
58
static const char* open_usage = "usage: copen [-i] size\n";
59
 
60
static void
61
rtems_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
 
128
static void
129
rtems_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
 
153
static void
154
rtems_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
 
178
static void
179
rtems_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
 
203
static void
204
rtems_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
 
286
static void
287
rtems_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
 
435
static void
436
rtems_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
 
502
static void
503
rtems_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
 
570
static rtems_boolean
571
rtems_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
 
622
static char const * watch_add_usage = "usage: cwadd [task name] [id]\n";
623
 
624
static void
625
rtems_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
 
680
static char const * watch_del_usage = "usage: cwdel [task name] [id]\n";
681
 
682
static void
683
rtems_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
 
737
static char const * watch_control_usage = "usage: cwctl [task name] [id] on/off\n";
738
 
739
static void
740
rtems_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
 
799
static char const * watch_global_usage = "usage: cwglob on/off\n";
800
 
801
static void
802
rtems_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
 
849
static char const * watch_ceiling_usage = "usage: cwceil priority\n";
850
 
851
static void
852
rtems_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
 
896
static char const * watch_floor_usage = "usage: cwfloor priority\n";
897
 
898
static void
899
rtems_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
 
943
static char const *trigger_set_usage = "usage: ctrig type [from] [fromid] [to] [to id]\n";
944
 
945
static void
946
rtems_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
 
1097
static void
1098
rtems_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
 
1218
static void
1219
rtems_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
 
1247
static 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
 
1256
  },
1257
  {
1258
    "cclose",
1259
    "usage: cclose\n",
1260
    0,
1261
    (void*) rtems_capture_cli_close,
1262
    0,
1263
 
1264
  },
1265
  {
1266
    "cenable",
1267
    "usage: cenable\n",
1268
    0,
1269
    (void*) rtems_capture_cli_enable,
1270
    0,
1271
 
1272
  },
1273
  {
1274
    "cdisable",
1275
    "usage: cdisable\n",
1276
    0,
1277
    (void*) rtems_capture_cli_disable,
1278
    0,
1279
 
1280
  },
1281
  {
1282
    "ctlist",
1283
    "usage: ctlist \n",
1284
    0,
1285
    (void*) rtems_capture_cli_task_list,
1286
    0,
1287
 
1288
  },
1289
  {
1290
    "ctload",
1291
    "usage: ctload \n",
1292
    0,
1293
    (void*) rtems_capture_cli_task_load,
1294
    0,
1295
 
1296
  },
1297
  {
1298
    "cwlist",
1299
    "usage: cwlist\n",
1300
    0,
1301
    (void*) rtems_capture_cli_watch_list,
1302
    0,
1303
 
1304
  },
1305
  {
1306
    "cwadd",
1307
    "usage: cwadd [task name] [id]\n",
1308
    0,
1309
    (void*) rtems_capture_cli_watch_add,
1310
    0,
1311
 
1312
  },
1313
  {
1314
    "cwdel",
1315
    "usage: cwdel [task name] [id]\n",
1316
    0,
1317
    (void*) rtems_capture_cli_watch_del,
1318
    0,
1319
 
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
 
1328
  },
1329
  {
1330
    "cwglob",
1331
    "usage: cwglob on/off\n",
1332
    0,
1333
    (void*) rtems_capture_cli_watch_global,
1334
    0,
1335
 
1336
  },
1337
  {
1338
    "cwceil",
1339
    "usage: cwceil priority\n",
1340
    0,
1341
    (void*) rtems_capture_cli_watch_ceiling,
1342
    0,
1343
 
1344
  },
1345
  {
1346
    "cwfloor",
1347
    "usage: cwfloor priority\n",
1348
    0,
1349
    (void*) rtems_capture_cli_watch_floor,
1350
    0,
1351
 
1352
  },
1353
  {
1354
    "ctrace",
1355
    "usage: ctrace [-c] [-r records]\n",
1356
    0,
1357
    (void*) rtems_capture_cli_trace_records,
1358
    0,
1359
 
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
 
1368
  },
1369
  {
1370
    "cflush",
1371
    "usage: cflush [-n]\n",
1372
    0,
1373
    (void*) rtems_capture_cli_flush,
1374
    0,
1375
 
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
 
1389
rtems_status_code
1390
rtems_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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.