как читать и записывать данные в последовательный порт с помощью потоков

Я создаю приложение для последовательного порта, в котором я создаю два потока: один - WRITER THREAD, который будет записывать данные в последовательный порт, и READER THREAD, который будет читать данные из последовательного порта. Я знаю, как открывать, настраивать, читать и записывать данные на последовательный порт, но как это сделать с помощью потоков.

Я использую LINUX (ubuntu) и пытаюсь открыть программирование порта ttyS0 на C.


person tejendra    schedule 16.03.2011    source источник


Ответы (2)


Раньше я делал это так, чтобы настроить порт для асинхронного ввода-вывода с использованием VMIN 0 и VTIME, скажем, 5 децисекунд. Цель этого заключалась в том, чтобы позволить потоку заметить, когда пришло время для завершения работы приложения, поскольку он мог попытаться прочитать, время ожидания, проверить флаг выхода, а затем попытаться прочитать еще.

Вот пример функции чтения:

size_t myread(char *buf, size_t len) {
    size_t total = 0;
    while (len > 0) {
        ssize_t bytes = read(fd, buf, len);
        if (bytes == -1) {
            if (errno != EAGAIN && errno != EINTR) {
                // A real error, not something that trying again will fix
                if (total > 0) {
                    return total;
                }
                else {
                    return -1;
                }
            }
        }
        else if (bytes == 0) {
            // EOF
            return total;
        }
        else {
            total += bytes;
            buf += bytes;
            len -= bytes;
        }
    }

    return total;
}

Функция записи будет выглядеть так, как и следовало ожидать.

В функции настройки обязательно установите:

struct termios tios;
...
tios.c_cflag &= ~ICANON;
tios.c_cc[VMIN] = 0;
tios.c_cc[VTIME] = 5; // You may want to tweak this; 5 = 1/2 second, 10 = 1 second, ...
...
person Jonathan    schedule 16.03.2011
comment
Что заставило вас поверить, что последовательные порты не могут отправлять и получать одновременно? - person Lundin; 16.03.2011
comment
я не хочу отправлять и получать данные одновременно. Сначала я напишу данные, а после этого я буду читать записанные данные с помощью потока чтения. На самом деле я хочу реализовать его только с помощью потоков, в противном случае без потока я уже это сделал, расскажите, пожалуйста, что-нибудь, как я могу реализовать это с помощью потоков. - person tejendra; 16.03.2011
comment
Соединения последовательного порта @Lundin содержат контакты, готовые к отправке и готовые к приему, специально для управления, какая сторона имеет возможность отправлять данные в данный момент, поскольку обе стороны не могут одновременно. Я считаю, что для этого и нужны параллельные порты. - person Jonathan; 16.03.2011
comment
Насколько я понимаю, RS-232 является (или, по крайней мере, может быть) полнодуплексным - person Joe; 16.03.2011
comment
как эти потоки взаимодействуют с последовательным портом ... конкретнее ... не помогайте мне в синхронизации потоков ... - person tejendra; 17.03.2011
comment
Джонатан, здесь ты не мог больше ошибаться. RS-232 определенно может работать в полнодуплексном режиме, что обычно и происходит. Запрос на отправку (RTS) и Clear-to-Send (CTS) используются для управления потоком, когда буфер хоста заполняется для приема большего количества данных. Дело в том, что аппаратное управление потоком информации больше не используется и уж точно не требуется. Параллельные порты будут выстраивать в линию 8 бит для одновременной отправки. Вы также должны знать, что только позже параллельные порты стали работать даже в двунаправленном режиме. Конечно, были статусные строки, но на этом все. - person Brad; 17.03.2011
comment
@Brad Спасибо, прошу прощения за мое невежество. Я неправильно понял механизм. Однако является ли мой ответ неверным? Отредактирую бит о полудуплексе. - person Jonathan; 17.03.2011
comment
@ Джонатан, мои комментарии касались ваших заявлений о дуплексной печати и не более того. - person Brad; 17.03.2011
comment
@Jonathan Взгляните на асинхронный ввод-вывод. davmac.org/davpage/linux/async-io.html Я никогда не сделал это в Linux, так что извините, если эта статья вам не сильно поможет. - person RedX; 17.03.2011

Использование последовательного порта из 2 потоков просто, если только один поток читает, а другой только пишет.

Вы должны использовать один файловый дескриптор для последовательного порта.

Откройте и инициализируйте его в одном потоке, используя обычные функции open, tcsetattr и т. Д. Затем доставьте дескриптор файла другому потоку (ам).

Теперь поток чтения может использовать read() функцию, а писатель может использовать write() функцию без дополнительной синхронизации. Вы также можете использовать select() в обоих потоках.

Закрытие файлового дескриптора требует внимания, во избежание проблем вы должны делать это в одном потоке.

person SKi    schedule 30.08.2012