Последовательный порт чтения и записи с C - PullRequest
0 голосов
/ 10 августа 2010

Я пишу программу на C, которая будет читать и писать с / на последовательный порт. Каждая запись будет сопровождаться чтением, которое будет содержать данные, основанные на записи. У меня будет около 16 различных операций записи, за которыми следует чтение.

Я все еще новичок в серийном программировании и пытаюсь определить, как к этому подойти. Должна ли программа блокироваться во время каждой записи / чтения (в основном это большой цикл while (1) записи и чтения)?

Возможно ли, чтобы один поток отправлял записи, а другой поток выполняет чтение? Можно ли создать обратный вызов, чтобы позволить потоку узнать, когда доступны данные для чтения с последовательного порта?

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

Edit:

ОС: Linux

Ответы [ 2 ]

1 голос
/ 10 августа 2010

Звучит как простой цикл с чтением и записью.Если вам нужен больший контроль (например, сохранение активности после X секунд отсутствия ввода), используйте select или poll;они позволяют вам «определять», доступны ли данные, поэтому read не будет блокировать (однако вы все равно должны читать неблокирующее в случае, если что-то происходит между select и read).Многопоточность в этом случае не имеет смысла.

select и poll также позволяют вам проверить, не блокируется ли запись;снова, напишите неблокирующее просто чтобы быть уверенным.Как правило, вы не хотите, чтобы ваш процесс зависал в каком-то блокирующем системном вызове, кроме select или poll, то есть.(по крайней мере, я не знаю)

Используйте ioctl для установки различных параметров последовательной линии.Используйте

$ strace -o /tmp/strace.minicom -f minicom

, чтобы запустить Minicom (или любую другую терминальную программу) и посмотреть, что они делают, чтобы все заработало, если вы застряли.И, как всегда, см. man select/poll/read/ioctl для получения дополнительной информации.

0 голосов
/ 10 августа 2010

Есть несколько способов сделать это в целом. Вероятно, наилучший выбор зависит от того, какой тип данных вы просматриваете, когда читаете последовательный порт, и от того, как вы хотите устранить ошибки в этих данных.

Первый способ - открыть последовательный файл для блокировки ввода-вывода и выполнить:

while (question) {
    write(ser_fd, question.data, question.len);
    sleep(1);
    ioctl(ser_fd, FIONREAD, &answer.len);
    answer.data = realloc(answer.data, answer.len);
    read(ser_fd, question.answer, question.answer_len);
    question = next(question);
    answer = next(answer);
}

Хотя я не занимался обработкой ошибок в этом.

Если вы хотите иметь возможность ожидания ожидания ответа на последовательный порт, то это многое меняет. Вы должны изучить использование системных вызовов select, pselect, poll, ppoll или epoll. Это позволяет вашей программе блокировать (спать) до тех пор, пока не будут готовы данные для чтения. Затем вы можете циклически выполнять опрос и читать до тех пор, пока не завершите свой ответ или не истечет время.

Другой вариант - попытаться использовать SIGIO, но я не рекомендую это. Нелегко сделать это правильно и трудно отладить.

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

Если вы пытаетесь использовать процедуры ввода и вывода stdio, тогда это намного сложнее. Вы застрянете с чем-то похожим на первый метод, не имея возможности спросить, сколько данных готово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...