source: rtems/testsuites/libtests/termios/init.c @ c0ffdee

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

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.

  • 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
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 <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#if !defined(fileno)
50int fileno( FILE *stream); /* beyond ANSI */
51#endif
52
53/* Some of the termios dumping code depends on bit positions! */
54
55void print_32bits( unsigned long bits, unsigned char size, char * names[] )
56{
57  unsigned char i;
58
59  for( i = 0; i < size; i++ ) {
60    if( (bits >> i) & 0x1 )
61      printf( "%s ", names[i] );
62  }
63}
64
65
66void print_c_iflag( struct termios * tp )
67{
68  char * c_iflag_bits [] = {
69    "IGNBRK",   /* 0000001 */
70    "BRKINT",   /* 0000002 */
71    "IGNPAR",   /* 0000004 */
72    "PARMRK",   /* 0000010 */
73    "INPCK",    /* 0000020 */
74    "ISTRIP",   /* 0000040 */
75    "INLCR",    /* 0000100 */
76    "IGNCR",    /* 0000200 */
77    "ICRNL",    /* 0000400 */
78    "IUCLC",    /* 0001000 */
79    "IXON",     /* 0002000 */
80    "IXANY",    /* 0004000 */
81    "IXOFF",    /* 0010000 */
82    "IMAXBEL",  /* 0020000 */
83    "unknown",  /* 0040000 */
84    "unknown",  /* 0100000 */
85    "unknown",  /* 0200000 */
86    "unknown",  /* 0400000 */
87    "unknown",  /* 1000000 */
88    "unknown",  /* 2000000 */
89    "unknown"   /* 4000000 */
90  };
91
92  printf( "c_iflag = 0x%08x\n\t", tp->c_iflag );
93  print_32bits( tp->c_iflag, sizeof( c_iflag_bits )/sizeof( char * ), c_iflag_bits );
94  printf( "\n" );
95}
96
97
98void print_c_oflag( struct termios * tp )
99{
100  printf( "c_oflag = 0x%08x\n\t", tp->c_oflag );
101
102  if( tp->c_oflag & OPOST )
103    printf( "OPOST " );
104   
105  if( tp->c_oflag & OLCUC )
106    printf( "OLCUC " );
107   
108  if( tp->c_oflag & ONLCR )
109    printf( "ONLCR " );
110   
111  if( tp->c_oflag & OCRNL )
112    printf( "OCRNL " );
113   
114  if( tp->c_oflag & ONOCR )
115    printf( "ONOCR " );
116   
117  if( tp->c_oflag & ONLRET )
118    printf( "ONLRET " );
119   
120  if( tp->c_oflag & OFILL )
121    printf( "OFILL " );
122   
123  if( tp->c_oflag & OFDEL )
124    printf( "OFDEL " );
125
126  switch( tp->c_oflag & NLDLY ) {
127    case NL0:
128      printf( "NL0 " );
129      break;
130     
131    case NL1:
132      printf( "NL1 " );
133      break;
134  }
135 
136  switch( tp->c_oflag & CRDLY ) {
137    case CR0:
138      printf( "CR0 " );
139      break;
140     
141    case CR1:
142      printf( "CR1 " );
143      break;
144     
145    case CR2:
146      printf( "CR2 " );
147      break;
148     
149    case CR3:
150      printf( "CR3 " );
151      break;
152  }
153 
154  switch( tp->c_oflag & TABDLY ) {
155    case TAB0:
156      printf( "TAB0 " );
157      break;
158     
159    case TAB1:
160      printf( "TAB1 " );
161      break;
162     
163    case TAB2:
164      printf( "TAB2 " );
165      break;
166     
167    case TAB3:
168      printf( "TAB3 " );
169      break;
170  }
171 
172  switch( tp->c_oflag & BSDLY ) {
173    case BS0:
174      printf( "BS0 " );
175      break;
176     
177    case BS1:
178      printf( "BS1 " );
179      break;
180  }
181 
182  switch( tp->c_oflag & VTDLY ) {
183    case VT0:
184      printf( "VT0 " );
185      break;
186     
187    case VT1:
188      printf( "VT1 " );
189      break;
190  }
191 
192  switch( tp->c_oflag & FFDLY ) {
193    case FF0:
194      printf( "FF0" );
195      break;
196     
197    case FF1:
198      printf( "FF1" );
199      break;
200  }
201  printf( "\n" );
202}
203
204
205void print_c_lflag( struct termios * tp )
206{
207  char * c_lflag_bits [] = {
208    "ISIG",        /* 0000001 */
209    "ICANON",      /* 0000002 */
210    "XCASE",       /* 0000004 */
211    "ECHO",        /* 0000010 */
212    "ECHOE",       /* 0000020 */
213    "ECHOK",       /* 0000040 */
214    "ECHONL",      /* 0000100 */
215    "NOFLSH",      /* 0000200 */
216    "TOSTOP",      /* 0000400 */
217    "ECHOCTL",     /* 0001000 */
218    "ECHOPRT",     /* 0002000 */
219    "ECHOKE",      /* 0004000 */
220    "FLUSHO",      /* 0010000 */
221    "unknown",     /* 0020000 */
222    "PENDIN",      /* 0040000 */
223    "IEXTEN",      /* 0100000 */
224    "unknown",     /* 0200000 */
225    "unknown",     /* 0400000 */
226    "unknown",     /* 1000000 */
227    "unknown",     /* 2000000 */
228    "unknown",     /* 4000000 */
229  };
230 
231  printf( "c_lflag = 0x%08x\n\t", tp->c_lflag );
232  print_32bits( tp->c_lflag, sizeof( c_lflag_bits )/sizeof( char * ), c_lflag_bits );
233  printf( "\n" );
234}
235
236
237void print_c_cflag( struct termios * tp )
238{
239  unsigned int baud;
240 
241  printf( "c_cflag = 0x%08x\n", tp->c_cflag );
242
243  baud = (tp->c_cflag & CBAUD) ;
244#if defined(__sh2__)
245  if ( tp->c_cflag & CBAUDEX )
246#endif
247  switch( baud ) {
248    case B0:
249      printf( "\tCBAUD =\tB0\n" );
250      break;
251     
252    case B50:
253      printf( "\tCBAUD =\tB50\n" );
254      break;
255     
256    case B75:
257      printf( "\tCBAUD =\tB75\n" );
258      break;
259     
260    case B110:
261      printf( "\tCBAUD =\tB110\n" );
262      break;
263     
264    case B134:
265      printf( "\tCBAUD =\tB134\n" );
266      break;
267     
268    case B150:
269      printf( "\tCBAUD =\tB150\n" );
270      break;
271     
272    case B200:
273      printf( "\tCBAUD =\tB200\n" );
274      break;
275     
276    case B300:
277      printf( "\tCBAUD =\tB300\n" );
278      break;
279     
280    case B600:
281      printf( "\tCBAUD =\tB600\n" );
282      break;
283     
284    case B1200:
285      printf( "\tCBAUD =\tB1200\n" );
286      break;
287     
288    case B1800:
289      printf( "\tCBAUD =\tB1800\n" );
290      break;
291     
292    case B2400:
293      printf( "\tCBAUD =\tB2400\n" );
294      break;
295     
296    case B4800:
297      printf( "\tCBAUD =\tB4800\n" );
298      break;
299     
300    case B9600:
301      printf( "\tCBAUD =\tB9600\n" );
302      break;
303     
304    case B19200:
305      printf( "\tCBAUD =\tB19200\n" );
306      break;
307     
308    case B38400:
309      printf( "\tCBAUD =\tB38400\n" );
310      break;
311#if defined(__sh2__)
312    }
313    else
314    switch ( baud )
315    {
316#endif
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  int 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 < NCCS; 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( TRUE ) {
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()
484{
485  int parity;
486 
487  while( TRUE ) {
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()
512{
513  int stop_bits;
514
515  while( TRUE ) {
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()
537{
538  int data_bits;
539
540  while( TRUE ) {
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    exit( 1 );
593  }
594  printf( "Line settings set.\n" );
595}
596
597
598void canonical_input( struct termios *tp )
599{
600  char c, first_time = TRUE;
601   
602  printf( "\nTesting canonical input\n\n" );
603
604  printf( "Setting line to canonical input mode.\n" );
605  tp->c_lflag = ISIG | ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL | IEXTEN;
606  tp->c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
607  if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
608    perror( "canonical_input(): tcsetattr() failed" );
609    exit( 1 );
610  }
611 
612  while ( ( c = getchar () ) != '\n');
613  printf( "Testing getchar(). Type some text followed by carriage return\n" );
614  printf( "Each character you entered will be echoed back to you\n\n" );
615  while ( ( c = getchar () ) != '\n') {
616    if( first_time ) {
617      printf( "\nYou typed:\n");
618      first_time = FALSE;
619    }
620    printf( "%c", c );
621  }
622  printf( "\n\nCanonical input test done.\n" );
623}
624
625
626/*
627 * Test raw (ICANON=0) input
628 */
629void do_raw_input( int vmin, int vtime )
630{
631  int i;
632  struct termios old, new;
633  rtems_interval ticksPerSecond, then, now;
634  unsigned int msec;
635  unsigned long count;
636  int nread;
637  unsigned char cbuf[100];
638
639  printf( "Raw input test with VMIN=%d  VTIME=%d\n", vmin, vtime );
640 
641  rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond );
642  if ( tcgetattr( fileno ( stdin ), &old ) < 0 ) {
643    perror( "do_raw_input(): tcgetattr() failed" );
644    return;
645  }
646 
647  new = old;
648  new.c_lflag &= ~( ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL );
649  new.c_cc[VMIN] = vmin;
650  new.c_cc[VTIME] = vtime;
651  if( tcsetattr( fileno( stdin ), TCSADRAIN, &new ) < 0 ) {
652    perror ("do_raw_input(): tcsetattr() failed" );
653    return;
654  }
655 
656  do {
657    rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &then );
658    count = 0;
659    for(;;) {
660      nread = read( fileno( stdin ), cbuf, sizeof cbuf );
661      if( nread < 0 ) {
662        perror( "do_raw_input(): read() failed" );
663        goto out;
664      }
665      count++;
666      if( nread != 0 )
667        break;
668    }
669    rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now );
670    msec = (now - then) * 1000 / ticksPerSecond;
671    printf( "Count:%-10lu  Interval:%3u.%3.3d  Char:",
672          count, msec / 1000, msec % 1000 );
673         
674    for( i = 0 ; i < nread ; i++ )
675      printf (" 0x%2.2x", cbuf[i]);
676    printf ("\n");
677   
678  } while( cbuf[0] != 'q' );
679 
680out:
681  if( tcsetattr( fileno( stdin ), TCSADRAIN, &old) < 0 )
682    perror("do_raw_input(): tcsetattr() failed: %s\n" );
683   
684  printf ("*** End of Raw input  VMIN=%d  VTIME=%d ***\n", vmin, vtime);
685}
686
687
688void raw_input( struct termios *tp )
689{
690  printf( "\nTesting raw input input\n\n" );
691  printf( "Hit 'q' to terminate the test\n" );
692
693  do_raw_input( 0, 0 );
694  do_raw_input( 0, 20 );
695  do_raw_input( 5, 0 );
696  do_raw_input( 5, 20 );
697 
698  printf( "\nRaw input test done.\n" );
699}
700
701
702void usage( void )
703{
704  printf( "\nYou have the following choices:\n" );
705  printf( "  1 - Reset the struct termios\n" );
706  printf( "  2 - Look at the current termios setting\n" );
707  printf( "  3 - Change the line characteristics\n" );
708  printf( "  4 - Test canonical input\n" );
709  printf( "  5 - Test raw input\n" );
710  printf( "  9 - Exit\n" );
711  printf( "Enter your choice (1 to 5 or 9, followed by a carriage return): " );
712}
713
714
715/*
716 * RTEMS Startup Task
717 */
718rtems_task
719Init (rtems_task_argument ignored)
720{
721  char c ;
722  struct termios orig_termios, test_termios;
723 
724  printf( "\n\n*** TEST OF TERMIOS INPUT CAPABILITIES ***\n" );
725
726  if( tcgetattr( fileno( stdin ), &orig_termios ) < 0 ) {
727    perror( "tcgetattr() failed" );
728    exit( 0 );
729  }
730
731  test_termios = orig_termios;
732
733  usage();
734  for(;;) {
735    switch( c = getchar() ) {
736      case '1':
737        printf( "\nResetting the line to the original termios setting\n\n" );
738        test_termios = orig_termios;
739        if( tcsetattr( fileno( stdin ), TCSADRAIN, &test_termios ) < 0 ) {
740          perror( "tcsetattr() failed" );
741          exit( 1 );
742        }
743        usage();
744        break;
745
746      case '2':
747        print_termios( &test_termios );
748        usage();
749        break;
750
751      case '3':
752        change_line_settings( &test_termios );
753        usage();
754        break;
755
756      case '4':
757        canonical_input( &test_termios );
758        usage();
759        break;
760
761      case '5':
762        raw_input( &test_termios );
763        usage();
764        break;
765
766      case '9':
767        exit( 1 );
768
769      case '\n':
770        break;
771         
772      default:
773        printf( "\n%c is not a valid choice. Try again\n\n", c );
774        usage();
775        break;
776    }
777  }
778}
779
Note: See TracBrowser for help on using the repository browser.