Я пытаюсь прослушивать последовательный порт с помощью программы C, использующей CRTSCTS (чтобы предотвратить перезагрузку Arduino с автономным питанием после того, как компьютер подключен к перезагрузке).
Я начал с кода отсюда: Последовательный порт Linux в каноническом режиме
После некоторых доработок это выглядит так:
#define SERIALTERMINAL "/dev/ttyUSB0"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= CLOCAL | CREAD;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
//tty.c_cflag &= ~CRTSCTS;
tty.c_cflag |= ~CRTSCTS; //trying to turn on CRTSCTS
tty.c_cflag &= ~HUPCL; //trying turning off HUPCL - it works!
tty.c_lflag |= ICANON | ISIG; /* canonical input */
tty.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN);
tty.c_iflag &= ~IGNCR; /* preserve carriage return */
tty.c_iflag &= ~INPCK;
tty.c_iflag &= ~(INLCR | ICRNL | IUCLC | IMAXBEL);
tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* no SW flowcontrol */
//tty.c_iflag |= ~IXON; //try ixon
tty.c_oflag &= ~OPOST;
tty.c_cc[VEOL] = 0;
tty.c_cc[VEOL2] = 0;
tty.c_cc[VEOF] = 0x04;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
int main()
{
char *portname = SERIALTERMINAL;
int fd;
int wlen;
//fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); original version
fd = open(portname, O_RDONLY | O_NOCTTY);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
/*baudrate 115200, 8 bits, no parity, 1 stop bit */
set_interface_attribs(fd, B115200);
/* simple canonical input */
do {
unsigned char buf[700];
unsigned char *p;
int rdlen;
rdlen = read(fd, buf, sizeof(buf) - 1);
if (rdlen > 0) {
buf[rdlen] = 0;
printf("%s", buf);
} else if (rdlen < 0) {
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
} else { /* rdlen == 0 */
printf("Nothing read. EOF?\n");
}
/* repeat read */
} while (1);
}
Когда программа запущена, она ничего не выводит.
Выход из режима CRTSCTS путем замены:
tty.c_cflag |= ~CRTSCTS;
с участием
tty.c_cflag &= ~CRTSCTS;
программа покажет вывод, но тогда он не будет в режиме CRTSCTS, который мне нужен, чтобы предотвратить отправку сигнала DTR, который приводит к сбросу Arduino.
После прочтения документации Termios я попробовал несколько различных вариантов: http://man7.org/linux/man-pages/man3/termios.3.html, но безрезультатно.
Итак, вопрос в том, какая комбинация опций позволит читать из последовательного порта без отправки сигнала DTR?
tty.c_cflag |= ~CRTSCTS;
должна бытьtty.c_cflag |= CRTSCTS;
. Обратите внимание, что~
- это двоичный оператор не (побитовая инверсия). - person the busybee   schedule 17.09.2019