Как прослушивать последовательный порт с помощью C с помощью CRTSCTS

Я пытаюсь прослушивать последовательный порт с помощью программы 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?


person user2395126    schedule 17.09.2019    source источник
comment
Строка tty.c_cflag |= ~CRTSCTS; должна быть tty.c_cflag |= CRTSCTS;. Обратите внимание, что ~ - это двоичный оператор не (побитовая инверсия).   -  person the busybee    schedule 17.09.2019
comment
Спасибо! Я исправил код, но кажется, что Arduino все еще получает сигнал DTR. Какие-либо предложения?   -  person user2395126    schedule 20.09.2019
comment
Arduino все еще получает сигнал DTR. - Если DTR используется для управления платой, а не для последовательного установления связи, отключите управление потоком HW в termios. Затем вы можете попытаться манипулировать строкой DTR, используя команды ioctl () TIOCMBIC и TIOCMBIS для флага TIOCM_DTR. См. страницу руководства для tty_ioctl.   -  person sawdust    schedule 05.10.2019