如何使用文件描述符刷新写入?

Jam*_*mie 35 c linux stdio i2c

事实证明,对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);
Run Code Online (Sandbox Code Playgroud)

我的问题是我需要使用,ioctl()而不使用流指针.即

int fd = open("filename",O_RDWR);
ioctl(fd,...);
Run Code Online (Sandbox Code Playgroud)

建议?

Dan*_*Xie 33

我想你想要的可能是什么

int fsync(int fd);
Run Code Online (Sandbox Code Playgroud)

要么

int fdatasync(int fd);
Run Code Online (Sandbox Code Playgroud)

fsync将文件从内核缓冲区刷新到磁盘.fdatasync除了元数据之外,它也会做.

  • 虽然这不是OP问题的解决方案,但对其他人提出主要标题问题是有用的.我**是通过fd写入磁盘,所以看看如何刷新内核缓冲区非常有帮助. (3认同)
  • 好的,i2c 开发节点不是页面缓冲的,因此不需要刷新/同步。设备驱动程序中的 fop 决定了实际执行的操作。 (2认同)

Aln*_*tak 26

你有两个选择:

  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);
Run Code Online (Sandbox Code Playgroud)

  • 让我们弄清楚术语-UNIX文件描述符是整数索引,应该被缓冲,以便立即进行写/读调用。对于“大”写入,它应该非常有效,而对于单字节写入,则效率很低。fopen为您提供了缓冲的I / O。使用打开/读取/写入。 (2认同)

unw*_*ind 9

fflush()仅刷新由stdio fopen()层添加的缓冲,由FILE *对象管理.如内核所见,底层文件本身不会在此级别进行缓冲.这意味着绕过该FILE *层的写入,使用fileno()和raw write(),也不会以fflush()刷新的方式进行缓冲.

正如其他人所指出的那样,尽量不要混淆两者.如果您需要使用"原始"I/O功能ioctl(),那么open()直接使用文件,而不使用fopen<()stdio中的朋友.


rus*_*tyx 5

您是否尝试过禁用缓冲?

setvbuf(fd, NULL, _IONBF, 0);
Run Code Online (Sandbox Code Playgroud)

  • 这只适用于 fopen(),不适用于 open()。最初的问题询问如何禁用 open() 调用的缓冲。 (2认同)
  • `open()` 没有缓冲区,它直接进入设备驱动程序。 (2认同)