Как можно очистить запись, используя файловый дескриптор?
Оказывается, что все это непонимание 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 ответов:
У вас есть два варианта:
Используйте
fileno()
для получения файлового дескриптора, связанного с указателем потокаstdio
Не используйте
<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()
только сбрасывает буферизацию, добавленную слоем stdiofopen()
, управляемым объектомFILE *
. Сам базовый файл, как видно из ядра, не буферизуется на этом уровне. Это означает, что записи, которые обходят слойFILE *
, используяfileno()
и rawwrite()
, также не буферизуются таким образом, чтоfflush()
будет смываться.Как уже отмечалось, попробовать Не смешения двух. Если вам нужно использовать "сырые" функции ввода-вывода, такие как
ioctl()
, тоopen()
файл непосредственно, Без использованияfopen<()
и друзей из stdio.
Похоже, что вы ищете функцию fsync () (или fdatasync ()?), или вы можете использовать флаг O_SYNC в вызове open ().