首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Linux驱动程序中文件操作结构体file_operations中定义的操作函数open、read、write 和 release 等函数都有固定的参数形式和返回值类型,它们何时被调用,各参数意义是?

  • 25-03-05 04:42
  • 4223
  • 11124
blog.csdn.net

结构体file_operations的定义和各成员函数的作用

结构体file_operations 的完整定义可参考下面这篇博文:
http://iyenn.com/rec/1709536.html

因为定义比较长,所以这里只截取部分作为其简单定义,能把问题说明清楚就行。

简单定义如下:

struct file_operations {
    struct module *owner;              // 指向模块的指针,防止模块卸载时被调用
    loff_t (*llseek)(struct file *, loff_t, int);
    ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
    int (*open)(struct inode *, struct file *);
    int (*release)(struct inode *, struct file *);
    long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
    ...
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

从这个定义我们可以看出,file_operations 中最常用的 open、read、write 和 release 函数都有固定的参数形式和返回值类型,内核通过这些标准化的接口来调用驱动程序。这些函数的原型是固定的,驱动程序必须遵循这些原型,以便内核能够正确调用并与驱动程序进行交互。

它们的作用和何时被调用的情况分别如下:

  • open:当文件被打开时调用,比如系统内核函数open会调用它。
  • read:当文件被读取时调用,比如系统内核函数read会调用它。
  • write:当数据写入文件时调用,比如系统内核函数write会调用它。
  • release:当文件被关闭时调用,比如系统内核函数close会调用它,典型的语句为close(fd)。

各操作函数的参数意义

下面介绍这些函数的固定参数的意义。

下面这几个函数都或多或少的用到了参数inode和file,关于这两个参数的详细介绍,请参考下面这篇博文:
http://iyenn.com/rec/1709313.html

下面这几个函数都或多或少的用到了参数inode和file,关于这两个参数的详细介绍,请参考下面这篇博文:
http://iyenn.com/rec/1709313.html

下面这几个函数都或多或少的用到了参数inode和file,关于这两个参数的详细介绍,请参考下面这篇博文:
http://iyenn.com/rec/1709313.html

所以在下面对各参数的介绍中,就不再对参数inode和file作深入的介绍了。

1. open 操作函数

int (*open) (struct inode *inode, struct file *file);
  • 1
  • inode:指向文件的 inode 结构体,表示文件的元数据。通过 inode,驱动程序可以获取文件的状态、权限等信息。调用文件操作结构体file_operations中open操作函数时,内核会把系统中的inode实例赋给它。
  • file:指向与打开的文件相关的 struct file 结构体,包含与文件操作相关的状态信息,对于驱动程序,还可以通过它的成员private_data访问和管理文件的私有数据。调用文件操作结构体file_operations中open操作函数时,内核会把系统中的file实例赋给它。

open 成员函数在系统内核的open函数每次打开文件时被调用。你可以在这个函数中初始化一些设备的状态或分配资源。

2. read 操作函数

ssize_t (*read) (struct file *file, char __user *buf, size_t count, loff_t *offset);
  • 1
  • file:指向与打开的文件相关的 struct file 结构体。包含了文件的私有数据、状态等信息。
  • buf:指向用户空间的缓冲区,内核会将数据从内核空间复制到这个缓冲区。这个参数由系统内核的read函数传递给它,系统内核的read函数的原型为:ssize_t read(int fd, void *buf, size_t count);,这里面的参数void *buf会传递给 read 操作函数的参数char __user *buf。
  • count:表示请求读取的数据量。这个参数由系统内核的read函数传递给它,系统内核的read函数的原型为:ssize_t read(int fd, void *buf, size_t count);,这里面的参数size_t count会传递给 read 操作函数的参数size_t count。
  • offset:文件或设备的当前偏移量,内核会在每次读取操作时传递给驱动程序,并且在读取后自动更新它。这个量实际上存储在每个文件中struct file实例中的,调用文件操作结构体file_operations中的read操作函数时,系统会把这个量自动赋给它。

值得注意的是,这个函数的返回值类型是ssize_t,它表示从内核空间读取了多少个字节的数据到用户空间。它的返回值也会作为系统内核函数read的返回值。

read 成员函数在每次读取操作时被调用,比如系统内核函数read会调用它,驱动程序需要将数据从内核缓冲区复制到用户缓冲区。

3. write 操作函数

ssize_t (*write) (struct file *file, const char __user *buf, size_t count, loff_t *offset);
  • 1
  • file:指向与打开的文件相关的 struct file 结构体。
  • buf:指向用户空间的缓冲区,内核会将用户空间的数据从 buf 复制到内核空间。这个参数由系统内核的write函数传递给它,系统内核的write函数的原型为:ssize_t write(int fd, const void *buf, size_t count);,这里面的参数const void *buf会传递给 write 操作函数的参数const char __user *buf,。这里面的const表示缓冲区数据不能被修改,这是为了防止在写入数据的过程中,源数据被意外修改。
  • count:表示请求写入的数据量。这个参数由系统内核的write函数传递给它,系统内核的write函数的原型为:ssize_t write(int fd, const void *buf, size_t count);,这里面的参数size_t count会传递给 write 操作函数的参数size_t count。
  • offset:文件或设备的当前偏移量,内核会在每次写入操作时传递给驱动程序,并且在写入后自动更新它。这个量实际上存储在每个文件中struct file实例中的,调用文件操作结构体file_operations中的write操作函数时,系统会把这个量自动赋给它。

值得注意的是,这个函数的返回值类型是ssize_t,它表示写入了多个字节的数据到内核空间。它的返回值也会作为系统内核函数write的返回值。

write 函数在每次写入操作时被调用,比如系统内核函数write会调用它,驱动程序需要将数据从用户缓冲区复制到内核缓冲区或设备。

4. release 操作函数

int (*release) (struct inode *inode, struct file *file);
  • 1
  • inode:指向文件的 inode 结构体,表示文件的元数据。
  • file:指向与文件相关的 struct file 结构体,包含文件的私有数据和状态信息。

release 函数在文件关闭时被调用,比如系统内核函数close会调用它,典型的语句如close(fd)。驱动程序可以在这里清理资源,例如释放在 open 函数中分配的内存或关闭设备。

总结

是的,file_operations 中的 open、read、write 和 release 函数都具有固定的参数形式。这些函数的签名由内核定义,驱动程序必须按照这些签名来实现相应的操作。通过这些函数,内核与设备驱动之间能够进行标准化的交互,保证设备操作的一致性和可管理性。

昊虹嵌入式技术交流群
QQ群名片
注:本文转载自blog.csdn.net的昊虹AI笔记的文章"https://blog.csdn.net/wenhao_ir/article/details/144934865"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top