Аппаратное управление потоком с помощью termios (CRTSCTS) для устройства UART

прямо сейчас я общаюсь с устройством через UART на C ++ на Udoo Neo. Для этого я использую termios для настройки соединения и записи данных на устройство. Для этой цели я хочу использовать аппаратное управление потоком и установил флаг (CRTSCTS) с помощью termios.

Для аппаратного управления потоком я подключил линию RTS устройства к платам CTS, а также проверил с помощью осциллографа, что устройство выдает мне активный высокий уровень, если оно не готово к чтению.

Проблема в том, что я все еще теряю байты в следующем примере простого спама устройства с числами, но вывод платы говорит, что все было написано правильно.

Я думал, что UART будет заблокирован при использовании управления потоком HW, так что никакая информация не будет потеряна. Я неправильно это понимаю - или в коде есть ошибка?

Спасибо за помощь

const char dev[] = "/dev/ttymxc4";

int main(int argc, char **argv) {

int fd;
struct termios t; ///< control structure for a general asynchronous interface
// edited code
tcgetattr(fd, &t);

t.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
                 INLCR | PARMRK | INPCK | ISTRIP | IXON);
t.c_oflag = 0;
t.c_cflag &= ~(CSIZE | PARENB);
t.c_cflag |= (CS8 | CRTSCTS);

// edited code 
t.c_cflag |= (CLOCAL | CREAD);

t.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);

t.c_cc[VMIN]  = 0;
t.c_cc[VTIME] = 0;

cfsetispeed(&t,B57600); /* normal shall be: B115200 Baud */

fd = ::open(dev, O_RDWR);
if (fd==-1) {
    printf("UART: cannot open file: %s\n",dev);
    return -1;
}

tcsetattr(fd,TCSANOW, &t);

// edited code
fcntl(fd, F_SETFL, 0);

int count = 0;
while (true) {

    count++;
    std::stringstream output;
    output << count << ",";

    ::write(fd, output.str().c_str(), output.str().length());
    printf("%d, writing: %s\n", fd, output.str().c_str());
    usleep(10000);
}
return 0;

}


person Dingodoodl    schedule 28.09.2016    source источник
comment
(1) Структура termios используется без инициализации. tcgetattr () никогда не вызывается. (2) Инициализация структуры termios не завершена. Указана только входная скорость передачи. CREAD и CLOCAL установлены неправильно. VMIN = 0 и VTIME = 0 считается проблематичным. (3) у fcntl () отсутствует параметр.   -  person sawdust    schedule 28.09.2016
comment
Спасибо за помощь - внесены изменения. - tcgetattr (fd, & t); - t.c_cflag | = (CLOCAL | CREAD); - fcntl (fd, F_SETFL, 0); Я все еще теряю пакеты при запуске теста. При проверке сигнала CTS вручную (с помощью ioctl) я вижу, что CTS установлен активным / неактивным, и поэтому я даже могу получить все пакеты, проверив флаг вручную. Я просто подумал, что этим займется ядро?   -  person Dingodoodl    schedule 30.09.2016
comment
Отредактируйте свое сообщение, чтобы показать исправленный код для просмотра.   -  person sawdust    schedule 30.09.2016
comment
Только что обновил исходный пост, все изменения имеют комментарий // отредактированный код. Еще раз спасибо;)   -  person Dingodoodl    schedule 04.10.2016
comment
Изучите Правильная настройка режимов терминала и Руководство по последовательному программированию для операционных систем POSIX. Проверьте код возврата от каждого системного вызова на наличие ошибок. НАПРИМЕР. tcgetattr () выполняется до назначения fd.   -  person sawdust    schedule 05.10.2016


Ответы (1)


Ссылаясь на ссылки @sawdust, управление потоком HW управляется через

CCTS_OFLOW и CRTS_IFLOW через libc-doc

Макрос: tcflag_t CCTS_OFLOW
Если этот бит установлен, включить управление потоком вывода на основе кабеля CTS (протокол RS232).
Макрос: tcflag_t CRTS_IFLOW
Если этот бит установлен, включить управление потоком ввода по RTS-проводу (протокол RS232).

CNEW_RTSCTS и CRTSCTS через SerProgGuide

Некоторые версии UNIX поддерживают аппаратное управление потоком с использованием сигнальных линий CTS (Clear To Send) и RTS (Request To Send). Если в вашей системе определены константы CNEW_RTSCTS или CRTSCTS, то, вероятно, поддерживается аппаратное управление потоком. Для включения аппаратного управления потоком выполните следующие действия:

options.c_cflag |= CNEW_RTSCTS;    /* Also called CRTSCTS */

Обратите внимание, что Некоторые версии ... и ..., вероятно, поддерживаются.

В моей конкретной инструментальной цепочке кросс-компиляции (Linaro GCC 6.5-2018.12), если я grep для этих значений, CRTSCTS не документирован, но определен, CCTS_OFLOW находится во многих информационных файлах, но не в файлах заголовков ...

libc/usr/include/bits/termios.h:
174:# define CRTSCTS  020000000000              /* flow control */

Как вы сказали в своем комментарии

... Я просто подумал, что этим займется ядро?

Я вижу такое явление, что даже если я добавлю соответствующие свойства rts / cts в дерево устройств ({rts,cts}-gpios или uart-has-rtscts), команда stty -a -F /dev/ttyS по-прежнему сообщает -crtscts, что означает, что рукопожатие RTS / CTS выполняется отключен, поэтому даже без приложения пользовательского пространства это не кажется тривиальной конфигурацией. (Ядро 5.4)

person lnksz    schedule 25.08.2020