Saya menulis ini sejak lama ( dari tahun 1985-1992, hanya dengan beberapa perubahan sejak saat itu ), dan cukup salin dan tempel bit yang diperlukan ke dalam setiap proyek.
Anda harus memanggil cfmakerawpada ttydiperoleh dari tcgetattr. Anda tidak dapat menghilangkan nol struct termios, mengkonfigurasinya, dan kemudian mengatur ttydengan tcsetattr. Jika Anda menggunakan metode zero-out, maka Anda akan mengalami kegagalan intermiten yang tidak dapat dijelaskan, terutama pada BSD dan OS X. "Kegagalan intermiten yang tidak dapat dijelaskan" termasuk bertahan 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;
tty.c_iflag &= ~IGNBRK;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 5;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~(PARENB | PARODD);
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;
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_blocking (fd, 0);
write (fd, "hello!\n", 7);
usleep ((7 + 25) * 100);
char buf [100];
int n = read (fd, buf, sizeof buf);
Nilai untuk kecepatan yang B115200, B230400, B9600, B19200, B38400, B57600, B1200, B2400, B4800, dll nilai untuk paritas 0(artinya tidak ada paritas), PARENB|PARODD(memungkinkan paritas dan menggunakan aneh), PARENB(memungkinkan paritas dan menggunakan bahkan), PARENB|PARODD|CMSPAR(mark paritas), dan PARENB|CMSPAR( ruang paritas).
"Blocking" mengatur apakah a read()di port menunggu sampai sejumlah karakter tertentu tiba. Menetapkan tanpa pemblokiran berarti bahwa read()pengembalian berapa pun banyak karakter tersedia tanpa menunggu lebih lama, hingga batas buffer.
Tambahan:
CMSPARhanya diperlukan untuk memilih paritas mark dan spasi, yang tidak umum. Untuk sebagian besar aplikasi, ini dapat dihilangkan. File header saya /usr/include/bits/termios.hmemungkinkan definisi CMSPARhanya jika simbol preprocessor __USE_MISCdidefinisikan. Definisi itu muncul (dalam features.h) dengan
#if defined _BSD_SOURCE || defined _SVID_SOURCE
#define __USE_MISC 1
#endif
Komentar pengantar <features.h>mengatakan: