как читать и записывать данные на последовательный порт, используя потоки - PullRequest
3 голосов
/ 16 марта 2011

Я создаю приложение последовательного порта, в котором я создаю два потока, один из которых - ПИСАТЕЛЬНАЯ РЕЗЬБА, которая будет записывать данные в последовательный порт, и ЧИТАТЕЛЬНАЯ РЕЗЬБА, которая будет считывать данные из последовательного порта. Я знаю, как открывать, настраивать, читать и записать данные на последовательный порт, но как это сделать с помощью потоков.

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

Ответы [ 3 ]

1 голос
/ 16 марта 2011

Способ, которым я делал это в прошлом, заключается в том, чтобы настроить порт для асинхронного ввода-вывода, используя 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, ...
...
0 голосов
/ 30 августа 2012

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

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

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

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

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

0 голосов
/ 30 августа 2012

Я нахожусь в довольно похожей ситуации.

Мои темы работают с этим кодом:

HANDLE thandle; 
thandle = (HANDLE) _beginthread(ThreadProc_Read,0,&serial); // create thread
WaitForSingleObject(thandle,INFINITE);

void ThreadProc_Write(void *param)
{

    LONG    lLastError = ERROR_SUCCESS;
    printf("Thread is Running!\n");

    MpHostSendCommandReadBluetoothAddr(param);

    _endthread();

}

Беда в том, чтобы постоянно реагировать на чтение при любом событии записи. Я использую перекрывающийся ввод-вывод для перехвата любых новых событий wirte в моей ветке чтения, но он не работает должным образом Я не могу поймать ответ, вызванный потоком записи. Я слишком благодарен за любую помощь в этом вопросе.

...