source: rtems/testsuites/libtests/termios/init.c @ 8f71a36

4.104.114.84.9
Last change on this file since 8f71a36 was 8f71a36, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 20, 2004 at 7:09:31 AM

Remove stray white spaces.

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