Чтение / запись на устройство в C ++ - PullRequest
2 голосов
/ 29 июня 2011

Как я могу читать / писать на устройстве в C ++? устройство в /dev/ttyPA1.
Я думал о fstream, но не могу знать, есть ли у устройства вывод, который я могу прочитать, не блокируя приложение.
Моя цель - создать приложение, в котором вы что-то пишете в терминал, и оно отправляется в /dev/ttyPA1. Если устройству есть что записать, оно будет считывать это с устройства и записывать на экран. Если нет, то пользователю будет предложено снова написать на устройство.
Как я могу это сделать?

Ответы [ 2 ]

6 голосов
/ 29 июня 2011

Используйте open(2), read(2) и write(2) для чтения и записи на устройство (и не забудьте close(2), когда вы закончите).Вы также можете использовать функции C stdio (fopen(3) и друзья) или классы fstream C ++, но если вы это сделаете, вы почти наверняка захотите отключить буферизацию (setvbuf(3)для stdio или outFile.rdbuf()->pubsetbuf(0, 0) для потоков).

Однако все они будут работать в режиме , блокирующем .Вы можете использовать select(2) для проверки возможности чтения или записи в файловый дескриптор без блокировки (если это невозможно, вам не следует этого делать).Кроме того, вы можете открыть файл с флагом O_NONBLOCK (или использовать fcntl(2), чтобы установить флаг после открытия) в дескрипторе файла, чтобы сделать его неблокирующим;затем любой вызов read(2) или write(2), который вместо этого блокирует, немедленно завершается с ошибкой EWOULDBLOCK.

Например:

// Open the device in non-blocking mode
int fd = open("/dev/ttyPA1", O_RDWR | O_NONBLOCK);
if(fd < 0)
    ;  // handle error

// Try to write some data
ssize_t written = write(fd, "data", 4);
if(written >= 0)
    ;  // handle successful write (which might be a partial write!)
else if(errno == EWOULDBLOCK)
    ;  // handle case where the write would block
else
    ;  // handle real error

// Reading data is similar
0 голосов
/ 29 июня 2011

Вы можете использовать fstream, но вам нужно будет посмотреть спецификации того, как ваше устройство хотело бы получать данные. Некоторые устройства будут в порядке, используя данные ASCII, другим устройствам потребуется определенная двоичная последовательность битов / байтов данных. Возможно, вам также придется написать собственные объекты сериализации, которые перегружают функции operator<< и operator>> для данных, которые вы пытаетесь записать. Либо так, либо вы могли бы использовать методы read() и write() для чтения / записи необработанных двоичных данных из / в буферные массивы, выделенные в вашей программе.

Редактировать : если вас беспокоит поведение блокировки, у вас есть два варианта. Вам нужно будет либо использовать POSIX API, и проверить открытый дескриптор файла с помощью poll() или select(), чтобы узнать, доступны ли данные, либо вам придется поддерживать любые вызовы записи или чтения файлов в наборе отдельные потоки, которые могут в основном действовать как асинхронные действия чтения / записи. Таким образом, вы в основном отправляете сообщение потоку чтения / записи, и этот поток блокирует при необходимости вызовы fstream, однако остальная часть вашей программы может продолжать функционировать. Возможно, ваша программа не предназначена для потоков, и если это так, то POSIX API был бы единственным выходом.

...