J'ai écrit ceci il y a longtemps ( des années 1985-1992, avec juste quelques modifications depuis ), et il suffit de copier et coller les éléments nécessaires dans chaque projet.
Vous devez faire appel cfmakerawà un ttyobtenu de tcgetattr. Vous ne pouvez pas mettre à zéro un struct termios, le configurer, puis définir le ttyavec tcsetattr. Si vous utilisez la méthode zéro-out, vous rencontrerez des pannes intermittentes inexpliquées, en particulier sur les BSD et OS X. Les «pannes intermittentes inexpliquées» incluent la suspension read(3).
#include <errno.h>
#include <fcntl.h> 
#include <string.h>
#include <termios.h>
#include <unistd.h>
int
set_interface_attribs (int fd, int speed, int parity)
{
        struct termios tty;
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tcgetattr", errno);
                return -1;
        }
        cfsetospeed (&tty, speed);
        cfsetispeed (&tty, speed);
        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        // disable IGNBRK for mismatched speed tests; otherwise receive break
        // as \000 chars
        tty.c_iflag &= ~IGNBRK;         // disable break processing
        tty.c_lflag = 0;                // no signaling chars, no echo,
                                        // no canonical processing
        tty.c_oflag = 0;                // no remapping, no delays
        tty.c_cc[VMIN]  = 0;            // read doesn't block
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
        tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl
        tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
        tty.c_cflag |= parity;
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;
        if (tcsetattr (fd, TCSANOW, &tty) != 0)
        {
                error_message ("error %d from tcsetattr", errno);
                return -1;
        }
        return 0;
}
void
set_blocking (int fd, int should_block)
{
        struct termios tty;
        memset (&tty, 0, sizeof tty);
        if (tcgetattr (fd, &tty) != 0)
        {
                error_message ("error %d from tggetattr", errno);
                return;
        }
        tty.c_cc[VMIN]  = should_block ? 1 : 0;
        tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout
        if (tcsetattr (fd, TCSANOW, &tty) != 0)
                error_message ("error %d setting term attributes", errno);
}
...
char *portname = "/dev/ttyUSB1"
 ...
int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0)
{
        error_message ("error %d opening %s: %s", errno, portname, strerror (errno));
        return;
}
set_interface_attribs (fd, B115200, 0);  // set speed to 115,200 bps, 8n1 (no parity)
set_blocking (fd, 0);                // set no blocking
write (fd, "hello!\n", 7);           // send 7 character greeting
usleep ((7 + 25) * 100);             // sleep enough to transmit the 7 plus
                                     // receive 25:  approx 100 uS per char transmit
char buf [100];
int n = read (fd, buf, sizeof buf);  // read up to 100 characters if ready to read
Les valeurs de vitesse sont B115200, B230400, B9600, B19200, B38400, B57600, B1200, B2400, B4800, etc. Les valeurs de parité sont 0( ce qui signifie pas de parité), PARENB|PARODD(activer la parité et l' utilisation impair), PARENB(activer la parité et l' utilisation même), PARENB|PARODD|CMSPAR(parité de marque) et PARENB|CMSPAR( parité spatiale).
"Blocking" définit si un read()sur le port attend que le nombre spécifié de caractères arrive. La définition de l' absence de blocage signifie que a read()renvoie le nombre de caractères disponibles sans attendre davantage, jusqu'à la limite de la mémoire tampon.
Addenda:
CMSPARn'est nécessaire que pour choisir la parité entre les marques et les espaces, ce qui est rare. Pour la plupart des applications, il peut être omis. Mon fichier d'en-tête /usr/include/bits/termios.hpermet de définir CMSPARuniquement si le symbole du préprocesseur __USE_MISCest défini. Cette définition se produit (dans features.h) avec
#if defined _BSD_SOURCE || defined _SVID_SOURCE
 #define __USE_MISC     1
#endif
Les commentaires introductifs de <features.h>dit:
/* These are defined by the user (or the compiler)
   to specify the desired environment:
...
   _BSD_SOURCE          ISO C, POSIX, and 4.3BSD things.
   _SVID_SOURCE         ISO C, POSIX, and SVID things.
...
 */