Подтвердить что ты не робот

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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

int fsync(int fd);

или

int fdatasync(int fd);

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

                                                          FDOPEN(P)

NAME

       fdopen - associate a stream with a file descriptor

SYNOPSIS

       #include <stdio.h>

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

Ответ 6

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

setvbuf(fd, NULL, _IONBF, 0);