ファイル記述子を使用して書き込みをフラッシュするにはどうすればよいですか?
質問
open()対fopen()のこの誤解は、ARM上のLinux 2.6.14カーネルのバグのあるI2Cドライバーに起因していることがわかりました。正常に動作するビットドライバーをバックポートすることで、ここで解決しようとしていた問題の根本原因を解決しました。
Linux(I2C)のシリアルデバイスドライバーの問題を見つけようとしています。デバイスでの書き込みと読み取りの間に時間指定されたOSの一時停止(スリープ)を追加することで、動作が(はるかに)良くなるようです。
脇: 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,...);
提案?
解決
2つの選択肢があります:
-
fileno()
を使用して、stdio
ストリームポインターに関連付けられたファイル記述子を取得します -
<stdio.h>
はまったく使用しないでください。フラッシュを心配する必要はありません。すべての書き込みはすぐにデバイスに送信され、キャラクターデバイスの場合はwrite()
呼び出しは行われません。 (理論上)下位IOが完了するまで戻ります。
デバイスレベルのIOの場合、open()
を使用するのはかなり珍しいと思います。代わりに下位レベルのread()
、<=>、および<=>関数を使用することを強くお勧めします(後の返信に基づいて):
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()
は、fopen()
オブジェクトによって管理されるstdio FILE *
レイヤーによって追加されたバッファリングのみをフラッシュします。カーネルから見た基礎となるファイル自体は、このレベルではバッファリングされません。これは、fileno()
およびraw write()
を使用して、ioctl()
レイヤーをバイパスする書き込みも、open()
がフラッシュするような方法でバッファリングされないことを意味します。
他の人が指摘しているように、2つを混在させないでくださいしない。 <!> quot; raw <!> quot;を使用する必要がある場合fopen<()
などのI / O関数、次に<=>自分でファイルを直接、なしで <=>とstdioの友人を使用して
探しているのはfsync()関数(またはfdatasync()?)、またはopen()呼び出しでO_SYNCフラグを使用できるようです。
逆の方法(FILE *を既存のファイル記述子に関連付ける)を行う場合は、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);