source: rtems/testsuites/libtests/termios/init.c @ 11b9b5d

4.115
Last change on this file since 11b9b5d was 11b9b5d, checked in by Sebastian Huber <sebastian.huber@…>, on 09/16/11 at 09:24:52

2011-09-16 Sebastian Huber <Sebastian.Huber@…>

  • monitor/monitor.scn, termios/termios.scn: New files.
  • monitor/init.c, termios01/init.c: Use rtems_shell_wait_for_input().
  • Property mode set to 100644
File size: 17.3 KB
Line 
1/*
2 * RTEMS configuration/initialization
3 *
4 * This program may be distributed and used for any purpose.
5 * I ask only that you:
6 *  1. Leave this author information intact.
7 *  2. Document any changes you make.
8 *
9 * W. Eric Norum
10 * Saskatchewan Accelerator Laboratory
11 * University of Saskatchewan
12 * Saskatoon, Saskatchewan, CANADA
13 * eric@skatter.usask.ca
14 *
15 * Additions:
16 * Charles-Antoine Gauthier
17 * Software Engineering Group
18 * Institute for Information Technology
19 * National Research Council of Canada
20 * charles.gauthier@nrc.ca
21 *
22 *  $Id$
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <bsp.h>
30
31
32#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
33#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
34
35#define CONFIGURE_MAXIMUM_TASKS       1
36
37#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
38
39#define CONFIGURE_MICROSECONDS_PER_TICK 1000
40
41#define CONFIGURE_INIT
42
43rtems_task Init (rtems_task_argument argument);
44
45#include <rtems/confdefs.h>
46#include <rtems/shell.h>
47
48#include <stdio.h>
49#include <unistd.h>
50#include <termios.h>
51#include <errno.h>
52#include <string.h>
53
54#include <tmacros.h>
55
56#if !defined(fileno)
57int fileno( FILE *stream); /* beyond ANSI */
58#endif
59
60/* Some of the termios dumping code depends on bit positions! */
61
62void print_32bits( unsigned long bits, unsigned char size, char * names[] )
63{
64  unsigned char i;
65
66  for( i = 0; i < size; i++ ) {
67    if( (bits >> i) & 0x1 )
68      printf( "%s ", names[i] );
69  }
70}
71
72
73void print_c_iflag( struct termios * tp )
74{
75  char * c_iflag_bits [] = {
76    "IGNBRK",   /* 0000001 */
77    "BRKINT",   /* 0000002 */
78    "IGNPAR",   /* 0000004 */
79    "PARMRK",   /* 0000010 */
80    "INPCK",    /* 0000020 */
81    "ISTRIP",   /* 0000040 */
82    "INLCR",    /* 0000100 */
83    "IGNCR",    /* 0000200 */
84    "ICRNL",    /* 0000400 */
85    "IUCLC",    /* 0001000 */
86    "IXON",     /* 0002000 */
87    "IXANY",    /* 0004000 */
88    "IXOFF",    /* 0010000 */
89    "IMAXBEL",  /* 0020000 */
90    "unknown",  /* 0040000 */
91    "unknown",  /* 0100000 */
92    "unknown",  /* 0200000 */
93    "unknown",  /* 0400000 */
94    "unknown",  /* 1000000 */
95    "unknown",  /* 2000000 */
96    "unknown"   /* 4000000 */
97  };
98
99  printf( "c_iflag = 0x%08x\n\t", tp->c_iflag );
100  print_32bits( tp->c_iflag, sizeof( c_iflag_bits )/sizeof( char * ), c_iflag_bits );
101  printf( "\n" );
102}
103
104
105void print_c_oflag( struct termios * tp )
106{
107  printf( "c_oflag = 0x%08x\n\t", tp->c_oflag );
108
109  if( tp->c_oflag & OPOST )
110    printf( "OPOST " );
111
112  if( tp->c_oflag & OLCUC )
113    printf( "OLCUC " );
114
115  if( tp->c_oflag & ONLCR )
116    printf( "ONLCR " );
117
118  if( tp->c_oflag & OCRNL )
119    printf( "OCRNL " );
120
121  if( tp->c_oflag & ONOCR )
122    printf( "ONOCR " );
123
124  if( tp->c_oflag & ONLRET )
125    printf( "ONLRET " );
126
127  if( tp->c_oflag & OFILL )
128    printf( "OFILL " );
129
130  if( tp->c_oflag & OFDEL )
131    printf( "OFDEL " );
132
133  switch( tp->c_oflag & NLDLY ) {
134    case NL0:
135      printf( "NL0 " );
136      break;
137
138    case NL1:
139      printf( "NL1 " );
140      break;
141  }
142
143  switch( tp->c_oflag & CRDLY ) {
144    case CR0:
145      printf( "CR0 " );
146      break;
147
148    case CR1:
149      printf( "CR1 " );
150      break;
151
152    case CR2:
153      printf( "CR2 " );
154      break;
155
156    case CR3:
157      printf( "CR3 " );
158      break;
159  }
160
161  switch( tp->c_oflag & TABDLY ) {
162    case TAB0:
163      printf( "TAB0 " );
164      break;
165
166    case TAB1:
167      printf( "TAB1 " );
168      break;
169
170    case TAB2:
171      printf( "TAB2 " );
172      break;
173
174    case TAB3:
175      printf( "TAB3 " );
176      break;
177  }
178
179  switch( tp->c_oflag & BSDLY ) {
180    case BS0:
181      printf( "BS0 " );
182      break;
183
184    case BS1:
185      printf( "BS1 " );
186      break;
187  }
188
189  switch( tp->c_oflag & VTDLY ) {
190    case VT0:
191      printf( "VT0 " );
192      break;
193
194    case VT1:
195      printf( "VT1 " );
196      break;
197  }
198
199  switch( tp->c_oflag & FFDLY ) {
200    case FF0:
201      printf( "FF0" );
202      break;
203
204    case FF1:
205      printf( "FF1" );
206      break;
207  }
208  printf( "\n" );
209}
210
211
212void print_c_lflag( struct termios * tp )
213{
214  char * c_lflag_bits [] = {
215    "ISIG",        /* 0000001 */
216    "ICANON",      /* 0000002 */
217    "XCASE",       /* 0000004 */
218    "ECHO",        /* 0000010 */
219    "ECHOE",       /* 0000020 */
220    "ECHOK",       /* 0000040 */
221    "ECHONL",      /* 0000100 */
222    "NOFLSH",      /* 0000200 */
223    "TOSTOP",      /* 0000400 */
224    "ECHOCTL",     /* 0001000 */
225    "ECHOPRT",     /* 0002000 */
226    "ECHOKE",      /* 0004000 */
227    "FLUSHO",      /* 0010000 */
228    "unknown",     /* 0020000 */
229    "PENDIN",      /* 0040000 */
230    "IEXTEN",      /* 0100000 */
231    "unknown",     /* 0200000 */
232    "unknown",     /* 0400000 */
233    "unknown",     /* 1000000 */
234    "unknown",     /* 2000000 */
235    "unknown",     /* 4000000 */
236  };
237
238  printf( "c_lflag = 0x%08x\n\t", tp->c_lflag );
239  print_32bits( tp->c_lflag, sizeof( c_lflag_bits )/sizeof( char * ), c_lflag_bits );
240  printf( "\n" );
241}
242
243
244void print_c_cflag( struct termios * tp )
245{
246  unsigned int baud;
247
248  printf( "c_cflag = 0x%08x\n", tp->c_cflag );
249
250  baud = (tp->c_cflag & CBAUD) ;
251  if ( tp->c_cflag & CBAUDEX )
252  switch( baud ) {
253    case B0:
254      printf( "\tCBAUD =\tB0\n" );
255      break;
256
257    case B50:
258      printf( "\tCBAUD =\tB50\n" );
259      break;
260
261    case B75:
262      printf( "\tCBAUD =\tB75\n" );
263      break;
264
265    case B110:
266      printf( "\tCBAUD =\tB110\n" );
267      break;
268
269    case B134:
270      printf( "\tCBAUD =\tB134\n" );
271      break;
272
273    case B150:
274      printf( "\tCBAUD =\tB150\n" );
275      break;
276
277    case B200:
278      printf( "\tCBAUD =\tB200\n" );
279      break;
280
281    case B300:
282      printf( "\tCBAUD =\tB300\n" );
283      break;
284
285    case B600:
286      printf( "\tCBAUD =\tB600\n" );
287      break;
288
289    case B1200:
290      printf( "\tCBAUD =\tB1200\n" );
291      break;
292
293    case B1800:
294      printf( "\tCBAUD =\tB1800\n" );
295      break;
296
297    case B2400:
298      printf( "\tCBAUD =\tB2400\n" );
299      break;
300
301    case B4800:
302      printf( "\tCBAUD =\tB4800\n" );
303      break;
304
305    case B9600:
306      printf( "\tCBAUD =\tB9600\n" );
307      break;
308
309    case B19200:
310      printf( "\tCBAUD =\tB19200\n" );
311      break;
312
313    case B38400:
314      printf( "\tCBAUD =\tB38400\n" );
315      break;
316
317    case B57600:
318      printf( "\tCBAUD =\tB57600\n" );
319      break;
320
321    case B115200:
322      printf( "\tCBAUD =\tB115200\n" );
323      break;
324
325    case B230400:
326      printf( "\tCBAUD =\tB230400\n" );
327      break;
328
329    case B460800:
330      printf( "\tCBAUD =\tB460800\n" );
331      break;
332
333    default:
334      printf( "\tCBAUD =\tunknown (0x%08x)\n", baud );
335      break;
336    }
337
338  switch( tp->c_cflag & CSIZE ) {
339    case CS5:
340      printf( "\tCSIZE =\tCS5\n" );
341      break;
342
343    case CS6:
344      printf( "\tCSIZE =\tCS6\n" );
345      break;
346
347    case CS7:
348      printf( "\tCSIZE =\tCS7\n" );
349      break;
350
351    case CS8:
352      printf( "\tCSIZE =\tCS8\n" );
353      break;
354  }
355
356  if( tp->c_cflag & CSTOPB )
357    printf( "\tCSTOPB set: send 2 stop bits\n" );
358  else
359    printf( "\tCSTOPB clear: send 1 stop bit\n" );
360
361  if( tp->c_cflag & PARENB )
362    printf( "\tPARENB set: parity enabled\n" );
363  else
364    printf( "\tPARENB clear: parity disabled\n" );
365
366  if( tp->c_cflag & PARODD )
367    printf( "\tPARODD set: parity odd\n" );
368  else
369    printf( "\tPARODD clear: parity even\n" );
370
371  if( tp->c_cflag & CREAD )
372    printf( "\tCREAD set: receiver enabled\n" );
373  else
374    printf( "\tCREAD clear: treceiver disabled\n" );
375
376  if( tp->c_cflag & HUPCL )
377    printf( "\tHUPCL set: enabled\n" );
378  else
379    printf( "\tHUPCL clear: disabled\n" );
380
381  if( tp->c_cflag & CLOCAL )
382    printf( "\tCLOCAL set: ignore modem lines\n" );
383  else
384    printf( "\tCLOCAL clear: don't ignore modem lines\n" );
385
386#if defined(CBAUDEX)
387  if( tp->c_cflag & CBAUDEX )
388    printf( "\tCBAUDEX set: What does this do?\n" );
389  else
390    printf( "\tCBAUDEX clear: What does this do?\n" );
391#endif
392
393  if( tp->c_cflag & CRTSCTS )
394    printf( "\tCRTSCTS: harware flow control enabled?\n" );
395  else
396    printf( "\tCRTSCTS: hardware flow control disabled?\n" );
397}
398
399
400void print_c_cc( struct termios * tp )
401{
402  size_t i;
403  char * cc_index_names [ /* NCCS */ ] = {
404    "[VINTR]   ",   /* 0 */
405    "[VQUIT]   ",   /* 1 */
406    "[VERASE]  ",   /* 2 */
407    "[VKILL]   ",   /* 3 */
408    "[VEOF]    ",   /* 4 */
409    "[VTIME]   ",   /* 5 */
410    "[VMIN]    ",   /* 6 */
411    "[VSWTC    ",   /* 7 */
412    "[VSTART]  ",   /* 8 */
413    "[VSTOP]   ",   /* 9 */
414    "[VSUSP]   ",   /* 10 */
415    "[VEOL]    ",   /* 11 */
416    "[VREPRINT]",   /* 12 */
417    "[VDISCARD]",   /* 13 */
418    "[VWERASE] ",   /* 14 */
419    "[VLNEXT   ",   /* 15 */
420    "[VEOL2]   ",   /* 16 */
421    "unknown   ",   /* 17 */
422    "unknown   ",   /* 18 */
423  };
424
425  for( i = 0; i < sizeof(cc_index_names)/sizeof(char*) ; i++ ) {
426    printf( "c_cc%s = 0x%08x\n", cc_index_names[i], tp->c_cc[i] );
427  }
428}
429
430
431void print_termios( struct termios *tp )
432{
433  printf( "\nLooking at the current termios settings:\n\n" );
434  print_c_iflag( tp );
435  print_c_oflag( tp );
436  print_c_cflag( tp );
437  print_c_lflag( tp );
438  print_c_cc( tp );
439  printf( "\n" );
440}
441
442
443unsigned long get_baud_rate( void )
444{
445  unsigned long baud_rate;
446
447  while( 1 ) {
448    printf( "Enter the numerical value for the new baud rate.\n" );
449    printf( "Choices are: 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800\n" );
450    printf( "2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800\n" );
451    printf( "\nYour choice: " );
452    scanf( "%lu", &baud_rate );
453    printf( "\n" );
454    switch( baud_rate ) {
455      case 50:     return B50;
456      case 75:     return B75;
457      case 110:    return B110;
458      case 134:    return B134;
459      case 150:    return B150;
460      case 200:    return B200;
461      case 300:    return B300;
462      case 600:    return B600;
463      case 1200:   return B1200;
464      case 1800:   return B1800;
465      case 2400:   return B2400;
466      case 4800:   return B4800;
467      case 9600:   return B9600;
468      case 19200:  return B19200;
469      case 38400:  return B38400;
470      case 57600:  return B57600;
471      case 115200: return B115200;
472      case 230400: return B230400;
473      case 460800: return B460800;
474
475      default:
476        printf( "%lu is not a valid choice. Try again.\n\n", baud_rate );
477        break;
478    }
479  }
480}
481
482
483unsigned long get_parity(void)
484{
485  int parity;
486
487  while( 1 ) {
488    printf( "Enter the numerical value for the new parity\n" );
489    printf( "Choices are: 0 for no parity, 1 for even parity, 2 for odd parity\n" );
490    printf( "\nYour choice: " );
491    scanf( "%d", &parity );
492    printf( "\n" );
493    switch( parity ) {
494      case 0:
495        return 0;
496
497      case 1:
498        return PARENB;
499
500      case 2:
501        return PARENB | PARODD;
502
503      default:
504        printf( "%d is not a valid choice. Try again.\n\n", parity );
505        break;
506    }
507  }
508}
509
510
511unsigned long get_stop_bits(void)
512{
513  int stop_bits;
514
515  while( 1 ) {
516    printf( "Enter the numerical value for the new number of stop bits\n" );
517    printf( "Choices are: 1 or 2\n" );
518    printf( "\nYour choice: " );
519    scanf( "%d", &stop_bits );
520    printf( "\n" );
521    switch( stop_bits ) {
522      case 1:
523        return 0;
524
525      case 2:
526        return CSTOPB;
527
528      default:
529        printf( "%d is not a valid choice. Try again.\n\n", stop_bits );
530        break;
531    }
532  }
533}
534
535
536unsigned long get_data_bits(void)
537{
538  int data_bits;
539
540  while( 1 ) {
541    printf( "Enter the numerical value for the new number of data bits\n" );
542    printf( "Choices are: 5, 6, 7 or 8\n" );
543    printf( "\nYour choice: " );
544    scanf( "%d", &data_bits );
545    printf( "\n" );
546    switch( data_bits ) {
547      case 5:
548        return CS5;
549
550      case 6:
551        return CS6;
552
553      case 7:
554        return CS7;
555
556      case 8:
557        return CS8;
558
559      default:
560        printf( "%d is not a valid choice. Try again.\n\n", data_bits );
561        break;
562    }
563  }
564}
565
566
567void change_line_settings( struct termios *tp )
568{
569  unsigned long baud_rate, parity, stop_bits, data_bits, sleep_time;
570
571  printf( "\nSetting line characteristics\n\n" );
572
573  baud_rate = get_baud_rate();
574  parity = get_parity();
575  stop_bits = get_stop_bits();
576  data_bits = get_data_bits();
577
578  printf( "NOTE: You will not see output until you switch your terminal settings!\n" );
579  printf( "WARNING: If you do not switch your terminal settings, your terminal may hang.\n" );
580  printf( "Enter the number of seconds the test will wait for you to switch your terminal\n" );
581  printf( "settings before it continues\n" );
582  printf( "Sleep time (in seconds): " );
583  scanf( "%lu", &sleep_time );
584  printf( "\n" );
585  printf( "Setting line to new termios settings in %lu seconds.\n", sleep_time );
586
587  sleep( sleep_time );
588
589  tp->c_cflag = CLOCAL | CREAD | parity | stop_bits | data_bits | baud_rate;
590  if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
591    perror( "change_line_settings(): tcsetattr() failed" );
592    rtems_test_exit( 1 );
593  }
594  printf( "Line settings set.\n" );
595}
596
597
598void canonical_input( struct termios *tp )
599{
600  char c;
601  bool first_time = true;
602
603  printf( "\nTesting canonical input\n\n" );
604
605  printf( "Setting line to canonical input mode.\n" );
606  tp->c_lflag = ISIG | ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL | IEXTEN;
607  tp->c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
608  if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
609    perror( "canonical_input(): tcsetattr() failed" );
610    rtems_test_exit( 1 );
611  }
612
613  while ( ( c = getchar () ) != '\n');
614  printf( "Testing getchar(). Type some text followed by carriage return\n" );
615  printf( "Each character you entered will be echoed back to you\n\n" );
616  while ( ( c = getchar () ) != '\n') {
617    if( first_time ) {
618      printf( "\nYou typed:\n");
619      first_time = false;
620    }
621    printf( "%c", c );
622  }
623  printf( "\n\nCanonical input test done.\n" );
624}
625
626
627/*
628 * Test raw (ICANON=0) input
629 */
630void do_raw_input( int vmin, int vtime )
631{
632  int i;
633  struct termios old, new;
634  rtems_interval ticksPerSecond, then, now;
635  unsigned int msec;
636  unsigned long count;
637  int nread;
638  unsigned char cbuf[100];
639
640  printf( "Raw input test with VMIN=%d  VTIME=%d\n", vmin, vtime );
641
642  ticksPerSecond = rtems_clock_get_ticks_per_second();
643  if ( tcgetattr( fileno ( stdin ), &old ) < 0 ) {
644    perror( "do_raw_input(): tcgetattr() failed" );
645    return;
646  }
647
648  new = old;
649  new.c_lflag &= ~( ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL );
650  new.c_cc[VMIN] = vmin;
651  new.c_cc[VTIME] = vtime;
652  if( tcsetattr( fileno( stdin ), TCSADRAIN, &new ) < 0 ) {
653    perror ("do_raw_input(): tcsetattr() failed" );
654    return;
655  }
656
657  do {
658    then = rtems_clock_get_ticks_since_boot();
659    count = 0;
660    for(;;) {
661      nread = read( fileno( stdin ), cbuf, sizeof cbuf );
662      if( nread < 0 ) {
663        perror( "do_raw_input(): read() failed" );
664        goto out;
665      }
666      count++;
667      if( nread != 0 )
668        break;
669    }
670    now = rtems_clock_get_ticks_since_boot();
671    msec = (now - then) * 1000 / ticksPerSecond;
672    printf( "Count:%-10lu  Interval:%3u.%3.3d  Char:",
673          count, msec / 1000, msec % 1000 );
674
675    for( i = 0 ; i < nread ; i++ )
676      printf (" 0x%2.2x", cbuf[i]);
677    printf ("\n");
678
679  } while( cbuf[0] != 'q' );
680
681out:
682  if( tcsetattr( fileno( stdin ), TCSADRAIN, &old) < 0 )
683    perror("do_raw_input(): tcsetattr() failed: %s\n" );
684
685  printf ("*** End of Raw input  VMIN=%d  VTIME=%d ***\n", vmin, vtime);
686}
687
688
689static void raw_input( struct termios *tp )
690{
691  printf( "\nTesting raw input input\n\n" );
692  printf( "Hit 'q' to terminate the test\n" );
693
694  do_raw_input( 0, 0 );
695  do_raw_input( 0, 20 );
696  do_raw_input( 5, 0 );
697  do_raw_input( 5, 20 );
698
699  printf( "\nRaw input test done.\n" );
700}
701
702
703void usage( void )
704{
705  printf( "\nYou have the following choices:\n" );
706  printf( "  1 - Reset the struct termios\n" );
707  printf( "  2 - Look at the current termios setting\n" );
708  printf( "  3 - Change the line characteristics\n" );
709  printf( "  4 - Test canonical input\n" );
710  printf( "  5 - Test raw input\n" );
711  printf( "  9 - Exit\n" );
712  printf( "Enter your choice (1 to 5 or 9, followed by a carriage return): " );
713}
714
715static void notification( int fd, int seconds_remaining, void *arg )
716{
717  printf(
718    "Press any key to check the termios input capabilities (%is remaining)\n",
719    seconds_remaining
720  );
721}
722
723/*
724 * RTEMS Startup Task
725 */
726rtems_task
727Init (rtems_task_argument ignored)
728{
729  rtems_status_code status;
730  char c ;
731  struct termios orig_termios, test_termios;
732
733  puts( "\n\n*** TEST TERMIOS INPUT CAPABILITIES ***" );
734
735  status = rtems_shell_wait_for_input(
736    STDIN_FILENO,
737    20,
738    notification,
739    NULL
740  );
741  if (status == RTEMS_SUCCESSFUL) {
742    if( tcgetattr( fileno( stdin ), &orig_termios ) < 0 ) {
743      perror( "tcgetattr() failed" );
744      rtems_test_exit( 0 );
745    }
746
747    test_termios = orig_termios;
748
749    usage();
750    for(;;) {
751      switch( c = getchar() ) {
752        case '1':
753          printf( "\nResetting the line to the original termios setting\n\n" );
754          test_termios = orig_termios;
755          if( tcsetattr( fileno( stdin ), TCSADRAIN, &test_termios ) < 0 ) {
756            perror( "tcsetattr() failed" );
757            rtems_test_exit( 1 );
758          }
759          usage();
760          break;
761
762        case '2':
763          print_termios( &test_termios );
764          usage();
765          break;
766
767        case '3':
768          change_line_settings( &test_termios );
769          usage();
770          break;
771
772        case '4':
773          canonical_input( &test_termios );
774          usage();
775          break;
776
777        case '5':
778          raw_input( &test_termios );
779          usage();
780          break;
781
782        case '9':
783          rtems_test_exit( 1 );
784
785        case '\n':
786          break;
787
788        default:
789          printf( "\n%c is not a valid choice. Try again\n\n", c );
790          usage();
791          break;
792      }
793    }
794  } else {
795    puts( "*** END OF TEST TERMIOS INPUT CAPABILITIES ***" );
796
797    rtems_test_exit( 0 );
798  }
799}
Note: See TracBrowser for help on using the repository browser.