Таким образом, у меня есть этот тестовый код для отправки "ПРИВЕТ" по последовательному порту 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 секунд после того, как программа выполнена. Как я могу добраться "ПРИВЕТ", чтобы быть сразу отправленным после записи () команда вместо на завершении ()?
Из справочной страницы write ()
:
Успешный возврат из write () не дает никаких гарантий эти данные были записаны на диск. Фактически, в некоторых реализациях с ошибками это даже не гарантирует, что пространство было успешно зарезервировано для данных. Единственный способ быть уверенным - это вызвать fsync (2) после того, как вы закончите запись всех ваших данных.
Вам необходимо вызвать fsync ()
для вашего файлового дескриптора, чтобы убедиться, что данные действительно зафиксированы.
См. этот вопрос . B Как правило, вам нужно очистить файл, чтобы ввод-вывод имел место, когда вы хотите.
Устройство является tty устройством, поэтому fsync не поможет, возможно, и не fflush.
По умолчанию устройство работает в каноническом режиме, что означает, что данные упаковываются в блоки строк. Вы, вероятно, обнаружите, что добавление пары cr / lf к вашим данным приведет к их отправке.
Убедитесь, что канонический режим отключен. Также будет полезен ответ Р.
Попробуйте выполнить
fflush( NULL );
после write ()
. Может быть, есть какой-то внутренний буфер, который не сбрасывается.
Измените эту строку:
tty.c_cc[VMIN] = 0;
на эту:
tty.c_cc[VMIN] = 1;
Выходные порты часто буферизуются, так что существует больший или меньший промежуток между записью в выходной поток и фактической отправкой содержимого на диск, в линию или куда-либо еще. Обычно это делается для повышения эффективности.
См. fflush(3) для принудительной фиксации буфера на выходе.
Вы также можете открыть дескриптор вывода таким образом, чтобы он не был буферизован, но использование fflush
для того, чтобы сказать "все, я закончил", вероятно, лучше.