Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:34

0001 /*
0002  * RTEMS configuration/initialization
0003  */
0004 
0005 /*
0006  * This program may be distributed and used for any purpose.
0007  *
0008  * Copyright (c) 1997 Eric Norum <eric@norum.ca>
0009  *
0010  * Copyright (c) 2000 Charles-Antoine Gauthier <charles.gauthier@nrc.ca>
0011  * Software Engineering Group
0012  * Institute for Information Technology
0013  * National Research Council of Canada
0014  * charles.gauthier@nrc.ca
0015  */
0016 
0017 #ifdef HAVE_CONFIG_H
0018 #include "config.h"
0019 #endif
0020 
0021 #include <bsp.h>
0022 
0023 #include <rtems/shell.h>
0024 #include <rtems/termiostypes.h>
0025 
0026 #include <stdio.h>
0027 #include <unistd.h>
0028 #include <termios.h>
0029 #include <errno.h>
0030 #include <string.h>
0031 
0032 #include <tmacros.h>
0033 
0034 const char rtems_test_name[] = "TERMIOS";
0035 
0036 /* forward declarations to avoid warnings */
0037 rtems_task Init(rtems_task_argument argument);
0038 void print_32bits(unsigned long bits, unsigned char size, char * names[]);
0039 void print_c_iflag(struct termios * tp);
0040 void print_c_oflag(struct termios * tp);
0041 void print_c_lflag(struct termios * tp);
0042 void print_c_cflag(struct termios * tp);
0043 void print_c_cc(struct termios * tp);
0044 void print_baud(const char* name, speed_t spd);
0045 void print_termios(struct termios *tp);
0046 unsigned long get_baud_rate(void);
0047 unsigned long get_parity(void);
0048 unsigned long get_stop_bits(void);
0049 unsigned long get_data_bits(void);
0050 void change_line_settings(struct termios *tp);
0051 void canonical_input(struct termios *tp);
0052 void do_raw_input(int vmin, int vtime);
0053 void usage(void);
0054 
0055 #if !defined(fileno)
0056 int fileno( FILE *stream); /* beyond ANSI */
0057 #endif
0058 
0059 /* Some of the termios dumping code depends on bit positions! */
0060 
0061 void print_32bits( unsigned long bits, unsigned char size, char * names[] )
0062 {
0063   unsigned char i;
0064 
0065   for( i = 0; i < size; i++ ) {
0066     if( (bits >> i) & 0x1 )
0067       printf( "%s ", names[i] );
0068   }
0069 }
0070 
0071 
0072 void print_c_iflag( struct termios * tp )
0073 {
0074   char * c_iflag_bits [] = {
0075     "IGNBRK",   /* 0000001 */
0076     "BRKINT",   /* 0000002 */
0077     "IGNPAR",   /* 0000004 */
0078     "PARMRK",   /* 0000010 */
0079     "INPCK",    /* 0000020 */
0080     "ISTRIP",   /* 0000040 */
0081     "INLCR",    /* 0000100 */
0082     "IGNCR",    /* 0000200 */
0083     "ICRNL",    /* 0000400 */
0084     "IUCLC",    /* 0001000 */
0085     "IXON",     /* 0002000 */
0086     "IXANY",    /* 0004000 */
0087     "IXOFF",    /* 0010000 */
0088     "IMAXBEL",  /* 0020000 */
0089     "unknown",  /* 0040000 */
0090     "unknown",  /* 0100000 */
0091     "unknown",  /* 0200000 */
0092     "unknown",  /* 0400000 */
0093     "unknown",  /* 1000000 */
0094     "unknown",  /* 2000000 */
0095     "unknown"   /* 4000000 */
0096   };
0097 
0098   printf( "c_iflag = 0x%08x\n\t", tp->c_iflag );
0099   print_32bits( tp->c_iflag, sizeof( c_iflag_bits )/sizeof( char * ), c_iflag_bits );
0100   printf( "\n" );
0101 }
0102 
0103 
0104 void print_c_oflag( struct termios * tp )
0105 {
0106   printf( "c_oflag = 0x%08x\n\t", tp->c_oflag );
0107 
0108   if( tp->c_oflag & OPOST )
0109     printf( "OPOST " );
0110 
0111   if( tp->c_oflag & OLCUC )
0112     printf( "OLCUC " );
0113 
0114   if( tp->c_oflag & ONLCR )
0115     printf( "ONLCR " );
0116 
0117   if( tp->c_oflag & ONOEOT )
0118     printf( "ONOEOT " );
0119 
0120   if( tp->c_oflag & OCRNL )
0121     printf( "OCRNL " );
0122 
0123   if( tp->c_oflag & ONOCR )
0124     printf( "ONOCR " );
0125 
0126   if( tp->c_oflag & ONLRET )
0127     printf( "ONLRET " );
0128 
0129   printf( "\n" );
0130 }
0131 
0132 
0133 void print_c_lflag( struct termios * tp )
0134 {
0135   char * c_lflag_bits [] = {
0136     "ECHOKE",      /* 0x00000001 */
0137     "ECHOE",       /* 0x00000002 */
0138     "ECHOK",       /* 0x00000004 */
0139     "ECHO",        /* 0x00000008 */
0140     "ECHONL",      /* 0x00000010 */
0141     "ECHOPRT",     /* 0x00000020 */
0142     "ECHOCTL",     /* 0x00000040 */
0143     "ISIG",        /* 0x00000080 */
0144     "ICANON",      /* 0x00000100 */
0145     "ALTWERASE",   /* 0x00000200 */
0146     "IEXTEN",      /* 0x00000400 */
0147     "EXTPROC",     /* 0x00000800 */
0148     "XCASE",       /* 0x00001000 */
0149     "unknown",     /* 0x00002000 */
0150     "unknown",     /* 0x00004000 */
0151     "unknown",     /* 0x00008000 */
0152     "unknown",     /* 0x00010000 */
0153     "unknown",     /* 0x00020000 */
0154     "unknown",     /* 0x00040000 */
0155     "unknown",     /* 0x00080000 */
0156     "unknown",     /* 0x00100000 */
0157     "unknown",     /* 0x00200000 */
0158     "TOSTOP",      /* 0x00400000 */
0159     "FLUSHO",      /* 0x00800000 */
0160     "unknown",     /* 0x01000000 */
0161     "NOKERNINFO",  /* 0x02000000 */
0162     "unknown",     /* 0x04000000 */
0163     "unknown",     /* 0x08000000 */
0164     "unknown",     /* 0x10000000 */
0165     "PENDIN",      /* 0x20000000 */
0166     "unknown",     /* 0x40000000 */
0167     "NOFLSH",      /* 0x80000000 */
0168   };
0169 
0170   printf( "c_lflag = 0x%08x\n\t", tp->c_lflag );
0171   print_32bits( tp->c_lflag, sizeof( c_lflag_bits )/sizeof( char * ), c_lflag_bits );
0172   printf( "\n" );
0173 }
0174 
0175 
0176 void print_c_cflag( struct termios * tp )
0177 {
0178   printf( "c_cflag = 0x%08x\n", tp->c_cflag );
0179 
0180   switch( tp->c_cflag & CSIZE ) {
0181     case CS5:
0182       printf( "\tCSIZE =\tCS5\n" );
0183       break;
0184 
0185     case CS6:
0186       printf( "\tCSIZE =\tCS6\n" );
0187       break;
0188 
0189     case CS7:
0190       printf( "\tCSIZE =\tCS7\n" );
0191       break;
0192 
0193     case CS8:
0194       printf( "\tCSIZE =\tCS8\n" );
0195       break;
0196   }
0197 
0198   if( tp->c_cflag & CIGNORE )
0199     printf( "\tCIGNORE set: iqnore c_cflags enabled\n" );
0200   else
0201     printf( "\tCIGNORE clear: iqnore c_cflags disabled\n" );
0202 
0203   if( tp->c_cflag & CSTOPB )
0204     printf( "\tCSTOPB set: send 2 stop bits\n" );
0205   else
0206     printf( "\tCSTOPB clear: send 1 stop bit\n" );
0207 
0208   if( tp->c_cflag & PARENB )
0209     printf( "\tPARENB set: parity enabled\n" );
0210   else
0211     printf( "\tPARENB clear: parity disabled\n" );
0212 
0213   if( tp->c_cflag & PARODD )
0214     printf( "\tPARODD set: parity odd\n" );
0215   else
0216     printf( "\tPARODD clear: parity even\n" );
0217 
0218   if( tp->c_cflag & CREAD )
0219     printf( "\tCREAD set: receiver enabled\n" );
0220   else
0221     printf( "\tCREAD clear: treceiver disabled\n" );
0222 
0223   if( tp->c_cflag & HUPCL )
0224     printf( "\tHUPCL set: enabled\n" );
0225   else
0226     printf( "\tHUPCL clear: disabled\n" );
0227 
0228   if( tp->c_cflag & CLOCAL )
0229     printf( "\tCLOCAL set: ignore modem lines\n" );
0230   else
0231     printf( "\tCLOCAL clear: don't ignore modem lines\n" );
0232 
0233   if( tp->c_cflag & CCTS_OFLOW )
0234     printf( "\tCCTS_OFLOW: hardware CTS output flow control enabled\n" );
0235   else
0236     printf( "\tCCTS_OFLOW: hardware CTS output flow control disabled\n" );
0237 
0238   if( tp->c_cflag & CRTS_IFLOW )
0239     printf( "\tCRTS_IFLOW: hardware RTS input flow control enabled\n" );
0240   else
0241     printf( "\tCRTS_IFLOW: hardware RTS input flow control disabled\n" );
0242 
0243   if( tp->c_cflag & CRTSCTS )
0244     printf( "\tCRTSCTS: harware flow control enabled?\n" );
0245   else
0246     printf( "\tCRTSCTS: hardware flow control disabled?\n" );
0247 
0248   if( tp->c_cflag & CDSR_OFLOW )
0249     printf( "\tCDSR_OFLOW: hardware DSR output flow control enabled\n" );
0250   else
0251     printf( "\tCDSR_OFLOW: hardware DSR output flow control disabled\n" );
0252 
0253   if( tp->c_cflag & CDTR_IFLOW )
0254     printf( "\tCDTR_IFLOW: hardware DTR input flow control enabled\n" );
0255   else
0256     printf( "\tCDTR_IFLOW: hardware DTR input flow control disabled\n" );
0257 
0258   if( tp->c_cflag & CCAR_OFLOW )
0259     printf( "\tCCAR_OFLOW: hardware CD output flow control enabled\n" );
0260   else
0261     printf( "\tCCAR_OFLOW: hardware CD output flow control disabled\n" );
0262 }
0263 
0264 
0265 void print_c_cc( struct termios * tp )
0266 {
0267   size_t i;
0268   char * cc_index_names [ /* NCCS */ ] = {
0269     "[VEOF]    ",   /* 0 */
0270     "[VEOL]    ",   /* 1 */
0271     "[VEOL2]   ",   /* 2 */
0272     "[VERASE]  ",   /* 3 */
0273     "[VWERASE] ",   /* 4 */
0274     "[VKILL]   ",   /* 5 */
0275     "[VREPRINT]",   /* 6 */
0276     "[VERASE2] ",   /* 7 */
0277     "[VINTR]   ",   /* 8 */
0278     "[VQUIT]   ",   /* 9 */
0279     "[VSUSP]   ",   /* 10 */
0280     "[VDSUSP]  ",   /* 11 */
0281     "[VSTART]  ",   /* 12 */
0282     "[VSTOP]   ",   /* 13 */
0283     "[VLNEXT]  ",   /* 14 */
0284     "[VDISCARD]",   /* 15 */
0285     "[VMIN]    ",   /* 16 */
0286     "[VTIME]   ",   /* 17 */
0287     "[VSTATUS] ",   /* 18 */
0288     "unknown   ",   /* 19 */
0289   };
0290 
0291   for( i = 0; i < sizeof(cc_index_names)/sizeof(char*) ; i++ ) {
0292     printf( "c_cc%s = 0x%08x\n", cc_index_names[i], tp->c_cc[i] );
0293   }
0294 }
0295 
0296 
0297 void print_baud( const char* name, speed_t spd )
0298 {
0299   switch( spd ) {
0300   case B0:
0301     printf( "%s = B0\n", name );
0302     break;
0303 
0304   case B50:
0305     printf( "%s = B50\n", name );
0306     break;
0307 
0308   case B75:
0309     printf( "%s = B75\n", name );
0310     break;
0311 
0312   case B110:
0313     printf( "%s = B110\n", name );
0314     break;
0315 
0316   case B134:
0317     printf( "%s = B134\n", name );
0318     break;
0319 
0320   case B150:
0321     printf( "%s = B150\n", name );
0322     break;
0323 
0324   case B200:
0325     printf( "%s = B200\n", name );
0326     break;
0327 
0328   case B300:
0329     printf( "%s = B300\n", name );
0330     break;
0331 
0332   case B600:
0333     printf( "%s = B600\n", name );
0334     break;
0335 
0336   case B1200:
0337     printf( "%s = B1200\n", name );
0338     break;
0339 
0340   case B1800:
0341     printf( "%s = B1800\n", name );
0342     break;
0343 
0344   case B2400:
0345     printf( "%s = B2400\n", name );
0346     break;
0347 
0348   case B4800:
0349     printf( "%s = B4800\n", name );
0350     break;
0351 
0352   case B9600:
0353     printf( "%s = B9600\n", name );
0354     break;
0355 
0356   case B19200:
0357     printf( "%s = B19200\n", name );
0358     break;
0359 
0360   case B38400:
0361     printf( "%s = B38400\n", name );
0362     break;
0363 
0364   case B7200:
0365     printf( "%s = B7200\n", name );
0366     break;
0367 
0368   case B14400:
0369     printf( "%s = B14400\n", name );
0370     break;
0371 
0372   case B28800:
0373     printf( "%s = B28800\n", name );
0374     break;
0375 
0376   case B57600:
0377     printf( "%s = B57600\n", name );
0378     break;
0379 
0380   case B76800:
0381     printf( "%s = B76800\n", name );
0382     break;
0383 
0384   case B115200:
0385     printf( "%s = B115200\n", name );
0386     break;
0387 
0388   case B230400:
0389     printf( "%s = B230400\n", name );
0390     break;
0391 
0392   case B460800:
0393     printf( "%s = B460800\n", name );
0394     break;
0395 
0396   case B921600:
0397     printf( "%s = B921600\n", name );
0398     break;
0399 
0400   default:
0401     printf( "%s = unknown (0x%08x)\n", name, (unsigned int)spd );
0402     break;
0403   }
0404 }
0405 
0406 
0407 void print_termios( struct termios *tp )
0408 {
0409   printf( "\nLooking at the current termios settings:\n\n" );
0410   print_c_iflag( tp );
0411   print_c_oflag( tp );
0412   print_c_cflag( tp );
0413   print_c_lflag( tp );
0414   print_c_cc( tp );
0415   print_baud( "c_ispeed", tp->c_ispeed );
0416   print_baud( "c_ospeed", tp->c_ospeed );
0417   printf( "\n" );
0418 }
0419 
0420 
0421 unsigned long get_baud_rate(void)
0422 {
0423   unsigned long baud_rate;
0424 
0425   while( 1 ) {
0426     printf( "Enter the numerical value for the new baud rate.\n" );
0427     printf( "Choices are: 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800\n" );
0428     printf( "2400, 4800, 9600, 19200, 38400, 7200, 14400, 28800, 57600, 76800\n" );
0429     printf( "115200, 230400, 460800, 921600\n" );
0430     printf( "\nYour choice: " );
0431     scanf( "%lu", &baud_rate );
0432     printf( "\n" );
0433     switch( baud_rate ) {
0434       case 50:     return B50;
0435       case 75:     return B75;
0436       case 110:    return B110;
0437       case 134:    return B134;
0438       case 150:    return B150;
0439       case 200:    return B200;
0440       case 300:    return B300;
0441       case 600:    return B600;
0442       case 1200:   return B1200;
0443       case 1800:   return B1800;
0444       case 2400:   return B2400;
0445       case 4800:   return B4800;
0446       case 9600:   return B9600;
0447       case 19200:  return B19200;
0448       case 38400:  return B38400;
0449       case 7200:   return B7200;
0450       case 14400:  return B14400;
0451       case 28800:  return B28800;
0452       case 57600:  return B57600;
0453       case 76800:  return B76800;
0454       case 115200: return B115200;
0455       case 230400: return B230400;
0456       case 460800: return B460800;
0457       case 921600: return B921600;
0458 
0459       default:
0460         printf( "%lu is not a valid choice. Try again.\n\n", baud_rate );
0461         break;
0462     }
0463   }
0464 }
0465 
0466 
0467 unsigned long get_parity(void)
0468 {
0469   int parity;
0470 
0471   while( 1 ) {
0472     printf( "Enter the numerical value for the new parity\n" );
0473     printf( "Choices are: 0 for no parity, 1 for even parity, 2 for odd parity\n" );
0474     printf( "\nYour choice: " );
0475     scanf( "%d", &parity );
0476     printf( "\n" );
0477     switch( parity ) {
0478       case 0:
0479         return 0;
0480 
0481       case 1:
0482         return PARENB;
0483 
0484       case 2:
0485         return PARENB | PARODD;
0486 
0487       default:
0488         printf( "%d is not a valid choice. Try again.\n\n", parity );
0489         break;
0490     }
0491   }
0492 }
0493 
0494 
0495 unsigned long get_stop_bits(void)
0496 {
0497   int stop_bits;
0498 
0499   while( 1 ) {
0500     printf( "Enter the numerical value for the new number of stop bits\n" );
0501     printf( "Choices are: 1 or 2\n" );
0502     printf( "\nYour choice: " );
0503     scanf( "%d", &stop_bits );
0504     printf( "\n" );
0505     switch( stop_bits ) {
0506       case 1:
0507         return 0;
0508 
0509       case 2:
0510         return CSTOPB;
0511 
0512       default:
0513         printf( "%d is not a valid choice. Try again.\n\n", stop_bits );
0514         break;
0515     }
0516   }
0517 }
0518 
0519 
0520 unsigned long get_data_bits(void)
0521 {
0522   int data_bits;
0523 
0524   while( 1 ) {
0525     printf( "Enter the numerical value for the new number of data bits\n" );
0526     printf( "Choices are: 5, 6, 7 or 8\n" );
0527     printf( "\nYour choice: " );
0528     scanf( "%d", &data_bits );
0529     printf( "\n" );
0530     switch( data_bits ) {
0531       case 5:
0532         return CS5;
0533 
0534       case 6:
0535         return CS6;
0536 
0537       case 7:
0538         return CS7;
0539 
0540       case 8:
0541         return CS8;
0542 
0543       default:
0544         printf( "%d is not a valid choice. Try again.\n\n", data_bits );
0545         break;
0546     }
0547   }
0548 }
0549 
0550 
0551 void change_line_settings( struct termios *tp )
0552 {
0553   unsigned long baud_rate, parity, stop_bits, data_bits, sleep_time;
0554 
0555   printf( "\nSetting line characteristics\n\n" );
0556 
0557   baud_rate = get_baud_rate();
0558   parity = get_parity();
0559   stop_bits = get_stop_bits();
0560   data_bits = get_data_bits();
0561 
0562   printf( "NOTE: You will not see output until you switch your terminal settings!\n" );
0563   printf( "WARNING: If you do not switch your terminal settings, your terminal may hang.\n" );
0564   printf( "Enter the number of seconds the test will wait for you to switch your terminal\n" );
0565   printf( "settings before it continues\n" );
0566   printf( "Sleep time (in seconds): " );
0567   scanf( "%lu", &sleep_time );
0568   printf( "\n" );
0569   printf( "Setting line to new termios settings in %lu seconds.\n", sleep_time );
0570 
0571   sleep( sleep_time );
0572 
0573   tp->c_cflag = CLOCAL | CREAD | parity | stop_bits | data_bits;
0574   tp->c_ispeed = baud_rate;
0575   tp->c_ospeed = baud_rate;
0576   if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
0577     perror( "change_line_settings(): tcsetattr() failed" );
0578     rtems_test_exit( 1 );
0579   }
0580   printf( "Line settings set.\n" );
0581 }
0582 
0583 
0584 void canonical_input( struct termios *tp )
0585 {
0586   char c;
0587   bool first_time = true;
0588 
0589   printf( "\nTesting canonical input\n\n" );
0590 
0591   printf( "Setting line to canonical input mode.\n" );
0592   tp->c_lflag = ISIG | ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL | IEXTEN;
0593   tp->c_iflag = BRKINT | ICRNL | IXON | IMAXBEL;
0594   if( tcsetattr( fileno( stdin ), TCSADRAIN, tp ) < 0 ) {
0595     perror( "canonical_input(): tcsetattr() failed" );
0596     rtems_test_exit( 1 );
0597   }
0598 
0599   while ( ( c = getchar () ) != '\n');
0600   printf( "Testing getchar(). Type some text followed by carriage return\n" );
0601   printf( "Each character you entered will be echoed back to you\n\n" );
0602   while ( ( c = getchar () ) != '\n') {
0603     if( first_time ) {
0604       printf( "\nYou typed:\n");
0605       first_time = false;
0606     }
0607     printf( "%c", c );
0608   }
0609   printf( "\n\nCanonical input test done.\n" );
0610 }
0611 
0612 
0613 /*
0614  * Test raw (ICANON=0) input
0615  */
0616 void do_raw_input( int vmin, int vtime )
0617 {
0618   int i;
0619   struct termios old, new;
0620   rtems_interval ticksPerSecond, then, now;
0621   unsigned int msec;
0622   unsigned long count;
0623   int nread;
0624   unsigned char cbuf[100];
0625 
0626   printf( "Raw input test with VMIN=%d  VTIME=%d\n", vmin, vtime );
0627 
0628   ticksPerSecond = rtems_clock_get_ticks_per_second();
0629   if ( tcgetattr( fileno ( stdin ), &old ) < 0 ) {
0630     perror( "do_raw_input(): tcgetattr() failed" );
0631     return;
0632   }
0633 
0634   new = old;
0635   new.c_lflag &= ~( ICANON | ECHO | ECHONL | ECHOK | ECHOE | ECHOPRT | ECHOCTL );
0636   new.c_cc[VMIN] = vmin;
0637   new.c_cc[VTIME] = vtime;
0638   if( tcsetattr( fileno( stdin ), TCSADRAIN, &new ) < 0 ) {
0639     perror ("do_raw_input(): tcsetattr() failed" );
0640     return;
0641   }
0642 
0643   do {
0644     then = rtems_clock_get_ticks_since_boot();
0645     count = 0;
0646     for(;;) {
0647       nread = read( fileno( stdin ), cbuf, sizeof cbuf );
0648       if( nread < 0 ) {
0649         perror( "do_raw_input(): read() failed" );
0650         goto out;
0651       }
0652       count++;
0653       if( nread != 0 )
0654         break;
0655     }
0656     now = rtems_clock_get_ticks_since_boot();
0657     msec = (now - then) * 1000 / ticksPerSecond;
0658     printf( "Count:%-10lu  Interval:%3u.%3.3d  Char:",
0659           count, msec / 1000, msec % 1000 );
0660 
0661     for( i = 0 ; i < nread ; i++ )
0662       printf (" 0x%2.2x", cbuf[i]);
0663     printf ("\n");
0664 
0665   } while( cbuf[0] != 'q' );
0666 
0667 out:
0668   if( tcsetattr( fileno( stdin ), TCSADRAIN, &old) < 0 )
0669     perror("do_raw_input(): tcsetattr() failed: %s\n" );
0670 
0671   TEST_BEGIN();
0672 }
0673 
0674 
0675 static void raw_input( struct termios *tp )
0676 {
0677   printf( "\nTesting raw input input\n\n" );
0678   printf( "Hit 'q' to terminate the test\n" );
0679 
0680   do_raw_input( 0, 0 );
0681   do_raw_input( 0, 20 );
0682   do_raw_input( 5, 0 );
0683   do_raw_input( 5, 20 );
0684 
0685   printf( "\nRaw input test done.\n" );
0686 }
0687 
0688 
0689 void usage( void )
0690 {
0691   printf( "\nYou have the following choices:\n" );
0692   printf( "  1 - Reset the struct termios\n" );
0693   printf( "  2 - Look at the current termios setting\n" );
0694   printf( "  3 - Change the line characteristics\n" );
0695   printf( "  4 - Test canonical input\n" );
0696   printf( "  5 - Test raw input\n" );
0697   printf( "  9 - Exit\n" );
0698   printf( "Enter your choice (1 to 5 or 9, followed by a carriage return): " );
0699 }
0700 
0701 static void notification( int fd, int seconds_remaining, void *arg )
0702 {
0703   printf(
0704     "Press any key to check the termios input capabilities (%is remaining)\n",
0705     seconds_remaining
0706   );
0707 }
0708 
0709 /*
0710  * RTEMS Startup Task
0711  */
0712 rtems_task
0713 Init (rtems_task_argument ignored)
0714 {
0715   rtems_status_code status;
0716   char c ;
0717   struct termios orig_termios, test_termios;
0718 
0719   TEST_BEGIN();
0720 
0721   status = rtems_shell_wait_for_input(
0722     STDIN_FILENO,
0723     20,
0724     notification,
0725     NULL
0726   );
0727   if (status == RTEMS_SUCCESSFUL) {
0728     if( tcgetattr( fileno( stdin ), &orig_termios ) < 0 ) {
0729       perror( "tcgetattr() failed" );
0730       rtems_test_exit( 0 );
0731     }
0732 
0733     test_termios = orig_termios;
0734 
0735     usage();
0736     for(;;) {
0737       switch( c = getchar() ) {
0738         case '1':
0739           printf( "\nResetting the line to the original termios setting\n\n" );
0740           test_termios = orig_termios;
0741           if( tcsetattr( fileno( stdin ), TCSADRAIN, &test_termios ) < 0 ) {
0742             perror( "tcsetattr() failed" );
0743             rtems_test_exit( 1 );
0744           }
0745           usage();
0746           break;
0747 
0748         case '2':
0749           print_termios( &test_termios );
0750           usage();
0751           break;
0752 
0753         case '3':
0754           change_line_settings( &test_termios );
0755           usage();
0756           break;
0757 
0758         case '4':
0759           canonical_input( &test_termios );
0760           usage();
0761           break;
0762 
0763         case '5':
0764           raw_input( &test_termios );
0765           usage();
0766           break;
0767 
0768         case '9':
0769           rtems_test_exit( 1 );
0770 
0771         case '\n':
0772           break;
0773 
0774         default:
0775           printf( "\n%c is not a valid choice. Try again\n\n", c );
0776           usage();
0777           break;
0778       }
0779     }
0780   } else {
0781     TEST_END();
0782 
0783     rtems_test_exit( 0 );
0784   }
0785 }
0786 
0787 /* application configuration */
0788 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0789 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
0790 
0791 #define CONFIGURE_MAXIMUM_TASKS       1
0792 
0793 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0794 
0795 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0796 
0797 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0798 
0799 #define CONFIGURE_INIT
0800 
0801 #include <rtems/confdefs.h>
0802 /* end of configuration */
0803