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

Last change on this file since 09b6a093 was 09b6a093, checked in by Joel Sherrill <joel.sherrill@…>, on 05/24/00 at 17:06:54

Significantly lowered the default memory requirements:

  • CONFIGURE_RTEMS_INIT_TASKS_TABLE was 10 now 0
  • CONFIGURE_POSIX_INIT_THREAD_TABLE was 10 now 0
  • CONFIGURE_ITRON_INIT_TASK_TABLE was 10 now 0
  • CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS was 20 now 3
  • added CONFIGURE_NUMBER_OF_TERMIOS_PORTS and defaulted to 1
  • added CONFIGURE_TERMIOS_DISABLED defaulted to "enabled"
  • miniIMFS is now the default

Added configuration error checks that:

+ Ensure > 0 tasks/threads are configured
+ Ensure at least one inititalization task/thread is defined

bsp.h now defines these so BSP specific requirements
are accounted for.

+ CONFIGURE_NUMBER_OF_TERMIOS_PORTS
+ CONFIGURE_INTERRUPT_STACK_MEMORY

console_reserve_resources and rtems_termios_reserve_resources
are no longer required and considered obsolete. Calls to
rtems_termios_reserve_resources have been eliminated although
the routine is still there and the body "if 0'ed".

We are very close to having NO reason to modify the
configuration tables in the BSP. Be warned that eventually
we would like to see the need for BSP_Configuration
eliminated!

  • Property mode set to 100644
