//* program to echo characters from stdin to the serial port *

#include <termios.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> volatile int echo_serial_go; /* Echo characters to the serial port from stdin, until an error occurs, or until some other thread sets echo_serial_go to zero. */ int echo_to_serial( char *serial_device, speed_t baud_rate ) { int fd; /* file descriptor for serial I/O */ struct termios prev_tio; struct termios tio; /* port i/o settings */ int incc; /* input character count (from fread) */ int outcc; /* output character count (from write) */ const int BUFFER_SIZE = 256; char buffer[BUFFER_SIZE]; fd = open( serial_device, /* open serial device (duh...) */ O_RDWR | O_NOCTTY); /* read/write/serial not controlling terminal*/ if (fd < 0) { perror( serial_device ); return(-1); } tcgetattr( fd, &prev_tio); /* preserve the current port settings */ /* set up port for reading or writing */ memset( &tio, '\0', sizeof( struct termios ) ); tio.c_iflag = IGNPAR; /* input mode: ignore framing/parity errors */ tio.c_oflag = 0; /* output mode */ tio.c_cflag = ( /* control mode: */ baud_rate /* must use predefined codes (see termios) */ | CS8 /* 8 bits per character */ /* no parity (PARENB enables parity) */ /* one stop bit (CSTOPB sets two) */ | CREAD /* enable receiver */ | CLOCAL /* ignore modem control lines */ | CRTSCTS ); /* use flow control lines */ tio.c_lflag = 0; /* local mode */ /* adjust behavior for read/write functions */ tio.c_cc[VTIME] = 0; /* never timeout; if non-zero, timeout occurs*/ /* if no character after c_cc[VTIME] * 0.1s */ tio.c_cc[VMIN] = 8; /* a minimum of 8 char's retrieved each read */ tcflush( fd, TCIFLUSH); /* flush input buffer */ tcsetattr( fd, TCSANOW, &tio);/* install new port settings (immediately) */ while ( echo_serial_go ) { /* copy stdin to serial port */ incc = fread( buffer, sizeof(char), BUFFER_SIZE, stdin ); if ( incc > 0 ) { outcc = write( fd, buffer, incc ); if ( outcc < 0 ) { perror( serial_device ); break; } } else if ( feof( stdin ) ) /* test if end of file */ break; } tcsetattr( fd, TCSANOW, &prev_tio ); /* kindly restore previous settings */ } /* return a baud rate code based on the requested rate */ speed_t choose_baud_rate( int *rate ) { if ( *rate <= 9600 ) { /* more rates are available... */ *rate = 9600; return( B9600 ); } else if ( *rate <= 19200 ) { *rate = 19200; return( B19200 ); } else if ( *rate <= 38400 ) { *rate = 38400; return( B38400 ); } else if ( *rate <= 57600 ) { *rate = 57600; return( B57600 ); } else { *rate = 115200; return( B115200 ); } } int main( int argc, char **argv ) { speed_t baudrate; int i_rate; int itemp; if( argc < 2 ) { fprintf( stderr, "usage: %s serial_device [baud_rate]\n" "example: %s /dev/ttyS0\n", argv[0], argv[0] ); } else { if ( argc >= 3 ) { itemp = i_rate = atoi( argv[2] ); baudrate = choose_baud_rate( &i_rate ); if( i_rate != itemp ) fprintf( stderr, "unsupported baud rate, using %d instead\n", i_rate ); } else { baudrate = B9600; } echo_serial_go = 1; echo_to_serial( argv[1], baudrate ); } }