事实certificate,对open()和fopen()的误解源于ARM上的Linux 2.6.14内核中有错误的I2C驱动程序。 支持一个工作位的巴士司机解决了我想在这里解决的问题的根源。
我试图找出在Linux(I2C)串行设备驱动程序的问题。 看来,通过添加定时操作系统暂停(睡觉)之间的写入和读取设备的事情工作…(很多)更好。
除此之外,I2C的本质是主机读取或写入的每个字节都由线路另一端(从机)的设备确认 – 暂停的改进促使我将驱动程序视为asynchronous工作 – 这是我与巴士的工作方式无法协调。 Anyhoo …
我想要刷新写入以确保(而不是使用固定持续时间的暂停), 或以某种方式testing写入/读取事务已经以multithreading友好的方式完成。
使用fflush(fd);
的麻烦fflush(fd);
是它需要'fd'是stream指针(而不是文件描述符),即
FILE * fd = fopen("filename","r+"); ... // do read and writes fflush(fd);
我的问题是,我需要使用ioctl()
,它不使用stream指针。 即
int fd = open("filename",O_RDWR); ioctl(fd,...);
build议?
你有两个选择:
使用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()
仅刷新由stdio fopen()
图层添加的缓冲区,由FILE *
对象管理。 内核所看到的底层文件本身并没有被缓存在这个级别上。 这意味着使用fileno()
和raw write()
来绕过FILE *
层的write()
也不会以fflush()
将会刷新的方式进行缓冲。
正如其他人所指出的, 不要混淆两者。 如果您需要使用“原始”I / O函数(如ioctl()
,则直接open()
该文件, 而不使用fopen<()
和来自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);