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

Last change on this file since e734e576 was e734e576, checked in by Joel Sherrill <joel.sherrill@…>, on 07/03/00 at 20:48:00

Patch rtems-rc-20000702-1.diff from Ralf Corsepius <corsepiu@…>
that is a hack to workaround a switch generation compiler bug for the
SH2 and cleaned up some warnings.
CVS: ----------------------------------------------------------------------
CVS: Enter Log. Lines beginning with `CVS:' are removed automatically
CVS:
CVS: Committing in .
CVS:
CVS: Modified Files:
CVS: c/src/tests/libtests/termios/init.c
CVS: ----------------------------------------------------------------------

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