C запись () не отправляет данные, пока близкий (fd) не назван

Таким образом, у меня есть этот тестовый код для отправки "ПРИВЕТ" по последовательному порту USB:

int fd;
struct termios tty;

if((fd = open("/dev/ttyUSB0", O_WRONLY|O_NONBLOCK|O_NOCTTY)) == -1){
err(1, "Cannot open write on /dev/ttyUSB0");
}

tcgetattr(fd, &tty);
tty.c_iflag = 0;
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 0;
cfsetospeed(&tty, B19200);
cfsetispeed(&tty, B19200);
tty.c_cflag |= CREAD|CRTSCTS|HUPCL|CS8;
tcsetattr(fd, TCSANOW, &tty);

printf("Write: %i\n", write(fd, "HELLO", 5));

sleep(5);

if(close(fd) != 0){
warn("Could not close write fd");
}

Программа выполняется прекрасный и "ПРИВЕТ" отправляется, но существует одна проблема. "ПРИВЕТ", кажется, не отправляется, когда запись () функция вызвана, а скорее когда дескриптор файла закрывается. Я добавил сон (5) строка выше для проверения этой теории и конечно же, "ПРИВЕТ" отправляюсь спустя ~5 секунд после того, как программа выполнена. Как я могу добраться "ПРИВЕТ", чтобы быть сразу отправленным после записи () команда вместо на завершении ()?

7
задан dsolimano 5 November 2012 в 17:35
поделиться

7 ответов

Из справочной страницы write () :

Успешный возврат из write () не дает никаких гарантий эти данные были записаны на диск. Фактически, в некоторых реализациях с ошибками это даже не гарантирует, что пространство было успешно зарезервировано для данных. Единственный способ быть уверенным - это вызвать fsync (2) после того, как вы закончите запись всех ваших данных.

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

5
ответ дан 6 December 2019 в 14:00
поделиться

См. этот вопрос . B Как правило, вам нужно очистить файл, чтобы ввод-вывод имел место, когда вы хотите.

-1
ответ дан 6 December 2019 в 14:00
поделиться

Устройство является tty устройством, поэтому fsync не поможет, возможно, и не fflush.

По умолчанию устройство работает в каноническом режиме, что означает, что данные упаковываются в блоки строк. Вы, вероятно, обнаружите, что добавление пары cr / lf к вашим данным приведет к их отправке.

Убедитесь, что канонический режим отключен. Также будет полезен ответ Р.

http://en.wikibooks.org/wiki/Serial_Programming/termios

8
ответ дан 6 December 2019 в 14:00
поделиться

Попробуйте выполнить

fflush( NULL );

после write () . Может быть, есть какой-то внутренний буфер, который не сбрасывается.

-1
ответ дан 6 December 2019 в 14:00
поделиться

Измените эту строку:

tty.c_cc[VMIN] = 0;

на эту:

tty.c_cc[VMIN] = 1;
0
ответ дан 6 December 2019 в 14:00
поделиться

буфер не очищается. fflush.

-1
ответ дан 6 December 2019 в 14:00
поделиться

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

См. fflush(3) для принудительной фиксации буфера на выходе.

Вы также можете открыть дескриптор вывода таким образом, чтобы он не был буферизован, но использование fflush для того, чтобы сказать "все, я закончил", вероятно, лучше.

2
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: