100 likes | 263 Views
Linux Serial Programming for POSIX Operating Systems. What Are Serial Communications ?. Speed : in bits-per-second (“bps”) . Represents the number of ones and zeroes that can be sent in one second.
E N D
What Are Serial Communications ? • Speed : in bits-per-second (“bps”) . Represents the number of ones and zeroes that can be sent in one second. • The modulation rate can be lower than the bits-per-second (bps) rate when we encode more than one bits in a single change of symbol. The number of changes per second in the signal is termed “baud rate”. • Half Duplex – It is necessary to control RTS, CTS, and possibly DCD Signals • Flow Control • None • Hardware – RS232 – RTS – CTS signals • Software – Special Characters start XON (or DC1) or stop (XOFF or DC3) • Full Duplex – No need to Control RTS and CTS Signals • Asynchronous of Synchronous • Communication via RS-232 • Communication via RS-485 (Differential Mode)
About Serial Ports • On Windows • Com1, Com2, Com3 • On Linux • /dev/ttyS0, /dev/ttyS1, /dev/ttyS2 • On Solaris/SunOS • /dev/ttya, /dev/ttyb, /dev/ttyc • On POSIX systems, a serial port is a file (/dev/ttyS0). Thus, the Open( ) and Close ( ) functions have to be used to work with the serial port.
Input Concepts for Serial Devices - 1 • The appropriate concept has to be chosen for the intended application. Whenever possible, do not loop reading single characters to get a complete string because there may get characters lost. • Canonical Input Processing • This is the normal processing mode for terminals. A read( ) will only return a full line of input. It means that the process (or thread) will not proceed until a full line is received !!!. A line is by default terminated by a NL (ASCII LF), and end of file, or and end of line character. A CR (DOS/Windows default end-of-line) will not terminate a line with the default settings.
Input Concepts for Serial Devices - 2 • Non-Canonical Input Processing • Non-Canonical Input Processing will handle a fixed amount of charactersper read, and allows for a character timer (to specify RX timeout). • When the serial port is programmed to read a number N of chars, it will not return N chars. It will return the number of chars already available in the input buffer !!!!!!!!!!. The user has to control it. • Two parameters control the behavior of this mode: • c_cc [VTIME] sets the character timer • c_cc [VMIN] sets the minimum number of characters to receive before satisfying the read. • If MIN > 0 and TIME=0, MIN sets the number of chars to receive before the read is satisfied. As TIME is zero, the timer is not used. • If MIN=0 and TIME > 0, TIME serves as a timeout value. The read will be satisfied if a single char is read, or TIME is exceeded.
Input Concepts for Serial Devices - 3 • The two modes above can be used in synchronous and asynchronous modes. • In synchronous mode the read () operation will block until the read is satisfied. • In asynchronous mode the read () statement will return immediately and send a signal to the calling program upon completion. This signal can be received by a signal handler. • There is also Raw input – Raw input is unprocessed, that is, the receiver does not interpretate any character. To accomplish this, deselect the ICANON, ECHO, ECHOE and ISIG options when using raw input: • Options.c_flag &= ~(ICANON | ECHO | ECHOE | ISIG);
Configuring a Serial Port # indclude “global.h” # include <sys/ioctl.h> # include <sys/io.h> # include <asm/system.h> # include <sys/termios.h> # include <sys/fcntl.h> # define BAUDRATE B9600 # define MODEMDEVICE “/dev/ttyS2” # define …………… FILE *input; FILE *output; Int fd, tty, struct termios oldtio, newtio; Struct ……….. void configure_serial () { fd = open (MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) { perror (MODEMDEVICE); exit (-1); } tcgetattr (fd, &oldtio); // ==== save current port settings ==== // bzero (&newtio, sizeof (newtio)); newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | READ; newtio.c_iflag = IGNPAR; // Ignore parity errors newtio.c_oflag = 0; // newtio.c_lflag = 0; newtio.c_cc[VTIME] = 0; // === timer not used ====== newtio.c_cc[VIMIN] = 1; // === blocking read until 1 char read tcflush (fd, TCIFLUSH); tcsetattr (fd, TCSANOW, &newtio); } O_RDWR – Open for Read and Write Mode O_NOCTTY – tell Unix this prog is no controlling terminal for that port O_NONBLOCK – Non Blocking Mode c_flag – Control Options (control speed, no data bits, parity, stop bits, etc) i_flag – Input Options (enable/disable parity check, ignore break, etc) o_flag – Output options ( Map lower to upper case, map CR to NL, etc) l_flag – line options ( TCSANOW – specifies all changes to occur NOW without waiting for output data to finish sending or input data finish receiving TCIFLUSH – Flush Input and Output buffers and make the change c_cc char array – control char definitions as well as timeout parameters
RECEIVING A CHARACTER Void recebe_caracter (char ch, char tout) { char carac; int ……; for (I=0; I<N, I++) buf[I] = ‘\0’; // Limpa buffer de recepçao timeout = FALSE; // Timeout de caractere do { res = read (fd, buf, 1); if (res == 0) timeout = TRUE; carac = buf [0]; printf (“carac lido = %02X\r\n“, carac); } while (( buf[0] != EOT) && (timeout == FALSE); if (timeout == TRUE) { - - - - - - - - - - - - - - - - - - } - - - - - - - - - - - - - - - - - - }
Sending a Message Function Void envia_mensagem (int tamanho) // FUNÇÃO DE ENVIAR { int flags, nbytes, para1; char ch; long int I; ioctl (fd, TIOCMGET, &flags); // == Get the current MODEM status bits for (I = 0; I < 1000000; I++); // espera 10 ms antes de acionar RTS flags | = TIOCM_RTS; // prepara RTS (Request to Send) if (( ioctl (fd, TIOCMSET, &flags) < 0)) perror ( “IOCTL”); // Seta RTS na serial while ((( inb (0x3ED) & 0x60) != 0x60)); // 3ED=ttyS2 ; 3FD = ttyS0; 2FD = ttyS1; for (I =0; I < 50000; I++); // espera 10ms antes de enviar dados nbytes = write (fd, buf_tx, tamanho); // transmite msg while ((( inb(0x3ED) & 0x40) != 0x40)); // Espera transmitir - valores para COM2; for (I= 0; I<50; I++); // espera 10ms antes de retirar RTS flags &= ~TIOCM_RTS; // prepara variavel de RTS, resetando if ((ioctl (fd, TIOCMSET, &flags) < 0)) perror ( “IOCTL”); // reseta RTS, na serial } Draw Picture with Half – Duplex RS 485 or RS 422 Scheme NOTE: Under Linux the serial port is configured using the ioctl( ) system call
CLOSING THE SERIAL COMMUNICATION Void fecha_e_restabelece () // FUNÇÃO DE FECHAMENTO { tcsetattr (fd, TCSANOW, &oldtio); // restabelece configuração anterior close (fd); // fecha dispositivo da serial fclose (input); fclose (output); }