source: rtems/c/src/tests/libtests/termios/init.c @ 33677ef5

Last change on this file since 33677ef5 was 33677ef5, checked in by Joel Sherrill <joel.sherrill@…>, on 04/03/00 at 15:31:17

Enhancements from Charles-Antoine Gauthier <charles.gauthier@…>.

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