このopen()対fopen()の全体的な誤解は、ARM上のLinux 2.6.14カーネルのバグのあるI2Cドライバーに起因することがわかります。動作するビットバッシュドライバーをバックポートすることで、ここで解決しようとしていた問題の根本原因を解決しました。
Linux(I2C)のシリアルデバイスドライバーの問題を見つけようとしています。デバイスでの書き込みと読み取りの間に時間指定されたOSの一時停止(スリープ)を追加することで、動作が(はるかに)良くなるようです。
余談:I2Cの性質は、マスターによって読み書きされる各バイトが、ワイヤの反対側のデバイス(スレーブ)によって確認されることです。非同期的に動作するドライバ-バスの動作と調和しないもの。 Anyhoo ...
flush確実に書き込む(固定期間の一時停止を使用するのではなく)、or何らかの方法で、書き込み/読み取りトランザクションに完了があることを、マルチスレッドに対応した方法でテストします。
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 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()
は、_FILE *
_オブジェクトによって管理されるstdio fopen()
レイヤーによって追加されたバッファリングのみをフラッシュします。カーネルから見た基礎となるファイル自体は、このレベルではバッファリングされません。これは、fileno()
および生のwrite()
を使用して_FILE *
_レイヤーをバイパスする書き込みも、fflush()
がフラッシュする方法でバッファリングされないことを意味します。 。
他の人が指摘したように、notを2つ混ぜてみてください。 ioctl()
などの「生の」I/O関数を使用する必要がある場合は、ファイルを直接open()
します。without using fopen<()
およびstdioの友人。
バッファリングを無効にしようとしましたか?
setvbuf(fd, NULL, _IONBF, 0);
あなたが探しているのは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);