File size: 17.0 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  int baud;
239 
240  printf( "c_cflag = 0x%08x\n", tp->c_cflag );
241 
242  switch( baud = (tp->c_cflag & CBAUD) ) {
243    case B0:
244      printf( "\tCBAUD =\tB0\n" );
245      break;
246     
247    case B50:
248      printf( "\tCBAUD =\tB50\n" );
249      break;
250     
251    case B75:
252      printf( "\tCBAUD =\tB75\n" );
253      break;
254     
255    case B110:
256      printf( "\tCBAUD =\tB110\n" );
257      break;
258     
259    case B134:
260      printf( "\tCBAUD =\tB134\n" );
261      break;
262     
263    case B150:
264      printf( "\tCBAUD =\tB150\n" );
265      break;
266     
267    case B200:
268      printf( "\tCBAUD =\tB200\n" );
269      break;
270     
271    case B300:
272      printf( "\tCBAUD =\tB300\n" );
273      break;
274     
275    case B600:
276      printf( "\tCBAUD =\tB600\n" );
277      break;
278     
279    case B1200:
280      printf( "\tCBAUD =\tB1200\n" );
281      break;
282     
283    case B1800:
284      printf( "\tCBAUD =\tB1800\n" );
285      break;
286     
287    case B2400:
288      printf( "\tCBAUD =\tB2400\n" );
289      break;
290     
291    case B4800:
292      printf( "\tCBAUD =\tB4800\n" );
293      break;
294     
295    case B9600:
296      printf( "\tCBAUD =\tB9600\n" );
297      break;
298     
299    case B19200:
300      printf( "\tCBAUD =\tB19200\n" );
301      break;
302     
303    case B38400:
304      printf( "\tCBAUD =\tB38400\n" );
305      break;
306     
307    case B57600:
308      printf( "\tCBAUD =\tB57600\n" );
309      break;
310     
311    case B115200:
312      printf( "\tCBAUD =\tB115200\n" );
313      break;
314     
315    case B230400:
316      printf( "\tCBAUD =\tB230400\n" );
317      break;
318     
319    case B460800:
320      printf( "\tCBAUD =\tB460800\n" );
321      break;
322     
323    default:
324      printf( "\tCBAUD =\tunknown (0x%08x)\n", baud );
325      break;
326    }
327
328  switch( tp->c_cflag & CSIZE ) {
329    case CS5:
330      printf( "\tCSIZE =\tCS5\n" );
331      break;
332     
333    case CS6:
334      printf( "\tCSIZE =\tCS6\n" );
335      break;
336     
337    case CS7:
338      printf( "\tCSIZE =\tCS7\n" );
339      break;
340     
341    case CS8:
342      printf( "\tCSIZE =\tCS8\n" );
343      break;
344  }
345
346  if( tp->c_cflag & CSTOPB )
347    printf( "\tCSTOPB set: send 2 stop bits\n" );
348  else
349    printf( "\tCSTOPB clear: send 1 stop bit\n" );
350 
351  if( tp->c_cflag & PARENB )
352    printf( "\tPARENB set: parity enabled\n" );
353  else
354    printf( "\tPARENB clear: parity disabled\n" );
355 
356  if( tp->c_cflag & PARODD )
357    printf( "\tPARODD set: parity odd\n" );
358  else
359    printf( "\tPARODD clear: parity even\n" );
360 
361  if( tp->c_cflag & CREAD )
362    printf( "\tCREAD set: receiver enabled\n" );
363  else
364    printf( "\tCREAD clear: treceiver disabled\n" );
365 
366  if( tp->c_cflag & HUPCL )
367    printf( "\tHUPCL set: enabled\n" );
368  else
369    printf( "\tHUPCL clear: disabled\n" );
370 
371  if( tp->c_cflag & CLOCAL )
372    printf( "\tCLOCAL set: ignore modem lines\n" );
373  else
374    printf( "\tCLOCAL clear: don't ignore modem lines\n" );
375 
376#if defined(CBAUDEX)
377  if( tp->c_cflag & CBAUDEX )
378    printf( "\tCBAUDEX set: What does this do?\n" );
379  else
380    printf( "\tCBAUDEX clear: What does this do?\n" );
381#endif
382 
383  if( tp->c_cflag & CRTSCTS )
384    printf( "\tCRTSCTS: harware flow control enabled?\n" );
385  else
386    printf( "\tCRTSCTS: hardware flow control disabled?\n" );
387}
388
389
390void print_c_cc( struct termios * tp )
391{
392  int i;
393  char * cc_index_names [NCCS] = {
394    "[VINTR]   ",   /* 0 */
395    "[VQUIT]   ",   /* 1 */
396    "[VERASE]  ",   /* 2 */
397    "[VKILL]   ",   /* 3 */
398    "[VEOF]    ",   /* 4 */
399    "[VTIME]   ",   /* 5 */
400    "[VMIN]    ",   /* 6 */
401    "[VSWTC    ",   /* 7 */
402    "[VSTART]  ",   /* 8 */
403    "[VSTOP]   ",   /* 9 */
404    "[VSUSP]   ",   /* 10 */
405    "[VEOL]    ",   /* 11 */
406    "[VREPRINT]",   /* 12 */
407    "[VDISCARD]",   /* 13 */
408    "[VWERASE] ",   /* 14 */
409    "[VLNEXT   ",   /* 15 */
410    "[VEOL2]   ",   /* 16 */
411    "unknown   ",   /* 17 */
412    "unknown   ",   /* 18 */
413  };
414
415  for( i = 0; i < NCCS; i++ ) {
416    printf( "c_cc%s = 0x%08x\n", cc_index_names[i], tp->c_cc[i] );
417  }
418}
419
420
421void print_termios( struct termios *tp )
422{
423  printf( "\nLooking at the current termios settings:\n\n" );
424  print_c_iflag( tp );
425  print_c_oflag( tp );
426  print_c_cflag( tp );
427  print_c_lflag( tp );
428  print_c_cc( tp );
429  printf( "\n" );
430}
431
432
433unsigned long get_baud_rate( void )
434{
435  unsigned long baud_rate;
436 
437  while( TRUE ) {
438    printf( "Enter the numerical value for the new baud rate.\n" );
439    printf( "Choices are: 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800\n" );
440    printf( "2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800\n" );
441    printf( "\nYour choice: " );
442    scanf( "%lu", &baud_rate );
443    printf( "\n" );
444    switch( baud_rate ) {
445      case 50:     return B50;
446      case 75:     return B75;
447      case 110:    return B110;
448      case 134:    return B134;
449      case 150:    return B150;
450      case 200:    return B200;
451      case 300:    return B300;
452      case 600:    return B600;
453      case 1200:   return B1200;
454      case 1800:   return B1800;
455      case 2400:   return B2400;
456      case 4800:   return B4800;
457      case 9600:   return B9600;
458      case 19200:  return B19200;
459      case 38400:  return B38400;
460      case 57600:  return B57600;
461      case 115200: return B115200;
462      case 230400: return B230400;
463      case 460800: return B460800;
464
465      default:
466        printf( "%lu is not a valid choice. Try again.\n\n", baud_rate );
467        break;
468    }
469  }
470}
471
472
473unsigned long get_parity()
474{
475  int parity;
476 
477  while( TRUE ) {
478    printf( "Enter the numerical value for the new parity\n" );
479    printf( "Choices are: 0 for no parity, 1 for even parity, 2 for odd parity\n" );
480    printf( "\nYour choice: " );
481    scanf( "%d", &parity );
482    printf( "\n" );
483    switch( parity ) {
484      case 0:
485        return 0;
486
487      case 1:
488        return PARENB;
489
490      case 2:
491        return PARENB | PARODD;
492
493      default:
494        printf( "%d is not a valid choice. Try again.\n\n", parity );
495        break;
496    }
497  }
498}
499
500
501unsigned long get_stop_bits()
502{
503  int stop_bits;
504
505  while( TRUE ) {
506    printf( "Enter the numerical value for the new number of stop bits\n" );
507    printf( "Choices are: 1 or 2\n" );
508    printf( "\nYour choice: " );
509    scanf( "%d", &stop_bits );
510    printf( "\n" );
511    switch( stop_bits ) {
512      case 1:
513        return 0;
514       
515      case 2:
516        return CSTOPB;
517
518      default:
519        printf( "%d is not a valid choice. Try again.\n\n", stop_bits );
520        break;
521    }
522  }
523}
524
525
526unsigned long get_data_bits()
527{
528  int data_bits;
529
530  while( TRUE ) {
531    printf( "Enter the numerical value for the new number of data bits\n" );
532    printf( "Choices are: 5, 6, 7 or 8\n" );
533    printf( "\nYour choice: " );
534    scanf( "%d", &data_bits );
535    printf( "\n" );
536    switch( data_bits ) {
537      case 5:
538        return CS5;
539       
540      case 6:
541        return CS6;
542       
543      case 7:
544        return CS7;
545       
546      case 8:
547        return CS8;
548
549      default:
550        printf( "%d is not a valid choice. Try again.\n\n", data_bits );
551        break;
552    }
553  }
554}
555
556
557void change_line_settings( struct termios *tp )
558{
559  unsigned long baud_rate, parity, stop_bits, data_bits, sleep_time;
560   
561  printf( "\nSetting line characteristics\n\n" );
562 
563  baud_rate = get_baud_rate();
564  parity = get_parity();
565  stop_bits = get_stop_bits();
566  data_bits = get_data_bits();
567
568  printf( "NOTE: You will not see output until you switch your terminal settings!\n" );
569  printf( "WARNING: If you do not switch your terminal settings, your terminal may hang.\n" );
570  printf( "Enter the number of seconds the test will wait for you to switch your terminal\n" );
571  printf( "settings before it continues\n" );
572  printf( "Sleep time (in seconds): " );
573  scanf( "%lu", &sleep_time );
574  printf( "\n" );
575  printf( "Setting line to new termios settings in %lu seconds.\n", sleep_time );
576
577  sleep( sleep_time );
578 
579  tp->c_cflag = CLOCAL | CREAD | parity | stop_bits | data_bits | baud_rate;
580  if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
581    perror( "change_line_settings(): tcsetattr() failed" );
582    exit( 1 );
583  }
584  printf( "Line settings set.\n" );
585}
586
587
588void canonical_input( struct termios *tp )
589{
590    char c, first_time = TRUE;
591   
592  printf( "\nTesting canonical input\n\n" );
593
594  printf( "Setting line to canonical input mode.\n" );
595  tp->c_lflag = ISIG | ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL | IEXTEN;
596  tp->c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
597  if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
598    perror( "canonical_input(): tcsetattr() failed" );
599    exit( 1 );
600  }
601 
602  while ( ( c = getchar () ) != '\n');
603  printf( "Testing getchar(). Type some text followed by carriage return\n" );
604  printf( "Each character you entered will be echoed back to you\n\n" );
605  while ( ( c = getchar () ) != '\n') {
606    if( first_time ) {
607      printf( "\nYou typed:\n");
608      first_time = FALSE;
609    }
610    printf( "%c", c );
611  }
612  printf( "\n\nCanonical input test done.\n" );
613}
614
615/*
616 * Test raw (ICANON=0) input
617 */
618void do_raw_input( int vmin, int vtime )
619{
620  int i;
621  struct termios old, new;
622  rtems_interval ticksPerSecond, then, now;
623  unsigned int msec;
624  unsigned long count;
625  int nread;
626  unsigned char cbuf[100];
627
628  printf( "Raw input test with VMIN=%d  VTIME=%d\n", vmin, vtime );
629 
630  rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond );
631  if ( tcgetattr( fileno ( stdin ), &old ) < 0 ) {
632    perror( "do_raw_input(): tcgetattr() failed" );
633    return;
634  }
635 
636  new = old;
637  new.c_lflag &= ~( ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL );
638  new.c_cc[VMIN] = vmin;
639  new.c_cc[VTIME] = vtime;
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  if( tcsetattr( fileno( stdin ), TCSADRAIN, &old) < 0 )
671    perror("do_raw_input(): tcsetattr() failed: %s\n" );
672   
673  printf ("*** End of Raw input  VMIN=%d  VTIME=%d ***\n", vmin, vtime);
674}
675
676
677void raw_input( struct termios *tp )
678{
679  printf( "\nTesting raw input input\n\n" );
680  printf( "Hit 'q' to terminate the test\n" );
681
682  do_raw_input( 0, 0 );
683  do_raw_input( 0, 20 );
684  do_raw_input( 5, 0 );
685  do_raw_input( 5, 20 );
686 
687  printf( "\nRaw input test done.\n" );
688}
689
690
691void usage( void )
692{
693  printf( "\nYou have the following choices:\n" );
694  printf( "  1 - Reset the struct termios\n" );
695  printf( "  2 - Look at the current termios setting\n" );
696  printf( "  3 - Change the line characteristics\n" );
697  printf( "  4 - Test canonical input\n" );
698  printf( "  5 - Test raw input\n" );
699  printf( "  9 - Exit\n" );
700  printf( "Enter your choice (1 to 5 or 9, followed by a carriage return): " );
701}
702
703
704/*
705 * RTEMS Startup Task
706 */
707rtems_task
708Init (rtems_task_argument ignored)
709{
710  char c;
711  struct termios orig_termios, test_termios;
712 
713  printf( "\n\n*** TEST OF TERMIOS INPUT CAPABILITIES ***\n" );
714
715  if( tcgetattr( fileno( stdin ), &orig_termios ) < 0 ) {
716    perror( "tcgetattr() failed" );
717    exit( 0 );
718  }
719
720  test_termios = orig_termios;
721
722  usage();
723  for(;;) {
724    switch( c = getchar() ) {
725      case '1':
726        printf( "\nResetting the line to the original termios setting\n\n" );
727        test_termios = orig_termios;
728        if( tcsetattr( fileno( stdin ), TCSADRAIN, &test_termios ) < 0 ) {
729          perror( "tcsetattr() failed" );
730          exit( 1 );
731        }
732        usage();
733        break;
734
735      case '2':
736        print_termios( &test_termios );
737        usage();
738        break;
739
740      case '3':
741        change_line_settings( &test_termios );
742        usage();
743        break;
744
745      case '4':
746        canonical_input( &test_termios );
747        usage();
748        break;
749
750      case '5':
751        raw_input( &test_termios );
752        usage();
753        break;
754
755      case '9':
756        exit( 1 );
757
758      case '\n':
759        break;
760         
761      default:
762        printf( "\n%c is not a valid choice. Try again\n\n", c );
763        usage();
764        break;
765    }
766  }
767}
768
Note: See TracBrowser for help on using the repository browser.