source: rtems/testsuites/libtests/termios/init.c @ 7d3f9c6

4.115
Last change on this file since 7d3f9c6 was 7d3f9c6, checked in by Ralf Corsepius <ralf.corsepius@…>, on 02/22/11 at 07:37:03

Add HAVE_CONFIG_H.

  • 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#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
47#include <stdio.h>
48#include <unistd.h>
49#include <termios.h>
50#include <errno.h>
51#include <string.h>
52
53#include <tmacros.h>
54
55#if !defined(fileno)
56int fileno( FILE *stream); /* beyond ANSI */
57#endif
58
59/* Some of the termios dumping code depends on bit positions! */
60
61void print_32bits( unsigned long bits, unsigned char size, char * names[] )
62{
63  unsigned char i;
64
65  for( i = 0; i < size; i++ ) {
66    if( (bits >> i) & 0x1 )
67      printf( "%s ", names[i] );
68  }
69}
70
71
72void print_c_iflag( struct termios * tp )
73{
74  char * c_iflag_bits [] = {
75    "IGNBRK",   /* 0000001 */
76    "BRKINT",   /* 0000002 */
77    "IGNPAR",   /* 0000004 */
78    "PARMRK",   /* 0000010 */
79    "INPCK",    /* 0000020 */
80    "ISTRIP",   /* 0000040 */
81    "INLCR",    /* 0000100 */
82    "IGNCR",    /* 0000200 */
83    "ICRNL",    /* 0000400 */
84    "IUCLC",    /* 0001000 */
85    "IXON",     /* 0002000 */
86    "IXANY",    /* 0004000 */
87    "IXOFF",    /* 0010000 */
88    "IMAXBEL",  /* 0020000 */
89    "unknown",  /* 0040000 */
90    "unknown",  /* 0100000 */
91    "unknown",  /* 0200000 */
92    "unknown",  /* 0400000 */
93    "unknown",  /* 1000000 */
94    "unknown",  /* 2000000 */
95    "unknown"   /* 4000000 */
96  };
97
98  printf( "c_iflag = 0x%08x\n\t", tp->c_iflag );
99  print_32bits( tp->c_iflag, sizeof( c_iflag_bits )/sizeof( char * ), c_iflag_bits );
100  printf( "\n" );
101}
102
103
104void print_c_oflag( struct termios * tp )
105{
106  printf( "c_oflag = 0x%08x\n\t", tp->c_oflag );
107
108  if( tp->c_oflag & OPOST )
109    printf( "OPOST " );
110
111  if( tp->c_oflag & OLCUC )
112    printf( "OLCUC " );
113
114  if( tp->c_oflag & ONLCR )
115    printf( "ONLCR " );
116
117  if( tp->c_oflag & OCRNL )
118    printf( "OCRNL " );
119
120  if( tp->c_oflag & ONOCR )
121    printf( "ONOCR " );
122
123  if( tp->c_oflag & ONLRET )
124    printf( "ONLRET " );
125
126  if( tp->c_oflag & OFILL )
127    printf( "OFILL " );
128
129  if( tp->c_oflag & OFDEL )
130    printf( "OFDEL " );
131
132  switch( tp->c_oflag & NLDLY ) {
133    case NL0:
134      printf( "NL0 " );
135      break;
136
137    case NL1:
138      printf( "NL1 " );
139      break;
140  }
141
142  switch( tp->c_oflag & CRDLY ) {
143    case CR0:
144      printf( "CR0 " );
145      break;
146
147    case CR1:
148      printf( "CR1 " );
149      break;
150
151    case CR2:
152      printf( "CR2 " );
153      break;
154
155    case CR3:
156      printf( "CR3 " );
157      break;
158  }
159
160  switch( tp->c_oflag & TABDLY ) {
161    case TAB0:
162      printf( "TAB0 " );
163      break;
164
165    case TAB1:
166      printf( "TAB1 " );
167      break;
168
169    case TAB2:
170      printf( "TAB2 " );
171      break;
172
173    case TAB3:
174      printf( "TAB3 " );
175      break;
176  }
177
178  switch( tp->c_oflag & BSDLY ) {
179    case BS0:
180      printf( "BS0 " );
181      break;
182
183    case BS1:
184      printf( "BS1 " );
185      break;
186  }
187
188  switch( tp->c_oflag & VTDLY ) {
189    case VT0:
190      printf( "VT0 " );
191      break;
192
193    case VT1:
194      printf( "VT1 " );
195      break;
196  }
197
198  switch( tp->c_oflag & FFDLY ) {
199    case FF0:
200      printf( "FF0" );
201      break;
202
203    case FF1:
204      printf( "FF1" );
205      break;
206  }
207  printf( "\n" );
208}
209
210
211void print_c_lflag( struct termios * tp )
212{
213  char * c_lflag_bits [] = {
214    "ISIG",        /* 0000001 */
215    "ICANON",      /* 0000002 */
216    "XCASE",       /* 0000004 */
217    "ECHO",        /* 0000010 */
218    "ECHOE",       /* 0000020 */
219    "ECHOK",       /* 0000040 */
220    "ECHONL",      /* 0000100 */
221    "NOFLSH",      /* 0000200 */
222    "TOSTOP",      /* 0000400 */
223    "ECHOCTL",     /* 0001000 */
224    "ECHOPRT",     /* 0002000 */
225    "ECHOKE",      /* 0004000 */
226    "FLUSHO",      /* 0010000 */
227    "unknown",     /* 0020000 */
228    "PENDIN",      /* 0040000 */
229    "IEXTEN",      /* 0100000 */
230    "unknown",     /* 0200000 */
231    "unknown",     /* 0400000 */
232    "unknown",     /* 1000000 */
233    "unknown",     /* 2000000 */
234    "unknown",     /* 4000000 */
235  };
236
237  printf( "c_lflag = 0x%08x\n\t", tp->c_lflag );
238  print_32bits( tp->c_lflag, sizeof( c_lflag_bits )/sizeof( char * ), c_lflag_bits );
239  printf( "\n" );
240}
241
242
243void print_c_cflag( struct termios * tp )
244{
245  unsigned int baud;
246
247  printf( "c_cflag = 0x%08x\n", tp->c_cflag );
248
249  baud = (tp->c_cflag & CBAUD) ;
250  if ( tp->c_cflag & CBAUDEX )
251  switch( baud ) {
252    case B0:
253      printf( "\tCBAUD =\tB0\n" );
254      break;
255
256    case B50:
257      printf( "\tCBAUD =\tB50\n" );
258      break;
259
260    case B75:
261      printf( "\tCBAUD =\tB75\n" );
262      break;
263
264    case B110:
265      printf( "\tCBAUD =\tB110\n" );
266      break;
267
268    case B134:
269      printf( "\tCBAUD =\tB134\n" );
270      break;
271
272    case B150:
273      printf( "\tCBAUD =\tB150\n" );
274      break;
275
276    case B200:
277      printf( "\tCBAUD =\tB200\n" );
278      break;
279
280    case B300:
281      printf( "\tCBAUD =\tB300\n" );
282      break;
283
284    case B600:
285      printf( "\tCBAUD =\tB600\n" );
286      break;
287
288    case B1200:
289      printf( "\tCBAUD =\tB1200\n" );
290      break;
291
292    case B1800:
293      printf( "\tCBAUD =\tB1800\n" );
294      break;
295
296    case B2400:
297      printf( "\tCBAUD =\tB2400\n" );
298      break;
299
300    case B4800:
301      printf( "\tCBAUD =\tB4800\n" );
302      break;
303
304    case B9600:
305      printf( "\tCBAUD =\tB9600\n" );
306      break;
307
308    case B19200:
309      printf( "\tCBAUD =\tB19200\n" );
310      break;
311
312    case B38400:
313      printf( "\tCBAUD =\tB38400\n" );
314      break;
315
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  size_t 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 < sizeof(cc_index_names)/sizeof(char*) ; 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( 1 ) {
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(void)
483{
484  int parity;
485
486  while( 1 ) {
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(void)
511{
512  int stop_bits;
513
514  while( 1 ) {
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(void)
536{
537  int data_bits;
538
539  while( 1 ) {
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    rtems_test_exit( 1 );
592  }
593  printf( "Line settings set.\n" );
594}
595
596
597void canonical_input( struct termios *tp )
598{
599  char c;
600  bool 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    rtems_test_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  ticksPerSecond = rtems_clock_get_ticks_per_second();
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    then = rtems_clock_get_ticks_since_boot();
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    now = rtems_clock_get_ticks_since_boot();
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
688static void 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    rtems_test_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          rtems_test_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        rtems_test_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}
Note: See TracBrowser for help on using the repository browser.