块设备在Linux上读写直接使用IO
最近有接触到一些嵌入式设备,因为长期用Go,对C语言比较生疏,那也就直接使用CGO直接对数据进行读写。当我以为是很简单的一件事的时候,但我发现Linux下,直接对块设备通信,发生了一些问题。
通过挂载的文件,和设备进行通信,但如果使用简单的open
和fopen
,并不能直接讲数据写到设备中,非常奇怪,先天然的就想到是不是缓存问题,当文件被close掉,数据则应该被落盘才对,怎么一点反应都没有呢?
询问过后发现,open函数中,有一个flag参数O_DIRECT
,可以绕过缓冲区高速缓存,直接进行IO操作。
直接IO:Linux允许应用程序在执行磁盘IO时绕过缓冲区高速缓存,从用户空间直接将数据传递到文件或磁盘设备,称为直接IO(direct IO)或者裸IO(raw IO)。
也就是这行图显示的:
上图中,左侧虚线方框中为可于任何时刻显式强制刷新各类缓冲区的调用。
右侧所示为促使刷新自动化的调用:通过禁用stdio的缓冲,和在文件输出类的系统调用中启用同步,从而使每个write()调用立刻刷新到磁盘。
但使用直接IO是有一些限制的:
- 用于传递数据的缓冲区,其内存边界必须对齐为块大小的整数倍
- 数据传输的开始点,即文件和设备的偏移量,必须是块大小的整数倍
- 待传递数据的长度必须是块大小的整数倍。
不遵守上述任一限制均将导致EINVAL错误。这些错误我也遇到了。
如何遵守呢?按照其规定,定义一个字节对齐,且长度为块大小的整数倍的buffer。即使数据长度不足buffer长度,写入数据时,也需要是直接写入整个buffer。
1 |
|
__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
aligned (alignment):该属性设定一个指定大小的对齐格式(以字节 为单位)
参考链接:
本文标题:块设备在Linux上读写直接使用IO
文章作者:小师
发布时间:2020-11-04
最后更新:2022-05-04
原始链接:chunlife.top/2020/11/04/块设备在Linux上读写直接使用IO/
版权声明:本站所有文章均采用知识共享署名4.0国际许可协议进行许可