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


Оказывается, что все это непонимание open () против fopen () происходит из-за багги драйвера I2C в ядре Linux 2.6.14 на ARM. Обратная транспортировка рабочего немного помятого драйвера решила основную причину проблемы, которую я пытался решить здесь.

Я пытаюсь решить проблему с драйвером последовательного устройства в Linux (I2C). Похоже, что при добавлении временных пауз ОС (sleeps) между записями и чтениями на устройстве все работает ... (гораздо лучше.

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

Я либо хотел бы промыть запись, чтобы быть уверенным (вместо использования фиксированной длительности паузы), или как-то проверить, что пишут/читают транзакция завершена многопоточным дружественным способом.

Проблема с использованием fflush(fd); заключается в том, что он требует, чтобы' fd ' был указателем потока (а не файловым дескриптором), т. е.

FILE * fd = fopen("filename","r+");
... // do read and writes
fflush(fd);

Моя проблема заключается в том, что я требую использования ioctl(), который не использует указатель потока. то есть

int fd = open("filename",O_RDWR);
ioctl(fd,...);

Предложения?

6 29

6 ответов:

У вас есть два варианта:

  1. Используйте fileno() для получения файлового дескриптора, связанного с указателем потока stdio

  2. Не используйте <stdio.h> вообще, таким образом, вам не нужно беспокоиться о Флеше - все записи будут немедленно отправляться на устройство, а для символьных устройств вызов write() даже не вернется, пока не завершится ввод-вывод нижнего уровня (теоретически).

Для ввода-вывода уровня устройства я бы сказал, что это довольно необычно использовать stdio. Я бы сильно рекомендуем использовать нижний уровень open(), read() и write() функции вместо этого (на основе вашего последующего ответа):

int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);

Я думаю, что то, что вы ищете, может быть

int fsync(int fd);

Или

int fdatasync(int fd);

fsync будет сброшен файл из буфера ядра на диск. fdatasync также будет делать за исключением метаданных.

fflush() только сбрасывает буферизацию, добавленную слоем stdio fopen(), управляемым объектом FILE *. Сам базовый файл, как видно из ядра, не буферизуется на этом уровне. Это означает, что записи, которые обходят слой FILE *, используя fileno() и raw write(), также не буферизуются таким образом, что fflush() будет смываться.

Как уже отмечалось, попробовать Не смешения двух. Если вам нужно использовать "сырые" функции ввода-вывода, такие как ioctl(), то open() файл непосредственно, Без использования fopen<() и друзей из stdio.

Похоже, что вы ищете функцию fsync () (или fdatasync ()?), или вы можете использовать флаг O_SYNC в вызове open ().

Если вы хотите пойти другим путем (связать файл* с существующим файловым дескриптором), используйте fdopen ():

                                                          FDOPEN(P)

NAME

       fdopen - associate a stream with a file descriptor

SYNOPSIS

       #include <stdio.h>

       FILE *fdopen(int fildes, const char *mode);

Вы пробовали отключить буферизацию?

setvbuf(fd, NULL, _IONBF, 0);