44

この open() と fopen() の誤解は、ARM 上の Linux 2.6.14 カーネルのバグのある I2C ドライバーに起因することが判明しました。動作中のビット バッシュ ドライバーをバックポートすることで、ここで対処しようとしていた問題の根本原因が解決されました。

Linux (I2C) のシリアル デバイス ドライバーの問題を解決しようとしています。デバイスの書き込みと読み取りの間に時間指定された OS 一時停止 (スリープ) を追加することで、動作が (はるかに) 良くなったようです。

余談: I2C の性質は、マスターによって読み書きされる各バイトが、ワイヤーの反対側 (スレーブ) のデバイスによって認識されることです。バスの仕組みに納得がいかない。とにかく...

(固定期間の一時停止を使用するのではなく) 確実に書き込みをフラッシュする、書き込み/読み取りトランザクションがマルチスレッドに適した方法で 完了したことを何らかの形でテストしたいと思います。

使用に関する問題fflush(fd);は、「fd」がストリームポインター(ファイル記述子ではない)である必要があることです。

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

私の問題はioctl()、ストリーム ポインターを使用しない を使用する必要があることです。すなわち

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

提案?

4

6 に答える 6

40

私はあなたが探しているものがあると思います

int fsync(int fd);

また

int fdatasync(int fd);

fsyncファイルをカーネルバッファからディスクにフラッシュします。fdatasyncメタデータ以外も行います。

于 2010-07-03T23:08:11.707 に答える
29

次の 2 つの選択肢があります。

  1. ストリーム ポインタfileno()に関連付けられたファイル記述子を取得するために使用しますstdio

  2. まったく使用<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);
于 2008-11-03T17:34:23.217 に答える
12

fflush()fopen()オブジェクトによって管理されているように、stdioレイヤーによって追加されたバッファリングのみをフラッシュしFILE *ます。カーネルから見た場合、基になるファイル自体はこのレベルではバッファリングされません。これは、とrawFILE *を使用してレイヤーをバイパスする書き込みも、フラッシュするような方法でバッファリングされないことを意味します。fileno()write()fflush()

他の人が指摘しているように、2つを混ぜないようにしてください。などの「生の」I/O関数を使用する必要がある場合はioctl()、stdioの友人を使用せずopen()に、自分で直接ファイルを作成します。fopen<()

于 2008-11-04T07:32:32.477 に答える
2

あなたが探しているのは fsync() 関数 (または fdatasync()?) のようですが、open() 呼び出しで O_SYNC フラグを使用することもできます。

于 2009-11-08T14:33:42.423 に答える
2

逆の方法 (既存のファイル記述子に FILE* を関連付ける) を行う場合は、 fdopen() を使用します。

                                                          FDOPEN(P)

NAME

       fdopen - associate a stream with a file descriptor

SYNOPSIS

       #include <stdio.h>

       FILE *fdopen(int fildes, const char *mode);
于 2008-11-04T14:14:12.200 に答える